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  css::uno::Any ex( cppu::getCaughtException() );
306  SAL_WARN("sw.vba", "Got exception " << exceptionToString(ex));
307  }
308  uno::Any aReturn;
309  if ( rPropName == "LineCount" ) // special processing needed
310  {
311  if ( mpDocShell )
312  {
313  SwFEShell* pFEShell = mpDocShell->GetFEShell();
314  if(pFEShell)
315  {
316  aReturn <<= pFEShell->GetLineCount();
317  }
318  }
319  }
320  else
321  {
322  uno::Sequence< beans::NamedValue > const stats(
323  m_xDocProps->getDocumentStatistics());
324 
325  sal_Int32 nLen = stats.getLength();
326  bool bFound = false;
327  for ( sal_Int32 index = 0; index < nLen && !bFound ; ++index )
328  {
329  if ( rPropName == stats[ index ].Name )
330  {
331  aReturn = stats[ index ].Value;
332  bFound = true;
333  }
334  }
335  if ( !bFound )
336  throw uno::RuntimeException(); // bad Property
337  }
338  return aReturn;
339  }
340 
341  virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
342  {
343  uno::Sequence< beans::NamedValue > stats(
344  m_xDocProps->getDocumentStatistics());
345 
346  sal_Int32 nLen = stats.getLength();
347  for ( sal_Int32 index = 0; index < nLen; ++index )
348  {
349  if ( rPropName == stats[ index ].Name )
350  {
351  stats[ index ].Value = aValue;
352  m_xDocProps->setDocumentStatistics(stats);
353  break;
354  }
355  }
356  }
357 };
358 
360 {
361 public:
362  OUString msMSODesc;
363  OUString msOOOPropName;
364  std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
365 
366  static DocPropInfo createDocPropInfo( const OUString& sDesc, const OUString& sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
367  {
368  DocPropInfo aItem;
369  aItem.msMSODesc = sDesc;
370  aItem.msOOOPropName = sPropName;
371  aItem.mpPropGetSetHelper = rHelper;
372  return aItem;
373  }
374 
375  static DocPropInfo createDocPropInfo( const sal_Char* sDesc, const sal_Char* sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
376  {
377  return createDocPropInfo( OUString::createFromAscii( sDesc ), OUString::createFromAscii( sPropName ), rHelper );
378  }
380  {
381  if ( mpPropGetSetHelper.get() )
382  return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
383  return uno::Any();
384  }
385  void setValue( const uno::Any& rValue )
386  {
387  if ( mpPropGetSetHelper.get() )
388  mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
389  }
390  uno::Reference< beans::XPropertySet > getUserDefinedProperties()
391  {
392  uno::Reference< beans::XPropertySet > xProps;
393  if ( mpPropGetSetHelper.get() )
394  return mpPropGetSetHelper->getUserDefinedProperties();
395  return xProps;
396  }
397 };
398 
399 typedef std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;
400 
402 {
404 
405 public:
406  explicit BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel )
407  {
408  std::shared_ptr< PropertGetSetHelper > aStandardHelper( new BuiltinPropertyGetSetHelper( xModel ) );
409  std::shared_ptr< PropertGetSetHelper > aUsingStatsHelper( new StatisticPropertyGetSetHelper( xModel ) );
410 
411  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper );
412  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper );
413  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper );
414  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper );
415  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper );
416  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper );
417  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
418  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
419  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
420  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
421  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper );
422  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper );
423  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct
424  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ?
425  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ?
426  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ?
427  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist
428  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in
429  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist
430  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in
431  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in
432  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 )
433  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling
434  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling
435  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist
436  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist
437  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper ); // doesn't seem to exist
438  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist
439  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper );
440  m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported
441  }
442 
443  MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
444 };
445 
447 
449 {
450 protected:
452 public:
453  SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
454  // XDocumentProperty
455  virtual void SAL_CALL Delete( ) override;
456  virtual OUString SAL_CALL getName( ) override;
457  virtual void SAL_CALL setName( const OUString& Name ) override;
458  virtual ::sal_Int8 SAL_CALL getType( ) override;
459  virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
460  virtual sal_Bool SAL_CALL getLinkToContent( ) override;
461  virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
462  virtual uno::Any SAL_CALL getValue( ) override;
463  virtual void SAL_CALL setValue( const uno::Any& Value ) override;
464  virtual OUString SAL_CALL getLinkSource( ) override;
465  virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
466  //XDefaultProperty
467  virtual OUString SAL_CALL getDefaultPropertyName( ) override { return OUString("Value"); }
468  // XHelperInterface
469  virtual OUString getServiceImplName() override;
470  virtual uno::Sequence<OUString> getServiceNames() override;
471 };
472 
474 {
475 public:
476 
477  SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
478 
479  virtual sal_Bool SAL_CALL getLinkToContent( ) override;
480  virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
481 
482  virtual OUString SAL_CALL getLinkSource( ) override;
483  virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
484  virtual void SAL_CALL Delete( ) override;
485  virtual void SAL_CALL setName( const OUString& Name ) override;
486  virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
487 
488 };
489 
490 SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
491 {
492 }
493 
494 sal_Bool
496 {
497  // #FIXME we need to store the link content somewhere
498  return false;
499 }
500 
501 void
503 {
504 }
505 
506 OUString
508 {
509  // #FIXME we need to store the link content somewhere
510  return OUString();
511 }
512 
513 void
514 SwVbaCustomDocumentProperty::setLinkSource( const OUString& /*rsLinkContent*/ )
515 {
516  // #FIXME we need to store the link source somewhere
517 }
518 
519 void SAL_CALL
520 SwVbaCustomDocumentProperty::setName( const OUString& /*Name*/ )
521 {
522  // setName on existing property ?
523  // #FIXME
524  // do we need to delete existing property and create a new one?
525 }
526 
527 void SAL_CALL
529 {
530  // setType, do we need to do a conversion?
531  // #FIXME the underlying value needs to be changed to the new type
532 }
533 
534 void SAL_CALL
536 {
537  uno::Reference< beans::XPropertyContainer > xContainer(
538  mPropInfo.getUserDefinedProperties(), uno::UNO_QUERY_THROW);
539  xContainer->removeProperty( getName() );
540 }
541 
542 SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo( rInfo )
543 {
544 }
545 
546 void SAL_CALL
548 {
549  // not valid for Builtin
550  throw uno::RuntimeException();
551 }
552 
553 OUString SAL_CALL
555 {
556  return mPropInfo.msMSODesc;
557 }
558 
559 void SAL_CALL
561 {
562  // not valid for Builtin
563  throw uno::RuntimeException();
564 }
565 
566 ::sal_Int8 SAL_CALL
568 {
569  return lcl_toMSOPropType( getValue().getValueType() );
570 }
571 
572 void SAL_CALL
574 {
575  // not valid for Builtin
576  throw uno::RuntimeException();
577 }
578 
579 sal_Bool SAL_CALL
581 {
582  return false; // built-in always false
583 }
584 
585 void SAL_CALL
587 {
588  // not valid for Builtin
589  throw uno::RuntimeException();
590 }
591 
592 uno::Any SAL_CALL
594 {
595  uno::Any aRet = mPropInfo.getValue();
596  if ( !aRet.hasValue() )
597  throw uno::RuntimeException();
598  return aRet;
599 }
600 
601 void SAL_CALL
603 {
604  mPropInfo.setValue( Value );
605 }
606 
607 OUString SAL_CALL
609 {
610  // not valid for Builtin
611  throw uno::RuntimeException();
612 }
613 
614 void SAL_CALL
615 SwVbaBuiltInDocumentProperty::setLinkSource( const OUString& /*LinkSource*/ )
616 {
617  // not valid for Builtin
618  throw uno::RuntimeException();
619 }
620 
621 OUString
623 {
624  return OUString("SwVbaBuiltinDocumentProperty");
625 }
626 
627 uno::Sequence<OUString>
629 {
630  static uno::Sequence< OUString > const aServiceNames
631  {
632  "ooo.vba.word.DocumentProperty"
633  };
634  return aServiceNames;
635 }
636 typedef ::cppu::WeakImplHelper< css::container::XIndexAccess
637  ,css::container::XNameAccess
638  ,css::container::XEnumerationAccess
640 
641 typedef std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;
642 
643 class DocPropEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration >
644 {
646  DocProps::iterator mIt;
647 public:
648 
649  explicit DocPropEnumeration( const DocProps& rProps ) : mDocProps( rProps ), mIt( mDocProps.begin() ) {}
650  virtual sal_Bool SAL_CALL hasMoreElements( ) override
651  {
652  return mIt != mDocProps.end();
653  }
654  virtual uno::Any SAL_CALL nextElement( ) override
655  {
656  if ( !hasMoreElements() )
657  throw container::NoSuchElementException();
658  return uno::makeAny( mIt++->second );
659  }
660 };
661 
662 typedef std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName;
663 
665 {
666 protected:
667 
668  uno::Reference< frame::XModel > m_xModel;
669 
672 
673  public:
674  BuiltInPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : m_xModel( xModel )
675  {
676  BuiltInIndexHelper builtIns( m_xModel );
677  for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
678  {
679  mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
680  mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
681  }
682  }
683 // XIndexAccess
684  virtual ::sal_Int32 SAL_CALL getCount( ) override
685  {
686  return mDocProps.size();
687  }
688  virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
689  {
690  // correct the correct by the base class for 1 based indices
691  DocProps::iterator it = mDocProps.find( ++Index );
692  if ( it == mDocProps.end() )
693  throw lang::IndexOutOfBoundsException();
694  return uno::makeAny( it->second );
695  }
696  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
697  {
698  if ( !hasByName( aName ) )
699  throw container::NoSuchElementException();
700  DocPropsByName::iterator it = mNamedDocProps.find( aName );
701  return uno::Any( it->second );
702 
703  }
704  virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
705  {
706  uno::Sequence< OUString > aNames( getCount() );
707  OUString* pName = aNames.getArray();
708  for (const auto& rEntry : mNamedDocProps)
709  {
710  *pName = rEntry.first;
711  ++pName;
712  }
713  return aNames;
714  }
715 
716  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
717  {
718  DocPropsByName::iterator it = mNamedDocProps.find( aName );
719  if ( it == mNamedDocProps.end() )
720  return false;
721  return true;
722  }
723 // XElementAccess
724  virtual uno::Type SAL_CALL getElementType( ) override
725  {
727  }
728  virtual sal_Bool SAL_CALL hasElements( ) override
729  {
730  return !mDocProps.empty();
731  }
732  virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
733  {
734  return new DocPropEnumeration( mDocProps );
735  }
736 };
737 
738 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 ) ) )
739 {
740 }
741 
742 uno::Reference< XDocumentProperty > SAL_CALL
743 SwVbaBuiltinDocumentProperties::Add( const OUString& /*Name*/, sal_Bool /*LinkToContent*/, ::sal_Int8 /*Type*/, const uno::Any& /*value*/, const uno::Any& /*LinkSource*/ )
744 {
745  throw uno::RuntimeException( "not supported for Builtin properties" );
746 }
747 
748 // XEnumerationAccess
749 uno::Type SAL_CALL
751 {
753 }
754 
755 uno::Reference< container::XEnumeration > SAL_CALL
757 {
758  uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
759  return xEnumAccess->createEnumeration();
760 }
761 
762 // ScVbaCollectionBaseImpl
763 uno::Any
765 {
766  // pass through
767  return aSource;
768 }
769 
770 // XHelperInterface
771 OUString
773 {
774  return OUString("SwVbaBuiltinDocumentProperties");
775 }
776 
777 uno::Sequence<OUString>
779 {
780  static uno::Sequence< OUString > const aServiceNames
781  {
782  "ooo.vba.word.DocumentProperties"
783  };
784  return aServiceNames;
785 }
786 
788 {
789  uno::Reference< XHelperInterface > m_xParent;
790  uno::Reference< uno::XComponentContext > m_xContext;
791  uno::Reference< frame::XModel > m_xModel;
792  uno::Reference< beans::XPropertySet > mxUserDefinedProp;
793  std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
794 public:
795  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 )
796  {
797  // suck in the document( custom ) properties
798  mpPropGetSetHelper.reset( new CustomPropertyGetSetHelper( m_xModel ) );
799  mxUserDefinedProp.set(mpPropGetSetHelper->getUserDefinedProperties(),
800  uno::UNO_SET_THROW);
801  };
802  // XIndexAccess
803  virtual ::sal_Int32 SAL_CALL getCount( ) override
804  {
805  return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
806  }
807 
808  virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
809  {
810  uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
811  if ( Index >= aProps.getLength() )
812  throw lang::IndexOutOfBoundsException();
813  // How to determine type e.g Date? ( com.sun.star.util.DateTime )
814  DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
815  return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
816  }
817 
818  virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
819  {
820  if ( !hasByName( aName ) )
821  throw container::NoSuchElementException();
822 
823  DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
824  return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
825  }
826 
827  virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override
828  {
829  uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
830  uno::Sequence< OUString > aNames( aProps.getLength() );
831  OUString* pString = aNames.getArray();
832  OUString* pEnd = pString + aNames.getLength();
833  beans::Property* pProp = aProps.getArray();
834  for ( ; pString != pEnd; ++pString, ++pProp )
835  *pString = pProp->Name;
836  return aNames;
837  }
838 
839  virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
840  {
841  SAL_INFO("sw.vba", "hasByName(" << aName << ") returns " << mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
842  return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
843  }
844 
845  // XElementAccess
846  virtual uno::Type SAL_CALL getElementType( ) override
847  {
849  }
850 
851  virtual sal_Bool SAL_CALL hasElements( ) override
852  {
853  return getCount() > 0;
854  }
855 
856  virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) override
857  {
858  // create a map of properties ( the key doesn't matter )
859  SAL_INFO("sw.vba", "Creating an enumeration");
860  sal_Int32 key = 0;
861  sal_Int32 nElem = getCount();
862  DocProps simpleDocPropSnapShot;
863  for ( ; key < nElem; ++key )
864  simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
865  SAL_INFO("sw.vba", "After creating the enumeration");
866  return new DocPropEnumeration( simpleDocPropSnapShot );
867  }
868 
869  void addProp( const OUString& Name, const uno::Any& Value )
870  {
871  uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
872  // TODO fixme, perform the necessary Type Value conversions
873  xContainer->addProperty( Name, sal_Int16(128), Value );
874  }
875 
876 };
877 
878 SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
879 {
880  // replace the m_xIndexAccess implementation ( we need a virtual init )
881  m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
882  m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
883 }
884 
885 uno::Reference< XDocumentProperty > SAL_CALL
886 SwVbaCustomDocumentProperties::Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 /*Type*/, const uno::Any& Value, const uno::Any& LinkSource )
887 {
888  CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
889  uno::Reference< XDocumentProperty > xDocProp;
890  if ( pCustomProps )
891  {
892  OUString sLinkSource;
893  pCustomProps->addProp( Name, Value );
894 
895  xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
896  xDocProp->setLinkToContent( LinkToContent );
897 
898  if ( LinkSource >>= sLinkSource )
899  xDocProp->setLinkSource( sLinkSource );
900  }
901  return xDocProp;
902 }
903 
904 // XHelperInterface
905 OUString
907 {
908  return OUString("SwVbaCustomDocumentProperties");
909 }
910 
911 /* 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
css::beans::Optional< css::uno::Any > getValue(OUString const &id)
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
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
Any SAL_CALL getCaughtException()
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
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
OString exceptionToString(const css::uno::Any &caught)
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:1245
static DocPropInfo createDocPropInfo(const OUString &sDesc, const OUString &sPropName, std::shared_ptr< PropertGetSetHelper > const &rHelper)
virtual OUString SAL_CALL getDefaultPropertyName() override
#define SAL_WARN(area, stream)
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