1*e6ed5fbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*e6ed5fbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*e6ed5fbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*e6ed5fbcSAndrew Rist  * distributed with this work for additional information
6*e6ed5fbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*e6ed5fbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*e6ed5fbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*e6ed5fbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*e6ed5fbcSAndrew Rist  *
11*e6ed5fbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e6ed5fbcSAndrew Rist  *
13*e6ed5fbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*e6ed5fbcSAndrew Rist  * software distributed under the License is distributed on an
15*e6ed5fbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*e6ed5fbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*e6ed5fbcSAndrew Rist  * specific language governing permissions and limitations
18*e6ed5fbcSAndrew Rist  * under the License.
19*e6ed5fbcSAndrew Rist  *
20*e6ed5fbcSAndrew Rist  *************************************************************/
21*e6ed5fbcSAndrew Rist 
22*e6ed5fbcSAndrew Rist 
23cdf0e10cSrcweir #include "vbacommandbarhelper.hxx"
24cdf0e10cSrcweir #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
25cdf0e10cSrcweir #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
26cdf0e10cSrcweir #include <com/sun/star/ui/XModuleUIConfigurationManager.hpp>
27cdf0e10cSrcweir #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
28cdf0e10cSrcweir #include <com/sun/star/ui/XUIElement.hpp>
29cdf0e10cSrcweir #include <com/sun/star/ui/UIElementType.hpp>
30cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
31cdf0e10cSrcweir #include <vbahelper/vbahelper.hxx>
32cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
33cdf0e10cSrcweir #include <time.h>
34cdf0e10cSrcweir #include <map>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace com::sun::star;
37cdf0e10cSrcweir using namespace ooo::vba;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #define CREATEOUSTRING(asciistr) rtl::OUString::createFromAscii(asciistr)
40cdf0e10cSrcweir 
41cdf0e10cSrcweir typedef std::map< rtl::OUString, rtl::OUString > MSO2OOCommandbarMap;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir class MSO2OOCommandbarHelper
44cdf0e10cSrcweir {
45cdf0e10cSrcweir private:
46cdf0e10cSrcweir     static MSO2OOCommandbarHelper* pMSO2OOCommandbarHelper;
47cdf0e10cSrcweir     MSO2OOCommandbarMap maBuildinToolbarMap;
48cdf0e10cSrcweir 
MSO2OOCommandbarHelper()49cdf0e10cSrcweir     MSO2OOCommandbarHelper()
50cdf0e10cSrcweir     {
51cdf0e10cSrcweir         // Buildin toolbars
52cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Standard"),CREATEOUSTRING("private:resource/toolbar/standardbar") ) );
53cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Formatting"),CREATEOUSTRING("private:resource/toolbar/formatobjectbar") ) );
54cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Drawing"),CREATEOUSTRING("private:resource/toolbar/drawbar") ) );
55cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Toolbar List"),CREATEOUSTRING("private:resource/toolbar/toolbar") ) );
56cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Forms"),CREATEOUSTRING("private:resource/toolbar/formcontrols") ) );
57cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Form Controls"),CREATEOUSTRING("private:resource/toolbar/formcontrols") ) );
58cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Full Screen"),CREATEOUSTRING("private:resource/toolbar/fullscreenbar") ) );
59cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Chart"),CREATEOUSTRING("private:resource/toolbar/flowchartshapes") ) );
60cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("Picture"),CREATEOUSTRING("private:resource/toolbar/graphicobjectbar") ) );
61cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("WordArt"),CREATEOUSTRING("private:resource/toolbar/fontworkobjectbar") ) );
62cdf0e10cSrcweir         maBuildinToolbarMap.insert( std::make_pair( CREATEOUSTRING("3-D Settings"),CREATEOUSTRING("private:resource/toolbar/extrusionobjectbar") ) );
63cdf0e10cSrcweir     }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir public:
~MSO2OOCommandbarHelper()66cdf0e10cSrcweir     virtual ~MSO2OOCommandbarHelper() {};
getMSO2OOCommandbarHelper()67cdf0e10cSrcweir     static MSO2OOCommandbarHelper* getMSO2OOCommandbarHelper()
68cdf0e10cSrcweir     {
69cdf0e10cSrcweir         if( pMSO2OOCommandbarHelper == NULL )
70cdf0e10cSrcweir         {
71cdf0e10cSrcweir             pMSO2OOCommandbarHelper = new MSO2OOCommandbarHelper();
72cdf0e10cSrcweir         }
73cdf0e10cSrcweir         return pMSO2OOCommandbarHelper;
74cdf0e10cSrcweir     }
75cdf0e10cSrcweir 
findBuildinToolbar(const rtl::OUString & sToolbarName)76cdf0e10cSrcweir     rtl::OUString findBuildinToolbar( const rtl::OUString& sToolbarName )
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         MSO2OOCommandbarMap::iterator it = maBuildinToolbarMap.begin();
79cdf0e10cSrcweir         for(; it != maBuildinToolbarMap.end(); it++ )
80cdf0e10cSrcweir         {
81cdf0e10cSrcweir             rtl::OUString sName = it->first;
82cdf0e10cSrcweir             if( sName.equalsIgnoreAsciiCase( sToolbarName ) )
83cdf0e10cSrcweir                 return it->second;
84cdf0e10cSrcweir         }
85cdf0e10cSrcweir         return rtl::OUString();
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir };
88cdf0e10cSrcweir 
89cdf0e10cSrcweir MSO2OOCommandbarHelper* MSO2OOCommandbarHelper::pMSO2OOCommandbarHelper = NULL;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 
VbaCommandBarHelper(const css::uno::Reference<css::uno::XComponentContext> & xContext,const css::uno::Reference<css::frame::XModel> & xModel)92cdf0e10cSrcweir VbaCommandBarHelper::VbaCommandBarHelper( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException) : mxContext( xContext ), mxModel( xModel )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     Init();
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
Init()97cdf0e10cSrcweir void VbaCommandBarHelper::Init( ) throw (css::uno::RuntimeException)
98cdf0e10cSrcweir {
99cdf0e10cSrcweir     uno::Reference< css::ui::XUIConfigurationManagerSupplier > xUICfgSupplier( mxModel, uno::UNO_QUERY_THROW );
100cdf0e10cSrcweir     m_xDocCfgMgr = xUICfgSupplier->getUIConfigurationManager();
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel, uno::UNO_QUERY_THROW );
103cdf0e10cSrcweir     if( xServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") ) ) )
104cdf0e10cSrcweir     {
105cdf0e10cSrcweir         maModuleId = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.SpreadsheetDocument") );
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir     else if( xServiceInfo->supportsService( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument" ) ) ) )
108cdf0e10cSrcweir     {
109cdf0e10cSrcweir         maModuleId = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextDocument") );
110cdf0e10cSrcweir     }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir     if( maModuleId.getLength() == 0 )
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() );
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 	uno::Reference< lang::XMultiServiceFactory > xServiceManager( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	css::uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier > xUICfgMgrSupp( xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))), uno::UNO_QUERY_THROW );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     m_xAppCfgMgr.set( xUICfgMgrSupp->getUIConfigurationManager( maModuleId ), uno::UNO_QUERY_THROW );
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 	css::uno::Reference< css::container::XNameAccess > xNameAccess( xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.WindowStateConfiguration" ))), uno::UNO_QUERY_THROW );
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     m_xWindowState.set( xNameAccess->getByName( maModuleId ), uno::UNO_QUERY_THROW );
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
getSettings(const rtl::OUString & sResourceUrl)128cdf0e10cSrcweir css::uno::Reference< css::container::XIndexAccess > VbaCommandBarHelper::getSettings( const rtl::OUString& sResourceUrl ) throw (css::uno::RuntimeException)
129cdf0e10cSrcweir {
130cdf0e10cSrcweir     if( m_xDocCfgMgr->hasSettings( sResourceUrl ) )
131cdf0e10cSrcweir         return m_xDocCfgMgr->getSettings( sResourceUrl, sal_True );
132cdf0e10cSrcweir     else if( m_xAppCfgMgr->hasSettings( sResourceUrl ) )
133cdf0e10cSrcweir         return m_xAppCfgMgr->getSettings( sResourceUrl, sal_True );
134cdf0e10cSrcweir     else
135cdf0e10cSrcweir     {
136cdf0e10cSrcweir         css::uno::Reference< css::container::XIndexAccess > xSettings( m_xAppCfgMgr->createSettings( ), uno::UNO_QUERY_THROW );
137cdf0e10cSrcweir         return xSettings;
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
removeSettings(const rtl::OUString & sResourceUrl)141cdf0e10cSrcweir void VbaCommandBarHelper::removeSettings( const rtl::OUString& sResourceUrl ) throw (css::uno::RuntimeException)
142cdf0e10cSrcweir {
143cdf0e10cSrcweir     if( m_xDocCfgMgr->hasSettings( sResourceUrl ) )
144cdf0e10cSrcweir         m_xDocCfgMgr->removeSettings( sResourceUrl );
145cdf0e10cSrcweir     else if( m_xAppCfgMgr->hasSettings( sResourceUrl ) )
146cdf0e10cSrcweir         m_xAppCfgMgr->removeSettings( sResourceUrl );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     // persistChanges();
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
ApplyChange(const rtl::OUString & sResourceUrl,const css::uno::Reference<css::container::XIndexAccess> & xSettings,sal_Bool bTemporary)151cdf0e10cSrcweir void VbaCommandBarHelper::ApplyChange( const rtl::OUString& sResourceUrl, const css::uno::Reference< css::container::XIndexAccess >& xSettings, sal_Bool bTemporary ) throw (css::uno::RuntimeException)
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     if( m_xDocCfgMgr->hasSettings( sResourceUrl ) )
154cdf0e10cSrcweir     {
155cdf0e10cSrcweir         m_xDocCfgMgr->replaceSettings( sResourceUrl, xSettings );
156cdf0e10cSrcweir     }
157cdf0e10cSrcweir     else
158cdf0e10cSrcweir     {
159cdf0e10cSrcweir         m_xDocCfgMgr->insertSettings( sResourceUrl, xSettings );
160cdf0e10cSrcweir     }
161cdf0e10cSrcweir     if( !bTemporary )
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         persistChanges();
164cdf0e10cSrcweir     }
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
persistChanges()167cdf0e10cSrcweir sal_Bool VbaCommandBarHelper::persistChanges() throw (css::uno::RuntimeException)
168cdf0e10cSrcweir {
169cdf0e10cSrcweir     uno::Reference< css::ui::XUIConfigurationPersistence > xConfigPersistence( m_xDocCfgMgr, uno::UNO_QUERY_THROW );
170cdf0e10cSrcweir     sal_Bool result = sal_False;
171cdf0e10cSrcweir     if( xConfigPersistence->isModified() )
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir         xConfigPersistence->store();
174cdf0e10cSrcweir         result = sal_True;
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     return result;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
getLayoutManager()179cdf0e10cSrcweir uno::Reference< frame::XLayoutManager > VbaCommandBarHelper::getLayoutManager() throw (uno::RuntimeException)
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     uno::Reference< frame::XFrame > xFrame( getModel()->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW );
182cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xPropertySet( xFrame, uno::UNO_QUERY_THROW );
183cdf0e10cSrcweir     uno::Reference< frame::XLayoutManager > xLayoutManager( xPropertySet->getPropertyValue( rtl::OUString::createFromAscii("LayoutManager") ), uno::UNO_QUERY_THROW );
184cdf0e10cSrcweir     return xLayoutManager;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
hasToolbar(const rtl::OUString & sResourceUrl,const rtl::OUString & sName)187cdf0e10cSrcweir sal_Bool VbaCommandBarHelper::hasToolbar( const rtl::OUString& sResourceUrl, const rtl::OUString& sName ) throw (css::uno::RuntimeException)
188cdf0e10cSrcweir {
189cdf0e10cSrcweir     if( m_xDocCfgMgr->hasSettings( sResourceUrl ) )
190cdf0e10cSrcweir     {
191cdf0e10cSrcweir         rtl::OUString sUIName;
192cdf0e10cSrcweir         uno::Reference< beans::XPropertySet > xPropertySet( m_xDocCfgMgr->getSettings( sResourceUrl, sal_False ), uno::UNO_QUERY_THROW );
193cdf0e10cSrcweir         xPropertySet->getPropertyValue( rtl::OUString::createFromAscii(ITEM_DESCRIPTOR_UINAME) ) >>= sUIName;
194cdf0e10cSrcweir         if( sName.equalsIgnoreAsciiCase( sUIName ) )
195cdf0e10cSrcweir             return sal_True;
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir     return sal_False;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir // return the resource url if found
findToolbarByName(const css::uno::Reference<css::container::XNameAccess> & xNameAccess,const rtl::OUString & sName)201cdf0e10cSrcweir rtl::OUString VbaCommandBarHelper::findToolbarByName( const css::uno::Reference< css::container::XNameAccess >& xNameAccess, const rtl::OUString& sName ) throw (css::uno::RuntimeException)
202cdf0e10cSrcweir {
203cdf0e10cSrcweir     rtl::OUString sResourceUrl;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     // check if it is an buildin toolbar
206cdf0e10cSrcweir     sResourceUrl = MSO2OOCommandbarHelper::getMSO2OOCommandbarHelper()->findBuildinToolbar( sName );
207cdf0e10cSrcweir     if( sResourceUrl.getLength() > 0 )
208cdf0e10cSrcweir         return sResourceUrl;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString > allNames = xNameAccess->getElementNames();
211cdf0e10cSrcweir     for( sal_Int32 i = 0; i < allNames.getLength(); i++ )
212cdf0e10cSrcweir     {
213cdf0e10cSrcweir         sResourceUrl = allNames[i];
214cdf0e10cSrcweir         if(sResourceUrl.indexOf( rtl::OUString::createFromAscii( ITEM_TOOLBAR_URL ) ) == 0 )
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir             if( hasToolbar( sResourceUrl, sName ) )
217cdf0e10cSrcweir                 return sResourceUrl;
218cdf0e10cSrcweir         }
219cdf0e10cSrcweir     }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     // the customize toolbars creating during importing, shoud found there.
222cdf0e10cSrcweir     static rtl::OUString sToolbarPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/custom_" ) );
223cdf0e10cSrcweir     sResourceUrl = sToolbarPrefix.concat( sName );
224cdf0e10cSrcweir     if( hasToolbar( sResourceUrl, sName ) )
225cdf0e10cSrcweir         return sResourceUrl;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     return rtl::OUString();
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir // if found, return the position of the control. if not found, return -1
findControlByName(const css::uno::Reference<css::container::XIndexAccess> & xIndexAccess,const rtl::OUString & sName,bool bMenu)231cdf0e10cSrcweir sal_Int32 VbaCommandBarHelper::findControlByName( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, const rtl::OUString& sName, bool bMenu ) throw (css::uno::RuntimeException)
232cdf0e10cSrcweir {
233cdf0e10cSrcweir     sal_Int32 nCount = xIndexAccess->getCount();
234cdf0e10cSrcweir     css::uno::Sequence< css::beans::PropertyValue > aProps;
235cdf0e10cSrcweir     for( sal_Int32 i = 0; i < nCount; i++ )
236cdf0e10cSrcweir     {
237cdf0e10cSrcweir         rtl::OUString sLabel;
238cdf0e10cSrcweir         xIndexAccess->getByIndex( i ) >>= aProps;
239cdf0e10cSrcweir         getPropertyValue( aProps, rtl::OUString::createFromAscii(ITEM_DESCRIPTOR_LABEL) ) >>= sLabel;
240cdf0e10cSrcweir         // handle the hotkey marker '~' (remove in toolbars (?), replace by '&' in menus)
241cdf0e10cSrcweir         ::rtl::OUStringBuffer aBuffer;
242cdf0e10cSrcweir         sal_Int32 index = sLabel.indexOf( sal_Unicode('~') );
243cdf0e10cSrcweir         if( index < 0 )
244cdf0e10cSrcweir         {
245cdf0e10cSrcweir             aBuffer = sLabel;
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir         else
248cdf0e10cSrcweir         {
249cdf0e10cSrcweir             aBuffer.append( sLabel.copy( 0, index ) );
250cdf0e10cSrcweir             if( bMenu )
251cdf0e10cSrcweir                 aBuffer.append( sal_Unicode( '&' ) );
252cdf0e10cSrcweir             aBuffer.append( sLabel.copy( index + 1 ) );
253cdf0e10cSrcweir         }
254cdf0e10cSrcweir         rtl::OUString sNewLabel = aBuffer.makeStringAndClear();
255cdf0e10cSrcweir         OSL_TRACE("VbaCommandBarHelper::findControlByName, control name: %s", rtl::OUStringToOString( sNewLabel, RTL_TEXTENCODING_UTF8 ).getStr() );
256cdf0e10cSrcweir         if( sName.equalsIgnoreAsciiCase( sNewLabel ) )
257cdf0e10cSrcweir             return i;
258cdf0e10cSrcweir     }
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     // not found
261cdf0e10cSrcweir     return -1;
262cdf0e10cSrcweir }
263cdf0e10cSrcweir 
generateCustomURL()264cdf0e10cSrcweir rtl::OUString VbaCommandBarHelper::generateCustomURL()
265cdf0e10cSrcweir {
266cdf0e10cSrcweir     rtl::OUString url = rtl::OUString::createFromAscii( ITEM_TOOLBAR_URL );
267cdf0e10cSrcweir     url += rtl::OUString::createFromAscii( CUSTOM_TOOLBAR_STR );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir     // use a random number to minimize possible clash with existing custom toolbars
270cdf0e10cSrcweir     srand( unsigned( time( NULL ) ));
271cdf0e10cSrcweir     url += rtl::OUString::valueOf( sal_Int64( rand() ), 16 );
272cdf0e10cSrcweir     return url;
273cdf0e10cSrcweir }
274