merge the formfield patch from ooo-build
[ooovba.git] / sw / source / ui / vba / vbadocumentproperties.cxx
blobf07b9788ffb59e7cd55c0d52103830700edd8dbf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: vbadocument.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "vbadocumentproperties.hxx"
31 #include <cppuhelper/implbase1.hxx>
32 #include <cppuhelper/implbase3.hxx>
33 #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
34 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
35 #include <com/sun/star/beans/NamedValue.hpp>
36 #include <com/sun/star/beans/XPropertyContainer.hpp>
37 #include <ooo/vba/word/WdBuiltInProperty.hpp>
38 #include <ooo/vba/office/MsoDocProperties.hpp>
39 #include <memory>
40 #include <boost/shared_ptr.hpp>
41 #include "wordvbahelper.hxx"
42 #include "fesh.hxx"
43 #include "docsh.hxx"
44 using namespace ::ooo::vba;
45 using namespace css;
47 sal_Int8 lcl_toMSOPropType( const uno::Type& aType ) throw ( lang::IllegalArgumentException )
49 sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString;
51 switch ( aType.getTypeClass() )
53 case uno::TypeClass_BOOLEAN:
54 msoType = office::MsoDocProperties::msoPropertyTypeBoolean;
55 break;
56 case uno::TypeClass_FLOAT:
57 msoType = office::MsoDocProperties::msoPropertyTypeFloat;
58 break;
59 case uno::TypeClass_STRUCT: // Assume date
60 msoType = office::MsoDocProperties::msoPropertyTypeDate;
61 break;
62 case uno::TypeClass_BYTE:
63 case uno::TypeClass_SHORT:
64 case uno::TypeClass_LONG:
65 case uno::TypeClass_HYPER:
66 msoType = office::MsoDocProperties::msoPropertyTypeNumber;
67 break;
68 default:
69 throw lang::IllegalArgumentException();
71 return msoType;
74 class PropertGetSetHelper
76 protected:
77 uno::Reference< frame::XModel > m_xModel;
78 uno::Reference< beans::XPropertySet > mxProps;
79 public:
80 PropertGetSetHelper( const uno::Reference< frame::XModel >& xModel ):m_xModel( xModel )
82 uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( m_xModel, uno::UNO_QUERY_THROW );
83 mxProps.set( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW );
85 virtual ~PropertGetSetHelper() {}
86 virtual uno::Any getPropertyValue( const rtl::OUString& rPropName ) = 0;
87 virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue ) = 0;
88 virtual uno::Reference< beans::XPropertySet > getUnoProperties() { return mxProps; }
92 class BuiltinPropertyGetSetHelper : public PropertGetSetHelper
94 public:
95 BuiltinPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel )
98 virtual uno::Any getPropertyValue( const rtl::OUString& rPropName )
100 if ( rPropName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("EditingDuration" ) ) ) )
102 sal_Int32 nSecs = 0;
103 mxProps->getPropertyValue( rPropName ) >>= nSecs;
104 return uno::makeAny( nSecs/60 ); // minutes
106 return mxProps->getPropertyValue( rPropName );
108 virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue )
110 mxProps->setPropertyValue( rPropName, aValue );
114 class CustomPropertyGetSetHelper : public BuiltinPropertyGetSetHelper
116 public:
117 CustomPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :BuiltinPropertyGetSetHelper( xModel )
119 uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( mxProps, uno::UNO_QUERY_THROW );
120 uno::Reference< document::XDocumentProperties > xDocProp( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
121 mxProps.set( xDocProp->getUserDefinedProperties(), uno::UNO_QUERY_THROW );
124 class StatisticPropertyGetSetHelper : public PropertGetSetHelper
126 SwDocShell* mpDocShell;
127 uno::Reference< beans::XPropertySet > mxModelProps;
128 public:
129 StatisticPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( NULL )
131 mxModelProps.set( m_xModel, uno::UNO_QUERY_THROW );
132 mpDocShell = word::getDocShell( xModel );
134 virtual uno::Any getPropertyValue( const rtl::OUString& rPropName )
136 uno::Sequence< beans::NamedValue > stats;
137 try
139 // Characters, ParagraphCount & WordCount are available from
140 // the model ( and addtionally these also update the statics object )
141 //return mxProps->getPropertyValue( rPropName );
142 return mxModelProps->getPropertyValue( rPropName );
144 catch( uno::Exception& )
146 OSL_TRACE("Got exception");
148 uno::Any aReturn;
149 if ( rPropName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineCount")) ) ) // special processing needed
151 if ( mpDocShell )
153 SwFEShell* pFEShell = mpDocShell->GetFEShell();
154 if(pFEShell)
156 aReturn <<= pFEShell->GetLineCount(FALSE);
160 else
162 mxModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ParagraphCount") ) ) >>= stats;
163 mxProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ) ) >>= stats;
165 sal_Int32 nLen = stats.getLength();
166 bool bFound = false;
167 for ( sal_Int32 index = 0; index < nLen && !bFound ; ++index )
169 if ( rPropName.equals( stats[ index ].Name ) )
171 aReturn = stats[ index ].Value;
172 bFound = true;
175 if ( !bFound )
176 throw uno::RuntimeException(); // bad Property
178 return aReturn;
181 virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue )
184 uno::Sequence< beans::NamedValue > stats;
185 mxProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ) ) >>= stats;
187 sal_Int32 nLen = stats.getLength();
188 for ( sal_Int32 index = 0; index < nLen; ++index )
190 if ( rPropName.equals( stats[ index ].Name ) )
192 stats[ index ].Value = aValue;
193 mxProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ), uno::makeAny( stats ) );
194 break;
200 class DocPropInfo
202 public:
203 rtl::OUString msMSODesc;
204 rtl::OUString msOOOPropName;
205 boost::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
207 static DocPropInfo createDocPropInfo( const rtl::OUString& sDesc, const rtl::OUString& sPropName, boost::shared_ptr< PropertGetSetHelper >& rHelper )
209 return createDocPropInfo( rtl::OUStringToOString( sDesc, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sPropName, RTL_TEXTENCODING_UTF8 ).getStr(), rHelper );
212 static DocPropInfo createDocPropInfo( const sal_Char* sDesc, const sal_Char* sPropName, boost::shared_ptr< PropertGetSetHelper >& rHelper )
214 DocPropInfo aItem;
215 aItem.msMSODesc = rtl::OUString::createFromAscii( sDesc );
216 aItem.msOOOPropName = rtl::OUString::createFromAscii( sPropName );
217 aItem.mpPropGetSetHelper = rHelper;
218 return aItem;
220 uno::Any getValue()
222 if ( mpPropGetSetHelper.get() )
223 return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
224 return uno::Any();
226 void setValue( const uno::Any& rValue )
228 if ( mpPropGetSetHelper.get() )
229 mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
231 uno::Reference< beans::XPropertySet > getUnoProperties()
234 uno::Reference< beans::XPropertySet > xProps;
235 if ( mpPropGetSetHelper.get() )
236 return mpPropGetSetHelper->getUnoProperties();
237 return xProps;
242 typedef std::hash_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;
244 class BuiltInIndexHelper
246 MSOIndexToOODocPropInfo m_docPropInfoMap;
247 BuiltInIndexHelper();
248 public:
249 BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel )
251 boost::shared_ptr< PropertGetSetHelper > aStandardHelper( new BuiltinPropertyGetSetHelper( xModel ) );
252 boost::shared_ptr< PropertGetSetHelper > aUsingStatsHelper( new StatisticPropertyGetSetHelper( xModel ) );
254 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper );
255 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper );
256 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper );
257 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper );
258 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper );
259 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper );
260 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
261 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
262 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
263 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
264 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper );
265 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper );
266 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct
267 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ?
268 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ?
269 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ?
270 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist
271 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in
272 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist
273 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in
274 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in
275 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 )
276 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling
277 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling
278 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist
279 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist
280 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper ); // doesn't seem to exist
281 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist
282 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper );
283 m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported
286 MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
290 typedef InheritedHelperInterfaceImpl1< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE;
292 class SwVbaBuiltInDocumentProperty : public SwVbaDocumentProperty_BASE
294 protected:
295 DocPropInfo mPropInfo;
296 public:
297 SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
298 // XDocumentProperty
299 virtual void SAL_CALL Delete( ) throw (script::BasicErrorException, uno::RuntimeException);
300 virtual ::rtl::OUString SAL_CALL getName( ) throw (script::BasicErrorException, uno::RuntimeException);
301 virtual void SAL_CALL setName( const ::rtl::OUString& Name ) throw (script::BasicErrorException, uno::RuntimeException);
302 virtual ::sal_Int8 SAL_CALL getType( ) throw (script::BasicErrorException, uno::RuntimeException);
303 virtual void SAL_CALL setType( ::sal_Int8 Type ) throw (script::BasicErrorException, uno::RuntimeException);
304 virtual ::sal_Bool SAL_CALL getLinkToContent( ) throw (script::BasicErrorException, uno::RuntimeException);
305 virtual void SAL_CALL setLinkToContent( ::sal_Bool LinkToContent ) throw (script::BasicErrorException, uno::RuntimeException);
306 virtual uno::Any SAL_CALL getValue( ) throw (script::BasicErrorException, uno::RuntimeException);
307 virtual void SAL_CALL setValue( const uno::Any& Value ) throw (script::BasicErrorException, uno::RuntimeException);
308 virtual rtl::OUString SAL_CALL getLinkSource( ) throw (script::BasicErrorException, uno::RuntimeException);
309 virtual void SAL_CALL setLinkSource( const rtl::OUString& LinkSource ) throw (script::BasicErrorException, uno::RuntimeException);
310 //XDefaultProperty
311 virtual ::rtl::OUString SAL_CALL getDefaultPropertyName( ) throw (uno::RuntimeException) { return rtl::OUString::createFromAscii("Value"); }
312 // XHelperInterface
313 virtual rtl::OUString& getServiceImplName();
314 virtual uno::Sequence<rtl::OUString> getServiceNames();
317 class SwVbaCustomDocumentProperty : public SwVbaBuiltInDocumentProperty
319 public:
321 SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
323 virtual ::sal_Bool SAL_CALL getLinkToContent( ) throw (script::BasicErrorException, uno::RuntimeException);
324 virtual void SAL_CALL setLinkToContent( ::sal_Bool LinkToContent ) throw (script::BasicErrorException, uno::RuntimeException);
326 virtual rtl::OUString SAL_CALL getLinkSource( ) throw (script::BasicErrorException, uno::RuntimeException);
327 virtual void SAL_CALL setLinkSource( const rtl::OUString& LinkSource ) throw (script::BasicErrorException, uno::RuntimeException);
328 virtual void SAL_CALL Delete( ) throw (script::BasicErrorException, uno::RuntimeException);
329 virtual void SAL_CALL setName( const ::rtl::OUString& Name ) throw (script::BasicErrorException, uno::RuntimeException);
330 virtual void SAL_CALL setType( ::sal_Int8 Type ) throw (script::BasicErrorException, uno::RuntimeException);
335 SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
339 sal_Bool
340 SwVbaCustomDocumentProperty::getLinkToContent( ) throw (script::BasicErrorException, uno::RuntimeException)
342 // #FIXME we need to store the link content somewhere
343 return sal_False;
346 void
347 SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool /*bLinkContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
351 rtl::OUString
352 SwVbaCustomDocumentProperty::getLinkSource( ) throw (script::BasicErrorException, uno::RuntimeException)
354 // #FIXME we need to store the link content somewhere
355 return rtl::OUString();;
358 void
359 SwVbaCustomDocumentProperty::setLinkSource( const rtl::OUString& /*rsLinkContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
361 // #FIXME we need to store the link source somewhere
364 void SAL_CALL
365 SwVbaCustomDocumentProperty::setName( const ::rtl::OUString& /*Name*/ ) throw (script::BasicErrorException, uno::RuntimeException)
367 // setName on existing property ?
368 // #FIXME
369 // do we need to delete existing property and create a new one?
372 void SAL_CALL
373 SwVbaCustomDocumentProperty::setType( ::sal_Int8 /*Type*/ ) throw (script::BasicErrorException, uno::RuntimeException)
375 // setType, do we need to do a conversion?
376 // #FIXME the underlying value needs to be changed to the new type
379 void SAL_CALL
380 SwVbaCustomDocumentProperty::Delete( ) throw (script::BasicErrorException, uno::RuntimeException)
382 uno::Reference< beans::XPropertyContainer > xContainer( mPropInfo.getUnoProperties(), uno::UNO_QUERY_THROW );
383 xContainer->removeProperty( getName() );
386 SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo( rInfo )
390 void SAL_CALL
391 SwVbaBuiltInDocumentProperty::Delete( ) throw (script::BasicErrorException, uno::RuntimeException)
393 // not valid for Builtin
394 throw uno::RuntimeException();
397 ::rtl::OUString SAL_CALL
398 SwVbaBuiltInDocumentProperty::getName( ) throw (script::BasicErrorException, uno::RuntimeException)
400 return mPropInfo.msMSODesc;
403 void SAL_CALL
404 SwVbaBuiltInDocumentProperty::setName( const rtl::OUString& ) throw (script::BasicErrorException, uno::RuntimeException)
406 // not valid for Builtin
407 throw uno::RuntimeException();
410 ::sal_Int8 SAL_CALL
411 SwVbaBuiltInDocumentProperty::getType( ) throw (script::BasicErrorException, uno::RuntimeException)
413 return lcl_toMSOPropType( getValue().getValueType() );
416 void SAL_CALL
417 SwVbaBuiltInDocumentProperty::setType( ::sal_Int8 /*Type*/ ) throw (script::BasicErrorException, uno::RuntimeException)
419 // not valid for Builtin
420 throw uno::RuntimeException();
423 ::sal_Bool SAL_CALL
424 SwVbaBuiltInDocumentProperty::getLinkToContent( ) throw (script::BasicErrorException, uno::RuntimeException)
426 return sal_False; // built-in always false
429 void SAL_CALL
430 SwVbaBuiltInDocumentProperty::setLinkToContent( ::sal_Bool /*LinkToContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
432 // not valid for Builtin
433 throw uno::RuntimeException();
436 uno::Any SAL_CALL
437 SwVbaBuiltInDocumentProperty::getValue( ) throw (script::BasicErrorException, uno::RuntimeException)
439 uno::Any aRet = mPropInfo.getValue();
440 if ( !aRet.hasValue() )
441 throw uno::RuntimeException();
442 return aRet;
445 void SAL_CALL
446 SwVbaBuiltInDocumentProperty::setValue( const uno::Any& Value ) throw (script::BasicErrorException, uno::RuntimeException)
448 mPropInfo.setValue( Value );
451 rtl::OUString SAL_CALL
452 SwVbaBuiltInDocumentProperty::getLinkSource( ) throw (script::BasicErrorException, uno::RuntimeException)
454 // not valid for Builtin
455 throw uno::RuntimeException();
458 void SAL_CALL
459 SwVbaBuiltInDocumentProperty::setLinkSource( const rtl::OUString& /*LinkSource*/ ) throw (script::BasicErrorException, uno::RuntimeException)
461 // not valid for Builtin
462 throw uno::RuntimeException();
465 rtl::OUString&
466 SwVbaBuiltInDocumentProperty::getServiceImplName()
468 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBuiltinDocumentProperty") );
469 return sImplName;
472 uno::Sequence<rtl::OUString>
473 SwVbaBuiltInDocumentProperty::getServiceNames()
475 static uno::Sequence< rtl::OUString > aServiceNames;
476 if ( aServiceNames.getLength() == 0 )
478 aServiceNames.realloc( 1 );
479 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.DocumentProperty" ) );
481 return aServiceNames;
483 typedef ::cppu::WeakImplHelper3< com::sun::star::container::XIndexAccess
484 ,com::sun::star::container::XNameAccess
485 ,com::sun::star::container::XEnumerationAccess
486 > PropertiesImpl_BASE;
488 typedef std::hash_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;
490 typedef ::cppu::WeakImplHelper1< com::sun::star::container::XEnumeration > DocPropEnumeration_BASE;
491 class DocPropEnumeration : public DocPropEnumeration_BASE
493 DocProps mDocProps;
494 DocProps::iterator mIt;
495 public:
497 DocPropEnumeration( const DocProps& rProps ) : mDocProps( rProps ), mIt( mDocProps.begin() ) {}
498 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException)
500 return mIt != mDocProps.end();
502 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
504 if ( !hasMoreElements() )
505 throw container::NoSuchElementException();
506 return uno::makeAny( mIt++->second );
510 typedef std::hash_map< rtl::OUString, uno::Reference< XDocumentProperty >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > DocPropsByName;
512 class BuiltInPropertiesImpl : public PropertiesImpl_BASE
514 protected:
516 uno::Reference< XHelperInterface > m_xParent;
517 uno::Reference< uno::XComponentContext > m_xContext;
518 uno::Reference< frame::XModel > m_xModel;
519 uno::Reference< document::XDocumentInfo > m_xOOOBuiltIns;
521 DocProps mDocProps;
522 DocPropsByName mNamedDocProps;
524 public:
525 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 )
527 BuiltInIndexHelper builtIns( m_xModel );
528 for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
530 mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
531 mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
534 // XIndexAccess
535 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
537 return mDocProps.size();
539 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException )
541 // correct the correct by the base class for 1 based indices
542 DocProps::iterator it = mDocProps.find( ++Index );
543 if ( it == mDocProps.end() )
544 throw lang::IndexOutOfBoundsException();
545 return uno::makeAny( it->second );
547 virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
549 if ( !hasByName( aName ) )
550 throw container::NoSuchElementException();
551 DocPropsByName::iterator it = mNamedDocProps.find( aName );
552 return uno::Any( it->second );
555 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
557 uno::Sequence< rtl::OUString > aNames( getCount() );
558 rtl::OUString* pName = aNames.getArray();
559 DocPropsByName::iterator it_end = mNamedDocProps.end();
560 for( DocPropsByName::iterator it = mNamedDocProps.begin(); it != it_end; ++it, ++pName )
561 *pName = it->first;
562 return aNames;
565 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
567 DocPropsByName::iterator it = mNamedDocProps.find( aName );
568 if ( it == mNamedDocProps.end() )
569 return sal_False;
570 return sal_True;
572 // XElementAccess
573 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
575 return XDocumentProperty::static_type(0);
577 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
579 return mDocProps.size() > 0;
581 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
583 return new DocPropEnumeration( mDocProps );
587 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 )
591 uno::Reference< XDocumentProperty > SAL_CALL
592 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)
594 throw uno::RuntimeException(
595 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("not supported for Builtin properties") ), uno::Reference< uno::XInterface >() );
598 // XEnumerationAccess
599 uno::Type SAL_CALL
600 SwVbaBuiltinDocumentProperties::getElementType() throw (uno::RuntimeException)
602 return XDocumentProperty::static_type(0);
605 uno::Reference< container::XEnumeration > SAL_CALL
606 SwVbaBuiltinDocumentProperties::createEnumeration() throw (uno::RuntimeException)
608 uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
609 return xEnumAccess->createEnumeration();
612 // ScVbaCollectionBaseImpl
613 uno::Any
614 SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any& aSource )
616 // pass through
617 return aSource;
620 // XHelperInterface
621 rtl::OUString&
622 SwVbaBuiltinDocumentProperties::getServiceImplName()
624 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBuiltinDocumentProperties") );
625 return sImplName;
628 uno::Sequence<rtl::OUString>
629 SwVbaBuiltinDocumentProperties::getServiceNames()
631 static uno::Sequence< rtl::OUString > aServiceNames;
632 if ( aServiceNames.getLength() == 0 )
634 aServiceNames.realloc( 1 );
635 aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.DocumentProperties" ) );
637 return aServiceNames;
640 class CustomPropertiesImpl : public PropertiesImpl_BASE
642 uno::Reference< XHelperInterface > m_xParent;
643 uno::Reference< uno::XComponentContext > m_xContext;
644 uno::Reference< frame::XModel > m_xModel;
645 uno::Reference< beans::XPropertySet > mxUserDefinedProp;
646 boost::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
647 public:
648 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 )
650 // suck in the document( custom ) properties
651 uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( m_xModel, uno::UNO_QUERY_THROW );
652 uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW );
653 uno::Reference< document::XDocumentProperties > xDocProp( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
654 mxUserDefinedProp.set( xDocProp->getUserDefinedProperties(), uno::UNO_QUERY_THROW );
655 mpPropGetSetHelper.reset( new CustomPropertyGetSetHelper( m_xModel ) );
657 // XIndexAccess
658 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException)
660 return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
663 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException )
665 uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
666 if ( Index >= aProps.getLength() )
667 throw lang::IndexOutOfBoundsException();
668 // How to determine type e.g Date? ( com.sun.star.util.DateTime )
669 DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
670 return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
673 virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
675 if ( !hasByName( aName ) )
676 throw container::NoSuchElementException();
678 DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
679 return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
682 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException)
684 uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
685 uno::Sequence< rtl::OUString > aNames( aProps.getLength() );
686 rtl::OUString* pString = aNames.getArray();
687 rtl::OUString* pEnd = ( pString + aNames.getLength() );
688 beans::Property* pProp = aProps.getArray();
689 for ( ; pString != pEnd; ++pString, ++pProp )
690 *pString = pProp->Name;
691 return aNames;
694 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
696 OSL_TRACE("hasByName(%s) returns %d", rtl::OUStringToOString( aName, RTL_TEXTENCODING_UTF8 ).getStr(), mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
697 return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
700 // XElementAccess
701 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException)
703 return XDocumentProperty::static_type(0);
706 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException)
708 return getCount() > 0;
711 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException)
713 // create a map of properties ( the key doesn't matter )
714 OSL_TRACE("Creating an enumeration");
715 sal_Int32 key = 0;
716 sal_Int32 nElem = getCount();
717 DocProps simpleDocPropSnapShot;
718 for ( ; key < nElem; ++key )
719 simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
720 OSL_TRACE("After creating the enumeration");
721 return new DocPropEnumeration( simpleDocPropSnapShot );
724 void addProp( const ::rtl::OUString& Name, ::sal_Int8 /*Type*/, const uno::Any& Value )
726 sal_Int16 attributes = 128;
727 uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
728 // TODO fixme, perform the necessary Type Value conversions
729 xContainer->addProperty( Name, attributes, Value );
735 SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
737 // replace the m_xIndexAccess implementation ( we need a virtual init )
738 m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
739 m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
742 uno::Reference< XDocumentProperty > SAL_CALL
743 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)
745 CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
746 uno::Reference< XDocumentProperty > xDocProp;
747 if ( pCustomProps )
749 rtl::OUString sLinkSource;
750 pCustomProps->addProp( Name, Type, Value );
752 xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
753 xDocProp->setLinkToContent( LinkToContent );
755 if ( LinkSource >>= sLinkSource )
756 xDocProp->setLinkSource( sLinkSource );
758 return xDocProp;
761 // XHelperInterface
762 rtl::OUString&
763 SwVbaCustomDocumentProperties::getServiceImplName()
765 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaCustomDocumentProperties") );
766 return sImplName;