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