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 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_desktop.hxx" 30 31 #include <map> 32 #include <new> 33 #include <set> 34 35 #include "migration.hxx" 36 #include "migration_impl.hxx" 37 #include "cfgfilter.hxx" 38 39 #include <unotools/textsearch.hxx> 40 #include <comphelper/processfactory.hxx> 41 #include <comphelper/sequence.hxx> 42 #include <unotools/bootstrap.hxx> 43 #include <rtl/bootstrap.hxx> 44 #include <rtl/uri.hxx> 45 #include <tools/config.hxx> 46 #include <i18npool/lang.h> 47 #include <tools/urlobj.hxx> 48 #include <osl/file.hxx> 49 #include <osl/mutex.hxx> 50 #include <ucbhelper/content.hxx> 51 #include <osl/security.hxx> 52 #include <unotools/configmgr.hxx> 53 54 #include <com/sun/star/configuration/Update.hpp> 55 #include <com/sun/star/lang/XInitialization.hpp> 56 #include <com/sun/star/task/XJob.hpp> 57 #include <com/sun/star/beans/NamedValue.hpp> 58 #include <com/sun/star/beans/XPropertySet.hpp> 59 #include <com/sun/star/util/XRefreshable.hpp> 60 #include <com/sun/star/util/XChangesBatch.hpp> 61 #include <com/sun/star/util/XStringSubstitution.hpp> 62 #include <com/sun/star/embed/ElementModes.hpp> 63 #include <com/sun/star/embed/XStorage.hpp> 64 #include <com/sun/star/ui/XUIConfiguration.hpp> 65 #include <com/sun/star/ui/XUIConfigurationStorage.hpp> 66 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp> 67 68 using namespace rtl; 69 using namespace osl; 70 using namespace std; 71 using namespace com::sun::star::task; 72 using namespace com::sun::star::lang; 73 using namespace com::sun::star::beans; 74 using namespace com::sun::star::util; 75 using namespace com::sun::star::container; 76 using com::sun::star::uno::Exception; 77 using namespace com::sun::star; 78 79 namespace desktop { 80 81 static const ::rtl::OUString ITEM_DESCRIPTOR_COMMANDURL = ::rtl::OUString::createFromAscii("CommandURL"); 82 static const ::rtl::OUString ITEM_DESCRIPTOR_CONTAINER = ::rtl::OUString::createFromAscii("ItemDescriptorContainer"); 83 static const ::rtl::OUString ITEM_DESCRIPTOR_LABEL = ::rtl::OUString::createFromAscii("Label"); 84 85 static const ::rtl::OUString MENU_SEPERATOR = ::rtl::OUString::createFromAscii(" | "); 86 static const ::rtl::OUString MENU_SUBMENU = ::rtl::OUString::createFromAscii("..."); 87 88 ::rtl::OUString retrieveLabelFromCommand(const ::rtl::OUString& sCommand, const ::rtl::OUString& sModuleIdentifier) 89 { 90 ::rtl::OUString sLabel; 91 92 uno::Reference< container::XNameAccess > xUICommands; 93 uno::Reference< container::XNameAccess > xNameAccess( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.frame.UICommandDescription") ), uno::UNO_QUERY ); 94 if ( xNameAccess.is() ) 95 { 96 uno::Any a = xNameAccess->getByName( sModuleIdentifier ); 97 a >>= xUICommands; 98 } 99 if (xUICommands.is()) 100 { 101 if ( sCommand.getLength() > 0 ) 102 { 103 rtl::OUString aStr; 104 ::uno::Sequence< beans::PropertyValue > aPropSeq; 105 try 106 { 107 uno::Any a( xUICommands->getByName( sCommand )); 108 if ( a >>= aPropSeq ) 109 { 110 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) 111 { 112 if ( aPropSeq[i].Name.equalsAscii( "Label" )) 113 { 114 aPropSeq[i].Value >>= aStr; 115 break; 116 } 117 } 118 } 119 120 sLabel = aStr; 121 } 122 123 catch(container::NoSuchElementException&) 124 { 125 sLabel = sCommand; 126 sal_Int32 nIndex = sLabel.indexOf(':'); 127 if (nIndex>=0 && nIndex <= sLabel.getLength()-1) 128 sLabel = sLabel.copy(nIndex+1); 129 } 130 131 } 132 } 133 134 return sLabel; 135 } 136 137 ::rtl::OUString stripHotKey( const ::rtl::OUString& str ) 138 { 139 sal_Int32 index = str.indexOf( '~' ); 140 if ( index == -1 ) 141 { 142 return str; 143 } 144 else 145 { 146 return str.replaceAt( index, 1, ::rtl::OUString() ); 147 } 148 } 149 150 ::rtl::OUString mapModuleShortNameToIdentifier(const ::rtl::OUString& sShortName) 151 { 152 ::rtl::OUString sIdentifier; 153 154 if (sShortName.equals(::rtl::OUString::createFromAscii("StartModule"))) 155 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.frame.StartModule"); 156 157 else if (sShortName.equals(::rtl::OUString::createFromAscii("swriter"))) 158 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument"); 159 160 else if (sShortName.equals(::rtl::OUString::createFromAscii("scalc"))) 161 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument"); 162 163 else if (sShortName.equals(::rtl::OUString::createFromAscii("sdraw"))) 164 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument"); 165 166 else if (sShortName.equals(::rtl::OUString::createFromAscii("simpress"))) 167 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument"); 168 169 else if (sShortName.equals(::rtl::OUString::createFromAscii("smath"))) 170 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties"); 171 172 else if (sShortName.equals(::rtl::OUString::createFromAscii("schart"))) 173 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.chart2.ChartDocument"); 174 175 else if (sShortName.equals(::rtl::OUString::createFromAscii("BasicIDE"))) 176 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE"); 177 178 else if (sShortName.equals(::rtl::OUString::createFromAscii("dbapp"))) 179 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument"); 180 181 else if (sShortName.equals(::rtl::OUString::createFromAscii("sglobal"))) 182 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument"); 183 184 else if (sShortName.equals(::rtl::OUString::createFromAscii("sweb"))) 185 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument"); 186 187 else if (sShortName.equals(::rtl::OUString::createFromAscii("swxform"))) 188 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.xforms.XMLFormDocument"); 189 190 else if (sShortName.equals(::rtl::OUString::createFromAscii("sbibliography"))) 191 sIdentifier = ::rtl::OUString::createFromAscii("com.sun.star.frame.Bibliography"); 192 193 return sIdentifier; 194 } 195 196 static MigrationImpl *pImpl = 0; 197 static Mutex aMutex; 198 static MigrationImpl *getImpl() 199 { 200 MutexGuard aGuard(aMutex); 201 if (pImpl == 0) 202 pImpl = new MigrationImpl(comphelper::getProcessServiceFactory()); 203 return pImpl; 204 } 205 206 static void releaseImpl() 207 { 208 MutexGuard aGuard(aMutex); 209 if (pImpl != 0) 210 { 211 delete pImpl; 212 pImpl = 0; 213 } 214 } 215 216 // static main entry point for the migration process 217 void Migration::doMigration() 218 { 219 sal_Bool bResult = sal_False; 220 try { 221 bResult = getImpl()->doMigration(); 222 } catch (Exception& e) 223 { 224 OString aMsg("doMigration() exception: "); 225 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 226 OSL_ENSURE(sal_False, aMsg.getStr()); 227 } 228 OSL_ENSURE(bResult, "Migration has not been successfull"); 229 // shut down migration framework 230 releaseImpl(); 231 } 232 233 void Migration::cancelMigration() 234 { 235 releaseImpl(); 236 } 237 238 sal_Bool Migration::checkMigration() 239 { 240 return getImpl()->checkMigration(); 241 } 242 243 OUString Migration::getOldVersionName() 244 { 245 return getImpl()->getOldVersionName(); 246 } 247 248 OUString MigrationImpl::getOldVersionName() 249 { 250 return m_aInfo.productname; 251 } 252 253 sal_Bool MigrationImpl::checkMigration() 254 { 255 if (m_aInfo.userdata.getLength() > 0 && ! checkMigrationCompleted()) 256 return sal_True; 257 else 258 return sal_False; 259 } 260 261 MigrationImpl::MigrationImpl(const uno::Reference< XMultiServiceFactory >& xFactory) 262 : m_vrVersions(new strings_v) 263 , m_xFactory(xFactory) 264 { 265 readAvailableMigrations(m_vMigrationsAvailable); 266 sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable); 267 if ( nIndex >= 0 ) 268 m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name); 269 } 270 271 MigrationImpl::~MigrationImpl() 272 { 273 274 } 275 276 sal_Bool MigrationImpl::doMigration() 277 { 278 // compile file list for migration 279 m_vrFileList = compileFileList(); 280 281 sal_Bool result = sal_False; 282 try 283 { 284 NewVersionUIInfo aNewVersionUIInfo; 285 ::std::vector< MigrationModuleInfo > vModulesInfo = dectectUIChangesForAllModules(); 286 aNewVersionUIInfo.init(vModulesInfo); 287 288 copyFiles(); 289 290 const ::rtl::OUString sMenubarResourceURL = ::rtl::OUString::createFromAscii("private:resource/menubar/menubar"); 291 const ::rtl::OUString sToolbarResourcePre = ::rtl::OUString::createFromAscii("private:resource/toolbar/"); 292 for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i) 293 { 294 ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName); 295 if (sModuleIdentifier.getLength()==0) 296 continue; 297 298 uno::Sequence< uno::Any > lArgs(2); 299 ::rtl::OUString aOldCfgDataPath = m_aInfo.userdata + ::rtl::OUString::createFromAscii("/user/config/soffice.cfg/modules/"); 300 lArgs[0] <<= aOldCfgDataPath + vModulesInfo[i].sModuleShortName; 301 lArgs[1] <<= embed::ElementModes::READ; 302 303 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory")), uno::UNO_QUERY); 304 uno::Reference< embed::XStorage > xModules; 305 306 xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY); 307 uno::Reference< ui::XUIConfigurationManager > xOldCfgManager( m_xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.ui.UIConfigurationManager")), uno::UNO_QUERY ); 308 uno::Reference< ui::XUIConfigurationStorage > xOldCfgStorage( xOldCfgManager, uno::UNO_QUERY ); 309 uno::Reference< ui::XUIConfigurationPersistence > xOldCfgPersistence( xOldCfgManager, uno::UNO_QUERY ); 310 311 if ( xOldCfgStorage.is() && xOldCfgPersistence.is() && xModules.is() ) 312 { 313 xOldCfgStorage->setStorage( xModules ); 314 xOldCfgPersistence->reload(); 315 } 316 317 uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.getConfigManager(vModulesInfo[i].sModuleShortName); 318 319 if (vModulesInfo[i].bHasMenubar) 320 { 321 uno::Reference< container::XIndexContainer > xOldVersionMenuSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sMenubarResourceURL, sal_True), uno::UNO_QUERY); 322 uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.getNewMenubarSettings(vModulesInfo[i].sModuleShortName); 323 ::rtl::OUString sParent; 324 compareOldAndNewConfig(sParent, xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL); 325 mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL); 326 } 327 328 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size(); 329 if (nToolbars >0) 330 { 331 for (sal_Int32 j=0; j<nToolbars; ++j) 332 { 333 ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j]; 334 ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName; 335 336 uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sToolbarResourceURL, sal_True), uno::UNO_QUERY); 337 uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.getNewToolbarSettings(vModulesInfo[i].sModuleShortName, sToolbarName); 338 ::rtl::OUString sParent; 339 compareOldAndNewConfig(sParent, xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL); 340 mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL); 341 } 342 } 343 344 m_aOldVersionItemsHashMap.clear(); 345 m_aNewVersionItemsHashMap.clear(); 346 } 347 348 // execute the migration items from Setup.xcu 349 copyConfig(); 350 351 // execute custom migration services from Setup.xcu 352 // and refresh the cache 353 runServices(); 354 refresh(); 355 356 result = sal_True; 357 } catch (...) 358 { 359 OString aMsg("An unexpected exception was thrown during migration"); 360 aMsg += "\nOldVersion: " + OUStringToOString(m_aInfo.productname, RTL_TEXTENCODING_ASCII_US); 361 aMsg += "\nDataPath : " + OUStringToOString(m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US); 362 OSL_ENSURE(sal_False, aMsg.getStr()); 363 } 364 365 // prevent running the migration multiple times 366 setMigrationCompleted(); 367 return result; 368 } 369 370 void MigrationImpl::refresh() 371 { 372 uno::Reference< XRefreshable > xRefresh(m_xFactory->createInstance( 373 OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY); 374 if (xRefresh.is()) 375 xRefresh->refresh(); 376 else 377 OSL_ENSURE(sal_False, "could not get XRefresh interface from default config provider. No refresh done."); 378 379 } 380 381 void MigrationImpl::setMigrationCompleted() 382 { 383 try { 384 uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW); 385 aPropertySet->setPropertyValue(OUString::createFromAscii("MigrationCompleted"), uno::makeAny(sal_True)); 386 uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges(); 387 } catch (...) { 388 // fail silently 389 } 390 } 391 392 sal_Bool MigrationImpl::checkMigrationCompleted() 393 { 394 sal_Bool bMigrationCompleted = sal_False; 395 try { 396 uno::Reference< XPropertySet > aPropertySet( 397 getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW); 398 aPropertySet->getPropertyValue( 399 OUString::createFromAscii("MigrationCompleted")) >>= bMigrationCompleted; 400 } catch (Exception&) { 401 // just return false... 402 } 403 return bMigrationCompleted; 404 } 405 406 static void insertSorted(migrations_available& rAvailableMigrations, supported_migration& aSupportedMigration) 407 { 408 bool bInserted( false ); 409 migrations_available::iterator pIter = rAvailableMigrations.begin(); 410 while ( !bInserted && pIter != rAvailableMigrations.end()) 411 { 412 if ( pIter->nPriority < aSupportedMigration.nPriority ) 413 { 414 rAvailableMigrations.insert(pIter, aSupportedMigration ); 415 bInserted = true; 416 break; // i111193: insert invalidates iterator! 417 } 418 ++pIter; 419 } 420 if ( !bInserted ) 421 rAvailableMigrations.push_back( aSupportedMigration ); 422 } 423 424 bool MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigrations) 425 { 426 // get supported version names 427 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW); 428 uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames(); 429 430 const OUString aVersionIdentifiers( RTL_CONSTASCII_USTRINGPARAM( "VersionIdentifiers" )); 431 const OUString aPriorityIdentifier( RTL_CONSTASCII_USTRINGPARAM( "Priority" )); 432 433 for (sal_Int32 i=0; i<seqSupportedVersions.getLength(); i++) 434 { 435 sal_Int32 nPriority( 0 ); 436 uno::Sequence< OUString > seqVersions; 437 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW ); 438 xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions; 439 xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority; 440 441 supported_migration aSupportedMigration; 442 aSupportedMigration.name = seqSupportedVersions[i]; 443 aSupportedMigration.nPriority = nPriority; 444 for (sal_Int32 j=0; j<seqVersions.getLength(); j++) 445 aSupportedMigration.supported_versions.push_back(seqVersions[j].trim()); 446 insertSorted( rAvailableMigrations, aSupportedMigration ); 447 } 448 449 return true; 450 } 451 452 migrations_vr MigrationImpl::readMigrationSteps(const ::rtl::OUString& rMigrationName) 453 { 454 // get migration access 455 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW); 456 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW ); 457 458 // get migration description from from org.openoffice.Setup/Migration 459 // and build vector of migration steps 460 OUString aMigrationSteps( RTL_CONSTASCII_USTRINGPARAM( "MigrationSteps" )); 461 uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(aMigrationSteps), uno::UNO_QUERY_THROW); 462 uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames(); 463 uno::Reference< XNameAccess > tmpAccess; 464 uno::Reference< XNameAccess > tmpAccess2; 465 uno::Sequence< OUString > tmpSeq; 466 migrations_vr vrMigrations(new migrations_v); 467 for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++) 468 { 469 // get current migration step 470 theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess; 471 // tmpStepPtr = new migration_step(); 472 migration_step tmpStep; 473 tmpStep.name = seqMigrations[i]; 474 475 // read included files from current step description 476 ::rtl::OUString aSeqEntry; 477 if (tmpAccess->getByName(OUString::createFromAscii("IncludedFiles")) >>= tmpSeq) 478 { 479 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 480 { 481 aSeqEntry = tmpSeq[j]; 482 tmpStep.includeFiles.push_back(aSeqEntry); 483 } 484 } 485 486 // exluded files... 487 if (tmpAccess->getByName(OUString::createFromAscii("ExcludedFiles")) >>= tmpSeq) 488 { 489 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 490 tmpStep.excludeFiles.push_back(tmpSeq[j]); 491 } 492 493 // included nodes... 494 if (tmpAccess->getByName(OUString::createFromAscii("IncludedNodes")) >>= tmpSeq) 495 { 496 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 497 tmpStep.includeConfig.push_back(tmpSeq[j]); 498 } 499 500 // excluded nodes... 501 if (tmpAccess->getByName(OUString::createFromAscii("ExcludedNodes")) >>= tmpSeq) 502 { 503 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 504 tmpStep.excludeConfig.push_back(tmpSeq[j]); 505 } 506 507 // included extensions... 508 if (tmpAccess->getByName(OUString::createFromAscii("IncludedExtensions")) >>= tmpSeq) 509 { 510 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 511 tmpStep.includeExtensions.push_back(tmpSeq[j]); 512 } 513 514 // excluded extensions... 515 if (tmpAccess->getByName(OUString::createFromAscii("ExcludedExtensions")) >>= tmpSeq) 516 { 517 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) 518 { 519 aSeqEntry = tmpSeq[j]; 520 tmpStep.excludeExtensions.push_back(aSeqEntry); 521 } 522 } 523 524 // generic service 525 tmpAccess->getByName(OUString::createFromAscii("MigrationService")) >>= tmpStep.service; 526 527 vrMigrations->push_back(tmpStep); 528 } 529 return vrMigrations; 530 } 531 532 static FileBase::RC _checkAndCreateDirectory(INetURLObject& dirURL) 533 { 534 FileBase::RC result = Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI)); 535 if (result == FileBase::E_NOENT) 536 { 537 INetURLObject baseURL(dirURL); 538 baseURL.removeSegment(); 539 _checkAndCreateDirectory(baseURL); 540 return Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI)); 541 } else 542 return result; 543 } 544 545 install_info MigrationImpl::findInstallation(const strings_v& rVersions) 546 { 547 rtl::OUString aProductName; 548 uno::Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ); 549 aRet >>= aProductName; 550 aProductName = aProductName.toAsciiLowerCase(); 551 552 install_info aInfo; 553 strings_v::const_iterator i_ver = rVersions.begin(); 554 uno::Reference < util::XStringSubstitution > xSubst( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.PathSubstitution")), uno::UNO_QUERY ); 555 while (i_ver != rVersions.end()) 556 { 557 ::rtl::OUString aVersion, aProfileName; 558 sal_Int32 nSeparatorIndex = (*i_ver).indexOf('='); 559 if ( nSeparatorIndex != -1 ) 560 { 561 aVersion = (*i_ver).copy( 0, nSeparatorIndex ); 562 aProfileName = (*i_ver).copy( nSeparatorIndex+1 ); 563 } 564 565 if ( aVersion.getLength() && aProfileName.getLength() && 566 ( !aInfo.userdata.getLength() || !aProfileName.toAsciiLowerCase().compareTo( aProductName, aProductName.getLength() ) ) 567 ) 568 { 569 ::rtl::OUString aUserInst; 570 osl::Security().getConfigDir( aUserInst ); 571 if ( aUserInst.getLength() && aUserInst[ aUserInst.getLength()-1 ] != '/' ) 572 aUserInst += ::rtl::OUString::createFromAscii("/"); 573 #if defined UNX && ! defined MACOSX 574 // tribute to whoever had the "great" idea to use different names on Windows and Unix 575 aUserInst += ::rtl::OUString::createFromAscii("."); 576 #endif 577 aUserInst += aProfileName; 578 try 579 { 580 INetURLObject aObj(aUserInst); 581 ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment > () ); 582 aCnt.isDocument(); 583 aInfo.userdata = aObj.GetMainURL( INetURLObject::NO_DECODE ); 584 aInfo.productname = aVersion; 585 } 586 catch( uno::Exception& ){} 587 } 588 ++i_ver; 589 } 590 591 return aInfo; 592 } 593 594 sal_Int32 MigrationImpl::findPreferedMigrationProcess(const migrations_available& rAvailableMigrations) 595 { 596 sal_Int32 nIndex( -1 ); 597 sal_Int32 i( 0 ); 598 599 migrations_available::const_iterator rIter = rAvailableMigrations.begin(); 600 while ( rIter != rAvailableMigrations.end() ) 601 { 602 install_info aInstallInfo = findInstallation(rIter->supported_versions); 603 if (aInstallInfo.productname.getLength() > 0 ) 604 { 605 m_aInfo = aInstallInfo; 606 nIndex = i; 607 break; 608 } 609 ++i; 610 ++rIter; 611 } 612 613 return nIndex; 614 } 615 616 strings_vr MigrationImpl::applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const 617 { 618 using namespace utl; 619 strings_vr vrResult(new strings_v); 620 strings_v::const_iterator i_set; 621 strings_v::const_iterator i_pat = vPatterns.begin(); 622 while (i_pat != vPatterns.end()) 623 { 624 // find matches for this pattern in input set 625 // and copy them to the result 626 SearchParam param(*i_pat, SearchParam::SRCH_REGEXP); 627 TextSearch ts(param, LANGUAGE_DONTKNOW); 628 i_set = vSet.begin(); 629 xub_StrLen start = 0; 630 xub_StrLen end = 0; 631 while (i_set != vSet.end()) 632 { 633 end = (xub_StrLen)(i_set->getLength()); 634 if (ts.SearchFrwrd(*i_set, &start, &end)) 635 vrResult->push_back(*i_set); 636 i_set++; 637 } 638 i_pat++; 639 } 640 return vrResult; 641 } 642 643 strings_vr MigrationImpl::getAllFiles(const OUString& baseURL) const 644 { 645 using namespace osl; 646 strings_vr vrResult(new strings_v); 647 648 // get sub dirs 649 Directory dir(baseURL); 650 if (dir.open() == FileBase::E_None) 651 { 652 strings_v vSubDirs; 653 strings_vr vrSubResult; 654 655 // work through directory contents... 656 DirectoryItem item; 657 FileStatus fs(FileStatusMask_Type | FileStatusMask_FileURL); 658 while (dir.getNextItem(item) == FileBase::E_None) 659 { 660 if (item.getFileStatus(fs) == FileBase::E_None) 661 { 662 if (fs.getFileType() == FileStatus::Directory) 663 vSubDirs.push_back(fs.getFileURL()); 664 else 665 vrResult->push_back(fs.getFileURL()); 666 } 667 } 668 669 // recurse subfolders 670 strings_v::const_iterator i = vSubDirs.begin(); 671 while (i != vSubDirs.end()) 672 { 673 vrSubResult = getAllFiles(*i); 674 vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end()); 675 i++; 676 } 677 } 678 return vrResult; 679 } 680 681 strings_vr MigrationImpl::compileFileList() 682 { 683 684 strings_vr vrResult(new strings_v); 685 strings_vr vrInclude; 686 strings_vr vrExclude; 687 strings_vr vrTemp; 688 689 #ifdef SAL_OS2 690 if (m_aInfo.userdata.getLength() == 0) 691 return vrResult; 692 #endif 693 694 // get a list of all files: 695 strings_vr vrFiles = getAllFiles(m_aInfo.userdata); 696 697 // get a file list result for each migration step 698 migrations_v::const_iterator i_migr = m_vrMigrations->begin(); 699 while (i_migr != m_vrMigrations->end()) 700 { 701 vrInclude = applyPatterns(*vrFiles, i_migr->includeFiles); 702 vrExclude = applyPatterns(*vrFiles, i_migr->excludeFiles); 703 substract(*vrInclude, *vrExclude); 704 vrResult->insert(vrResult->end(), vrInclude->begin(), vrInclude->end()); 705 i_migr++; 706 } 707 return vrResult; 708 } 709 710 namespace { 711 712 struct componentParts { 713 std::set< rtl::OUString > includedPaths; 714 std::set< rtl::OUString > excludedPaths; 715 }; 716 717 typedef std::map< rtl::OUString, componentParts > Components; 718 719 bool getComponent(rtl::OUString const & path, rtl::OUString * component) { 720 OSL_ASSERT(component != 0); 721 if (path.getLength() == 0 || path[0] != '/') { 722 OSL_TRACE( 723 ("configuration migration in/exclude path %s ignored (does not" 724 " start with slash)"), 725 rtl::OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr()); 726 return false; 727 } 728 sal_Int32 i = path.indexOf('/', 1); 729 *component = i < 0 ? path.copy(1) : path.copy(1, i - 1); 730 return true; 731 } 732 733 uno::Sequence< rtl::OUString > setToSeq(std::set< rtl::OUString > const & set) { 734 std::set< rtl::OUString >::size_type n = set.size(); 735 if (n > SAL_MAX_INT32) { 736 throw std::bad_alloc(); 737 } 738 uno::Sequence< rtl::OUString > seq(static_cast< sal_Int32 >(n)); 739 sal_Int32 i = 0; 740 for (std::set< rtl::OUString >::const_iterator j(set.begin()); 741 j != set.end(); ++j) 742 { 743 seq[i++] = *j; 744 } 745 return seq; 746 } 747 748 } 749 750 void MigrationImpl::copyConfig() { 751 Components comps; 752 for (migrations_v::const_iterator i(m_vrMigrations->begin()); 753 i != m_vrMigrations->end(); ++i) 754 { 755 for (strings_v::const_iterator j(i->includeConfig.begin()); 756 j != i->includeConfig.end(); ++j) 757 { 758 rtl::OUString comp; 759 if (getComponent(*j, &comp)) { 760 comps[comp].includedPaths.insert(*j); 761 } 762 } 763 for (strings_v::const_iterator j(i->excludeConfig.begin()); 764 j != i->excludeConfig.end(); ++j) 765 { 766 rtl::OUString comp; 767 if (getComponent(*j, &comp)) { 768 comps[comp].excludedPaths.insert(*j); 769 } 770 } 771 } 772 for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) { 773 if (!i->second.includedPaths.empty()) { 774 rtl::OUStringBuffer buf(m_aInfo.userdata); 775 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/user/registry/data")); 776 sal_Int32 n = 0; 777 do { 778 rtl::OUString seg(i->first.getToken(0, '.', n)); 779 rtl::OUString enc( 780 rtl::Uri::encode( 781 seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict, 782 RTL_TEXTENCODING_UTF8)); 783 if (enc.getLength() == 0 && seg.getLength() != 0) { 784 OSL_TRACE( 785 ("configuration migration component %s ignored (cannot" 786 " be encoded as file path)"), 787 rtl::OUStringToOString( 788 i->first, RTL_TEXTENCODING_UTF8).getStr()); 789 goto next; 790 } 791 buf.append(sal_Unicode('/')); 792 buf.append(enc); 793 } while (n >= 0); 794 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(".xcu")); 795 configuration::Update::get( 796 comphelper::getProcessComponentContext())-> 797 insertModificationXcuFile( 798 buf.makeStringAndClear(), setToSeq(i->second.includedPaths), 799 setToSeq(i->second.excludedPaths)); 800 } else { 801 OSL_TRACE( 802 ("configuration migration component %s ignored (only excludes," 803 " no includes)"), 804 rtl::OUStringToOString( 805 i->first, RTL_TEXTENCODING_UTF8).getStr()); 806 } 807 next:; 808 } 809 } 810 811 // removes elements of vector 2 in vector 1 812 void MigrationImpl::substract(strings_v& va, const strings_v& vb_c) const 813 { 814 strings_v vb(vb_c); 815 // ensure uniqueness of entries 816 sort(va.begin(), va.end()); 817 sort(vb.begin(), vb.end()); 818 unique(va.begin(), va.end()); 819 unique(vb.begin(), vb.end()); 820 821 strings_v::const_iterator i_ex = vb.begin(); 822 strings_v::iterator i_in; 823 strings_v::iterator i_next; 824 while (i_ex != vb.end()) 825 { 826 i_in = va.begin(); 827 while (i_in != va.end()) 828 { 829 if ( *i_in == *i_ex) 830 { 831 i_next = i_in+1; 832 va.erase(i_in); 833 i_in = i_next; 834 // we can only find one match since we 835 // ensured uniquness of the entries. ergo: 836 break; 837 } 838 else 839 i_in++; 840 } 841 i_ex++; 842 } 843 } 844 845 uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate) 846 { 847 uno::Reference< XNameAccess > xNameAccess; 848 try{ 849 OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"); 850 OUString sAccessSrvc; 851 if (bUpdate) 852 sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"); 853 else 854 sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"); 855 856 OUString sConfigURL = OUString::createFromAscii(pPath); 857 858 // get configuration provider 859 uno::Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory(); 860 uno::Reference< XMultiServiceFactory > theConfigProvider = uno::Reference< XMultiServiceFactory > ( 861 theMSF->createInstance( sConfigSrvc ),uno::UNO_QUERY_THROW ); 862 863 // access the provider 864 uno::Sequence< uno::Any > theArgs(1); 865 theArgs[ 0 ] <<= sConfigURL; 866 xNameAccess = uno::Reference< XNameAccess > ( 867 theConfigProvider->createInstanceWithArguments( 868 sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW ); 869 } catch (com::sun::star::uno::Exception& e) 870 { 871 OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 872 OSL_ENSURE(sal_False, aMsg.getStr()); 873 } 874 return xNameAccess; 875 } 876 877 void MigrationImpl::copyFiles() 878 { 879 strings_v::const_iterator i_file = m_vrFileList->begin(); 880 OUString localName; 881 OUString destName; 882 OUString userInstall; 883 utl::Bootstrap::PathStatus aStatus; 884 aStatus = utl::Bootstrap::locateUserInstallation(userInstall); 885 if (aStatus == utl::Bootstrap::PATH_EXISTS) 886 { 887 while (i_file != m_vrFileList->end()) 888 { 889 890 // remove installation prefix from file 891 localName = i_file->copy(m_aInfo.userdata.getLength()); 892 destName = userInstall + localName; 893 INetURLObject aURL(destName); 894 // check whether destination directory exists 895 aURL.removeSegment(); 896 _checkAndCreateDirectory(aURL); 897 FileBase::RC copyResult = File::copy(*i_file, destName); 898 if (copyResult != FileBase::E_None) 899 { 900 OString msg("Cannot copy "); 901 msg += OUStringToOString(*i_file, RTL_TEXTENCODING_UTF8) + " to " 902 + OUStringToOString(destName, RTL_TEXTENCODING_UTF8); 903 OSL_ENSURE(sal_False, msg.getStr()); 904 } 905 i_file++; 906 } 907 } 908 else 909 { 910 OSL_ENSURE(sal_False, "copyFiles: UserInstall does not exist"); 911 } 912 } 913 914 void MigrationImpl::runServices() 915 { 916 // Build argument array 917 uno::Sequence< uno::Any > seqArguments(3); 918 seqArguments[0] = uno::makeAny(NamedValue( 919 OUString::createFromAscii("Productname"), 920 uno::makeAny(m_aInfo.productname))); 921 seqArguments[1] = uno::makeAny(NamedValue( 922 OUString::createFromAscii("UserData"), 923 uno::makeAny(m_aInfo.userdata))); 924 925 926 // create an instance of every migration service 927 // and execute the migration job 928 uno::Reference< XJob > xMigrationJob; 929 930 migrations_v::const_iterator i_mig = m_vrMigrations->begin(); 931 while (i_mig != m_vrMigrations->end()) 932 { 933 if( i_mig->service.getLength() > 0) 934 { 935 936 try 937 { 938 // set black list for extension migration 939 uno::Sequence< rtl::OUString > seqExtBlackList; 940 sal_uInt32 nSize = i_mig->excludeExtensions.size(); 941 if ( nSize > 0 ) 942 seqExtBlackList = comphelper::arrayToSequence< ::rtl::OUString >( 943 &i_mig->excludeExtensions[0], nSize ); 944 seqArguments[2] = uno::makeAny(NamedValue( 945 OUString::createFromAscii("ExtensionBlackList"), 946 uno::makeAny( seqExtBlackList ))); 947 948 xMigrationJob = uno::Reference< XJob >(m_xFactory->createInstanceWithArguments( 949 i_mig->service, seqArguments), uno::UNO_QUERY_THROW); 950 951 xMigrationJob->execute(uno::Sequence< NamedValue >()); 952 953 954 } catch (Exception& e) 955 { 956 OString aMsg("Execution of migration service failed (Exception caught).\nService: "); 957 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + "\nMessage: "; 958 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 959 OSL_ENSURE(sal_False, aMsg.getStr()); 960 } catch (...) 961 { 962 OString aMsg("Execution of migration service failed (Exception caught).\nService: "); 963 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + 964 "\nNo message available"; 965 OSL_ENSURE(sal_False, aMsg.getStr()); 966 } 967 968 } 969 i_mig++; 970 } 971 } 972 973 ::std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const 974 { 975 ::std::vector< MigrationModuleInfo > vModulesInfo; 976 const ::rtl::OUString MENUBAR = ::rtl::OUString::createFromAscii("menubar"); 977 const ::rtl::OUString TOOLBAR = ::rtl::OUString::createFromAscii("toolbar"); 978 979 uno::Sequence< uno::Any > lArgs(2); 980 lArgs[0] <<= m_aInfo.userdata + ::rtl::OUString::createFromAscii("/user/config/soffice.cfg/modules"); 981 lArgs[1] <<= embed::ElementModes::READ; 982 983 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory")), uno::UNO_QUERY); 984 uno::Reference< embed::XStorage > xModules; 985 986 xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY); 987 if (!xModules.is()) 988 return vModulesInfo; 989 990 uno::Reference< container::XNameAccess > xAccess = uno::Reference< container::XNameAccess >(xModules, uno::UNO_QUERY); 991 uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames(); 992 sal_Int32 nLength = lNames.getLength(); 993 for (sal_Int32 i=0; i<nLength; ++i) 994 { 995 ::rtl::OUString sModuleShortName = lNames[i]; 996 uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ); 997 if (xModule.is()) 998 { 999 MigrationModuleInfo aModuleInfo; 1000 1001 uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ); 1002 if (xMenubar.is()) 1003 { 1004 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xMenubar, uno::UNO_QUERY); 1005 if (xNameAccess->getElementNames().getLength() > 0) 1006 { 1007 aModuleInfo.sModuleShortName = sModuleShortName; 1008 aModuleInfo.bHasMenubar = sal_True; 1009 } 1010 } 1011 1012 uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ); 1013 if (xToolbar.is()) 1014 { 1015 const ::rtl::OUString RESOURCEURL_CUSTOM_ELEMENT = ::rtl::OUString::createFromAscii("custom_"); 1016 sal_Int32 nCustomLen = 7; 1017 1018 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xToolbar, uno::UNO_QUERY); 1019 ::uno::Sequence< ::rtl::OUString > lToolbars = xNameAccess->getElementNames(); 1020 for (sal_Int32 j=0; j<lToolbars.getLength(); ++j) 1021 { 1022 ::rtl::OUString sToolbarName = lToolbars[j]; 1023 if (sToolbarName.getLength()>=nCustomLen && 1024 sToolbarName.copy(0, nCustomLen).equals(RESOURCEURL_CUSTOM_ELEMENT)) 1025 continue; 1026 1027 aModuleInfo.sModuleShortName = sModuleShortName; 1028 sal_Int32 nIndex = sToolbarName.lastIndexOf('.'); 1029 if (nIndex > 0) 1030 { 1031 ::rtl::OUString sExtension(sToolbarName.copy(nIndex)); 1032 ::rtl::OUString sToolbarResourceName(sToolbarName.copy(0, nIndex)); 1033 if (sToolbarResourceName.getLength()>0 && sExtension.equalsAsciiL(".xml", 4)) 1034 aModuleInfo.m_vToolbars.push_back(sToolbarResourceName); 1035 } 1036 } 1037 } 1038 1039 if (aModuleInfo.sModuleShortName.getLength()>0) 1040 vModulesInfo.push_back(aModuleInfo); 1041 } 1042 } 1043 1044 return vModulesInfo; 1045 } 1046 1047 void MigrationImpl::compareOldAndNewConfig(const ::rtl::OUString& sParent, 1048 const uno::Reference< container::XIndexContainer >& xIndexOld, 1049 const uno::Reference< container::XIndexContainer >& xIndexNew, 1050 const ::rtl::OUString& sResourceURL) 1051 { 1052 ::std::vector< MigrationItem > vOldItems; 1053 ::std::vector< MigrationItem > vNewItems; 1054 uno::Sequence< beans::PropertyValue > aProp; 1055 sal_Int32 nOldCount = xIndexOld->getCount(); 1056 sal_Int32 nNewCount = xIndexNew->getCount(); 1057 1058 for (int n=0; n<nOldCount; ++n) 1059 { 1060 MigrationItem aMigrationItem; 1061 if (xIndexOld->getByIndex(n) >>= aProp) 1062 { 1063 for(int i=0; i<aProp.getLength(); ++i) 1064 { 1065 if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1066 aProp[i].Value >>= aMigrationItem.m_sCommandURL; 1067 else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER)) 1068 aProp[i].Value >>= aMigrationItem.m_xPopupMenu; 1069 } 1070 1071 if (aMigrationItem.m_sCommandURL.getLength()) 1072 vOldItems.push_back(aMigrationItem); 1073 } 1074 } 1075 1076 for (int n=0; n<nNewCount; ++n) 1077 { 1078 MigrationItem aMigrationItem; 1079 if (xIndexNew->getByIndex(n) >>= aProp) 1080 { 1081 for(int i=0; i<aProp.getLength(); ++i) 1082 { 1083 if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1084 aProp[i].Value >>= aMigrationItem.m_sCommandURL; 1085 else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER)) 1086 aProp[i].Value >>= aMigrationItem.m_xPopupMenu; 1087 } 1088 1089 if (aMigrationItem.m_sCommandURL.getLength()) 1090 vNewItems.push_back(aMigrationItem); 1091 } 1092 } 1093 1094 ::std::vector< MigrationItem >::iterator it; 1095 1096 ::rtl::OUString sSibling; 1097 for (it = vOldItems.begin(); it!=vOldItems.end(); ++it) 1098 { 1099 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vNewItems.begin(), vNewItems.end(), *it); 1100 if (pFound != vNewItems.end() && it->m_xPopupMenu.is()) 1101 { 1102 ::rtl::OUString sName; 1103 if (sParent.getLength()>0) 1104 sName = sParent + MENU_SEPERATOR + it->m_sCommandURL; 1105 else 1106 sName = it->m_sCommandURL; 1107 compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL); 1108 } 1109 else if (pFound == vNewItems.end()) 1110 { 1111 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu); 1112 if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end()) 1113 { 1114 ::std::vector< MigrationItem > vMigrationItems; 1115 m_aOldVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems)); 1116 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1117 } 1118 else 1119 { 1120 if (::std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end()) 1121 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1122 } 1123 } 1124 1125 sSibling = it->m_sCommandURL; 1126 } 1127 1128 ::rtl::OUString sNewSibling; 1129 uno::Reference< container::XIndexContainer > xPopup; 1130 for (it = vNewItems.begin(); it!=vNewItems.end(); ++it) 1131 { 1132 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vOldItems.begin(), vOldItems.end(), *it); 1133 if (pFound != vOldItems.end() && it->m_xPopupMenu.is()) 1134 { 1135 ::rtl::OUString sName; 1136 if (sParent.getLength()>0) 1137 sName = sParent + MENU_SEPERATOR + it->m_sCommandURL; 1138 else 1139 sName = it->m_sCommandURL; 1140 compareOldAndNewConfig(sName, pFound->m_xPopupMenu, it->m_xPopupMenu, sResourceURL); 1141 } 1142 else if (::std::find(vOldItems.begin(), vOldItems.end(), *it) == vOldItems.end()) 1143 { 1144 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu); 1145 if (m_aNewVersionItemsHashMap.find(sResourceURL)==m_aNewVersionItemsHashMap.end()) 1146 { 1147 ::std::vector< MigrationItem > vMigrationItems; 1148 m_aNewVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems)); 1149 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1150 } 1151 else 1152 { 1153 if (::std::find(m_aNewVersionItemsHashMap[sResourceURL].begin(), m_aNewVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aNewVersionItemsHashMap[sResourceURL].end()) 1154 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1155 } 1156 } 1157 } 1158 } 1159 1160 void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager, 1161 const uno::Reference< container::XIndexContainer>& xIndexContainer, 1162 const ::rtl::OUString& sModuleIdentifier, 1163 const ::rtl::OUString& sResourceURL) 1164 { 1165 MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL); 1166 if (pFound==m_aOldVersionItemsHashMap.end()) 1167 return; 1168 1169 ::std::vector< MigrationItem >::iterator it; 1170 for (it=pFound->second.begin(); it!=pFound->second.end(); ++it) 1171 { 1172 uno::Reference< container::XIndexContainer > xTemp = xIndexContainer; 1173 1174 ::rtl::OUString sParentNodeName = it->m_sParentNodeName; 1175 sal_Int32 nIndex = 0; 1176 do 1177 { 1178 ::rtl::OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim(); 1179 if (sToken.getLength()<=0) 1180 break; 1181 1182 sal_Int32 nCount = xTemp->getCount(); 1183 for (sal_Int32 i=0; i<nCount; ++i) 1184 { 1185 ::rtl::OUString sCommandURL; 1186 ::rtl::OUString sLabel; 1187 uno::Reference< container::XIndexContainer > xChild; 1188 1189 uno::Sequence< beans::PropertyValue > aPropSeq; 1190 xTemp->getByIndex(i) >>= aPropSeq; 1191 for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j) 1192 { 1193 ::rtl::OUString sPropName = aPropSeq[j].Name; 1194 if (sPropName.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1195 aPropSeq[j].Value >>= sCommandURL; 1196 else if (sPropName.equals(ITEM_DESCRIPTOR_LABEL)) 1197 aPropSeq[j].Value >>= sLabel; 1198 else if (sPropName.equals(ITEM_DESCRIPTOR_CONTAINER)) 1199 aPropSeq[j].Value >>= xChild; 1200 } 1201 1202 if (sCommandURL == sToken) 1203 { 1204 xTemp = xChild; 1205 break; 1206 } 1207 } 1208 1209 } while (nIndex>=0); 1210 1211 if (nIndex == -1) 1212 { 1213 uno::Sequence< beans::PropertyValue > aPropSeq(3); 1214 1215 aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL; 1216 aPropSeq[0].Value <<= it->m_sCommandURL; 1217 aPropSeq[1].Name = ITEM_DESCRIPTOR_LABEL; 1218 aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier); 1219 aPropSeq[2].Name = ITEM_DESCRIPTOR_CONTAINER; 1220 aPropSeq[2].Value <<= it->m_xPopupMenu; 1221 1222 if (it->m_sPrevSibling.getLength() == 0) 1223 xTemp->insertByIndex(0, uno::makeAny(aPropSeq)); 1224 else if (it->m_sPrevSibling.getLength() > 0) 1225 { 1226 sal_Int32 nCount = xTemp->getCount(); 1227 sal_Int32 i = 0; 1228 for (; i<nCount; ++i) 1229 { 1230 ::rtl::OUString sCmd; 1231 uno::Sequence< beans::PropertyValue > aTempPropSeq; 1232 xTemp->getByIndex(i) >>= aTempPropSeq; 1233 for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j) 1234 { 1235 if (aTempPropSeq[j].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1236 { 1237 aTempPropSeq[j].Value >>= sCmd; 1238 break; 1239 } 1240 } 1241 1242 if (sCmd.equals(it->m_sPrevSibling)) 1243 break; 1244 } 1245 1246 xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq)); 1247 } 1248 } 1249 } 1250 1251 uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY); 1252 if (xIndexAccess.is()) 1253 xCfgManager->replaceSettings(sResourceURL, xIndexAccess); 1254 1255 uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY); 1256 if (xUIConfigurationPersistence.is()) 1257 xUIConfigurationPersistence->store(); 1258 } 1259 1260 uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const ::rtl::OUString& sModuleShortName) const 1261 { 1262 uno::Reference< ui::XUIConfigurationManager > xCfgManager; 1263 1264 for (sal_Int32 i=0; i<m_lCfgManagerSeq.getLength(); ++i) 1265 { 1266 if (m_lCfgManagerSeq[i].Name.equals(sModuleShortName)) 1267 { 1268 m_lCfgManagerSeq[i].Value >>= xCfgManager; 1269 break; 1270 } 1271 } 1272 1273 return xCfgManager; 1274 } 1275 1276 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const 1277 { 1278 uno::Reference< container::XIndexContainer > xNewMenuSettings; 1279 1280 for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i) 1281 { 1282 if (m_lNewVersionMenubarSettingsSeq[i].Name.equals(sModuleShortName)) 1283 { 1284 m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings; 1285 break; 1286 } 1287 } 1288 1289 return xNewMenuSettings; 1290 } 1291 1292 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const 1293 { 1294 uno::Reference< container::XIndexContainer > xNewToolbarSettings; 1295 1296 for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i) 1297 { 1298 if (m_lNewVersionToolbarSettingsSeq[i].Name.equals(sModuleShortName)) 1299 { 1300 uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq; 1301 m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq; 1302 for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j) 1303 { 1304 if (lToolbarSettingsSeq[j].Name.equals(sToolbarName)) 1305 { 1306 lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings; 1307 break; 1308 } 1309 } 1310 1311 break; 1312 } 1313 } 1314 1315 return xNewToolbarSettings; 1316 } 1317 1318 void NewVersionUIInfo::init(const ::std::vector< MigrationModuleInfo >& vModulesInfo) 1319 { 1320 m_lCfgManagerSeq.realloc(vModulesInfo.size()); 1321 m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size()); 1322 m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size()); 1323 1324 const ::rtl::OUString sModuleCfgSupplier = ::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier"); 1325 const ::rtl::OUString sMenubarResourceURL = ::rtl::OUString::createFromAscii("private:resource/menubar/menubar"); 1326 const ::rtl::OUString sToolbarResourcePre = ::rtl::OUString::createFromAscii("private:resource/toolbar/"); 1327 1328 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = uno::Reference< ui::XModuleUIConfigurationManagerSupplier >(::comphelper::getProcessServiceFactory()->createInstance(sModuleCfgSupplier), uno::UNO_QUERY); 1329 1330 for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i) 1331 { 1332 ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName); 1333 if (sModuleIdentifier.getLength() > 0) 1334 { 1335 uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier); 1336 m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName; 1337 m_lCfgManagerSeq[i].Value <<= xCfgManager; 1338 1339 if (vModulesInfo[i].bHasMenubar) 1340 { 1341 m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName; 1342 m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, sal_True); 1343 } 1344 1345 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size(); 1346 if (nToolbars > 0) 1347 { 1348 uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars); 1349 for (sal_Int32 j=0; j<nToolbars; ++j) 1350 { 1351 ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j]; 1352 ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName; 1353 1354 lPropSeq[j].Name = sToolbarName; 1355 lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, sal_True); 1356 } 1357 1358 m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName; 1359 m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq; 1360 } 1361 } 1362 } 1363 } 1364 1365 } // namespace desktop 1366