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 if ( m_aInfo.productname.equals( OUString::createFromAscii("OpenOffice.org 3") ) ) 772 { 773 // OpenOffice.org 3 configuration file 774 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/user/registrymodifications.xcu")); 775 } 776 else 777 { 778 // OpenOffice.org 2 configuration files 779 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/user/registry/data")); 780 sal_Int32 n = 0; 781 do { 782 rtl::OUString seg(i->first.getToken(0, '.', n)); 783 rtl::OUString enc( 784 rtl::Uri::encode( 785 seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict, 786 RTL_TEXTENCODING_UTF8)); 787 if (enc.getLength() == 0 && seg.getLength() != 0) { 788 OSL_TRACE( 789 ("configuration migration component %s ignored (cannot" 790 " be encoded as file path)"), 791 rtl::OUStringToOString( 792 i->first, RTL_TEXTENCODING_UTF8).getStr()); 793 goto next; 794 } 795 buf.append(sal_Unicode('/')); 796 buf.append(enc); 797 } while (n >= 0); 798 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(".xcu")); 799 } 800 configuration::Update::get( 801 comphelper::getProcessComponentContext())-> 802 insertModificationXcuFile( 803 buf.makeStringAndClear(), setToSeq(i->second.includedPaths), 804 setToSeq(i->second.excludedPaths)); 805 } else { 806 OSL_TRACE( 807 ("configuration migration component %s ignored (only excludes," 808 " no includes)"), 809 rtl::OUStringToOString( 810 i->first, RTL_TEXTENCODING_UTF8).getStr()); 811 } 812 next:; 813 } 814 } 815 816 // removes elements of vector 2 in vector 1 817 void MigrationImpl::substract(strings_v& va, const strings_v& vb_c) const 818 { 819 strings_v vb(vb_c); 820 // ensure uniqueness of entries 821 sort(va.begin(), va.end()); 822 sort(vb.begin(), vb.end()); 823 unique(va.begin(), va.end()); 824 unique(vb.begin(), vb.end()); 825 826 strings_v::const_iterator i_ex = vb.begin(); 827 strings_v::iterator i_in; 828 strings_v::iterator i_next; 829 while (i_ex != vb.end()) 830 { 831 i_in = va.begin(); 832 while (i_in != va.end()) 833 { 834 if ( *i_in == *i_ex) 835 { 836 i_next = i_in+1; 837 va.erase(i_in); 838 i_in = i_next; 839 // we can only find one match since we 840 // ensured uniquness of the entries. ergo: 841 break; 842 } 843 else 844 i_in++; 845 } 846 i_ex++; 847 } 848 } 849 850 uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate) 851 { 852 uno::Reference< XNameAccess > xNameAccess; 853 try{ 854 OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"); 855 OUString sAccessSrvc; 856 if (bUpdate) 857 sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"); 858 else 859 sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"); 860 861 OUString sConfigURL = OUString::createFromAscii(pPath); 862 863 // get configuration provider 864 uno::Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory(); 865 uno::Reference< XMultiServiceFactory > theConfigProvider = uno::Reference< XMultiServiceFactory > ( 866 theMSF->createInstance( sConfigSrvc ),uno::UNO_QUERY_THROW ); 867 868 // access the provider 869 uno::Sequence< uno::Any > theArgs(1); 870 theArgs[ 0 ] <<= sConfigURL; 871 xNameAccess = uno::Reference< XNameAccess > ( 872 theConfigProvider->createInstanceWithArguments( 873 sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW ); 874 } catch (com::sun::star::uno::Exception& e) 875 { 876 OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 877 OSL_ENSURE(sal_False, aMsg.getStr()); 878 } 879 return xNameAccess; 880 } 881 882 void MigrationImpl::copyFiles() 883 { 884 strings_v::const_iterator i_file = m_vrFileList->begin(); 885 OUString localName; 886 OUString destName; 887 OUString userInstall; 888 utl::Bootstrap::PathStatus aStatus; 889 aStatus = utl::Bootstrap::locateUserInstallation(userInstall); 890 if (aStatus == utl::Bootstrap::PATH_EXISTS) 891 { 892 while (i_file != m_vrFileList->end()) 893 { 894 895 // remove installation prefix from file 896 localName = i_file->copy(m_aInfo.userdata.getLength()); 897 destName = userInstall + localName; 898 INetURLObject aURL(destName); 899 // check whether destination directory exists 900 aURL.removeSegment(); 901 _checkAndCreateDirectory(aURL); 902 FileBase::RC copyResult = File::copy(*i_file, destName); 903 if (copyResult != FileBase::E_None) 904 { 905 OString msg("Cannot copy "); 906 msg += OUStringToOString(*i_file, RTL_TEXTENCODING_UTF8) + " to " 907 + OUStringToOString(destName, RTL_TEXTENCODING_UTF8); 908 OSL_ENSURE(sal_False, msg.getStr()); 909 } 910 i_file++; 911 } 912 } 913 else 914 { 915 OSL_ENSURE(sal_False, "copyFiles: UserInstall does not exist"); 916 } 917 } 918 919 void MigrationImpl::runServices() 920 { 921 // Build argument array 922 uno::Sequence< uno::Any > seqArguments(3); 923 seqArguments[0] = uno::makeAny(NamedValue( 924 OUString::createFromAscii("Productname"), 925 uno::makeAny(m_aInfo.productname))); 926 seqArguments[1] = uno::makeAny(NamedValue( 927 OUString::createFromAscii("UserData"), 928 uno::makeAny(m_aInfo.userdata))); 929 930 931 // create an instance of every migration service 932 // and execute the migration job 933 uno::Reference< XJob > xMigrationJob; 934 935 migrations_v::const_iterator i_mig = m_vrMigrations->begin(); 936 while (i_mig != m_vrMigrations->end()) 937 { 938 if( i_mig->service.getLength() > 0) 939 { 940 941 try 942 { 943 // set black list for extension migration 944 uno::Sequence< rtl::OUString > seqExtBlackList; 945 sal_uInt32 nSize = i_mig->excludeExtensions.size(); 946 if ( nSize > 0 ) 947 seqExtBlackList = comphelper::arrayToSequence< ::rtl::OUString >( 948 &i_mig->excludeExtensions[0], nSize ); 949 seqArguments[2] = uno::makeAny(NamedValue( 950 OUString::createFromAscii("ExtensionBlackList"), 951 uno::makeAny( seqExtBlackList ))); 952 953 xMigrationJob = uno::Reference< XJob >(m_xFactory->createInstanceWithArguments( 954 i_mig->service, seqArguments), uno::UNO_QUERY_THROW); 955 956 xMigrationJob->execute(uno::Sequence< NamedValue >()); 957 958 959 } catch (Exception& e) 960 { 961 OString aMsg("Execution of migration service failed (Exception caught).\nService: "); 962 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + "\nMessage: "; 963 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 964 OSL_ENSURE(sal_False, aMsg.getStr()); 965 } catch (...) 966 { 967 OString aMsg("Execution of migration service failed (Exception caught).\nService: "); 968 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + 969 "\nNo message available"; 970 OSL_ENSURE(sal_False, aMsg.getStr()); 971 } 972 973 } 974 i_mig++; 975 } 976 } 977 978 ::std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const 979 { 980 ::std::vector< MigrationModuleInfo > vModulesInfo; 981 const ::rtl::OUString MENUBAR = ::rtl::OUString::createFromAscii("menubar"); 982 const ::rtl::OUString TOOLBAR = ::rtl::OUString::createFromAscii("toolbar"); 983 984 uno::Sequence< uno::Any > lArgs(2); 985 lArgs[0] <<= m_aInfo.userdata + ::rtl::OUString::createFromAscii("/user/config/soffice.cfg/modules"); 986 lArgs[1] <<= embed::ElementModes::READ; 987 988 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(m_xFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.embed.FileSystemStorageFactory")), uno::UNO_QUERY); 989 uno::Reference< embed::XStorage > xModules; 990 991 xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY); 992 if (!xModules.is()) 993 return vModulesInfo; 994 995 uno::Reference< container::XNameAccess > xAccess = uno::Reference< container::XNameAccess >(xModules, uno::UNO_QUERY); 996 uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames(); 997 sal_Int32 nLength = lNames.getLength(); 998 for (sal_Int32 i=0; i<nLength; ++i) 999 { 1000 ::rtl::OUString sModuleShortName = lNames[i]; 1001 uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ); 1002 if (xModule.is()) 1003 { 1004 MigrationModuleInfo aModuleInfo; 1005 1006 uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ); 1007 if (xMenubar.is()) 1008 { 1009 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xMenubar, uno::UNO_QUERY); 1010 if (xNameAccess->getElementNames().getLength() > 0) 1011 { 1012 aModuleInfo.sModuleShortName = sModuleShortName; 1013 aModuleInfo.bHasMenubar = sal_True; 1014 } 1015 } 1016 1017 uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ); 1018 if (xToolbar.is()) 1019 { 1020 const ::rtl::OUString RESOURCEURL_CUSTOM_ELEMENT = ::rtl::OUString::createFromAscii("custom_"); 1021 sal_Int32 nCustomLen = 7; 1022 1023 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xToolbar, uno::UNO_QUERY); 1024 ::uno::Sequence< ::rtl::OUString > lToolbars = xNameAccess->getElementNames(); 1025 for (sal_Int32 j=0; j<lToolbars.getLength(); ++j) 1026 { 1027 ::rtl::OUString sToolbarName = lToolbars[j]; 1028 if (sToolbarName.getLength()>=nCustomLen && 1029 sToolbarName.copy(0, nCustomLen).equals(RESOURCEURL_CUSTOM_ELEMENT)) 1030 continue; 1031 1032 aModuleInfo.sModuleShortName = sModuleShortName; 1033 sal_Int32 nIndex = sToolbarName.lastIndexOf('.'); 1034 if (nIndex > 0) 1035 { 1036 ::rtl::OUString sExtension(sToolbarName.copy(nIndex)); 1037 ::rtl::OUString sToolbarResourceName(sToolbarName.copy(0, nIndex)); 1038 if (sToolbarResourceName.getLength()>0 && sExtension.equalsAsciiL(".xml", 4)) 1039 aModuleInfo.m_vToolbars.push_back(sToolbarResourceName); 1040 } 1041 } 1042 } 1043 1044 if (aModuleInfo.sModuleShortName.getLength()>0) 1045 vModulesInfo.push_back(aModuleInfo); 1046 } 1047 } 1048 1049 return vModulesInfo; 1050 } 1051 1052 void MigrationImpl::compareOldAndNewConfig(const ::rtl::OUString& sParent, 1053 const uno::Reference< container::XIndexContainer >& xIndexOld, 1054 const uno::Reference< container::XIndexContainer >& xIndexNew, 1055 const ::rtl::OUString& sResourceURL) 1056 { 1057 ::std::vector< MigrationItem > vOldItems; 1058 ::std::vector< MigrationItem > vNewItems; 1059 uno::Sequence< beans::PropertyValue > aProp; 1060 sal_Int32 nOldCount = xIndexOld->getCount(); 1061 sal_Int32 nNewCount = xIndexNew->getCount(); 1062 1063 for (int n=0; n<nOldCount; ++n) 1064 { 1065 MigrationItem aMigrationItem; 1066 if (xIndexOld->getByIndex(n) >>= aProp) 1067 { 1068 for(int i=0; i<aProp.getLength(); ++i) 1069 { 1070 if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1071 aProp[i].Value >>= aMigrationItem.m_sCommandURL; 1072 else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER)) 1073 aProp[i].Value >>= aMigrationItem.m_xPopupMenu; 1074 } 1075 1076 if (aMigrationItem.m_sCommandURL.getLength()) 1077 vOldItems.push_back(aMigrationItem); 1078 } 1079 } 1080 1081 for (int n=0; n<nNewCount; ++n) 1082 { 1083 MigrationItem aMigrationItem; 1084 if (xIndexNew->getByIndex(n) >>= aProp) 1085 { 1086 for(int i=0; i<aProp.getLength(); ++i) 1087 { 1088 if (aProp[i].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1089 aProp[i].Value >>= aMigrationItem.m_sCommandURL; 1090 else if (aProp[i].Name.equals(ITEM_DESCRIPTOR_CONTAINER)) 1091 aProp[i].Value >>= aMigrationItem.m_xPopupMenu; 1092 } 1093 1094 if (aMigrationItem.m_sCommandURL.getLength()) 1095 vNewItems.push_back(aMigrationItem); 1096 } 1097 } 1098 1099 ::std::vector< MigrationItem >::iterator it; 1100 1101 ::rtl::OUString sSibling; 1102 for (it = vOldItems.begin(); it!=vOldItems.end(); ++it) 1103 { 1104 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vNewItems.begin(), vNewItems.end(), *it); 1105 if (pFound != vNewItems.end() && it->m_xPopupMenu.is()) 1106 { 1107 ::rtl::OUString sName; 1108 if (sParent.getLength()>0) 1109 sName = sParent + MENU_SEPERATOR + it->m_sCommandURL; 1110 else 1111 sName = it->m_sCommandURL; 1112 compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL); 1113 } 1114 else if (pFound == vNewItems.end()) 1115 { 1116 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu); 1117 if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end()) 1118 { 1119 ::std::vector< MigrationItem > vMigrationItems; 1120 m_aOldVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems)); 1121 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1122 } 1123 else 1124 { 1125 if (::std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end()) 1126 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1127 } 1128 } 1129 1130 sSibling = it->m_sCommandURL; 1131 } 1132 1133 ::rtl::OUString sNewSibling; 1134 uno::Reference< container::XIndexContainer > xPopup; 1135 for (it = vNewItems.begin(); it!=vNewItems.end(); ++it) 1136 { 1137 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vOldItems.begin(), vOldItems.end(), *it); 1138 if (pFound != vOldItems.end() && it->m_xPopupMenu.is()) 1139 { 1140 ::rtl::OUString sName; 1141 if (sParent.getLength()>0) 1142 sName = sParent + MENU_SEPERATOR + it->m_sCommandURL; 1143 else 1144 sName = it->m_sCommandURL; 1145 compareOldAndNewConfig(sName, pFound->m_xPopupMenu, it->m_xPopupMenu, sResourceURL); 1146 } 1147 else if (::std::find(vOldItems.begin(), vOldItems.end(), *it) == vOldItems.end()) 1148 { 1149 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu); 1150 if (m_aNewVersionItemsHashMap.find(sResourceURL)==m_aNewVersionItemsHashMap.end()) 1151 { 1152 ::std::vector< MigrationItem > vMigrationItems; 1153 m_aNewVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems)); 1154 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1155 } 1156 else 1157 { 1158 if (::std::find(m_aNewVersionItemsHashMap[sResourceURL].begin(), m_aNewVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aNewVersionItemsHashMap[sResourceURL].end()) 1159 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem); 1160 } 1161 } 1162 } 1163 } 1164 1165 void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager, 1166 const uno::Reference< container::XIndexContainer>& xIndexContainer, 1167 const ::rtl::OUString& sModuleIdentifier, 1168 const ::rtl::OUString& sResourceURL) 1169 { 1170 MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL); 1171 if (pFound==m_aOldVersionItemsHashMap.end()) 1172 return; 1173 1174 ::std::vector< MigrationItem >::iterator it; 1175 for (it=pFound->second.begin(); it!=pFound->second.end(); ++it) 1176 { 1177 uno::Reference< container::XIndexContainer > xTemp = xIndexContainer; 1178 1179 ::rtl::OUString sParentNodeName = it->m_sParentNodeName; 1180 sal_Int32 nIndex = 0; 1181 do 1182 { 1183 ::rtl::OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim(); 1184 if (sToken.getLength()<=0) 1185 break; 1186 1187 sal_Int32 nCount = xTemp->getCount(); 1188 for (sal_Int32 i=0; i<nCount; ++i) 1189 { 1190 ::rtl::OUString sCommandURL; 1191 ::rtl::OUString sLabel; 1192 uno::Reference< container::XIndexContainer > xChild; 1193 1194 uno::Sequence< beans::PropertyValue > aPropSeq; 1195 xTemp->getByIndex(i) >>= aPropSeq; 1196 for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j) 1197 { 1198 ::rtl::OUString sPropName = aPropSeq[j].Name; 1199 if (sPropName.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1200 aPropSeq[j].Value >>= sCommandURL; 1201 else if (sPropName.equals(ITEM_DESCRIPTOR_LABEL)) 1202 aPropSeq[j].Value >>= sLabel; 1203 else if (sPropName.equals(ITEM_DESCRIPTOR_CONTAINER)) 1204 aPropSeq[j].Value >>= xChild; 1205 } 1206 1207 if (sCommandURL == sToken) 1208 { 1209 xTemp = xChild; 1210 break; 1211 } 1212 } 1213 1214 } while (nIndex>=0); 1215 1216 if (nIndex == -1) 1217 { 1218 uno::Sequence< beans::PropertyValue > aPropSeq(3); 1219 1220 aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL; 1221 aPropSeq[0].Value <<= it->m_sCommandURL; 1222 aPropSeq[1].Name = ITEM_DESCRIPTOR_LABEL; 1223 aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier); 1224 aPropSeq[2].Name = ITEM_DESCRIPTOR_CONTAINER; 1225 aPropSeq[2].Value <<= it->m_xPopupMenu; 1226 1227 if (it->m_sPrevSibling.getLength() == 0) 1228 xTemp->insertByIndex(0, uno::makeAny(aPropSeq)); 1229 else if (it->m_sPrevSibling.getLength() > 0) 1230 { 1231 sal_Int32 nCount = xTemp->getCount(); 1232 sal_Int32 i = 0; 1233 for (; i<nCount; ++i) 1234 { 1235 ::rtl::OUString sCmd; 1236 uno::Sequence< beans::PropertyValue > aTempPropSeq; 1237 xTemp->getByIndex(i) >>= aTempPropSeq; 1238 for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j) 1239 { 1240 if (aTempPropSeq[j].Name.equals(ITEM_DESCRIPTOR_COMMANDURL)) 1241 { 1242 aTempPropSeq[j].Value >>= sCmd; 1243 break; 1244 } 1245 } 1246 1247 if (sCmd.equals(it->m_sPrevSibling)) 1248 break; 1249 } 1250 1251 xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq)); 1252 } 1253 } 1254 } 1255 1256 uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY); 1257 if (xIndexAccess.is()) 1258 xCfgManager->replaceSettings(sResourceURL, xIndexAccess); 1259 1260 uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY); 1261 if (xUIConfigurationPersistence.is()) 1262 xUIConfigurationPersistence->store(); 1263 } 1264 1265 uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const ::rtl::OUString& sModuleShortName) const 1266 { 1267 uno::Reference< ui::XUIConfigurationManager > xCfgManager; 1268 1269 for (sal_Int32 i=0; i<m_lCfgManagerSeq.getLength(); ++i) 1270 { 1271 if (m_lCfgManagerSeq[i].Name.equals(sModuleShortName)) 1272 { 1273 m_lCfgManagerSeq[i].Value >>= xCfgManager; 1274 break; 1275 } 1276 } 1277 1278 return xCfgManager; 1279 } 1280 1281 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const ::rtl::OUString& sModuleShortName) const 1282 { 1283 uno::Reference< container::XIndexContainer > xNewMenuSettings; 1284 1285 for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i) 1286 { 1287 if (m_lNewVersionMenubarSettingsSeq[i].Name.equals(sModuleShortName)) 1288 { 1289 m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings; 1290 break; 1291 } 1292 } 1293 1294 return xNewMenuSettings; 1295 } 1296 1297 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const ::rtl::OUString& sModuleShortName, const ::rtl::OUString& sToolbarName) const 1298 { 1299 uno::Reference< container::XIndexContainer > xNewToolbarSettings; 1300 1301 for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i) 1302 { 1303 if (m_lNewVersionToolbarSettingsSeq[i].Name.equals(sModuleShortName)) 1304 { 1305 uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq; 1306 m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq; 1307 for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j) 1308 { 1309 if (lToolbarSettingsSeq[j].Name.equals(sToolbarName)) 1310 { 1311 lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings; 1312 break; 1313 } 1314 } 1315 1316 break; 1317 } 1318 } 1319 1320 return xNewToolbarSettings; 1321 } 1322 1323 void NewVersionUIInfo::init(const ::std::vector< MigrationModuleInfo >& vModulesInfo) 1324 { 1325 m_lCfgManagerSeq.realloc(vModulesInfo.size()); 1326 m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size()); 1327 m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size()); 1328 1329 const ::rtl::OUString sModuleCfgSupplier = ::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier"); 1330 const ::rtl::OUString sMenubarResourceURL = ::rtl::OUString::createFromAscii("private:resource/menubar/menubar"); 1331 const ::rtl::OUString sToolbarResourcePre = ::rtl::OUString::createFromAscii("private:resource/toolbar/"); 1332 1333 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = uno::Reference< ui::XModuleUIConfigurationManagerSupplier >(::comphelper::getProcessServiceFactory()->createInstance(sModuleCfgSupplier), uno::UNO_QUERY); 1334 1335 for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i) 1336 { 1337 ::rtl::OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName); 1338 if (sModuleIdentifier.getLength() > 0) 1339 { 1340 uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier); 1341 m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName; 1342 m_lCfgManagerSeq[i].Value <<= xCfgManager; 1343 1344 if (vModulesInfo[i].bHasMenubar) 1345 { 1346 m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName; 1347 m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, sal_True); 1348 } 1349 1350 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size(); 1351 if (nToolbars > 0) 1352 { 1353 uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars); 1354 for (sal_Int32 j=0; j<nToolbars; ++j) 1355 { 1356 ::rtl::OUString sToolbarName = vModulesInfo[i].m_vToolbars[j]; 1357 ::rtl::OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName; 1358 1359 lPropSeq[j].Name = sToolbarName; 1360 lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, sal_True); 1361 } 1362 1363 m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName; 1364 m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq; 1365 } 1366 } 1367 } 1368 } 1369 1370 } // namespace desktop 1371