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