1*efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*efeef26fSAndrew Rist  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*efeef26fSAndrew Rist  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19*efeef26fSAndrew Rist  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir #include "vbadocumentproperties.hxx"
24cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
25cdf0e10cSrcweir #include <cppuhelper/implbase3.hxx>
26cdf0e10cSrcweir #include <com/sun/star/document/XDocumentInfoSupplier.hpp>
27cdf0e10cSrcweir #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
28cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
29cdf0e10cSrcweir #include <com/sun/star/beans/XPropertyContainer.hpp>
30cdf0e10cSrcweir #include <ooo/vba/word/WdBuiltInProperty.hpp>
31cdf0e10cSrcweir #include <ooo/vba/office/MsoDocProperties.hpp>
32cdf0e10cSrcweir #include <memory>
33cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
34cdf0e10cSrcweir #include "wordvbahelper.hxx"
35cdf0e10cSrcweir #include "fesh.hxx"
36cdf0e10cSrcweir #include "docsh.hxx"
37cdf0e10cSrcweir using namespace ::ooo::vba;
38cdf0e10cSrcweir using namespace css;
39cdf0e10cSrcweir 
lcl_toMSOPropType(const uno::Type & aType)40cdf0e10cSrcweir sal_Int8 lcl_toMSOPropType( const uno::Type& aType ) throw ( lang::IllegalArgumentException )
41cdf0e10cSrcweir {
42cdf0e10cSrcweir     sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir     switch ( aType.getTypeClass() )
45cdf0e10cSrcweir     {
46cdf0e10cSrcweir         case uno::TypeClass_BOOLEAN:
47cdf0e10cSrcweir             msoType =  office::MsoDocProperties::msoPropertyTypeBoolean;
48cdf0e10cSrcweir             break;
49cdf0e10cSrcweir         case uno::TypeClass_FLOAT:
50cdf0e10cSrcweir             msoType =  office::MsoDocProperties::msoPropertyTypeFloat;
51cdf0e10cSrcweir             break;
52cdf0e10cSrcweir         case uno::TypeClass_STRUCT: // Assume date
53cdf0e10cSrcweir             msoType =  office::MsoDocProperties::msoPropertyTypeDate;
54cdf0e10cSrcweir             break;
55cdf0e10cSrcweir         case  uno::TypeClass_BYTE:
56cdf0e10cSrcweir         case  uno::TypeClass_SHORT:
57cdf0e10cSrcweir         case  uno::TypeClass_LONG:
58cdf0e10cSrcweir         case  uno::TypeClass_HYPER:
59cdf0e10cSrcweir             msoType =  office::MsoDocProperties::msoPropertyTypeNumber;
60cdf0e10cSrcweir             break;
61cdf0e10cSrcweir         default:
62cdf0e10cSrcweir             throw lang::IllegalArgumentException();
63cdf0e10cSrcweir     }
64cdf0e10cSrcweir     return msoType;
65cdf0e10cSrcweir }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir class PropertGetSetHelper
68cdf0e10cSrcweir {
69cdf0e10cSrcweir protected:
70cdf0e10cSrcweir     uno::Reference< frame::XModel > m_xModel;
71cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > mxProps;
72cdf0e10cSrcweir public:
PropertGetSetHelper(const uno::Reference<frame::XModel> & xModel)73cdf0e10cSrcweir     PropertGetSetHelper( const uno::Reference< frame::XModel >& xModel ):m_xModel( xModel )
74cdf0e10cSrcweir     {
75cdf0e10cSrcweir         uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( m_xModel, uno::UNO_QUERY_THROW );
76cdf0e10cSrcweir         mxProps.set( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW );
77cdf0e10cSrcweir     }
~PropertGetSetHelper()78cdf0e10cSrcweir     virtual ~PropertGetSetHelper() {}
79cdf0e10cSrcweir     virtual uno::Any getPropertyValue( const rtl::OUString& rPropName ) = 0;
80cdf0e10cSrcweir     virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue ) = 0;
getUnoProperties()81cdf0e10cSrcweir     virtual uno::Reference< beans::XPropertySet > getUnoProperties() { return mxProps; }
82cdf0e10cSrcweir 
83cdf0e10cSrcweir };
84cdf0e10cSrcweir 
85cdf0e10cSrcweir class BuiltinPropertyGetSetHelper : public PropertGetSetHelper
86cdf0e10cSrcweir {
87cdf0e10cSrcweir public:
BuiltinPropertyGetSetHelper(const uno::Reference<frame::XModel> & xModel)88cdf0e10cSrcweir     BuiltinPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel )
89cdf0e10cSrcweir     {
90cdf0e10cSrcweir     }
getPropertyValue(const rtl::OUString & rPropName)91cdf0e10cSrcweir     virtual uno::Any getPropertyValue( const rtl::OUString& rPropName )
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         if ( rPropName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("EditingDuration" ) ) ) )
94cdf0e10cSrcweir         {
95cdf0e10cSrcweir             sal_Int32 nSecs = 0;
96cdf0e10cSrcweir             mxProps->getPropertyValue( rPropName ) >>= nSecs;
97cdf0e10cSrcweir             return uno::makeAny( nSecs/60 ); // minutes
98cdf0e10cSrcweir         }
99cdf0e10cSrcweir         return mxProps->getPropertyValue( rPropName );
100cdf0e10cSrcweir     }
setPropertyValue(const rtl::OUString & rPropName,const uno::Any & aValue)101cdf0e10cSrcweir     virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue )
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         mxProps->setPropertyValue( rPropName, aValue );
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir };
106cdf0e10cSrcweir 
107cdf0e10cSrcweir class CustomPropertyGetSetHelper : public BuiltinPropertyGetSetHelper
108cdf0e10cSrcweir {
109cdf0e10cSrcweir public:
CustomPropertyGetSetHelper(const uno::Reference<frame::XModel> & xModel)110cdf0e10cSrcweir     CustomPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :BuiltinPropertyGetSetHelper( xModel )
111cdf0e10cSrcweir     {
112cdf0e10cSrcweir         uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( mxProps, uno::UNO_QUERY_THROW );
113cdf0e10cSrcweir         uno::Reference< document::XDocumentProperties > xDocProp( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
114cdf0e10cSrcweir         mxProps.set( xDocProp->getUserDefinedProperties(), uno::UNO_QUERY_THROW );
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir };
117cdf0e10cSrcweir class StatisticPropertyGetSetHelper : public PropertGetSetHelper
118cdf0e10cSrcweir {
119cdf0e10cSrcweir     SwDocShell* mpDocShell;
120cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > mxModelProps;
121cdf0e10cSrcweir public:
StatisticPropertyGetSetHelper(const uno::Reference<frame::XModel> & xModel)122cdf0e10cSrcweir     StatisticPropertyGetSetHelper( const uno::Reference< frame::XModel >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( NULL )
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir             mxModelProps.set( m_xModel, uno::UNO_QUERY_THROW );
125cdf0e10cSrcweir             mpDocShell = word::getDocShell( xModel );
126cdf0e10cSrcweir     }
getPropertyValue(const rtl::OUString & rPropName)127cdf0e10cSrcweir     virtual uno::Any getPropertyValue( const rtl::OUString& rPropName )
128cdf0e10cSrcweir     {
129cdf0e10cSrcweir         uno::Sequence< beans::NamedValue > stats;
130cdf0e10cSrcweir         try
131cdf0e10cSrcweir         {
132cdf0e10cSrcweir             // Characters, ParagraphCount & WordCount are available from
133cdf0e10cSrcweir             // the model ( and addtionally these also update the statics object )
134cdf0e10cSrcweir             //return mxProps->getPropertyValue( rPropName );
135cdf0e10cSrcweir             return mxModelProps->getPropertyValue( rPropName );
136cdf0e10cSrcweir         }
137cdf0e10cSrcweir         catch( uno::Exception& )
138cdf0e10cSrcweir         {
139cdf0e10cSrcweir             OSL_TRACE("Got exception");
140cdf0e10cSrcweir         }
141cdf0e10cSrcweir         uno::Any aReturn;
142cdf0e10cSrcweir         if ( rPropName.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LineCount")) ) ) // special processing needed
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             if ( mpDocShell )
145cdf0e10cSrcweir             {
146cdf0e10cSrcweir                 SwFEShell* pFEShell = mpDocShell->GetFEShell();
147cdf0e10cSrcweir                 if(pFEShell)
148cdf0e10cSrcweir                 {
149cdf0e10cSrcweir                     aReturn <<= pFEShell->GetLineCount(sal_False);
150cdf0e10cSrcweir                 }
151cdf0e10cSrcweir             }
152cdf0e10cSrcweir         }
153cdf0e10cSrcweir         else
154cdf0e10cSrcweir         {
155cdf0e10cSrcweir             mxModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ParagraphCount") ) ) >>= stats;
156cdf0e10cSrcweir             mxProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ) ) >>= stats;
157cdf0e10cSrcweir 
158cdf0e10cSrcweir             sal_Int32 nLen = stats.getLength();
159cdf0e10cSrcweir             bool bFound = false;
160cdf0e10cSrcweir             for ( sal_Int32 index = 0; index < nLen && !bFound ; ++index )
161cdf0e10cSrcweir             {
162cdf0e10cSrcweir                 if ( rPropName.equals( stats[ index ].Name ) )
163cdf0e10cSrcweir                 {
164cdf0e10cSrcweir                     aReturn = stats[ index ].Value;
165cdf0e10cSrcweir                     bFound = true;
166cdf0e10cSrcweir                 }
167cdf0e10cSrcweir             }
168cdf0e10cSrcweir             if ( !bFound )
169cdf0e10cSrcweir                 throw uno::RuntimeException(); // bad Property
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir         return aReturn;
172cdf0e10cSrcweir     }
173cdf0e10cSrcweir 
setPropertyValue(const rtl::OUString & rPropName,const uno::Any & aValue)174cdf0e10cSrcweir     virtual void setPropertyValue( const rtl::OUString& rPropName, const uno::Any& aValue )
175cdf0e10cSrcweir     {
176cdf0e10cSrcweir 
177cdf0e10cSrcweir         uno::Sequence< beans::NamedValue > stats;
178cdf0e10cSrcweir         mxProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ) ) >>= stats;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir         sal_Int32 nLen = stats.getLength();
181cdf0e10cSrcweir         for ( sal_Int32 index = 0; index < nLen; ++index )
182cdf0e10cSrcweir         {
183cdf0e10cSrcweir             if ( rPropName.equals( stats[ index ].Name ) )
184cdf0e10cSrcweir             {
185cdf0e10cSrcweir                 stats[ index ].Value = aValue;
186cdf0e10cSrcweir                 mxProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DocumentStatistic") ), uno::makeAny( stats ) );
187cdf0e10cSrcweir                 break;
188cdf0e10cSrcweir             }
189cdf0e10cSrcweir         }
190cdf0e10cSrcweir     }
191cdf0e10cSrcweir };
192cdf0e10cSrcweir 
193cdf0e10cSrcweir class DocPropInfo
194cdf0e10cSrcweir {
195cdf0e10cSrcweir public:
196cdf0e10cSrcweir     rtl::OUString msMSODesc;
197cdf0e10cSrcweir     rtl::OUString msOOOPropName;
198cdf0e10cSrcweir     boost::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
199cdf0e10cSrcweir 
createDocPropInfo(const rtl::OUString & sDesc,const rtl::OUString & sPropName,boost::shared_ptr<PropertGetSetHelper> & rHelper)200cdf0e10cSrcweir     static DocPropInfo createDocPropInfo( const rtl::OUString& sDesc, const rtl::OUString& sPropName, boost::shared_ptr< PropertGetSetHelper >& rHelper )
201cdf0e10cSrcweir     {
202cdf0e10cSrcweir         return createDocPropInfo( rtl::OUStringToOString( sDesc, RTL_TEXTENCODING_UTF8 ).getStr(), rtl::OUStringToOString( sPropName, RTL_TEXTENCODING_UTF8 ).getStr(), rHelper );
203cdf0e10cSrcweir     }
204cdf0e10cSrcweir 
createDocPropInfo(const sal_Char * sDesc,const sal_Char * sPropName,boost::shared_ptr<PropertGetSetHelper> & rHelper)205cdf0e10cSrcweir     static DocPropInfo createDocPropInfo( const sal_Char* sDesc, const sal_Char* sPropName, boost::shared_ptr< PropertGetSetHelper >& rHelper )
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir         DocPropInfo aItem;
208cdf0e10cSrcweir         aItem.msMSODesc = rtl::OUString::createFromAscii( sDesc );
209cdf0e10cSrcweir         aItem.msOOOPropName = rtl::OUString::createFromAscii( sPropName );
210cdf0e10cSrcweir         aItem.mpPropGetSetHelper = rHelper;
211cdf0e10cSrcweir         return aItem;
212cdf0e10cSrcweir     }
getValue()213cdf0e10cSrcweir     uno::Any getValue()
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         if ( mpPropGetSetHelper.get() )
216cdf0e10cSrcweir             return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
217cdf0e10cSrcweir         return uno::Any();
218cdf0e10cSrcweir     }
setValue(const uno::Any & rValue)219cdf0e10cSrcweir     void setValue( const uno::Any& rValue )
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         if ( mpPropGetSetHelper.get() )
222cdf0e10cSrcweir             mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
223cdf0e10cSrcweir     }
getUnoProperties()224cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > getUnoProperties()
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > xProps;
228cdf0e10cSrcweir         if ( mpPropGetSetHelper.get() )
229cdf0e10cSrcweir             return mpPropGetSetHelper->getUnoProperties();
230cdf0e10cSrcweir         return xProps;
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir };
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 
235cdf0e10cSrcweir typedef std::hash_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;
236cdf0e10cSrcweir 
237cdf0e10cSrcweir class BuiltInIndexHelper
238cdf0e10cSrcweir {
239cdf0e10cSrcweir     MSOIndexToOODocPropInfo m_docPropInfoMap;
240cdf0e10cSrcweir     BuiltInIndexHelper();
241cdf0e10cSrcweir public:
BuiltInIndexHelper(const uno::Reference<frame::XModel> & xModel)242cdf0e10cSrcweir     BuiltInIndexHelper( const uno::Reference< frame::XModel >& xModel )
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         boost::shared_ptr< PropertGetSetHelper > aStandardHelper( new BuiltinPropertyGetSetHelper( xModel ) );
245cdf0e10cSrcweir         boost::shared_ptr< PropertGetSetHelper > aUsingStatsHelper( new StatisticPropertyGetSetHelper( xModel ) );
246cdf0e10cSrcweir 
247cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title", "Title", aStandardHelper );
248cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject", "Subject", aStandardHelper );
249cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author", "Author", aStandardHelper );
250cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords", "Keywords", aStandardHelper );
251cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments", "Description", aStandardHelper );
252cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template", "Template", aStandardHelper );
253cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author", "ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
254cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number", "EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
255cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name", "Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
256cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date", "PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
257cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date", "CreationDate", aStandardHelper );
258cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time", "ModifyDate", aStandardHelper );
259cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time", "EditingDuration", aStandardHelper ); // Not sure if this is correct
260cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages", "PageCount", aUsingStatsHelper ); // special handling required ?
261cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words", "WordCount", aUsingStatsHelper ); // special handling require ?
262cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters", "CharacterCount", aUsingStatsHelper ); // special handling required ?
263cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security", "", aStandardHelper ); // doesn't seem to exist
264cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category", "Category", aStandardHelper ); // hacked in
265cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format", "", aStandardHelper ); // doesn't seem to exist
266cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager", "Manager", aStandardHelper ); // hacked in
267cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company", "Company", aStandardHelper ); // hacked in
268cdf0e10cSrcweir         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 )
269cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines", "LineCount", aUsingStatsHelper ); // special handling
270cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs", "ParagraphCount", aUsingStatsHelper ); // special handling
271cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides", "" , aStandardHelper ); // doesn't seem to exist
272cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes", "", aStandardHelper ); // doesn't seem to exist
273cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides", "", aStandardHelper  ); // doesn't seem to exist
274cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips", "", aStandardHelper ); // doesn't seem to exist
275cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base", "AutoloadURL", aStandardHelper );
276cdf0e10cSrcweir         m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)", "", aStandardHelper ); // doesn't seem to be supported
277cdf0e10cSrcweir     }
278cdf0e10cSrcweir 
getDocPropInfoMap()279cdf0e10cSrcweir     MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
280cdf0e10cSrcweir };
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 
283cdf0e10cSrcweir typedef InheritedHelperInterfaceImpl1< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE;
284cdf0e10cSrcweir 
285cdf0e10cSrcweir class SwVbaBuiltInDocumentProperty : public SwVbaDocumentProperty_BASE
286cdf0e10cSrcweir {
287cdf0e10cSrcweir protected:
288cdf0e10cSrcweir     DocPropInfo mPropInfo;
289cdf0e10cSrcweir public:
290cdf0e10cSrcweir     SwVbaBuiltInDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
291cdf0e10cSrcweir     // XDocumentProperty
292cdf0e10cSrcweir     virtual void SAL_CALL Delete(  ) throw (script::BasicErrorException, uno::RuntimeException);
293cdf0e10cSrcweir     virtual ::rtl::OUString SAL_CALL getName(  ) throw (script::BasicErrorException, uno::RuntimeException);
294cdf0e10cSrcweir     virtual void SAL_CALL setName( const ::rtl::OUString& Name ) throw (script::BasicErrorException, uno::RuntimeException);
295cdf0e10cSrcweir     virtual ::sal_Int8 SAL_CALL getType(  ) throw (script::BasicErrorException, uno::RuntimeException);
296cdf0e10cSrcweir     virtual void SAL_CALL setType( ::sal_Int8 Type ) throw (script::BasicErrorException, uno::RuntimeException);
297cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL getLinkToContent(  ) throw (script::BasicErrorException, uno::RuntimeException);
298cdf0e10cSrcweir     virtual void SAL_CALL setLinkToContent( ::sal_Bool LinkToContent ) throw (script::BasicErrorException, uno::RuntimeException);
299cdf0e10cSrcweir     virtual uno::Any SAL_CALL getValue(  ) throw (script::BasicErrorException, uno::RuntimeException);
300cdf0e10cSrcweir     virtual void SAL_CALL setValue( const uno::Any& Value ) throw (script::BasicErrorException, uno::RuntimeException);
301cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getLinkSource(  ) throw (script::BasicErrorException, uno::RuntimeException);
302cdf0e10cSrcweir     virtual void SAL_CALL setLinkSource( const rtl::OUString& LinkSource ) throw (script::BasicErrorException, uno::RuntimeException);
303cdf0e10cSrcweir     //XDefaultProperty
getDefaultPropertyName()304cdf0e10cSrcweir     virtual ::rtl::OUString SAL_CALL getDefaultPropertyName(  ) throw (uno::RuntimeException) { return rtl::OUString::createFromAscii("Value"); }
305cdf0e10cSrcweir     // XHelperInterface
306cdf0e10cSrcweir     virtual rtl::OUString& getServiceImplName();
307cdf0e10cSrcweir     virtual uno::Sequence<rtl::OUString> getServiceNames();
308cdf0e10cSrcweir };
309cdf0e10cSrcweir 
310cdf0e10cSrcweir class SwVbaCustomDocumentProperty : public SwVbaBuiltInDocumentProperty
311cdf0e10cSrcweir {
312cdf0e10cSrcweir public:
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     SwVbaCustomDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL getLinkToContent(  ) throw (script::BasicErrorException, uno::RuntimeException);
317cdf0e10cSrcweir     virtual void SAL_CALL setLinkToContent( ::sal_Bool LinkToContent ) throw (script::BasicErrorException, uno::RuntimeException);
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     virtual rtl::OUString SAL_CALL getLinkSource(  ) throw (script::BasicErrorException, uno::RuntimeException);
320cdf0e10cSrcweir     virtual void SAL_CALL setLinkSource( const rtl::OUString& LinkSource ) throw (script::BasicErrorException, uno::RuntimeException);
321cdf0e10cSrcweir     virtual void SAL_CALL Delete(  ) throw (script::BasicErrorException, uno::RuntimeException);
322cdf0e10cSrcweir     virtual void SAL_CALL setName( const ::rtl::OUString& Name ) throw (script::BasicErrorException, uno::RuntimeException);
323cdf0e10cSrcweir     virtual void SAL_CALL setType( ::sal_Int8 Type ) throw (script::BasicErrorException, uno::RuntimeException);
324cdf0e10cSrcweir 
325cdf0e10cSrcweir };
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 
SwVbaCustomDocumentProperty(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const DocPropInfo & rInfo)328cdf0e10cSrcweir SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir sal_Bool
getLinkToContent()333cdf0e10cSrcweir SwVbaCustomDocumentProperty::getLinkToContent(  ) throw (script::BasicErrorException, uno::RuntimeException)
334cdf0e10cSrcweir {
335cdf0e10cSrcweir     // #FIXME we need to store the link content somewhere
336cdf0e10cSrcweir     return sal_False;
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir void
setLinkToContent(sal_Bool)340cdf0e10cSrcweir SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool /*bLinkContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
341cdf0e10cSrcweir {
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
344cdf0e10cSrcweir rtl::OUString
getLinkSource()345cdf0e10cSrcweir SwVbaCustomDocumentProperty::getLinkSource(  ) throw (script::BasicErrorException, uno::RuntimeException)
346cdf0e10cSrcweir {
347cdf0e10cSrcweir     // #FIXME we need to store the link content somewhere
348cdf0e10cSrcweir     return rtl::OUString();;
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir void
setLinkSource(const rtl::OUString &)352cdf0e10cSrcweir SwVbaCustomDocumentProperty::setLinkSource( const rtl::OUString& /*rsLinkContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     // #FIXME we need to store the link source somewhere
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir void SAL_CALL
setName(const::rtl::OUString &)358cdf0e10cSrcweir SwVbaCustomDocumentProperty::setName( const ::rtl::OUString& /*Name*/ ) throw (script::BasicErrorException, uno::RuntimeException)
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     // setName on existing property ?
361cdf0e10cSrcweir     // #FIXME
362cdf0e10cSrcweir     // do we need to delete existing property and create a new one?
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir void SAL_CALL
setType(::sal_Int8)366cdf0e10cSrcweir SwVbaCustomDocumentProperty::setType( ::sal_Int8 /*Type*/ ) throw (script::BasicErrorException, uno::RuntimeException)
367cdf0e10cSrcweir {
368cdf0e10cSrcweir     // setType, do we need to do a conversion?
369cdf0e10cSrcweir     // #FIXME the underlying value needs to be changed to the new type
370cdf0e10cSrcweir }
371cdf0e10cSrcweir 
372cdf0e10cSrcweir void SAL_CALL
Delete()373cdf0e10cSrcweir SwVbaCustomDocumentProperty::Delete(  ) throw (script::BasicErrorException, uno::RuntimeException)
374cdf0e10cSrcweir {
375cdf0e10cSrcweir     uno::Reference< beans::XPropertyContainer > xContainer( mPropInfo.getUnoProperties(), uno::UNO_QUERY_THROW );
376cdf0e10cSrcweir     xContainer->removeProperty( getName() );
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
SwVbaBuiltInDocumentProperty(const uno::Reference<ov::XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const DocPropInfo & rInfo)379cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo( rInfo )
380cdf0e10cSrcweir {
381cdf0e10cSrcweir }
382cdf0e10cSrcweir 
383cdf0e10cSrcweir void SAL_CALL
Delete()384cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::Delete(  ) throw (script::BasicErrorException, uno::RuntimeException)
385cdf0e10cSrcweir {
386cdf0e10cSrcweir     // not valid for Builtin
387cdf0e10cSrcweir     throw uno::RuntimeException();
388cdf0e10cSrcweir }
389cdf0e10cSrcweir 
390cdf0e10cSrcweir ::rtl::OUString SAL_CALL
getName()391cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getName(  ) throw (script::BasicErrorException, uno::RuntimeException)
392cdf0e10cSrcweir {
393cdf0e10cSrcweir     return mPropInfo.msMSODesc;
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir void SAL_CALL
setName(const rtl::OUString &)397cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::setName( const rtl::OUString& ) throw (script::BasicErrorException, uno::RuntimeException)
398cdf0e10cSrcweir {
399cdf0e10cSrcweir     // not valid for Builtin
400cdf0e10cSrcweir     throw uno::RuntimeException();
401cdf0e10cSrcweir }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir ::sal_Int8 SAL_CALL
getType()404cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getType(  ) throw (script::BasicErrorException, uno::RuntimeException)
405cdf0e10cSrcweir {
406cdf0e10cSrcweir     return lcl_toMSOPropType( getValue().getValueType() );
407cdf0e10cSrcweir }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir void SAL_CALL
setType(::sal_Int8)410cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::setType( ::sal_Int8 /*Type*/ ) throw (script::BasicErrorException, uno::RuntimeException)
411cdf0e10cSrcweir {
412cdf0e10cSrcweir     // not valid for Builtin
413cdf0e10cSrcweir     throw uno::RuntimeException();
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir ::sal_Bool SAL_CALL
getLinkToContent()417cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getLinkToContent(  ) throw (script::BasicErrorException, uno::RuntimeException)
418cdf0e10cSrcweir {
419cdf0e10cSrcweir     return sal_False; // built-in always false
420cdf0e10cSrcweir }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir void SAL_CALL
setLinkToContent(::sal_Bool)423cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::setLinkToContent( ::sal_Bool /*LinkToContent*/ ) throw (script::BasicErrorException, uno::RuntimeException)
424cdf0e10cSrcweir {
425cdf0e10cSrcweir     // not valid for Builtin
426cdf0e10cSrcweir     throw uno::RuntimeException();
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir uno::Any SAL_CALL
getValue()430cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getValue(  ) throw (script::BasicErrorException, uno::RuntimeException)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     uno::Any aRet = mPropInfo.getValue();
433cdf0e10cSrcweir     if ( !aRet.hasValue() )
434cdf0e10cSrcweir         throw uno::RuntimeException();
435cdf0e10cSrcweir     return aRet;
436cdf0e10cSrcweir }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir void SAL_CALL
setValue(const uno::Any & Value)439cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::setValue( const uno::Any& Value ) throw (script::BasicErrorException, uno::RuntimeException)
440cdf0e10cSrcweir {
441cdf0e10cSrcweir     mPropInfo.setValue( Value );
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir rtl::OUString SAL_CALL
getLinkSource()445cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getLinkSource(  ) throw (script::BasicErrorException, uno::RuntimeException)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     // not valid for Builtin
448cdf0e10cSrcweir     throw uno::RuntimeException();
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir void SAL_CALL
setLinkSource(const rtl::OUString &)452cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::setLinkSource( const rtl::OUString& /*LinkSource*/ ) throw (script::BasicErrorException, uno::RuntimeException)
453cdf0e10cSrcweir {
454cdf0e10cSrcweir     // not valid for Builtin
455cdf0e10cSrcweir     throw uno::RuntimeException();
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir rtl::OUString&
getServiceImplName()459cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getServiceImplName()
460cdf0e10cSrcweir {
461cdf0e10cSrcweir     static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBuiltinDocumentProperty") );
462cdf0e10cSrcweir     return sImplName;
463cdf0e10cSrcweir }
464cdf0e10cSrcweir 
465cdf0e10cSrcweir uno::Sequence<rtl::OUString>
getServiceNames()466cdf0e10cSrcweir SwVbaBuiltInDocumentProperty::getServiceNames()
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     static uno::Sequence< rtl::OUString > aServiceNames;
469cdf0e10cSrcweir     if ( aServiceNames.getLength() == 0 )
470cdf0e10cSrcweir     {
471cdf0e10cSrcweir         aServiceNames.realloc( 1 );
472cdf0e10cSrcweir         aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.DocumentProperty" ) );
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir     return aServiceNames;
475cdf0e10cSrcweir }
476cdf0e10cSrcweir typedef ::cppu::WeakImplHelper3< com::sun::star::container::XIndexAccess
477cdf0e10cSrcweir         ,com::sun::star::container::XNameAccess
478cdf0e10cSrcweir         ,com::sun::star::container::XEnumerationAccess
479cdf0e10cSrcweir         > PropertiesImpl_BASE;
480cdf0e10cSrcweir 
481cdf0e10cSrcweir typedef std::hash_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;
482cdf0e10cSrcweir 
483cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1< com::sun::star::container::XEnumeration > DocPropEnumeration_BASE;
484cdf0e10cSrcweir class DocPropEnumeration : public DocPropEnumeration_BASE
485cdf0e10cSrcweir {
486cdf0e10cSrcweir     DocProps mDocProps;
487cdf0e10cSrcweir     DocProps::iterator mIt;
488cdf0e10cSrcweir public:
489cdf0e10cSrcweir 
DocPropEnumeration(const DocProps & rProps)490cdf0e10cSrcweir     DocPropEnumeration( const DocProps& rProps ) : mDocProps( rProps ), mIt( mDocProps.begin() ) {}
hasMoreElements()491cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (uno::RuntimeException)
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         return mIt != mDocProps.end();
494cdf0e10cSrcweir     }
nextElement()495cdf0e10cSrcweir     virtual uno::Any SAL_CALL nextElement(  ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         if ( !hasMoreElements() )
498cdf0e10cSrcweir             throw container::NoSuchElementException();
499cdf0e10cSrcweir         return uno::makeAny( mIt++->second );
500cdf0e10cSrcweir     }
501cdf0e10cSrcweir };
502cdf0e10cSrcweir 
503cdf0e10cSrcweir typedef std::hash_map< rtl::OUString, uno::Reference< XDocumentProperty >, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > DocPropsByName;
504cdf0e10cSrcweir 
505cdf0e10cSrcweir class BuiltInPropertiesImpl : public PropertiesImpl_BASE
506cdf0e10cSrcweir {
507cdf0e10cSrcweir protected:
508cdf0e10cSrcweir 
509cdf0e10cSrcweir     uno::Reference< XHelperInterface > m_xParent;
510cdf0e10cSrcweir     uno::Reference< uno::XComponentContext > m_xContext;
511cdf0e10cSrcweir     uno::Reference< frame::XModel > m_xModel;
512cdf0e10cSrcweir     uno::Reference< document::XDocumentInfo > m_xOOOBuiltIns;
513cdf0e10cSrcweir 
514cdf0e10cSrcweir     DocProps mDocProps;
515cdf0e10cSrcweir     DocPropsByName mNamedDocProps;
516cdf0e10cSrcweir 
517cdf0e10cSrcweir     public:
BuiltInPropertiesImpl(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<frame::XModel> & xModel)518cdf0e10cSrcweir     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 )
519cdf0e10cSrcweir     {
520cdf0e10cSrcweir     	BuiltInIndexHelper builtIns( m_xModel );
521cdf0e10cSrcweir         for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
522cdf0e10cSrcweir         {
523cdf0e10cSrcweir             mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
524cdf0e10cSrcweir             mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
525cdf0e10cSrcweir         }
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir // XIndexAccess
getCount()528cdf0e10cSrcweir     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (uno::RuntimeException)
529cdf0e10cSrcweir     {
530cdf0e10cSrcweir         return mDocProps.size();
531cdf0e10cSrcweir     }
getByIndex(::sal_Int32 Index)532cdf0e10cSrcweir     virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException )
533cdf0e10cSrcweir     {
534cdf0e10cSrcweir         // correct the correct by the base class for 1 based indices
535cdf0e10cSrcweir         DocProps::iterator it = mDocProps.find( ++Index );
536cdf0e10cSrcweir         if ( it == mDocProps.end() )
537cdf0e10cSrcweir             throw lang::IndexOutOfBoundsException();
538cdf0e10cSrcweir         return uno::makeAny( it->second  );
539cdf0e10cSrcweir     }
getByName(const::rtl::OUString & aName)540cdf0e10cSrcweir     virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
541cdf0e10cSrcweir     {
542cdf0e10cSrcweir         if ( !hasByName( aName ) )
543cdf0e10cSrcweir 		throw container::NoSuchElementException();
544cdf0e10cSrcweir         DocPropsByName::iterator it = mNamedDocProps.find( aName );
545cdf0e10cSrcweir         return uno::Any( it->second );
546cdf0e10cSrcweir 
547cdf0e10cSrcweir     }
getElementNames()548cdf0e10cSrcweir     virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (uno::RuntimeException)
549cdf0e10cSrcweir     {
550cdf0e10cSrcweir         uno::Sequence< rtl::OUString > aNames( getCount() );
551cdf0e10cSrcweir         rtl::OUString* pName = aNames.getArray();
552cdf0e10cSrcweir         DocPropsByName::iterator it_end = mNamedDocProps.end();
553cdf0e10cSrcweir         for(  DocPropsByName::iterator it = mNamedDocProps.begin(); it != it_end; ++it, ++pName )
554cdf0e10cSrcweir            *pName = it->first;
555cdf0e10cSrcweir         return aNames;
556cdf0e10cSrcweir     }
557cdf0e10cSrcweir 
hasByName(const::rtl::OUString & aName)558cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
559cdf0e10cSrcweir     {
560cdf0e10cSrcweir         DocPropsByName::iterator it = mNamedDocProps.find( aName );
561cdf0e10cSrcweir         if ( it == mNamedDocProps.end() )
562cdf0e10cSrcweir             return sal_False;
563cdf0e10cSrcweir         return sal_True;
564cdf0e10cSrcweir     }
565cdf0e10cSrcweir // XElementAccess
getElementType()566cdf0e10cSrcweir     virtual uno::Type SAL_CALL getElementType(  ) throw (uno::RuntimeException)
567cdf0e10cSrcweir     {
568cdf0e10cSrcweir         return  XDocumentProperty::static_type(0);
569cdf0e10cSrcweir     }
hasElements()570cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (uno::RuntimeException)
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         return mDocProps.size() > 0;
573cdf0e10cSrcweir     }
createEnumeration()574cdf0e10cSrcweir     virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration(  ) throw (uno::RuntimeException)
575cdf0e10cSrcweir     {
576cdf0e10cSrcweir         return new DocPropEnumeration( mDocProps );
577cdf0e10cSrcweir     }
578cdf0e10cSrcweir };
579cdf0e10cSrcweir 
SwVbaBuiltinDocumentProperties(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<frame::XModel> & xModel)580cdf0e10cSrcweir 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 )
581cdf0e10cSrcweir {
582cdf0e10cSrcweir }
583cdf0e10cSrcweir 
584cdf0e10cSrcweir uno::Reference< XDocumentProperty > SAL_CALL
Add(const::rtl::OUString &,::sal_Bool,::sal_Int8,const uno::Any &,const uno::Any &)585cdf0e10cSrcweir 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)
586cdf0e10cSrcweir {
587cdf0e10cSrcweir     throw uno::RuntimeException(
588cdf0e10cSrcweir         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("not supported for Builtin properties") ), uno::Reference< uno::XInterface >() );
589cdf0e10cSrcweir }
590cdf0e10cSrcweir 
591cdf0e10cSrcweir // XEnumerationAccess
592cdf0e10cSrcweir uno::Type SAL_CALL
getElementType()593cdf0e10cSrcweir SwVbaBuiltinDocumentProperties::getElementType() throw (uno::RuntimeException)
594cdf0e10cSrcweir {
595cdf0e10cSrcweir     return  XDocumentProperty::static_type(0);
596cdf0e10cSrcweir }
597cdf0e10cSrcweir 
598cdf0e10cSrcweir uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()599cdf0e10cSrcweir SwVbaBuiltinDocumentProperties::createEnumeration() throw (uno::RuntimeException)
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
602cdf0e10cSrcweir     return xEnumAccess->createEnumeration();
603cdf0e10cSrcweir }
604cdf0e10cSrcweir 
605cdf0e10cSrcweir // ScVbaCollectionBaseImpl
606cdf0e10cSrcweir uno::Any
createCollectionObject(const uno::Any & aSource)607cdf0e10cSrcweir SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any& aSource )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir     // pass through
610cdf0e10cSrcweir     return aSource;
611cdf0e10cSrcweir }
612cdf0e10cSrcweir 
613cdf0e10cSrcweir // XHelperInterface
614cdf0e10cSrcweir rtl::OUString&
getServiceImplName()615cdf0e10cSrcweir SwVbaBuiltinDocumentProperties::getServiceImplName()
616cdf0e10cSrcweir {
617cdf0e10cSrcweir     static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaBuiltinDocumentProperties") );
618cdf0e10cSrcweir     return sImplName;
619cdf0e10cSrcweir }
620cdf0e10cSrcweir 
621cdf0e10cSrcweir uno::Sequence<rtl::OUString>
getServiceNames()622cdf0e10cSrcweir SwVbaBuiltinDocumentProperties::getServiceNames()
623cdf0e10cSrcweir {
624cdf0e10cSrcweir     static uno::Sequence< rtl::OUString > aServiceNames;
625cdf0e10cSrcweir     if ( aServiceNames.getLength() == 0 )
626cdf0e10cSrcweir     {
627cdf0e10cSrcweir         aServiceNames.realloc( 1 );
628cdf0e10cSrcweir         aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.word.DocumentProperties" ) );
629cdf0e10cSrcweir     }
630cdf0e10cSrcweir     return aServiceNames;
631cdf0e10cSrcweir }
632cdf0e10cSrcweir 
633cdf0e10cSrcweir class CustomPropertiesImpl : public PropertiesImpl_BASE
634cdf0e10cSrcweir {
635cdf0e10cSrcweir     uno::Reference< XHelperInterface > m_xParent;
636cdf0e10cSrcweir     uno::Reference< uno::XComponentContext > m_xContext;
637cdf0e10cSrcweir     uno::Reference< frame::XModel > m_xModel;
638cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > mxUserDefinedProp;
639cdf0e10cSrcweir     boost::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
640cdf0e10cSrcweir public:
CustomPropertiesImpl(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<frame::XModel> & xModel)641cdf0e10cSrcweir     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 )
642cdf0e10cSrcweir     {
643cdf0e10cSrcweir         // suck in the document( custom ) properties
644cdf0e10cSrcweir         uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( m_xModel, uno::UNO_QUERY_THROW );
645cdf0e10cSrcweir         uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW );
646cdf0e10cSrcweir         uno::Reference< document::XDocumentProperties > xDocProp( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW );
647cdf0e10cSrcweir         mxUserDefinedProp.set( xDocProp->getUserDefinedProperties(), uno::UNO_QUERY_THROW );
648cdf0e10cSrcweir         mpPropGetSetHelper.reset( new CustomPropertyGetSetHelper( m_xModel ) );
649cdf0e10cSrcweir     };
650cdf0e10cSrcweir     // XIndexAccess
getCount()651cdf0e10cSrcweir     virtual ::sal_Int32 SAL_CALL getCount(  ) throw (uno::RuntimeException)
652cdf0e10cSrcweir     {
653cdf0e10cSrcweir         return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
654cdf0e10cSrcweir     }
655cdf0e10cSrcweir 
getByIndex(::sal_Int32 Index)656cdf0e10cSrcweir     virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException )
657cdf0e10cSrcweir     {
658cdf0e10cSrcweir         uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
659cdf0e10cSrcweir         if ( Index >= aProps.getLength() )
660cdf0e10cSrcweir             throw lang::IndexOutOfBoundsException();
661cdf0e10cSrcweir         // How to determine type e.g Date? ( com.sun.star.util.DateTime )
662cdf0e10cSrcweir         DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
663cdf0e10cSrcweir         return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
664cdf0e10cSrcweir     }
665cdf0e10cSrcweir 
getByName(const::rtl::OUString & aName)666cdf0e10cSrcweir     virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
667cdf0e10cSrcweir     {
668cdf0e10cSrcweir         if ( !hasByName( aName ) )
669cdf0e10cSrcweir             throw container::NoSuchElementException();
670cdf0e10cSrcweir 
671cdf0e10cSrcweir         DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
672cdf0e10cSrcweir         return uno::makeAny( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
673cdf0e10cSrcweir     }
674cdf0e10cSrcweir 
getElementNames()675cdf0e10cSrcweir     virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(  ) throw (uno::RuntimeException)
676cdf0e10cSrcweir     {
677cdf0e10cSrcweir         uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
678cdf0e10cSrcweir         uno::Sequence< rtl::OUString > aNames( aProps.getLength() );
679cdf0e10cSrcweir         rtl::OUString* pString = aNames.getArray();
680cdf0e10cSrcweir         rtl::OUString* pEnd = ( pString + aNames.getLength() );
681cdf0e10cSrcweir         beans::Property* pProp = aProps.getArray();
682cdf0e10cSrcweir         for ( ; pString != pEnd; ++pString, ++pProp )
683cdf0e10cSrcweir             *pString = pProp->Name;
684cdf0e10cSrcweir         return aNames;
685cdf0e10cSrcweir     }
686cdf0e10cSrcweir 
hasByName(const::rtl::OUString & aName)687cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
688cdf0e10cSrcweir     {
689cdf0e10cSrcweir         OSL_TRACE("hasByName(%s) returns %d", rtl::OUStringToOString( aName, RTL_TEXTENCODING_UTF8 ).getStr(), mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
690cdf0e10cSrcweir         return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
691cdf0e10cSrcweir     }
692cdf0e10cSrcweir 
693cdf0e10cSrcweir     // XElementAccess
getElementType()694cdf0e10cSrcweir     virtual uno::Type SAL_CALL getElementType(  ) throw (uno::RuntimeException)
695cdf0e10cSrcweir     {
696cdf0e10cSrcweir         return  XDocumentProperty::static_type(0);
697cdf0e10cSrcweir     }
698cdf0e10cSrcweir 
hasElements()699cdf0e10cSrcweir     virtual ::sal_Bool SAL_CALL hasElements(  ) throw (uno::RuntimeException)
700cdf0e10cSrcweir     {
701cdf0e10cSrcweir         return getCount() > 0;
702cdf0e10cSrcweir     }
703cdf0e10cSrcweir 
createEnumeration()704cdf0e10cSrcweir     virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration(  ) throw (uno::RuntimeException)
705cdf0e10cSrcweir     {
706cdf0e10cSrcweir         // create a map of properties ( the key doesn't matter )
707cdf0e10cSrcweir         OSL_TRACE("Creating an enumeration");
708cdf0e10cSrcweir         sal_Int32 key = 0;
709cdf0e10cSrcweir         sal_Int32 nElem =  getCount();
710cdf0e10cSrcweir         DocProps simpleDocPropSnapShot;
711cdf0e10cSrcweir         for ( ; key < nElem; ++key )
712cdf0e10cSrcweir              simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
713cdf0e10cSrcweir         OSL_TRACE("After creating the enumeration");
714cdf0e10cSrcweir         return  new DocPropEnumeration( simpleDocPropSnapShot );
715cdf0e10cSrcweir     }
716cdf0e10cSrcweir 
addProp(const::rtl::OUString & Name,::sal_Int8,const uno::Any & Value)717cdf0e10cSrcweir     void addProp( const ::rtl::OUString& Name, ::sal_Int8 /*Type*/, const uno::Any& Value )
718cdf0e10cSrcweir     {
719cdf0e10cSrcweir         sal_Int16 attributes = 128;
720cdf0e10cSrcweir         uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
721cdf0e10cSrcweir         // TODO fixme, perform the necessary Type Value conversions
722cdf0e10cSrcweir         xContainer->addProperty( Name, attributes, Value );
723cdf0e10cSrcweir     }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir };
726cdf0e10cSrcweir 
727cdf0e10cSrcweir 
SwVbaCustomDocumentProperties(const uno::Reference<XHelperInterface> & xParent,const uno::Reference<uno::XComponentContext> & xContext,const uno::Reference<frame::XModel> & xModel)728cdf0e10cSrcweir SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< frame::XModel >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir     // replace the m_xIndexAccess implementation ( we need a virtual init )
731cdf0e10cSrcweir     m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
732cdf0e10cSrcweir     m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
733cdf0e10cSrcweir }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir uno::Reference< XDocumentProperty > SAL_CALL
Add(const::rtl::OUString & Name,::sal_Bool LinkToContent,::sal_Int8 Type,const uno::Any & Value,const uno::Any & LinkSource)736cdf0e10cSrcweir 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)
737cdf0e10cSrcweir {
738cdf0e10cSrcweir     CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
739cdf0e10cSrcweir     uno::Reference< XDocumentProperty > xDocProp;
740cdf0e10cSrcweir     if ( pCustomProps )
741cdf0e10cSrcweir     {
742cdf0e10cSrcweir         rtl::OUString sLinkSource;
743cdf0e10cSrcweir         pCustomProps->addProp( Name, Type, Value );
744cdf0e10cSrcweir 
745cdf0e10cSrcweir         xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
746cdf0e10cSrcweir         xDocProp->setLinkToContent( LinkToContent );
747cdf0e10cSrcweir 
748cdf0e10cSrcweir         if ( LinkSource >>= sLinkSource )
749cdf0e10cSrcweir            xDocProp->setLinkSource( sLinkSource );
750cdf0e10cSrcweir     }
751cdf0e10cSrcweir     return xDocProp;
752cdf0e10cSrcweir }
753cdf0e10cSrcweir 
754cdf0e10cSrcweir // XHelperInterface
755cdf0e10cSrcweir rtl::OUString&
getServiceImplName()756cdf0e10cSrcweir SwVbaCustomDocumentProperties::getServiceImplName()
757cdf0e10cSrcweir {
758cdf0e10cSrcweir     static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("SwVbaCustomDocumentProperties") );
759cdf0e10cSrcweir     return sImplName;
760cdf0e10cSrcweir }
761