LibreOffice Module sw (master)  1
vbadocumentproperties.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
20 #include <cppuhelper/implbase.hxx>
21 #include <sal/log.hxx>
22 #include <com/sun/star/document/XDocumentProperties.hpp>
23 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
24 #include <com/sun/star/beans/NamedValue.hpp>
25 #include <com/sun/star/beans/XPropertyContainer.hpp>
26 #include <ooo/vba/word/WdBuiltInProperty.hpp>
27 #include <ooo/vba/office/MsoDocProperties.hpp>
28 #include <tools/diagnose_ex.h>
29 #include <memory>
30 #include "wordvbahelper.hxx"
31 #include <fesh.hxx>
32 #include <docsh.hxx>
33 using namespace ::ooo::vba;
34 using namespace css;
35 
37 static sal_Int8 lcl_toMSOPropType( const uno::Type& aType )
38 {
39  sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString;
40 
41  switch ( aType.getTypeClass() )
42  {
43  case uno::TypeClass_BOOLEAN:
44  msoType = office::MsoDocProperties::msoPropertyTypeBoolean;
45  break;
46  case uno::TypeClass_FLOAT:
47  msoType = office::MsoDocProperties::msoPropertyTypeFloat;
48  break;
49  case uno::TypeClass_STRUCT: // Assume date
50  msoType = office::MsoDocProperties::msoPropertyTypeDate;
51  break;
52  case uno::TypeClass_BYTE:
53  case uno::TypeClass_SHORT:
54  case uno::TypeClass_LONG:
55  case uno::TypeClass_HYPER:
56  msoType = office::MsoDocProperties::msoPropertyTypeNumber;
57  break;
58  default:
59  throw lang::IllegalArgumentException();
60  }
61  return msoType;
62 }
63 
65 {
66 protected:
67  uno::Reference< frame::XModel > m_xModel;
68  uno::Reference<document::XDocumentProperties> m_xDocProps;
69 public:
70  explicit PropertGetSetHelper( const uno::Reference< frame::XModel >& xModel ):m_xModel( xModel )
71  {
72  uno::Reference<document::XDocumentPropertiesSupplier> const
73  xDocPropSupp(m_xModel, uno::UNO_QUERY_THROW);
74  m_xDocProps.set(xDocPropSupp->getDocumentProperties(),
75  uno::UNO_SET_THROW);
76  }
77  virtual ~PropertGetSetHelper() {}
78  virtual uno::Any getPropertyValue( const OUString& rPropName ) = 0;
79  virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) = 0;
80  uno::Reference< beans::XPropertySet > getUserDefinedProperties() {
81  return uno::Reference<beans::XPropertySet>(
82  m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
83  }
84 
85 };
86 
88 {
89 public:
90  explicit BuiltinPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel )
91  {
92  }
93  virtual uno::Any getPropertyValue( const OUString& rPropName ) override
94  {
95  if ( rPropName == "EditingDuration" )
96  {
97  sal_Int32 const nSecs = m_xDocProps->getEditingDuration();
98  return uno::makeAny( nSecs/60 ); // minutes
99  }
100  else if ("Title" == rPropName)
101  {
102  return uno::makeAny(m_xDocProps->getTitle());
103  }
104  else if ("Subject" == rPropName)
105  {
106  return uno::makeAny(m_xDocProps->getSubject());
107  }
108  else if ("Author" == rPropName)
109  {
110  return uno::makeAny(m_xDocProps->getAuthor());
111  }
112  else if ("Keywords" == rPropName)
113  {
114  return uno::makeAny(m_xDocProps->getKeywords());
115  }
116  else if ("Description" == rPropName)
117  {
118  return uno::makeAny(m_xDocProps->getDescription());
119  }
120  else if ("Template" == rPropName)
121  {
122  return uno::makeAny(m_xDocProps->getTemplateName());
123  }
124  else if ("ModifiedBy" == rPropName)
125  {
126  return uno::makeAny(m_xDocProps->getModifiedBy());
127  }
128  else if ("Generator" == rPropName)
129  {
130  return uno::makeAny(m_xDocProps->getGenerator());
131  }
132  else if ("PrintDate" == rPropName)
133  {
134  return uno::makeAny(m_xDocProps->getPrintDate());
135  }
136  else if ("CreationDate" == rPropName)
137  {
138  return uno::makeAny(m_xDocProps->getCreationDate());
139  }
140  else if ("ModifyDate" == rPropName)
141  {
142  return uno::makeAny(m_xDocProps->getModificationDate());
143  }
144  else if ("AutoloadURL" == rPropName)
145  {
146  return uno::makeAny(m_xDocProps->getAutoloadURL());
147  }
148  else
149  {
150  // fall back to user-defined properties
151  return getUserDefinedProperties()->getPropertyValue(rPropName);
152  }
153  }
154  virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
155  {
156  if ("EditingDuration" == rPropName)
157  {
158  sal_Int32 nMins = 0;
159  if (aValue >>= nMins)
160  {
161  m_xDocProps->setEditingDuration(nMins * 60); // convert minutes
162  }
163  }
164  else if ("Title" == rPropName)
165  {
166  OUString str;
167  if (aValue >>= str)
168  {
169  m_xDocProps->setTitle(str);
170  }
171  }
172  else if ("Subject" == rPropName)
173  {
174  OUString str;
175  if (aValue >>= str)
176  {
177  m_xDocProps->setSubject(str);
178  }
179  }
180  else if ("Author" == rPropName)
181  {
182  OUString str;
183  if (aValue >>= str)
184  {
185  m_xDocProps->setAuthor(str);
186  }
187  }
188  else if ("Keywords" == rPropName)
189  {
190  uno::Sequence<OUString> keywords;
191  if (aValue >>= keywords)
192  {
193  m_xDocProps->setKeywords(keywords);
194  }
195  }
196  else if ("Description" == rPropName)
197  {
198  OUString str;
199  if (aValue >>= str)
200  {
201  m_xDocProps->setDescription(str);
202  }
203  }
204  else if ("Template" == rPropName)
205  {
206  OUString str;
207  if (aValue >>= str)
208  {
209  m_xDocProps->setTemplateName(str);
210  }
211  }
212  else if ("ModifiedBy" == rPropName)
213  {
214  OUString str;
215  if (aValue >>= str)
216  {
217  m_xDocProps->setModifiedBy(str);
218  }
219  }
220  else if ("Generator" == rPropName)
221  {
222  OUString str;
223  if (aValue >>= str)
224  {
225  return m_xDocProps->setGenerator(str);
226  }
227  }
228  else if ("PrintDate" == rPropName)
229  {
230  util::DateTime dt;
231  if (aValue >>= dt)
232  {
233  m_xDocProps->setPrintDate(dt);
234  }
235  }
236  else if ("CreationDate" == rPropName)
237  {
238  util::DateTime dt;
239  if (aValue >>= dt)
240  {
241  m_xDocProps->setCreationDate(dt);
242  }
243  }
244  else if ("ModifyDate" == rPropName)
245  {
246  util::DateTime dt;
247  if (aValue >>= dt)
248  {
249  m_xDocProps->setModificationDate(dt);
250  }
251  }
252  else if ("AutoloadURL" == rPropName)
253  {
254  OUString str;
255  if (aValue >>= str)
256  {
257  m_xDocProps->setAutoloadURL(str);
258  }
259  }
260  else
261  {
262  // fall back to user-defined properties
263  getUserDefinedProperties()->setPropertyValue(rPropName, aValue);
264  }
265  }
266 };
267 
269 {
270 public:
271  explicit CustomPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :BuiltinPropertyGetSetHelper( xModel )
272  {
273  }
274  virtual uno::Any getPropertyValue( const OUString& rPropName ) override
275  {
276  return getUserDefinedProperties()->getPropertyValue(rPropName);
277  }
278  virtual void setPropertyValue(
279  const OUString& rPropName, const uno::Any& rValue) override
280  {
281  return getUserDefinedProperties()->setPropertyValue(rPropName, rValue);
282  }
283 };
284 
286 {
288  uno::Reference< beans::XPropertySet > mxModelProps;
289 public:
290  explicit StatisticPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( nullptr )
291  {
292  mxModelProps.set( m_xModel, uno::UNO_QUERY_THROW );
293  mpDocShell = word::getDocShell( xModel );
294  }
295  virtual uno::Any getPropertyValue( const OUString& rPropName ) override
296  {
297  try
298  {
299  // Characters, ParagraphCount & WordCount are available from
300  // the model ( and additionally these also update the statics object )
301  return mxModelProps->getPropertyValue( rPropName );
302  }
303  catch (const uno::Exception&)
304  {
305  TOOLS_WARN_EXCEPTION("sw.vba", "");
306  }
307  uno::Any aReturn;
308  if ( rPropName == "LineCount" ) // special processing needed
309  {
310  if ( mpDocShell )
311  {
312  SwFEShell* pFEShell = mpDocShell->GetFEShell();
313  if(pFEShell)
314  {
315  aReturn <<= pFEShell->GetLineCount();
316  }
317  }
318  }
319  else
320  {
321  uno::Sequence< beans::NamedValue > const stats(
322  m_xDocProps->getDocumentStatistics());
323 
324  auto pStat = std::find_if(stats.begin(), stats.end(),
325  [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
326  if (pStat == stats.end())
327  throw uno::RuntimeException(); // bad Property
328 
329  aReturn = pStat->Value;
330  }
331  return aReturn;
332  }
333 
334  virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
335  {
336  uno::Sequence< beans::NamedValue > stats(
337  m_xDocProps->getDocumentStatistics());
338 
339  auto pStat = std::find_if(stats.begin(), stats.end(),
340  [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
341  if (pStat != stats.end())
342  {
343  pStat->Value = aValue;
344  m_xDocProps->setDocumentStatistics(stats);
345  }
346  }
347 };
348 
350 {
351 public:
352  OUString msMSODesc;
353  OUString msOOOPropName;
354  std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
355 
356  static DocPropInfo createDocPropInfo( const OUString& sDesc, const OUString& sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
357  {
358  DocPropInfo aItem;
359  aItem.msMSODesc = sDesc;
360  aItem.msOOOPropName = sPropName;
361  aItem.mpPropGetSetHelper = rHelper;
362  return aItem;
363  }
364 
365  static DocPropInfo createDocPropInfo( const sal_Char* sDesc, const sal_Char* sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
366  {
367  return createDocPropInfo( OUString::createFromAscii( sDesc ), OUString::createFromAscii( sPropName ), rHelper );
368  }
370  {
371  if ( mpPropGetSetHelper.get() )
372  return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
373  return uno::Any();
374  }
375  void setValue( const uno::Any& rValue )
376  {
377  if ( mpPropGetSetHelper.get() )
378  mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
379  }
380  uno::Reference< beans::XPropertySet > getUserDefinedProperties()
381  {
382  uno::Reference< beans::XPropertySet > xProps;
383  if ( mpPropGetSetHelper.get() )
384  return mpPropGetSetHelper->getUserDefinedProperties();
385  return xProps;
386  }
387 };
388 
389 typedef std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;
390 
392 {
394 
395 public:
396  explicit BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel )
397  {
398  std::shared_ptr< PropertGetSetHelper > aStandardHelper( new BuiltinPropertyGetSetHelper( xModel ) );
399  std::shared_ptr< PropertGetSetHelper > aUsingStatsHelper( new StatisticPropertyGetSetHelper( xModel ) );
400 
401  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper );
402  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper );
403  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper );
404  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper );
405  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper );
406  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper );
407  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
408  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
409  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
410  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
411  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper );
412  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper );
413  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct
414  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ?
415  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ?
416  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ?
417  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist
418  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in
419  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist
420  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in
421  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in
422  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyBytes ] = DocPropInfo::createDocPropInfo( "Number of bytes", "", aStandardHelper ); // doesn't seem to exist - size on disk exists ( for an already saved document ) perhaps it will do ( or we need something else )
423  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling
424  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling
425  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist
426  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist
427  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper ); // doesn't seem to exist
428  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist
429  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper );
430  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported
431  }
432 
433  MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
434 };
435 
437 
439 {
440 protected:
442 public:
443  SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
444  // XDocumentProperty
445  virtual void SAL_CALL Delete( ) override;
446  virtual OUString SAL_CALL getName( ) override;
447  virtual void SAL_CALL setName( const OUString& Name ) override;
448  virtual ::sal_Int8 SAL_CALL getType( ) override;
449  virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
450  virtual sal_Bool SAL_CALL getLinkToContent( ) override;
451  virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
452  virtual uno::Any SAL_CALL getValue( ) override;
453  virtual void SAL_CALL setValue( const uno::Any& Value ) override;
454  virtual OUString SAL_CALL getLinkSource( ) override;
455  virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
456  //XDefaultProperty
457  virtual OUString SAL_CALL getDefaultPropertyName( ) override { return "Value"; }
458  // XHelperInterface
459  virtual OUString getServiceImplName() override;
460  virtual uno::Sequence<OUString> getServiceNames() override;
461 };
462 
464 {
465 public:
466 
467  SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
468 
469  virtual sal_Bool SAL_CALL getLinkToContent( ) override;
470  virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
471 
472  virtual OUString SAL_CALL getLinkSource( ) override;
473  virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
474  virtual void SAL_CALL Delete( ) override;
475  virtual void SAL_CALL setName( const OUString& Name ) override;
476  virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
477 
478 };
479 
480 SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
481 {
482 }
483 
484 sal_Bool
486 {
487  // #FIXME we need to store the link content somewhere
488  return false;
489 }
490 
491 void
493 {
494 }
495 
496 OUString
498 {
499  // #FIXME we need to store the link content somewhere
500  return OUString();
501 }
502 
503 void
504 SwVbaCustomDocumentProperty::setLinkSource( const OUString& /*rsLinkContent*/ )
505 {
506  // #FIXME we need to store the link source somewhere
507 }
508 
509 void SAL_CALL
510 SwVbaCustomDocumentProperty::setName( const OUString& /*Name*/ )
511 {
512  // setName on existing property ?
513  // #FIXME
514  // do we need to delete existing property and create a new one?
515 }
516 
517 void SAL_CALL
519 {
520  // setType, do we need to do a conversion?
521  // #FIXME the underlying value needs to be changed to the new type
522 }
523 
524 void SAL_CALL
526 {
527  uno::Reference< beans::XPropertyContainer > xContainer(
528  mPropInfo.getUserDefinedProperties(), uno::UNO_QUERY_THROW);
529  xContainer->removeProperty( getName() );
530 }
531 
532 SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo( rInfo )
533 {
534 }
535 
536 void SAL_CALL
538 {
539  // not valid for Builtin
540  throw uno::RuntimeException();
541 }
542 
543 OUString SAL_CALL
545 {
546  return mPropInfo.msMSODesc;
547 }
548 
549 void SAL_CALL
551 {
552  // not valid for Builtin
553  throw uno::RuntimeException();
554 }
555 
556 ::sal_Int8 SAL_CALL
558 {
559  return lcl_toMSOPropType( getValue().getValueType() );
560 }
561 
562 void SAL_CALL
564 {
565  // not valid for Builtin
566  throw uno::RuntimeException();
567 }
568 
569 sal_Bool SAL_CALL
571 {
572  return false; // built-in always false
573 }
574 
575 void SAL_CALL
577 {
578  // not valid for Builtin
579  throw uno::RuntimeException();
580 }
581 
582 uno::Any SAL_CALL
584 {
585  uno::Any aRet = mPropInfo.getValue();
586  if ( !aRet.hasValue() )
587  throw uno::RuntimeException();
588  return aRet;
589 }
590 
591 void SAL_CALL
593 {
594  mPropInfo.setValue( Value );
595 }
596 
597 OUString SAL_CALL
599 {
600  // not valid for Builtin
601  throw uno::RuntimeException();
602 }
603 
604 void SAL_CALL
605 SwVbaBuiltInDocumentProperty::setLinkSource( const OUString& /*LinkSource*/ )
606 {
607  // not valid for Builtin
608  throw uno::RuntimeException();
609 }
610 
611 OUString
613 {
614  return "SwVbaBuiltinDocumentProperty";
615 }
616 
617 uno::Sequence<OUString>
619 {
620  static uno::Sequence< OUString > const aServiceNames
621  {
622  "ooo.vba.word.DocumentProperty"
623  };
624  return aServiceNames;
625 }
626 typedef ::cppu::WeakImplHelper< css::container::XIndexAccess
627  ,css::container::XNameAccess
628  ,css::container::XEnumerationAccess
630 
631 typedef std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;
632 
633 class DocPropEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration >
634 {
636  DocProps::iterator mIt;
637 public:
638 
639  explicit DocPropEnumeration( const DocProps& rProps ) : mDocProps( rProps ), mIt( mDocProps.begin() ) {}
640  virtual sal_Bool SAL_CALL hasMoreElements( ) override
641  {
642  return mIt != mDocProps.end();
643  }
644  virtual uno::Any SAL_CALL nextElement( ) override
645  {
646  if ( !hasMoreElements() )
647  throw container::NoSuchElementException();
648  return uno::makeAny( mIt++->second );
649  }
650 };
651 
652 typedef std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName;
653 
655 {
656 protected:
657 
658  uno::Reference< frame::XModel > m_xModel;
659 
662 
663  public:
664  BuiltInPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : m_xModel( xModel )
665  {
666  BuiltInIndexHelper builtIns( m_xModel );
667  for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
668  {
669  mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
670  mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
671  }
672  }
673 // XIndexAccess
674  virtual ::sal_Int32 SAL_CALL getCount( ) override
675  {
676  return mDocProps.size();
677  }
678  virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
679  {
680  // correct the correct by the base class for 1 based indices
681  DocProps::iterator it = mDocProps.find( ++Index );
682  if ( it == mDocProps.end() )
683  throw lang::IndexOutOfBoundsException();
684  return uno::makeAny( it->second );
685  }
686  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
687  {
688  if ( !hasByName( aName ) )
689  throw container::NoSuchElementException();
690  DocPropsByName::iterator it = mNamedDocProps.find( aName );
691  return uno::Any( it->second );
692 
693  }
694  virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
695  {
696  uno::Sequence< OUString > aNames( getCount() );
697  OUString* pName = aNames.getArray();
698  for (const auto& rEntry : mNamedDocProps)
699  {
700  *pName = rEntry.first;
701  ++pName;
702  }
703  return aNames;
704  }
705 
706  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
707  {
708  DocPropsByName::iterator it = mNamedDocProps.find( aName );
709  if ( it == mNamedDocProps.end() )
710  return false;
711  return true;
712  }
713 // XElementAccess
714  virtual uno::Type SAL_CALL getElementType( ) override
715  {
717  }
718  virtual sal_Bool SAL_CALL hasElements( ) override
719  {
720  return !mDocProps.empty();
721  }
722  virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
723  {
724  return new DocPropEnumeration( mDocProps );
725  }
726 };
727 
728 SwVbaBuiltinDocumentProperties::SwVbaBuiltinDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaDocumentproperties_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( new BuiltInPropertiesImpl( xParent, xContext, xModel ) ) )
729 {
730 }
731 
732 uno::Reference< XDocumentProperty > SAL_CALL
733 SwVbaBuiltinDocumentProperties::Add( const OUString& /*Name*/, sal_Bool /*LinkToContent*/, ::sal_Int8 /*Type*/, const uno::Any& /*value*/, const uno::Any& /*LinkSource*/ )
734 {
735  throw uno::RuntimeException( "not supported for Builtin properties" );
736 }
737 
738 // XEnumerationAccess
739 uno::Type SAL_CALL
741 {
743 }
744 
745 uno::Reference< container::XEnumeration > SAL_CALL
747 {
748  uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
749  return xEnumAccess->createEnumeration();
750 }
751 
752 // ScVbaCollectionBaseImpl
753 uno::Any
755 {
756  // pass through
757  return aSource;
758 }
759 
760 // XHelperInterface
761 OUString
763 {
764  return "SwVbaBuiltinDocumentProperties";
765 }
766 
767 uno::Sequence<OUString>
769 {
770  static uno::Sequence< OUString > const aServiceNames
771  {
772  "ooo.vba.word.DocumentProperties"
773  };
774  return aServiceNames;
775 }
776 
778 {
779  uno::Reference< XHelperInterface > m_xParent;
780  uno::Reference< uno::XComponentContext > m_xContext;
781  uno::Reference< frame::XModel > m_xModel;
782  uno::Reference< beans::XPropertySet > mxUserDefinedProp;
783  std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
784 public:
785  CustomPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : m_xParent( xParent ), m_xContext( xContext ), m_xModel( xModel )
786  {
787  // suck in the document( custom ) properties
788  mpPropGetSetHelper.reset( new CustomPropertyGetSetHelper( m_xModel ) );
789  mxUserDefinedProp.set(mpPropGetSetHelper->getUserDefinedProperties(),
790  uno::UNO_SET_THROW);
791  };
792  // XIndexAccess
793  virtual ::sal_Int32 SAL_CALL getCount( ) override
794  {
795  return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
796  }
797 
798  virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
799  {
800  uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
801  if ( Index >= aProps.getLength() )
802  throw lang::IndexOutOfBoundsException();
803  // How to determine type e.g Date? ( com.sun.star.util.DateTime )
804  DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
805  return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
806  }
807 
808  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
809  {
810  if ( !hasByName( aName ) )
811  throw container::NoSuchElementException();
812 
813  DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
814  return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
815  }
816 
817  virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
818  {
819  uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
820  uno::Sequence< OUString > aNames( aProps.getLength() );
821  std::transform(aProps.begin(), aProps.end(), aNames.begin(),
822  [](const beans::Property& rProp) -> OUString { return rProp.Name; });
823  return aNames;
824  }
825 
826  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
827  {
828  SAL_INFO("sw.vba", "hasByName(" << aName << ") returns " << mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
829  return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
830  }
831 
832  // XElementAccess
833  virtual uno::Type SAL_CALL getElementType( ) override
834  {
836  }
837 
838  virtual sal_Bool SAL_CALL hasElements( ) override
839  {
840  return getCount() > 0;
841  }
842 
843  virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
844  {
845  // create a map of properties ( the key doesn't matter )
846  SAL_INFO("sw.vba", "Creating an enumeration");
847  sal_Int32 key = 0;
848  sal_Int32 nElem = getCount();
849  DocProps simpleDocPropSnapShot;
850  for ( ; key < nElem; ++key )
851  simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
852  SAL_INFO("sw.vba", "After creating the enumeration");
853  return new DocPropEnumeration( simpleDocPropSnapShot );
854  }
855 
856  void addProp( const OUString& Name, const uno::Any& Value )
857  {
858  uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
859  // TODO fixme, perform the necessary Type Value conversions
860  xContainer->addProperty( Name, sal_Int16(128), Value );
861  }
862 
863 };
864 
865 SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
866 {
867  // replace the m_xIndexAccess implementation ( we need a virtual init )
868  m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
869  m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
870 }
871 
872 uno::Reference< XDocumentProperty > SAL_CALL
873 SwVbaCustomDocumentProperties::Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 /*Type*/, const uno::Any& Value, const uno::Any& LinkSource )
874 {
875  CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
876  uno::Reference< XDocumentProperty > xDocProp;
877  if ( pCustomProps )
878  {
879  OUString sLinkSource;
880  pCustomProps->addProp( Name, Value );
881 
882  xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
883  xDocProp->setLinkToContent( LinkToContent );
884 
885  if ( LinkSource >>= sLinkSource )
886  xDocProp->setLinkSource( sLinkSource );
887  }
888  return xDocProp;
889 }
890 
891 // XHelperInterface
892 OUString
894 {
895  return "SwVbaCustomDocumentProperties";
896 }
897 
898 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName
RegError REGISTRY_CALLTYPE setValue(RegKeyHandle hKey, rtl_uString *keyName, RegValueType valueType, RegValue pData, sal_uInt32 valueSize)
virtual uno::Any SAL_CALL getValue() override
virtual uno::Type SAL_CALL getElementType() override
Type
InheritedHelperInterfaceWeakImpl< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE
virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() override
virtual OUString getServiceImplName() override
sal_uInt16 GetLineCount()
Definition: editsh.cxx:848
bool hasValue()
static sal_Int8 lcl_toMSOPropType(const uno::Type &aType)
virtual void SAL_CALL setName(const OUString &Name) override
void setValue(const uno::Any &rValue)
PropertGetSetHelper(const uno::Reference< frame::XModel > &xModel)
BuiltinPropertyGetSetHelper(const uno::Reference< frame::XModel > &xModel)
virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add(const OUString &Name, sal_Bool LinkToContent,::sal_Int8 Type, const css::uno::Any &Value, const css::uno::Any &LinkSource) override
uno::Reference< frame::XModel > m_xModel
bool getType(BSTR name, Type &type)
virtual ::sal_Int32 SAL_CALL getCount() override
virtual uno::Any getPropertyValue(const OUString &rPropName) override
virtual ::sal_Int32 SAL_CALL getCount() override
MSOIndexToOODocPropInfo m_docPropInfoMap
css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess
virtual void SAL_CALL Delete() override
signed char sal_Int8
virtual css::uno::Type SAL_CALL getElementType() override
virtual OUString getServiceImplName() override
virtual uno::Sequence< OUString > SAL_CALL getElementNames() override
css::beans::Optional< css::uno::Any > getValue(OUString const &id)
SwVbaCustomDocumentProperties(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel > &xDocument)
Reference
virtual sal_Bool SAL_CALL getLinkToContent() override
uno::Reference< beans::XPropertySet > getUserDefinedProperties()
OUString Name
virtual void SAL_CALL setValue(const uno::Any &Value) override
::cppu::WeakImplHelper< css::container::XIndexAccess,css::container::XNameAccess,css::container::XEnumerationAccess > PropertiesImpl_BASE
uno::Reference< frame::XModel > m_xModel
uno::Reference< beans::XPropertySet > mxUserDefinedProp
virtual uno::Any SAL_CALL getByIndex(::sal_Int32 Index) override
virtual uno::Sequence< OUString > SAL_CALL getElementNames() override
enumrange< T >::Iterator begin(enumrange< T >)
virtual uno::Any getPropertyValue(const OUString &rPropName) override
virtual void SAL_CALL setLinkToContent(sal_Bool LinkToContent) override
char sal_Char
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
virtual void SAL_CALL setType(::sal_Int8 Type) override
virtual css::uno::Sequence< OUString > getServiceNames() override
virtual OUString getServiceImplName() override
virtual css::uno::Reference< ::ooo::vba::XDocumentProperty > SAL_CALL Add(const OUString &Name, sal_Bool LinkToContent,::sal_Int8 Type, const css::uno::Any &Value, const css::uno::Any &LinkSource) override
virtual void setPropertyValue(const OUString &rPropName, const uno::Any &aValue) override
BuiltInIndexHelper(const uno::Reference< frame::XModel > &xModel)
virtual void SAL_CALL setName(const OUString &Name) override
virtual OUString SAL_CALL getName() override
virtual void setPropertyValue(const OUString &rPropName, const uno::Any &aValue) override
#define TOOLS_WARN_EXCEPTION(area, stream)
virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() override
SwVbaCustomDocumentProperty(const uno::Reference< ov::XHelperInterface > &xParent, const uno::Reference< uno::XComponentContext > &xContext, const DocPropInfo &rInfo)
virtual sal_Bool SAL_CALL hasElements() override
std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps
virtual uno::Any SAL_CALL getByIndex(::sal_Int32 Index) override
virtual sal_Bool SAL_CALL getLinkToContent() override
virtual void setPropertyValue(const OUString &rPropName, const uno::Any &rValue) override
css::uno::Reference< css::container::XNameAccess > m_xNameAccess
virtual OUString SAL_CALL getLinkSource() override
unsigned char sal_Bool
virtual uno::Sequence< OUString > getServiceNames() override
Object Value
DocPropEnumeration(const DocProps &rProps)
virtual void SAL_CALL Delete() override
css::uno::Type const & get()
sal_uInt16 sal_Char * pName
virtual void SAL_CALL setLinkToContent(sal_Bool LinkToContent) override
virtual css::uno::Any createCollectionObject(const css::uno::Any &aSource) override
tuple index
bool setPropertyValue(uno::Sequence< beans::PropertyValue > &aProp, const OUString &aName, const uno::Any &aValue)
virtual uno::Type SAL_CALL getElementType() override
virtual ::sal_Int8 SAL_CALL getType() override
MSOIndexToOODocPropInfo & getDocPropInfoMap()
uno::Reference< beans::XPropertySet > mxModelProps
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
virtual OUString SAL_CALL getLinkSource() override
uno::Reference< XHelperInterface > m_xParent
virtual uno::Any SAL_CALL getByName(const OUString &aName) override
SwDocShell * getDocShell(const uno::Reference< frame::XModel > &xModel)
void addProp(const OUString &Name, const uno::Any &Value)
static DocPropInfo createDocPropInfo(const sal_Char *sDesc, const sal_Char *sPropName, std::shared_ptr< PropertGetSetHelper > const &rHelper)
uno::Reference< document::XDocumentProperties > m_xDocProps
BuiltInPropertiesImpl(const uno::Reference< XHelperInterface > &xParent, const uno::Reference< uno::XComponentContext > &xContext, const uno::Reference< frame::XModel > &xModel)
SwVbaBuiltinDocumentProperties(const css::uno::Reference< ov::XHelperInterface > &xParent, const css::uno::Reference< css::uno::XComponentContext > &xContext, const css::uno::Reference< css::frame::XModel > &xDocument)
virtual sal_Bool SAL_CALL hasMoreElements() override
virtual uno::Any SAL_CALL nextElement() override
#define SAL_INFO(area, stream)
virtual void SAL_CALL setLinkSource(const OUString &LinkSource) override
CustomPropertiesImpl(const uno::Reference< XHelperInterface > &xParent, const uno::Reference< uno::XComponentContext > &xContext, const uno::Reference< frame::XModel > &xModel)
std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper
SwFEShell * GetFEShell()
For Core - it knows the DocShell but not the WrtShell!
Definition: docsh.cxx:1244
static DocPropInfo createDocPropInfo(const OUString &sDesc, const OUString &sPropName, std::shared_ptr< PropertGetSetHelper > const &rHelper)
virtual OUString SAL_CALL getDefaultPropertyName() override
virtual uno::Any getPropertyValue(const OUString &rPropName) override
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
uno::Reference< frame::XModel > m_xModel
virtual uno::Any SAL_CALL getByName(const OUString &aName) override
SwVbaBuiltInDocumentProperty(const uno::Reference< ov::XHelperInterface > &xParent, const uno::Reference< uno::XComponentContext > &xContext, const DocPropInfo &rInfo)
StatisticPropertyGetSetHelper(const uno::Reference< frame::XModel > &xModel)
CustomPropertyGetSetHelper(const uno::Reference< frame::XModel > &xModel)
virtual sal_Bool SAL_CALL hasElements() override
uno::Reference< beans::XPropertySet > getUserDefinedProperties()
uno::Reference< uno::XComponentContext > m_xContext
virtual void SAL_CALL setType(::sal_Int8 Type) override
std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper
void set(css::uno::UnoInterfaceReference const &value)
virtual void SAL_CALL setLinkSource(const OUString &LinkSource) override