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