Bump version to 6.0-36
[LibreOffice.git] / desktop / source / migration / migration.cxx
blob043fe62e6c8d98a93db7af3829995c9cb5c77120
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <algorithm>
23 #include <iterator>
24 #include <map>
25 #include <new>
26 #include <set>
28 #include <migration.hxx>
29 #include "migration_impl.hxx"
31 #include <sal/log.hxx>
32 #include <unotools/textsearch.hxx>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/sequence.hxx>
35 #include <unotools/bootstrap.hxx>
36 #include <rtl/bootstrap.hxx>
37 #include <rtl/uri.hxx>
38 #include <i18nlangtag/lang.h>
39 #include <tools/urlobj.hxx>
40 #include <osl/file.hxx>
41 #include <osl/security.hxx>
42 #include <unotools/configmgr.hxx>
44 #include <com/sun/star/configuration/Update.hpp>
45 #include <com/sun/star/configuration/theDefaultProvider.hpp>
46 #include <com/sun/star/lang/XInitialization.hpp>
47 #include <com/sun/star/task/XJob.hpp>
48 #include <com/sun/star/beans/NamedValue.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/util/XRefreshable.hpp>
51 #include <com/sun/star/util/XChangesBatch.hpp>
52 #include <com/sun/star/util/XStringSubstitution.hpp>
53 #include <com/sun/star/embed/ElementModes.hpp>
54 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
55 #include <com/sun/star/embed/XStorage.hpp>
56 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
57 #include <com/sun/star/frame/theUICommandDescription.hpp>
58 #include <com/sun/star/ui/UIConfigurationManager.hpp>
59 #include <com/sun/star/ui/XUIConfiguration.hpp>
60 #include <com/sun/star/ui/XUIConfigurationStorage.hpp>
61 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
63 using namespace osl;
64 using namespace std;
65 using namespace com::sun::star::task;
66 using namespace com::sun::star::lang;
67 using namespace com::sun::star::beans;
68 using namespace com::sun::star::util;
69 using namespace com::sun::star::container;
70 using com::sun::star::uno::Exception;
71 using namespace com::sun::star;
74 namespace desktop
77 static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
78 static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
79 static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
81 OUString retrieveLabelFromCommand(const OUString& sCommand, const OUString& sModuleIdentifier)
83 OUString sLabel;
85 uno::Reference< container::XNameAccess > xUICommands;
86 uno::Reference< container::XNameAccess > const xNameAccess(
87 frame::theUICommandDescription::get(
88 ::comphelper::getProcessComponentContext()) );
89 xNameAccess->getByName( sModuleIdentifier ) >>= xUICommands;
90 if (xUICommands.is()) {
91 if ( !sCommand.isEmpty() ) {
92 OUString aStr;
93 ::uno::Sequence< beans::PropertyValue > aPropSeq;
94 try {
95 uno::Any a( xUICommands->getByName( sCommand ));
96 if ( a >>= aPropSeq ) {
97 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) {
98 if ( aPropSeq[i].Name == "Label" ) {
99 aPropSeq[i].Value >>= aStr;
100 break;
105 sLabel = aStr;
106 } catch (const container::NoSuchElementException&) {
107 sLabel = sCommand;
108 sal_Int32 nIndex = sLabel.indexOf(':');
109 if (nIndex>=0 && nIndex <= sLabel.getLength()-1)
110 sLabel = sLabel.copy(nIndex+1);
116 return sLabel;
119 OUString mapModuleShortNameToIdentifier(const OUString& sShortName)
121 OUString sIdentifier;
123 if ( sShortName == "StartModule" )
124 sIdentifier = "com.sun.star.frame.StartModule";
126 else if ( sShortName == "swriter" )
127 sIdentifier = "com.sun.star.text.TextDocument";
129 else if ( sShortName == "scalc" )
130 sIdentifier = "com.sun.star.sheet.SpreadsheetDocument";
132 else if ( sShortName == "sdraw" )
133 sIdentifier = "com.sun.star.drawing.DrawingDocument";
135 else if ( sShortName == "simpress" )
136 sIdentifier = "com.sun.star.presentation.PresentationDocument";
138 else if ( sShortName == "smath" )
139 sIdentifier = "com.sun.star.formula.FormulaProperties";
141 else if ( sShortName == "schart" )
142 sIdentifier = "com.sun.star.chart2.ChartDocument";
144 else if ( sShortName == "BasicIDE" )
145 sIdentifier = "com.sun.star.script.BasicIDE";
147 else if ( sShortName == "dbapp" )
148 sIdentifier = "com.sun.star.sdb.OfficeDatabaseDocument";
150 else if ( sShortName == "sglobal" )
151 sIdentifier = "com.sun.star.text.GlobalDocument";
153 else if ( sShortName == "sweb" )
154 sIdentifier = "com.sun.star.text.WebDocument";
156 else if ( sShortName == "swxform" )
157 sIdentifier = "com.sun.star.xforms.XMLFormDocument";
159 else if ( sShortName == "sbibliography" )
160 sIdentifier = "com.sun.star.frame.Bibliography";
162 return sIdentifier;
165 bool MigrationImpl::alreadyMigrated()
167 OUString const MIGRATION_STAMP_NAME("/MIGRATED4");
168 OUString aStr = m_aInfo.userdata + MIGRATION_STAMP_NAME;
169 File aFile(aStr);
170 // create migration stamp, and/or check its existence
171 bool bRet = aFile.open (osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock) == FileBase::E_EXIST;
172 SAL_INFO( "desktop.migration", "File '" << aStr << "' exists? " << bRet );
173 return bRet;
176 bool MigrationImpl::initializeMigration()
178 bool bRet = false;
180 if (!checkMigrationCompleted()) {
181 readAvailableMigrations(m_vMigrationsAvailable);
182 sal_Int32 nIndex = findPreferredMigrationProcess(m_vMigrationsAvailable);
183 // m_aInfo is now set to the preferred migration source
184 if ( nIndex >= 0 ) {
185 if (alreadyMigrated())
186 return false;
187 m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
190 bRet = !m_aInfo.userdata.isEmpty();
193 SAL_INFO( "desktop.migration", "Migration " << ( bRet ? "needed" : "not required" ) );
195 return bRet;
198 void Migration::migrateSettingsIfNecessary()
200 MigrationImpl aImpl;
202 if (! aImpl.initializeMigration() )
203 return;
205 bool bResult = false;
206 try {
207 bResult = aImpl.doMigration();
208 } catch (const Exception& e) {
209 SAL_WARN( "desktop", "doMigration(): " << e);
211 OSL_ENSURE(bResult, "Migration has not been successful");
214 MigrationImpl::MigrationImpl()
218 MigrationImpl::~MigrationImpl()
222 // The main entry point for migrating settings
223 bool MigrationImpl::doMigration()
225 // compile file list for migration
226 m_vrFileList = compileFileList();
228 bool result = false;
229 try {
230 NewVersionUIInfo aNewVersionUIInfo;
231 std::vector< MigrationModuleInfo > vModulesInfo = dectectUIChangesForAllModules();
232 aNewVersionUIInfo.init(vModulesInfo);
234 copyFiles();
236 const OUString sMenubarResourceURL("private:resource/menubar/menubar");
237 const OUString sToolbarResourcePre("private:resource/toolbar/");
238 for (MigrationModuleInfo & i : vModulesInfo) {
239 OUString sModuleIdentifier = mapModuleShortNameToIdentifier(i.sModuleShortName);
240 if (sModuleIdentifier.isEmpty())
241 continue;
243 uno::Sequence< uno::Any > lArgs(2);
244 OUString aOldCfgDataPath = m_aInfo.userdata + "/user/config/soffice.cfg/modules/";
245 lArgs[0] <<= aOldCfgDataPath + i.sModuleShortName;
246 lArgs[1] <<= embed::ElementModes::READ;
248 uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext());
249 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(embed::FileSystemStorageFactory::create(xContext));
250 uno::Reference< embed::XStorage > xModules(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
251 uno::Reference< ui::XUIConfigurationManager2 > xOldCfgManager = ui::UIConfigurationManager::create(xContext);
253 if ( xModules.is() ) {
254 xOldCfgManager->setStorage( xModules );
255 xOldCfgManager->reload();
258 uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.getConfigManager(i.sModuleShortName);
260 if (i.bHasMenubar) {
261 uno::Reference< container::XIndexContainer > xOldVersionMenuSettings(xOldCfgManager->getSettings(sMenubarResourceURL, true), uno::UNO_QUERY);
262 uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.getNewMenubarSettings(i.sModuleShortName);
263 compareOldAndNewConfig(OUString(), xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL);
264 mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL);
267 sal_Int32 nToolbars = i.m_vToolbars.size();
268 if (nToolbars >0) {
269 for (sal_Int32 j=0; j<nToolbars; ++j) {
270 OUString sToolbarName = i.m_vToolbars[j];
271 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
273 uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings(xOldCfgManager->getSettings(sToolbarResourceURL, true), uno::UNO_QUERY);
274 uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.getNewToolbarSettings(i.sModuleShortName, sToolbarName);
275 compareOldAndNewConfig(OUString(), xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL);
276 mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL);
280 m_aOldVersionItemsHashMap.clear();
283 // execute the migration items from Setup.xcu
284 copyConfig();
286 // execute custom migration services from Setup.xcu
287 // and refresh the cache
288 runServices();
289 uno::Reference< XRefreshable >(
290 configuration::theDefaultProvider::get(comphelper::getProcessComponentContext()),
291 uno::UNO_QUERY_THROW)->refresh();
293 result = true;
294 } catch (css::uno::Exception & e) {
295 SAL_WARN(
296 "desktop.migration",
297 "ignored Exception \"" << e
298 << "\" while migrating from version \"" << m_aInfo.productname
299 << "\" data \"" << m_aInfo.userdata << "\"");
302 // prevent running the migration multiple times
303 setMigrationCompleted();
304 return result;
307 void MigrationImpl::setMigrationCompleted()
309 try {
310 uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
311 aPropertySet->setPropertyValue("MigrationCompleted", uno::makeAny(true));
312 uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
313 } catch (...) {
314 // fail silently
318 bool MigrationImpl::checkMigrationCompleted()
320 bool bMigrationCompleted = false;
321 try {
322 uno::Reference< XPropertySet > aPropertySet(
323 getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
324 aPropertySet->getPropertyValue("MigrationCompleted") >>= bMigrationCompleted;
326 if( !bMigrationCompleted && getenv("SAL_DISABLE_USERMIGRATION" ) ) {
327 // migration prevented - fake its success
328 setMigrationCompleted();
329 bMigrationCompleted = true;
331 } catch (const Exception&) {
332 // just return false...
334 SAL_INFO( "desktop.migration", "Migration " << ( bMigrationCompleted ? "already completed" : "not done" ) );
336 return bMigrationCompleted;
339 static void insertSorted(migrations_available& rAvailableMigrations, supported_migration const & aSupportedMigration)
341 bool bInserted( false );
342 migrations_available::iterator pIter = rAvailableMigrations.begin();
343 while ( !bInserted && pIter != rAvailableMigrations.end()) {
344 if ( pIter->nPriority < aSupportedMigration.nPriority ) {
345 rAvailableMigrations.insert(pIter, aSupportedMigration );
346 bInserted = true;
347 break; // i111193: insert invalidates iterator!
349 ++pIter;
351 if ( !bInserted )
352 rAvailableMigrations.push_back( aSupportedMigration );
355 bool MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigrations)
357 // get supported version names
358 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
359 uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
361 const OUString aVersionIdentifiers( "VersionIdentifiers" );
362 const OUString aPriorityIdentifier( "Priority" );
364 for (sal_Int32 i=0; i<seqSupportedVersions.getLength(); i++) {
365 sal_Int32 nPriority( 0 );
366 uno::Sequence< OUString > seqVersions;
367 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW );
368 xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions;
369 xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority;
371 supported_migration aSupportedMigration;
372 aSupportedMigration.name = seqSupportedVersions[i];
373 aSupportedMigration.nPriority = nPriority;
374 for (sal_Int32 j=0; j<seqVersions.getLength(); j++)
375 aSupportedMigration.supported_versions.push_back(seqVersions[j].trim());
376 insertSorted( rAvailableMigrations, aSupportedMigration );
377 SAL_INFO( "desktop.migration", " available migration '" << aSupportedMigration.name << "'" );
380 return true;
383 migrations_vr MigrationImpl::readMigrationSteps(const OUString& rMigrationName)
385 // get migration access
386 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
387 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW );
389 // get migration description from org.openoffice.Setup/Migration
390 // and build vector of migration steps
391 uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName("MigrationSteps"), uno::UNO_QUERY_THROW);
392 uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames();
393 uno::Reference< XNameAccess > tmpAccess;
394 uno::Sequence< OUString > tmpSeq;
395 migrations_vr vrMigrations(new migrations_v);
396 for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++) {
397 // get current migration step
398 theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess;
399 migration_step tmpStep;
400 tmpStep.name = seqMigrations[i];
402 // read included files from current step description
403 OUString aSeqEntry;
404 if (tmpAccess->getByName("IncludedFiles") >>= tmpSeq) {
405 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) {
406 aSeqEntry = tmpSeq[j];
407 tmpStep.includeFiles.push_back(aSeqEntry);
411 // excluded files...
412 if (tmpAccess->getByName("ExcludedFiles") >>= tmpSeq) {
413 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
414 tmpStep.excludeFiles.push_back(tmpSeq[j]);
417 // included nodes...
418 if (tmpAccess->getByName("IncludedNodes") >>= tmpSeq) {
419 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
420 tmpStep.includeConfig.push_back(tmpSeq[j]);
423 // excluded nodes...
424 if (tmpAccess->getByName("ExcludedNodes") >>= tmpSeq) {
425 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
426 tmpStep.excludeConfig.push_back(tmpSeq[j]);
429 // included extensions...
430 if (tmpAccess->getByName("IncludedExtensions") >>= tmpSeq) {
431 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
432 tmpStep.includeExtensions.push_back(tmpSeq[j]);
435 // excluded extensions...
436 if (tmpAccess->getByName("ExcludedExtensions") >>= tmpSeq) {
437 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++) {
438 aSeqEntry = tmpSeq[j];
439 tmpStep.excludeExtensions.push_back(aSeqEntry);
443 // generic service
444 tmpAccess->getByName("MigrationService") >>= tmpStep.service;
446 vrMigrations->push_back(tmpStep);
448 return vrMigrations;
451 static FileBase::RC _checkAndCreateDirectory(INetURLObject const & dirURL)
453 FileBase::RC result = Directory::create(dirURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri));
454 if (result == FileBase::E_NOENT) {
455 INetURLObject baseURL(dirURL);
456 baseURL.removeSegment();
457 _checkAndCreateDirectory(baseURL);
458 return Directory::create(dirURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri));
459 } else
460 return result;
463 #if defined UNX && ! defined MACOSX
465 static const char XDG_CONFIG_PART[] = "/.config/";
467 OUString MigrationImpl::preXDGConfigDir(const OUString& rConfigDir)
469 OUString aPreXDGConfigPath;
470 const char* pXDGCfgHome = getenv("XDG_CONFIG_HOME");
472 // cater for XDG_CONFIG_HOME change
473 // If XDG_CONFIG_HOME is set then we;
474 // assume the user knows what they are doing ( room for improvement here, we could
475 // of course search the default config dir etc. also - but this is more complex,
476 // we would need to weigh results from the current config dir against matches in
477 // the 'old' config dir etc. ) - currently we just use the returned config dir.
478 // If XDG_CONFIG_HOME is NOT set;
479 // assume then we should now using the default $HOME/.config config location for
480 // our user profiles, however *all* previous libreoffice and openoffice.org
481 // configurations will be in the 'old' config directory and that's where we need
482 // to search - we convert the returned config dir to the 'old' dir
483 if ( !pXDGCfgHome && rConfigDir.endsWith( XDG_CONFIG_PART ) )
484 // remove trailing '.config/' but leave the terminating '/'
485 aPreXDGConfigPath = rConfigDir.copy( 0, rConfigDir.getLength() - sizeof( XDG_CONFIG_PART ) + 2 );
486 else
487 aPreXDGConfigPath = rConfigDir;
489 // the application-specific config dir is no longer prefixed by '.' because it is hidden under ".config"
490 // we have to add the '.' for the pre-XDG directory names
491 aPreXDGConfigPath += ".";
493 return aPreXDGConfigPath;
495 #endif
497 void MigrationImpl::setInstallInfoIfExist(
498 install_info& aInfo,
499 const OUString& rConfigDir,
500 const OUString& rVersion)
502 OUString url(INetURLObject(rConfigDir).GetMainURL(INetURLObject::DecodeMechanism::NONE));
503 osl::DirectoryItem item;
504 osl::FileStatus stat(osl_FileStatus_Mask_Type);
506 if (osl::DirectoryItem::get(url, item) == osl::FileBase::E_None
507 && item.getFileStatus(stat) == osl::FileBase::E_None
508 && stat.getFileType() == osl::FileStatus::Directory) {
509 aInfo.userdata = url;
510 aInfo.productname = rVersion;
514 install_info MigrationImpl::findInstallation(const strings_v& rVersions)
517 OUString aTopConfigDir;
518 osl::Security().getConfigDir( aTopConfigDir );
519 if ( !aTopConfigDir.isEmpty() && aTopConfigDir[ aTopConfigDir.getLength()-1 ] != '/' )
520 aTopConfigDir += "/";
522 #if defined UNX && ! defined MACOSX
523 OUString aPreXDGTopConfigDir = preXDGConfigDir(aTopConfigDir);
524 #endif
526 install_info aInfo;
527 strings_v::const_iterator i_ver = rVersions.begin();
528 while (i_ver != rVersions.end()) {
529 OUString aVersion, aProfileName;
530 sal_Int32 nSeparatorIndex = (*i_ver).indexOf('=');
531 if ( nSeparatorIndex != -1 ) {
532 aVersion = (*i_ver).copy( 0, nSeparatorIndex );
533 aProfileName = (*i_ver).copy( nSeparatorIndex+1 );
536 if ( !aVersion.isEmpty() && !aProfileName.isEmpty() &&
537 ( aInfo.userdata.isEmpty() ||
538 aProfileName.equalsIgnoreAsciiCase(
539 utl::ConfigManager::getProductName() ) ) ) {
540 setInstallInfoIfExist(aInfo, aTopConfigDir + aProfileName, aVersion);
541 #if defined UNX && ! defined MACOSX
542 //try preXDG path if the new one does not exist
543 if ( aInfo.userdata.isEmpty())
544 setInstallInfoIfExist(aInfo, aPreXDGTopConfigDir + aProfileName, aVersion);
545 #endif
547 ++i_ver;
550 return aInfo;
553 sal_Int32 MigrationImpl::findPreferredMigrationProcess(const migrations_available& rAvailableMigrations)
555 sal_Int32 nIndex( -1 );
556 sal_Int32 i( 0 );
558 migrations_available::const_iterator rIter = rAvailableMigrations.begin();
559 while ( rIter != rAvailableMigrations.end() ) {
560 install_info aInstallInfo = findInstallation(rIter->supported_versions);
561 if (!aInstallInfo.productname.isEmpty() ) {
562 m_aInfo = aInstallInfo;
563 nIndex = i;
564 break;
566 ++i;
567 ++rIter;
570 SAL_INFO( "desktop.migration", " preferred migration is from product '" << m_aInfo.productname << "'");
571 SAL_INFO( "desktop.migration", " and settings directory '" << m_aInfo.userdata << "'");
573 return nIndex;
576 strings_vr MigrationImpl::applyPatterns(const strings_v& vSet, const strings_v& vPatterns)
578 using namespace utl;
579 strings_vr vrResult(new strings_v);
580 strings_v::const_iterator i_set;
581 strings_v::const_iterator i_pat = vPatterns.begin();
582 while (i_pat != vPatterns.end()) {
583 // find matches for this pattern in input set
584 // and copy them to the result
585 SearchParam param(*i_pat, SearchParam::SearchType::Regexp);
586 TextSearch ts(param, LANGUAGE_DONTKNOW);
587 i_set = vSet.begin();
588 sal_Int32 start = 0;
589 sal_Int32 end = 0;
590 while (i_set != vSet.end()) {
591 end = i_set->getLength();
592 if (ts.SearchForward(*i_set, &start, &end))
593 vrResult->push_back(*i_set);
594 ++i_set;
596 ++i_pat;
598 return vrResult;
601 strings_vr MigrationImpl::getAllFiles(const OUString& baseURL) const
603 strings_vr vrResult(new strings_v);
605 // get sub dirs
606 Directory dir(baseURL);
607 if (dir.open() == FileBase::E_None) {
608 strings_v vSubDirs;
609 strings_vr vrSubResult;
611 // work through directory contents...
612 DirectoryItem item;
613 FileStatus fs(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL);
614 while (dir.getNextItem(item) == FileBase::E_None) {
615 if (item.getFileStatus(fs) == FileBase::E_None) {
616 if (fs.getFileType() == FileStatus::Directory)
617 vSubDirs.push_back(fs.getFileURL());
618 else
619 vrResult->push_back(fs.getFileURL());
623 // recurse subfolders
624 strings_v::const_iterator i = vSubDirs.begin();
625 while (i != vSubDirs.end()) {
626 vrSubResult = getAllFiles(*i);
627 vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end());
628 ++i;
631 return vrResult;
634 namespace
637 // removes elements of vector 2 in vector 1
638 strings_v subtract(strings_v const & va, strings_v const & vb)
640 strings_v a(va);
641 std::sort(a.begin(), a.end());
642 strings_v::iterator ae(std::unique(a.begin(), a.end()));
643 strings_v b(vb);
644 std::sort(b.begin(), b.end());
645 strings_v::iterator be(std::unique(b.begin(), b.end()));
646 strings_v c;
647 std::set_difference(a.begin(), ae, b.begin(), be, std::back_inserter(c));
648 return c;
653 strings_vr MigrationImpl::compileFileList()
656 strings_vr vrResult(new strings_v);
657 strings_vr vrInclude;
658 strings_vr vrExclude;
660 // get a list of all files:
661 strings_vr vrFiles = getAllFiles(m_aInfo.userdata);
663 // get a file list result for each migration step
664 migrations_v::const_iterator i_migr = m_vrMigrations->begin();
665 while (i_migr != m_vrMigrations->end()) {
666 vrInclude = applyPatterns(*vrFiles, i_migr->includeFiles);
667 vrExclude = applyPatterns(*vrFiles, i_migr->excludeFiles);
668 strings_v sub(subtract(*vrInclude, *vrExclude));
669 vrResult->insert(vrResult->end(), sub.begin(), sub.end());
670 ++i_migr;
672 return vrResult;
675 namespace
678 struct componentParts {
679 std::set< OUString > includedPaths;
680 std::set< OUString > excludedPaths;
683 typedef std::map< OUString, componentParts > Components;
685 bool getComponent(OUString const & path, OUString * component)
687 OSL_ASSERT(component != nullptr);
688 if (path.isEmpty() || path[0] != '/') {
689 SAL_INFO( "desktop.migration", "configuration migration in/exclude path " << path << " ignored (does not start with slash)" );
690 return false;
692 sal_Int32 i = path.indexOf('/', 1);
693 *component = i < 0 ? path.copy(1) : path.copy(1, i - 1);
694 return true;
697 uno::Sequence< OUString > setToSeq(std::set< OUString > const & set)
699 std::set< OUString >::size_type n = set.size();
700 if (n > SAL_MAX_INT32) {
701 throw std::bad_alloc();
703 uno::Sequence< OUString > seq(static_cast< sal_Int32 >(n));
704 sal_Int32 i = 0;
705 for (std::set< OUString >::const_iterator j(set.begin());
706 j != set.end(); ++j) {
707 seq[i++] = *j;
709 return seq;
714 void MigrationImpl::copyConfig()
716 Components comps;
717 for (migrations_v::const_iterator i(m_vrMigrations->begin());
718 i != m_vrMigrations->end(); ++i) {
719 for (strings_v::const_iterator j(i->includeConfig.begin());
720 j != i->includeConfig.end(); ++j) {
721 OUString comp;
722 if (getComponent(*j, &comp)) {
723 comps[comp].includedPaths.insert(*j);
726 for (strings_v::const_iterator j(i->excludeConfig.begin());
727 j != i->excludeConfig.end(); ++j) {
728 OUString comp;
729 if (getComponent(*j, &comp)) {
730 comps[comp].excludedPaths.insert(*j);
735 // check if the shared registrymodifications.xcu file exists
736 bool bRegistryModificationsXcuExists = false;
737 OUString regFilePath(m_aInfo.userdata);
738 regFilePath += "/user/registrymodifications.xcu";
739 File regFile(regFilePath);
740 ::osl::FileBase::RC nError = regFile.open(osl_File_OpenFlag_Read);
741 if ( nError == ::osl::FileBase::E_None ) {
742 bRegistryModificationsXcuExists = true;
743 regFile.close();
746 for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) {
747 if (!i->second.includedPaths.empty()) {
748 if (!bRegistryModificationsXcuExists) {
749 // shared registrymodifications.xcu does not exists
750 // the configuration is split in many registry files
751 // determine the file names from the first element in included paths
752 OUStringBuffer buf(m_aInfo.userdata);
753 buf.append("/user/registry/data");
754 sal_Int32 n = 0;
755 do {
756 OUString seg(i->first.getToken(0, '.', n));
757 OUString enc(
758 rtl::Uri::encode(
759 seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict,
760 RTL_TEXTENCODING_UTF8));
761 if (enc.isEmpty() && !seg.isEmpty()) {
762 SAL_INFO( "desktop.migration", "configuration migration component " << i->first << " ignored (cannot be encoded as file path)" );
763 goto next;
765 buf.append('/');
766 buf.append(enc);
767 } while (n >= 0);
768 buf.append(".xcu");
769 regFilePath = buf.toString();
771 configuration::Update::get(
772 comphelper::getProcessComponentContext())->
773 insertModificationXcuFile(
774 regFilePath, setToSeq(i->second.includedPaths),
775 setToSeq(i->second.excludedPaths));
776 } else {
777 SAL_INFO( "desktop.migration", "configuration migration component " << i->first << " ignored (only excludes, no includes)" );
779 next:
784 uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, bool bUpdate)
786 uno::Reference< XNameAccess > xNameAccess;
787 try {
788 OUString sAccessSrvc;
789 if (bUpdate)
790 sAccessSrvc = "com.sun.star.configuration.ConfigurationUpdateAccess";
791 else
792 sAccessSrvc = "com.sun.star.configuration.ConfigurationAccess";
794 OUString sConfigURL = OUString::createFromAscii(pPath);
796 uno::Reference< XMultiServiceFactory > theConfigProvider(
797 configuration::theDefaultProvider::get(
798 comphelper::getProcessComponentContext()));
800 // access the provider
801 uno::Sequence< uno::Any > theArgs(1);
802 theArgs[ 0 ] <<= sConfigURL;
803 xNameAccess.set(
804 theConfigProvider->createInstanceWithArguments(
805 sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
806 } catch (const css::uno::Exception& e) {
807 SAL_WARN(
808 "desktop.migration", "ignoring Exception \"" << e << "\"");
810 return xNameAccess;
813 void MigrationImpl::copyFiles()
815 strings_v::const_iterator i_file = m_vrFileList->begin();
816 OUString localName;
817 OUString destName;
818 OUString userInstall;
819 utl::Bootstrap::PathStatus aStatus;
820 aStatus = utl::Bootstrap::locateUserInstallation(userInstall);
821 if (aStatus == utl::Bootstrap::PATH_EXISTS) {
822 while (i_file != m_vrFileList->end()) {
823 // remove installation prefix from file
824 localName = i_file->copy(m_aInfo.userdata.getLength());
825 if (localName.endsWith( "/autocorr/acor_.dat")) {
826 // Previous versions used an empty language tag for
827 // LANGUAGE_DONTKNOW with the "[All]" autocorrection entry.
828 // As of LibreOffice 4.0 it is 'und' for LANGUAGE_UNDETERMINED
829 // so the file name is "acor_und.dat".
830 localName = localName.copy( 0, localName.getLength() - 4) + "und.dat";
832 destName = userInstall + localName;
833 INetURLObject aURL(destName);
834 // check whether destination directory exists
835 aURL.removeSegment();
836 _checkAndCreateDirectory(aURL);
837 FileBase::RC copyResult = File::copy(*i_file, destName);
838 if (copyResult != FileBase::E_None) {
839 SAL_WARN( "desktop", "Cannot copy " << *i_file << " to " << destName);
841 ++i_file;
843 } else {
844 OSL_FAIL("copyFiles: UserInstall does not exist");
848 void MigrationImpl::runServices()
850 // Build argument array
851 uno::Sequence< uno::Any > seqArguments(3);
852 seqArguments[0] <<= NamedValue("Productname",
853 uno::makeAny(m_aInfo.productname));
854 seqArguments[1] <<= NamedValue("UserData",
855 uno::makeAny(m_aInfo.userdata));
858 // create an instance of every migration service
859 // and execute the migration job
860 uno::Reference< XJob > xMigrationJob;
862 uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext());
863 migrations_v::const_iterator i_mig = m_vrMigrations->begin();
864 while (i_mig != m_vrMigrations->end()) {
865 if( !i_mig->service.isEmpty()) {
867 try {
868 // set black list for extension migration
869 uno::Sequence< OUString > seqExtBlackList;
870 sal_uInt32 nSize = i_mig->excludeExtensions.size();
871 if ( nSize > 0 )
872 seqExtBlackList = comphelper::arrayToSequence< OUString >(
873 &i_mig->excludeExtensions[0], nSize );
874 seqArguments[2] <<= NamedValue("ExtensionBlackList",
875 uno::makeAny( seqExtBlackList ));
877 xMigrationJob.set(
878 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(i_mig->service, seqArguments, xContext),
879 uno::UNO_QUERY_THROW);
881 xMigrationJob->execute(uno::Sequence< NamedValue >());
884 } catch (const Exception& e) {
885 SAL_WARN( "desktop", "Execution of migration service failed (Exception caught).\nService: "
886 << i_mig->service
887 << "\nMessage: " << e);
888 } catch (...) {
889 SAL_WARN( "desktop", "Execution of migration service failed (Exception caught).\nService: "
890 << i_mig->service << "\nNo message available");
894 ++i_mig;
898 std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const
900 std::vector< MigrationModuleInfo > vModulesInfo;
901 const OUString MENUBAR("menubar");
902 const OUString TOOLBAR("toolbar");
904 uno::Sequence< uno::Any > lArgs(2);
905 lArgs[0] <<= m_aInfo.userdata + "/user/config/soffice.cfg/modules";
906 lArgs[1] <<= embed::ElementModes::READ;
908 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
909 embed::FileSystemStorageFactory::create(comphelper::getProcessComponentContext()));
910 uno::Reference< embed::XStorage > xModules;
912 xModules.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
913 if (!xModules.is())
914 return vModulesInfo;
916 uno::Reference< container::XNameAccess > xAccess(xModules, uno::UNO_QUERY);
917 uno::Sequence< OUString > lNames = xAccess->getElementNames();
918 sal_Int32 nLength = lNames.getLength();
919 for (sal_Int32 i=0; i<nLength; ++i) {
920 OUString sModuleShortName = lNames[i];
921 uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ);
922 if (xModule.is()) {
923 MigrationModuleInfo aModuleInfo;
925 uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ);
926 if (xMenubar.is()) {
927 uno::Reference< container::XNameAccess > xNameAccess(xMenubar, uno::UNO_QUERY);
928 if (xNameAccess->getElementNames().getLength() > 0) {
929 aModuleInfo.sModuleShortName = sModuleShortName;
930 aModuleInfo.bHasMenubar = true;
934 uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ);
935 if (xToolbar.is()) {
936 const OUString RESOURCEURL_CUSTOM_ELEMENT("custom_");
937 sal_Int32 nCustomLen = 7;
939 uno::Reference< container::XNameAccess > xNameAccess(xToolbar, uno::UNO_QUERY);
940 ::uno::Sequence< OUString > lToolbars = xNameAccess->getElementNames();
941 for (sal_Int32 j=0; j<lToolbars.getLength(); ++j) {
942 OUString sToolbarName = lToolbars[j];
943 if (sToolbarName.getLength()>=nCustomLen &&
944 sToolbarName.copy(0, nCustomLen) == RESOURCEURL_CUSTOM_ELEMENT)
945 continue;
947 aModuleInfo.sModuleShortName = sModuleShortName;
948 sal_Int32 nIndex = sToolbarName.lastIndexOf('.');
949 if (nIndex > 0) {
950 OUString sExtension(sToolbarName.copy(nIndex));
951 OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
952 if (!sToolbarResourceName.isEmpty() && sExtension == ".xml")
953 aModuleInfo.m_vToolbars.push_back(sToolbarResourceName);
958 if (!aModuleInfo.sModuleShortName.isEmpty())
959 vModulesInfo.push_back(aModuleInfo);
963 return vModulesInfo;
966 void MigrationImpl::compareOldAndNewConfig(const OUString& sParent,
967 const uno::Reference< container::XIndexContainer >& xIndexOld,
968 const uno::Reference< container::XIndexContainer >& xIndexNew,
969 const OUString& sResourceURL)
971 const OUString MENU_SEPARATOR(" | ");
973 std::vector< MigrationItem > vOldItems;
974 std::vector< MigrationItem > vNewItems;
975 uno::Sequence< beans::PropertyValue > aProp;
976 sal_Int32 nOldCount = xIndexOld->getCount();
977 sal_Int32 nNewCount = xIndexNew->getCount();
979 for (int n=0; n<nOldCount; ++n) {
980 MigrationItem aMigrationItem;
981 if (xIndexOld->getByIndex(n) >>= aProp) {
982 for(int i=0; i<aProp.getLength(); ++i) {
983 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
984 aProp[i].Value >>= aMigrationItem.m_sCommandURL;
985 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
986 aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
989 if (!aMigrationItem.m_sCommandURL.isEmpty())
990 vOldItems.push_back(aMigrationItem);
994 for (int n=0; n<nNewCount; ++n) {
995 MigrationItem aMigrationItem;
996 if (xIndexNew->getByIndex(n) >>= aProp) {
997 for(int i=0; i<aProp.getLength(); ++i) {
998 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
999 aProp[i].Value >>= aMigrationItem.m_sCommandURL;
1000 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
1001 aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
1004 if (!aMigrationItem.m_sCommandURL.isEmpty())
1005 vNewItems.push_back(aMigrationItem);
1009 std::vector< MigrationItem >::iterator it;
1011 OUString sSibling;
1012 for (it = vOldItems.begin(); it!=vOldItems.end(); ++it) {
1013 std::vector< MigrationItem >::iterator pFound = std::find(vNewItems.begin(), vNewItems.end(), *it);
1014 if (pFound != vNewItems.end() && it->m_xPopupMenu.is()) {
1015 OUString sName;
1016 if (!sParent.isEmpty())
1017 sName = sParent + MENU_SEPARATOR + it->m_sCommandURL;
1018 else
1019 sName = it->m_sCommandURL;
1020 compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL);
1021 } else if (pFound == vNewItems.end()) {
1022 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
1023 if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end()) {
1024 std::vector< MigrationItem > vMigrationItems;
1025 m_aOldVersionItemsHashMap.emplace(sResourceURL, vMigrationItems);
1026 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1027 } else {
1028 if (std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end())
1029 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1033 sSibling = it->m_sCommandURL;
1037 void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager,
1038 const uno::Reference< container::XIndexContainer>& xIndexContainer,
1039 const OUString& sModuleIdentifier,
1040 const OUString& sResourceURL)
1042 MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL);
1043 if (pFound==m_aOldVersionItemsHashMap.end())
1044 return;
1046 std::vector< MigrationItem >::iterator it;
1047 for (it=pFound->second.begin(); it!=pFound->second.end(); ++it) {
1048 uno::Reference< container::XIndexContainer > xTemp = xIndexContainer;
1050 OUString sParentNodeName = it->m_sParentNodeName;
1051 sal_Int32 nIndex = 0;
1052 do {
1053 OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim();
1054 if (sToken.isEmpty())
1055 break;
1057 sal_Int32 nCount = xTemp->getCount();
1058 for (sal_Int32 i=0; i<nCount; ++i) {
1059 OUString sCommandURL;
1060 OUString sLabel;
1061 uno::Reference< container::XIndexContainer > xChild;
1063 uno::Sequence< beans::PropertyValue > aPropSeq;
1064 xTemp->getByIndex(i) >>= aPropSeq;
1065 for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j) {
1066 OUString sPropName = aPropSeq[j].Name;
1067 if ( sPropName == ITEM_DESCRIPTOR_COMMANDURL )
1068 aPropSeq[j].Value >>= sCommandURL;
1069 else if ( sPropName == ITEM_DESCRIPTOR_LABEL )
1070 aPropSeq[j].Value >>= sLabel;
1071 else if ( sPropName == ITEM_DESCRIPTOR_CONTAINER )
1072 aPropSeq[j].Value >>= xChild;
1075 if (sCommandURL == sToken) {
1076 xTemp = xChild;
1077 break;
1081 } while (nIndex>=0);
1083 if (nIndex == -1) {
1084 uno::Sequence< beans::PropertyValue > aPropSeq(3);
1086 aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
1087 aPropSeq[0].Value <<= it->m_sCommandURL;
1088 aPropSeq[1].Name = ITEM_DESCRIPTOR_LABEL;
1089 aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier);
1090 aPropSeq[2].Name = ITEM_DESCRIPTOR_CONTAINER;
1091 aPropSeq[2].Value <<= it->m_xPopupMenu;
1093 if (it->m_sPrevSibling.isEmpty())
1094 xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
1095 else {
1096 sal_Int32 nCount = xTemp->getCount();
1097 sal_Int32 i = 0;
1098 for (; i<nCount; ++i) {
1099 OUString sCmd;
1100 uno::Sequence< beans::PropertyValue > aTempPropSeq;
1101 xTemp->getByIndex(i) >>= aTempPropSeq;
1102 for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j) {
1103 if ( aTempPropSeq[j].Name == ITEM_DESCRIPTOR_COMMANDURL ) {
1104 aTempPropSeq[j].Value >>= sCmd;
1105 break;
1109 if (sCmd == it->m_sPrevSibling)
1110 break;
1113 xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
1118 uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY);
1119 if (xIndexAccess.is())
1120 xCfgManager->replaceSettings(sResourceURL, xIndexAccess);
1122 uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY);
1123 if (xUIConfigurationPersistence.is())
1124 xUIConfigurationPersistence->store();
1127 uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const OUString& sModuleShortName) const
1129 uno::Reference< ui::XUIConfigurationManager > xCfgManager;
1131 for ( const css::beans::PropertyValue& rProp : m_lCfgManagerSeq) {
1132 if (rProp.Name == sModuleShortName) {
1133 rProp.Value >>= xCfgManager;
1134 break;
1138 return xCfgManager;
1141 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const OUString& sModuleShortName) const
1143 uno::Reference< container::XIndexContainer > xNewMenuSettings;
1145 for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i) {
1146 if (m_lNewVersionMenubarSettingsSeq[i].Name == sModuleShortName) {
1147 m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings;
1148 break;
1152 return xNewMenuSettings;
1155 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const OUString& sModuleShortName, const OUString& sToolbarName) const
1157 uno::Reference< container::XIndexContainer > xNewToolbarSettings;
1159 for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i) {
1160 if (m_lNewVersionToolbarSettingsSeq[i].Name == sModuleShortName) {
1161 uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
1162 m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq;
1163 for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j) {
1164 if (lToolbarSettingsSeq[j].Name == sToolbarName) {
1165 lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings;
1166 break;
1170 break;
1174 return xNewToolbarSettings;
1177 void NewVersionUIInfo::init(const std::vector< MigrationModuleInfo >& vModulesInfo)
1179 m_lCfgManagerSeq.resize(vModulesInfo.size());
1180 m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size());
1181 m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
1183 const OUString sMenubarResourceURL("private:resource/menubar/menubar");
1184 const OUString sToolbarResourcePre("private:resource/toolbar/");
1186 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = ui::theModuleUIConfigurationManagerSupplier::get( ::comphelper::getProcessComponentContext() );
1188 for (size_t i=0; i<vModulesInfo.size(); ++i) {
1189 OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
1190 if (!sModuleIdentifier.isEmpty()) {
1191 uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier);
1192 m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName;
1193 m_lCfgManagerSeq[i].Value <<= xCfgManager;
1195 if (vModulesInfo[i].bHasMenubar) {
1196 m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1197 m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, true);
1200 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
1201 if (nToolbars > 0) {
1202 uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars);
1203 for (sal_Int32 j=0; j<nToolbars; ++j) {
1204 OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
1205 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
1207 lPropSeq[j].Name = sToolbarName;
1208 lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, true);
1211 m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1212 m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq;
1218 } // namespace desktop
1220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */