1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #include "vbadocumentproperties.hxx"
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 <comphelper/diagnose_ex.hxx>
30 #include "wordvbahelper.hxx"
34 using namespace ::ooo::vba
;
37 /// @throws lang::IllegalArgumentException
38 static sal_Int8
lcl_toMSOPropType( const uno::Type
& aType
)
40 sal_Int16 msoType
= office::MsoDocProperties::msoPropertyTypeString
;
42 switch ( aType
.getTypeClass() )
44 case uno::TypeClass_BOOLEAN
:
45 msoType
= office::MsoDocProperties::msoPropertyTypeBoolean
;
47 case uno::TypeClass_FLOAT
:
48 msoType
= office::MsoDocProperties::msoPropertyTypeFloat
;
50 case uno::TypeClass_STRUCT
: // Assume date
51 msoType
= office::MsoDocProperties::msoPropertyTypeDate
;
53 case uno::TypeClass_BYTE
:
54 case uno::TypeClass_SHORT
:
55 case uno::TypeClass_LONG
:
56 case uno::TypeClass_HYPER
:
57 msoType
= office::MsoDocProperties::msoPropertyTypeNumber
;
60 throw lang::IllegalArgumentException();
67 class PropertGetSetHelper
70 uno::Reference
< frame::XModel
> m_xModel
;
71 uno::Reference
<document::XDocumentProperties
> m_xDocProps
;
73 explicit PropertGetSetHelper( uno::Reference
< frame::XModel
> xModel
):m_xModel(std::move( xModel
))
75 uno::Reference
<document::XDocumentPropertiesSupplier
> const
76 xDocPropSupp(m_xModel
, uno::UNO_QUERY_THROW
);
77 m_xDocProps
.set(xDocPropSupp
->getDocumentProperties(),
80 virtual ~PropertGetSetHelper() {}
81 virtual uno::Any
getPropertyValue( const OUString
& rPropName
) = 0;
82 virtual void setPropertyValue( const OUString
& rPropName
, const uno::Any
& aValue
) = 0;
83 uno::Reference
< beans::XPropertySet
> getUserDefinedProperties() {
84 return uno::Reference
<beans::XPropertySet
>(
85 m_xDocProps
->getUserDefinedProperties(), uno::UNO_QUERY_THROW
);
90 class BuiltinPropertyGetSetHelper
: public PropertGetSetHelper
93 explicit BuiltinPropertyGetSetHelper( const uno::Reference
< frame::XModel
>& xModel
) :PropertGetSetHelper( xModel
)
96 virtual uno::Any
getPropertyValue( const OUString
& rPropName
) override
98 if ( rPropName
== "EditingDuration" )
100 sal_Int32
const nSecs
= m_xDocProps
->getEditingDuration();
101 return uno::Any( nSecs
/60 ); // minutes
103 else if ("Title" == rPropName
)
105 return uno::Any(m_xDocProps
->getTitle());
107 else if ("Subject" == rPropName
)
109 return uno::Any(m_xDocProps
->getSubject());
111 else if ("Author" == rPropName
)
113 return uno::Any(m_xDocProps
->getAuthor());
115 else if ("Keywords" == rPropName
)
117 return uno::Any(m_xDocProps
->getKeywords());
119 else if ("Description" == rPropName
)
121 return uno::Any(m_xDocProps
->getDescription());
123 else if ("Template" == rPropName
)
125 return uno::Any(m_xDocProps
->getTemplateName());
127 else if ("ModifiedBy" == rPropName
)
129 return uno::Any(m_xDocProps
->getModifiedBy());
131 else if ("Generator" == rPropName
)
133 return uno::Any(m_xDocProps
->getGenerator());
135 else if ("PrintDate" == rPropName
)
137 return uno::Any(m_xDocProps
->getPrintDate());
139 else if ("CreationDate" == rPropName
)
141 return uno::Any(m_xDocProps
->getCreationDate());
143 else if ("ModifyDate" == rPropName
)
145 return uno::Any(m_xDocProps
->getModificationDate());
147 else if ("AutoloadURL" == rPropName
)
149 return uno::Any(m_xDocProps
->getAutoloadURL());
153 // fall back to user-defined properties
154 return getUserDefinedProperties()->getPropertyValue(rPropName
);
157 virtual void setPropertyValue( const OUString
& rPropName
, const uno::Any
& aValue
) override
159 if ("EditingDuration" == rPropName
)
162 if (aValue
>>= nMins
)
164 m_xDocProps
->setEditingDuration(nMins
* 60); // convert minutes
167 else if ("Title" == rPropName
)
172 m_xDocProps
->setTitle(str
);
175 else if ("Subject" == rPropName
)
180 m_xDocProps
->setSubject(str
);
183 else if ("Author" == rPropName
)
188 m_xDocProps
->setAuthor(str
);
191 else if ("Keywords" == rPropName
)
193 uno::Sequence
<OUString
> keywords
;
194 if (aValue
>>= keywords
)
196 m_xDocProps
->setKeywords(keywords
);
199 else if ("Description" == rPropName
)
204 m_xDocProps
->setDescription(str
);
207 else if ("Template" == rPropName
)
212 m_xDocProps
->setTemplateName(str
);
215 else if ("ModifiedBy" == rPropName
)
220 m_xDocProps
->setModifiedBy(str
);
223 else if ("Generator" == rPropName
)
228 return m_xDocProps
->setGenerator(str
);
231 else if ("PrintDate" == rPropName
)
236 m_xDocProps
->setPrintDate(dt
);
239 else if ("CreationDate" == rPropName
)
244 m_xDocProps
->setCreationDate(dt
);
247 else if ("ModifyDate" == rPropName
)
252 m_xDocProps
->setModificationDate(dt
);
255 else if ("AutoloadURL" == rPropName
)
260 m_xDocProps
->setAutoloadURL(str
);
265 // fall back to user-defined properties
266 getUserDefinedProperties()->setPropertyValue(rPropName
, aValue
);
271 class CustomPropertyGetSetHelper
: public BuiltinPropertyGetSetHelper
274 explicit CustomPropertyGetSetHelper( const uno::Reference
< frame::XModel
>& xModel
) :BuiltinPropertyGetSetHelper( xModel
)
277 virtual uno::Any
getPropertyValue( const OUString
& rPropName
) override
279 return getUserDefinedProperties()->getPropertyValue(rPropName
);
281 virtual void setPropertyValue(
282 const OUString
& rPropName
, const uno::Any
& rValue
) override
284 return getUserDefinedProperties()->setPropertyValue(rPropName
, rValue
);
288 class StatisticPropertyGetSetHelper
: public PropertGetSetHelper
290 SwDocShell
* mpDocShell
;
291 uno::Reference
< beans::XPropertySet
> mxModelProps
;
293 explicit StatisticPropertyGetSetHelper( const uno::Reference
< frame::XModel
>& xModel
) :PropertGetSetHelper( xModel
) , mpDocShell( nullptr )
295 mxModelProps
.set( m_xModel
, uno::UNO_QUERY_THROW
);
296 mpDocShell
= word::getDocShell( xModel
);
298 virtual uno::Any
getPropertyValue( const OUString
& rPropName
) override
302 // Characters, ParagraphCount & WordCount are available from
303 // the model ( and additionally these also update the statics object )
304 return mxModelProps
->getPropertyValue( rPropName
);
306 catch (const uno::Exception
&)
308 TOOLS_WARN_EXCEPTION("sw.vba", "");
311 if ( rPropName
== "LineCount" ) // special processing needed
315 if (SwFEShell
* pFEShell
= mpDocShell
->GetFEShell())
316 aReturn
<<= pFEShell
->GetLineCount();
321 uno::Sequence
< beans::NamedValue
> const stats(
322 m_xDocProps
->getDocumentStatistics());
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
329 aReturn
= pStat
->Value
;
334 virtual void setPropertyValue( const OUString
& rPropName
, const uno::Any
& aValue
) override
336 uno::Sequence
< beans::NamedValue
> stats(
337 m_xDocProps
->getDocumentStatistics());
339 auto [begin
, end
] = asNonConstRange(stats
);
340 auto pStat
= std::find_if(begin
, end
,
341 [&rPropName
](const beans::NamedValue
& rStat
) { return rPropName
== rStat
.Name
; });
344 pStat
->Value
= aValue
;
345 m_xDocProps
->setDocumentStatistics(stats
);
354 OUString msOOOPropName
;
355 std::shared_ptr
< PropertGetSetHelper
> mpPropGetSetHelper
;
357 static DocPropInfo
createDocPropInfo( const OUString
& sDesc
, const OUString
& sPropName
, std::shared_ptr
< PropertGetSetHelper
> const & rHelper
)
360 aItem
.msMSODesc
= sDesc
;
361 aItem
.msOOOPropName
= sPropName
;
362 aItem
.mpPropGetSetHelper
= rHelper
;
366 static DocPropInfo
createDocPropInfo( const char* sDesc
, const char* sPropName
, std::shared_ptr
< PropertGetSetHelper
> const & rHelper
)
368 return createDocPropInfo( OUString::createFromAscii( sDesc
), OUString::createFromAscii( sPropName
), rHelper
);
372 if ( mpPropGetSetHelper
)
373 return mpPropGetSetHelper
->getPropertyValue( msOOOPropName
);
376 void setValue( const uno::Any
& rValue
)
378 if ( mpPropGetSetHelper
)
379 mpPropGetSetHelper
->setPropertyValue( msOOOPropName
, rValue
);
381 uno::Reference
< beans::XPropertySet
> getUserDefinedProperties()
383 uno::Reference
< beans::XPropertySet
> xProps
;
384 if ( mpPropGetSetHelper
)
385 return mpPropGetSetHelper
->getUserDefinedProperties();
392 typedef std::unordered_map
< sal_Int32
, DocPropInfo
> MSOIndexToOODocPropInfo
;
396 class BuiltInIndexHelper
398 MSOIndexToOODocPropInfo m_docPropInfoMap
;
401 explicit BuiltInIndexHelper( const uno::Reference
< frame::XModel
>& xModel
)
403 auto aStandardHelper
= std::make_shared
<BuiltinPropertyGetSetHelper
>( xModel
);
404 auto aUsingStatsHelper
= std::make_shared
<StatisticPropertyGetSetHelper
>( xModel
);
406 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyTitle
] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper
);
407 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertySubject
] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper
);
408 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyAuthor
] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper
);
409 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyKeywords
] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper
);
410 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyComments
] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper
);
411 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyTemplate
] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper
);
412 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyLastAuthor
] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper
); // doesn't seem to exist - throw or return nothing ?
413 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyRevision
] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper
); // doesn't seem to exist - throw or return nothing ?
414 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyAppName
] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper
); // doesn't seem to exist - throw or return nothing ?
415 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted
] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper
); // doesn't seem to exist - throw or return nothing ?
416 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyTimeCreated
] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper
);
417 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyTimeLastSaved
] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper
);
418 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyVBATotalEdit
] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper
); // Not sure if this is correct
419 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyPages
] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper
); // special handling required ?
420 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyWords
] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper
); // special handling require ?
421 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyCharacters
] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper
); // special handling required ?
422 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertySecurity
] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper
); // doesn't seem to exist
423 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyCategory
] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper
); // hacked in
424 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyFormat
] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper
); // doesn't seem to exist
425 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyManager
] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper
); // hacked in
426 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyCompany
] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper
); // hacked in
427 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 )
428 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyLines
] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper
); // special handling
429 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyParas
] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper
); // special handling
430 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertySlides
] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper
); // doesn't seem to exist
431 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyNotes
] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper
); // doesn't seem to exist
432 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyHiddenSlides
] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper
); // doesn't seem to exist
433 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyMMClips
] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper
); // doesn't seem to exist
434 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyHyperlinkBase
] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper
);
435 m_docPropInfoMap
[ word::WdBuiltInProperty::wdPropertyCharsWSpaces
] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper
); // doesn't seem to be supported
438 MSOIndexToOODocPropInfo
& getDocPropInfoMap() { return m_docPropInfoMap
; }
443 typedef InheritedHelperInterfaceWeakImpl
< ooo::vba::XDocumentProperty
> SwVbaDocumentProperty_BASE
;
447 class SwVbaBuiltInDocumentProperty
: public SwVbaDocumentProperty_BASE
450 DocPropInfo mPropInfo
;
452 SwVbaBuiltInDocumentProperty( const uno::Reference
< ov::XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, DocPropInfo rInfo
);
454 virtual void SAL_CALL
Delete( ) override
;
455 virtual OUString SAL_CALL
getName( ) override
;
456 virtual void SAL_CALL
setName( const OUString
& Name
) override
;
457 virtual ::sal_Int8 SAL_CALL
getType( ) override
;
458 virtual void SAL_CALL
setType( ::sal_Int8 Type
) override
;
459 virtual sal_Bool SAL_CALL
getLinkToContent( ) override
;
460 virtual void SAL_CALL
setLinkToContent( sal_Bool LinkToContent
) override
;
461 virtual uno::Any SAL_CALL
getValue( ) override
;
462 virtual void SAL_CALL
setValue( const uno::Any
& Value
) override
;
463 virtual OUString SAL_CALL
getLinkSource( ) override
;
464 virtual void SAL_CALL
setLinkSource( const OUString
& LinkSource
) override
;
466 virtual OUString SAL_CALL
getDefaultPropertyName( ) override
{ return "Value"; }
468 virtual OUString
getServiceImplName() override
;
469 virtual uno::Sequence
<OUString
> getServiceNames() override
;
472 class SwVbaCustomDocumentProperty
: public SwVbaBuiltInDocumentProperty
476 SwVbaCustomDocumentProperty( const uno::Reference
< ov::XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, const DocPropInfo
& rInfo
);
478 virtual sal_Bool SAL_CALL
getLinkToContent( ) override
;
479 virtual void SAL_CALL
setLinkToContent( sal_Bool LinkToContent
) override
;
481 virtual OUString SAL_CALL
getLinkSource( ) override
;
482 virtual void SAL_CALL
setLinkSource( const OUString
& LinkSource
) override
;
483 virtual void SAL_CALL
Delete( ) override
;
484 virtual void SAL_CALL
setName( const OUString
& Name
) override
;
485 virtual void SAL_CALL
setType( ::sal_Int8 Type
) override
;
491 SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference
< ov::XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, const DocPropInfo
& rInfo
) : SwVbaBuiltInDocumentProperty( xParent
, xContext
, rInfo
)
496 SwVbaCustomDocumentProperty::getLinkToContent( )
498 // #FIXME we need to store the link content somewhere
503 SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool
/*bLinkContent*/ )
508 SwVbaCustomDocumentProperty::getLinkSource( )
510 // #FIXME we need to store the link content somewhere
515 SwVbaCustomDocumentProperty::setLinkSource( const OUString
& /*rsLinkContent*/ )
517 // #FIXME we need to store the link source somewhere
521 SwVbaCustomDocumentProperty::setName( const OUString
& /*Name*/ )
523 // setName on existing property ?
525 // do we need to delete existing property and create a new one?
529 SwVbaCustomDocumentProperty::setType( ::sal_Int8
/*Type*/ )
531 // setType, do we need to do a conversion?
532 // #FIXME the underlying value needs to be changed to the new type
536 SwVbaCustomDocumentProperty::Delete( )
538 uno::Reference
< beans::XPropertyContainer
> xContainer(
539 mPropInfo
.getUserDefinedProperties(), uno::UNO_QUERY_THROW
);
540 xContainer
->removeProperty( getName() );
543 SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference
< ov::XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, DocPropInfo rInfo
) : SwVbaDocumentProperty_BASE( xParent
, xContext
), mPropInfo(std::move( rInfo
))
548 SwVbaBuiltInDocumentProperty::Delete( )
550 // not valid for Builtin
551 throw uno::RuntimeException();
555 SwVbaBuiltInDocumentProperty::getName( )
557 return mPropInfo
.msMSODesc
;
561 SwVbaBuiltInDocumentProperty::setName( const OUString
& )
563 // not valid for Builtin
564 throw uno::RuntimeException();
568 SwVbaBuiltInDocumentProperty::getType( )
570 return lcl_toMSOPropType( getValue().getValueType() );
574 SwVbaBuiltInDocumentProperty::setType( ::sal_Int8
/*Type*/ )
576 // not valid for Builtin
577 throw uno::RuntimeException();
581 SwVbaBuiltInDocumentProperty::getLinkToContent( )
583 return false; // built-in always false
587 SwVbaBuiltInDocumentProperty::setLinkToContent( sal_Bool
/*LinkToContent*/ )
589 // not valid for Builtin
590 throw uno::RuntimeException();
594 SwVbaBuiltInDocumentProperty::getValue( )
596 uno::Any aRet
= mPropInfo
.getValue();
597 if ( !aRet
.hasValue() )
598 throw uno::RuntimeException();
603 SwVbaBuiltInDocumentProperty::setValue( const uno::Any
& Value
)
605 mPropInfo
.setValue( Value
);
609 SwVbaBuiltInDocumentProperty::getLinkSource( )
611 // not valid for Builtin
612 throw uno::RuntimeException();
616 SwVbaBuiltInDocumentProperty::setLinkSource( const OUString
& /*LinkSource*/ )
618 // not valid for Builtin
619 throw uno::RuntimeException();
623 SwVbaBuiltInDocumentProperty::getServiceImplName()
625 return "SwVbaBuiltinDocumentProperty";
628 uno::Sequence
<OUString
>
629 SwVbaBuiltInDocumentProperty::getServiceNames()
631 static uno::Sequence
< OUString
> const aServiceNames
633 "ooo.vba.word.DocumentProperty"
635 return aServiceNames
;
637 typedef ::cppu::WeakImplHelper
< css::container::XIndexAccess
638 ,css::container::XNameAccess
639 ,css::container::XEnumerationAccess
640 > PropertiesImpl_BASE
;
642 typedef std::unordered_map
< sal_Int32
, uno::Reference
< XDocumentProperty
> > DocProps
;
646 class DocPropEnumeration
: public ::cppu::WeakImplHelper
< css::container::XEnumeration
>
649 DocProps::iterator mIt
;
652 explicit DocPropEnumeration( DocProps
&& rProps
) : mDocProps( std::move(rProps
) ), mIt( mDocProps
.begin() ) {}
653 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
655 return mIt
!= mDocProps
.end();
657 virtual uno::Any SAL_CALL
nextElement( ) override
659 if ( !hasMoreElements() )
660 throw container::NoSuchElementException();
661 return uno::Any( mIt
++->second
);
667 typedef std::unordered_map
< OUString
, uno::Reference
< XDocumentProperty
> > DocPropsByName
;
671 class BuiltInPropertiesImpl
: public PropertiesImpl_BASE
675 uno::Reference
< frame::XModel
> m_xModel
;
678 DocPropsByName mNamedDocProps
;
681 BuiltInPropertiesImpl( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, uno::Reference
< frame::XModel
> xModel
) : m_xModel(std::move( xModel
))
683 BuiltInIndexHelper
builtIns( m_xModel
);
684 for ( sal_Int32 index
= word::WdBuiltInProperty::wdPropertyTitle
; index
<= word::WdBuiltInProperty::wdPropertyCharsWSpaces
; ++index
)
686 mDocProps
[ index
] = new SwVbaBuiltInDocumentProperty( xParent
, xContext
, builtIns
.getDocPropInfoMap()[ index
] );
687 mNamedDocProps
[ mDocProps
[ index
]->getName() ] = mDocProps
[ index
];
691 virtual ::sal_Int32 SAL_CALL
getCount( ) override
693 return mDocProps
.size();
695 virtual uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) override
697 // correct the correct by the base class for 1 based indices
698 DocProps::iterator it
= mDocProps
.find( ++Index
);
699 if ( it
== mDocProps
.end() )
700 throw lang::IndexOutOfBoundsException();
701 return uno::Any( it
->second
);
703 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
705 if ( !hasByName( aName
) )
706 throw container::NoSuchElementException();
707 DocPropsByName::iterator it
= mNamedDocProps
.find( aName
);
708 return uno::Any( it
->second
);
711 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
713 uno::Sequence
< OUString
> aNames( getCount() );
714 OUString
* pName
= aNames
.getArray();
715 for (const auto& rEntry
: mNamedDocProps
)
717 *pName
= rEntry
.first
;
723 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
725 DocPropsByName::iterator it
= mNamedDocProps
.find( aName
);
726 if ( it
== mNamedDocProps
.end() )
731 virtual uno::Type SAL_CALL
getElementType( ) override
733 return cppu::UnoType
<XDocumentProperty
>::get();
735 virtual sal_Bool SAL_CALL
hasElements( ) override
737 return !mDocProps
.empty();
739 virtual uno::Reference
< container::XEnumeration
> SAL_CALL
createEnumeration( ) override
741 return new DocPropEnumeration( std::unordered_map(mDocProps
) );
747 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
) ) )
751 uno::Reference
< XDocumentProperty
> SAL_CALL
752 SwVbaBuiltinDocumentProperties::Add( const OUString
& /*Name*/, sal_Bool
/*LinkToContent*/, ::sal_Int8
/*Type*/, const uno::Any
& /*value*/, const uno::Any
& /*LinkSource*/ )
754 throw uno::RuntimeException( "not supported for Builtin properties" );
757 // XEnumerationAccess
759 SwVbaBuiltinDocumentProperties::getElementType()
761 return cppu::UnoType
<XDocumentProperty
>::get();
764 uno::Reference
< container::XEnumeration
> SAL_CALL
765 SwVbaBuiltinDocumentProperties::createEnumeration()
767 uno::Reference
< container::XEnumerationAccess
> xEnumAccess( m_xIndexAccess
, uno::UNO_QUERY_THROW
);
768 return xEnumAccess
->createEnumeration();
771 // ScVbaCollectionBaseImpl
773 SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any
& aSource
)
781 SwVbaBuiltinDocumentProperties::getServiceImplName()
783 return "SwVbaBuiltinDocumentProperties";
786 uno::Sequence
<OUString
>
787 SwVbaBuiltinDocumentProperties::getServiceNames()
789 static uno::Sequence
< OUString
> const aServiceNames
791 "ooo.vba.word.DocumentProperties"
793 return aServiceNames
;
798 class CustomPropertiesImpl
: public PropertiesImpl_BASE
800 uno::Reference
< XHelperInterface
> m_xParent
;
801 uno::Reference
< uno::XComponentContext
> m_xContext
;
802 uno::Reference
< frame::XModel
> m_xModel
;
803 uno::Reference
< beans::XPropertySet
> mxUserDefinedProp
;
804 std::shared_ptr
< PropertGetSetHelper
> mpPropGetSetHelper
;
806 CustomPropertiesImpl( uno::Reference
< XHelperInterface
> xParent
, uno::Reference
< uno::XComponentContext
> xContext
, uno::Reference
< frame::XModel
> xModel
) : m_xParent(std::move( xParent
)), m_xContext(std::move( xContext
)), m_xModel(std::move( xModel
))
808 // suck in the document( custom ) properties
809 mpPropGetSetHelper
= std::make_shared
<CustomPropertyGetSetHelper
>( m_xModel
);
810 mxUserDefinedProp
.set(mpPropGetSetHelper
->getUserDefinedProperties(),
814 virtual ::sal_Int32 SAL_CALL
getCount( ) override
816 return mxUserDefinedProp
->getPropertySetInfo()->getProperties().getLength();
819 virtual uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) override
821 uno::Sequence
< beans::Property
> aProps
= mxUserDefinedProp
->getPropertySetInfo()->getProperties();
822 if ( Index
>= aProps
.getLength() )
823 throw lang::IndexOutOfBoundsException();
824 // How to determine type e.g Date? ( com.sun.star.util.DateTime )
825 DocPropInfo aPropInfo
= DocPropInfo::createDocPropInfo( aProps
[ Index
].Name
, aProps
[ Index
].Name
, mpPropGetSetHelper
);
826 return uno::Any( uno::Reference
< XDocumentProperty
>( new SwVbaCustomDocumentProperty( m_xParent
, m_xContext
, aPropInfo
) ) );
829 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
831 if ( !hasByName( aName
) )
832 throw container::NoSuchElementException();
834 DocPropInfo aPropInfo
= DocPropInfo::createDocPropInfo( aName
, aName
, mpPropGetSetHelper
);
835 return uno::Any( uno::Reference
< XDocumentProperty
>( new SwVbaCustomDocumentProperty( m_xParent
, m_xContext
, aPropInfo
) ) );
838 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
840 const uno::Sequence
< beans::Property
> aProps
= mxUserDefinedProp
->getPropertySetInfo()->getProperties();
841 uno::Sequence
< OUString
> aNames( aProps
.getLength() );
842 std::transform(aProps
.begin(), aProps
.end(), aNames
.getArray(),
843 [](const beans::Property
& rProp
) -> OUString
{ return rProp
.Name
; });
847 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
849 SAL_INFO("sw.vba", "hasByName(" << aName
<< ") returns " << mxUserDefinedProp
->getPropertySetInfo()->hasPropertyByName( aName
) );
850 return mxUserDefinedProp
->getPropertySetInfo()->hasPropertyByName( aName
);
854 virtual uno::Type SAL_CALL
getElementType( ) override
856 return cppu::UnoType
<XDocumentProperty
>::get();
859 virtual sal_Bool SAL_CALL
hasElements( ) override
861 return getCount() > 0;
864 virtual uno::Reference
< container::XEnumeration
> SAL_CALL
createEnumeration( ) override
866 // create a map of properties ( the key doesn't matter )
867 SAL_INFO("sw.vba", "Creating an enumeration");
869 sal_Int32 nElem
= getCount();
870 DocProps simpleDocPropSnapShot
;
871 for ( ; key
< nElem
; ++key
)
872 simpleDocPropSnapShot
[ key
].set( getByIndex( key
), uno::UNO_QUERY_THROW
);
873 SAL_INFO("sw.vba", "After creating the enumeration");
874 return new DocPropEnumeration( std::move(simpleDocPropSnapShot
) );
877 void addProp( const OUString
& Name
, const uno::Any
& Value
)
879 uno::Reference
< beans::XPropertyContainer
> xContainer( mxUserDefinedProp
, uno::UNO_QUERY_THROW
);
880 // TODO fixme, perform the necessary Type Value conversions
881 xContainer
->addProperty( Name
, sal_Int16(128), Value
);
888 SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
>& xContext
, const uno::Reference
< frame::XModel
>& xModel
) : SwVbaBuiltinDocumentProperties( xParent
, xContext
, xModel
)
890 // replace the m_xIndexAccess implementation ( we need a virtual init )
891 m_xIndexAccess
.set( new CustomPropertiesImpl( xParent
, xContext
, xModel
) );
892 m_xNameAccess
.set( m_xIndexAccess
, uno::UNO_QUERY_THROW
);
895 uno::Reference
< XDocumentProperty
> SAL_CALL
896 SwVbaCustomDocumentProperties::Add( const OUString
& Name
, sal_Bool LinkToContent
, ::sal_Int8
/*Type*/, const uno::Any
& Value
, const uno::Any
& LinkSource
)
898 CustomPropertiesImpl
* pCustomProps
= dynamic_cast< CustomPropertiesImpl
* > ( m_xIndexAccess
.get() );
899 uno::Reference
< XDocumentProperty
> xDocProp
;
902 OUString sLinkSource
;
903 pCustomProps
->addProp( Name
, Value
);
905 xDocProp
.set( m_xNameAccess
->getByName( Name
), uno::UNO_QUERY_THROW
);
906 xDocProp
->setLinkToContent( LinkToContent
);
908 if ( LinkSource
>>= sLinkSource
)
909 xDocProp
->setLinkSource( sLinkSource
);
916 SwVbaCustomDocumentProperties::getServiceImplName()
918 return "SwVbaCustomDocumentProperties";
921 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */