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