GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / desktop / source / migration / migration.cxx
blob974515f3822f3bb9953c3daba900f6afd0ea4be4
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 <unotools/textsearch.hxx>
32 #include <comphelper/processfactory.hxx>
33 #include <comphelper/sequence.hxx>
34 #include <unotools/bootstrap.hxx>
35 #include <rtl/bootstrap.hxx>
36 #include <rtl/uri.hxx>
37 #include <i18nlangtag/lang.h>
38 #include <tools/urlobj.hxx>
39 #include <osl/file.hxx>
40 #include <osl/mutex.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/ModuleUIConfigurationManagerSupplier.hpp>
57 #include <com/sun/star/frame/UICommandDescription.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 {
76 static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
77 static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
78 static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
80 OUString retrieveLabelFromCommand(const OUString& sCommand, const OUString& sModuleIdentifier)
82 OUString sLabel;
84 uno::Reference< container::XNameAccess > xUICommands;
85 uno::Reference< container::XNameAccess > const xNameAccess(
86 frame::UICommandDescription::create(
87 ::comphelper::getProcessComponentContext()) );
88 xNameAccess->getByName( sModuleIdentifier ) >>= xUICommands;
89 if (xUICommands.is())
91 if ( !sCommand.isEmpty() )
93 OUString aStr;
94 ::uno::Sequence< beans::PropertyValue > aPropSeq;
95 try
97 uno::Any a( xUICommands->getByName( sCommand ));
98 if ( a >>= aPropSeq )
100 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
102 if ( aPropSeq[i].Name == "Label" )
104 aPropSeq[i].Value >>= aStr;
105 break;
110 sLabel = aStr;
112 catch (const container::NoSuchElementException&)
114 sLabel = sCommand;
115 sal_Int32 nIndex = sLabel.indexOf(':');
116 if (nIndex>=0 && nIndex <= sLabel.getLength()-1)
117 sLabel = sLabel.copy(nIndex+1);
123 return sLabel;
126 OUString mapModuleShortNameToIdentifier(const OUString& sShortName)
128 OUString sIdentifier;
130 if ( sShortName == "StartModule" )
131 sIdentifier = "com.sun.star.frame.StartModule";
133 else if ( sShortName == "swriter" )
134 sIdentifier = "com.sun.star.text.TextDocument";
136 else if ( sShortName == "scalc" )
137 sIdentifier = "com.sun.star.sheet.SpreadsheetDocument";
139 else if ( sShortName == "sdraw" )
140 sIdentifier = "com.sun.star.drawing.DrawingDocument";
142 else if ( sShortName == "simpress" )
143 sIdentifier = "com.sun.star.presentation.PresentationDocument";
145 else if ( sShortName == "smath" )
146 sIdentifier = "com.sun.star.formula.FormulaProperties";
148 else if ( sShortName == "schart" )
149 sIdentifier = "com.sun.star.chart2.ChartDocument";
151 else if ( sShortName == "BasicIDE" )
152 sIdentifier = "com.sun.star.script.BasicIDE";
154 else if ( sShortName == "dbapp" )
155 sIdentifier = "com.sun.star.sdb.OfficeDatabaseDocument";
157 else if ( sShortName == "sglobal" )
158 sIdentifier = "com.sun.star.text.GlobalDocument";
160 else if ( sShortName == "sweb" )
161 sIdentifier = "com.sun.star.text.WebDocument";
163 else if ( sShortName == "swxform" )
164 sIdentifier = "com.sun.star.xforms.XMLFormDocument";
166 else if ( sShortName == "sbibliography" )
167 sIdentifier = "com.sun.star.frame.Bibliography";
169 return sIdentifier;
172 bool MigrationImpl::alreadyMigrated()
174 OUString MIGRATION_STAMP_NAME("/MIGRATED4");
175 OUString aStr = m_aInfo.userdata + MIGRATION_STAMP_NAME;
176 File aFile(aStr);
177 // create migration stamp, and/or check its existence
178 bool bRet = aFile.open (osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock) == FileBase::E_EXIST;
179 OSL_TRACE( "File '%s' exists? %d\n",
180 OUStringToOString(aStr, RTL_TEXTENCODING_ASCII_US).getStr(),
181 bRet );
182 return bRet;
185 bool MigrationImpl::initializeMigration()
187 bool bRet = false;
189 if (!checkMigrationCompleted()) {
190 readAvailableMigrations(m_vMigrationsAvailable);
191 sal_Int32 nIndex = findPreferedMigrationProcess(m_vMigrationsAvailable);
192 // m_aInfo is now set to the preferred migration source
193 if ( nIndex >= 0 ) {
194 if (alreadyMigrated())
195 return false;
196 m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].name);
199 bRet = !m_aInfo.userdata.isEmpty();
202 OSL_TRACE( "Migration %s", bRet ? "needed" : "not required" );
204 return bRet;
207 void Migration::migrateSettingsIfNecessary()
209 MigrationImpl aImpl;
211 if (! aImpl.initializeMigration() )
212 return;
214 sal_Bool bResult = sal_False;
217 bResult = aImpl.doMigration();
219 catch (const Exception& e)
221 OString aMsg("doMigration() exception: ");
222 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
223 OSL_FAIL(aMsg.getStr());
225 OSL_ENSURE(bResult, "Migration has not been successful");
226 (void)bResult;
229 MigrationImpl::MigrationImpl()
230 : m_vrVersions(new strings_v)
234 MigrationImpl::~MigrationImpl()
238 // The main entry point for migrating settings
239 sal_Bool MigrationImpl::doMigration()
241 // compile file list for migration
242 m_vrFileList = compileFileList();
244 sal_Bool result = sal_False;
247 NewVersionUIInfo aNewVersionUIInfo;
248 ::std::vector< MigrationModuleInfo > vModulesInfo = dectectUIChangesForAllModules();
249 aNewVersionUIInfo.init(vModulesInfo);
251 copyFiles();
253 const OUString sMenubarResourceURL("private:resource/menubar/menubar");
254 const OUString sToolbarResourcePre("private:resource/toolbar/");
255 for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
257 OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
258 if (sModuleIdentifier.isEmpty())
259 continue;
261 uno::Sequence< uno::Any > lArgs(2);
262 OUString aOldCfgDataPath = m_aInfo.userdata + OUString("/user/config/soffice.cfg/modules/");
263 lArgs[0] <<= aOldCfgDataPath + vModulesInfo[i].sModuleShortName;
264 lArgs[1] <<= embed::ElementModes::READ;
266 uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext());
267 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(embed::FileSystemStorageFactory::create(xContext));
268 uno::Reference< embed::XStorage > xModules(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
269 uno::Reference< ui::XUIConfigurationManager2 > xOldCfgManager = ui::UIConfigurationManager::create(xContext);
271 if ( xModules.is() )
273 xOldCfgManager->setStorage( xModules );
274 xOldCfgManager->reload();
277 uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.getConfigManager(vModulesInfo[i].sModuleShortName);
279 if (vModulesInfo[i].bHasMenubar)
281 uno::Reference< container::XIndexContainer > xOldVersionMenuSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sMenubarResourceURL, sal_True), uno::UNO_QUERY);
282 uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.getNewMenubarSettings(vModulesInfo[i].sModuleShortName);
283 OUString sParent;
284 compareOldAndNewConfig(sParent, xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL);
285 mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL);
288 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
289 if (nToolbars >0)
291 for (sal_Int32 j=0; j<nToolbars; ++j)
293 OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
294 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
296 uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings = uno::Reference< container::XIndexContainer >(xOldCfgManager->getSettings(sToolbarResourceURL, sal_True), uno::UNO_QUERY);
297 uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.getNewToolbarSettings(vModulesInfo[i].sModuleShortName, sToolbarName);
298 OUString sParent;
299 compareOldAndNewConfig(sParent, xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL);
300 mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL);
304 m_aOldVersionItemsHashMap.clear();
305 m_aNewVersionItemsHashMap.clear();
308 // execute the migration items from Setup.xcu
309 copyConfig();
311 // execute custom migration services from Setup.xcu
312 // and refresh the cache
313 runServices();
314 refresh();
316 result = sal_True;
318 catch (css::uno::Exception & e)
320 SAL_WARN(
321 "desktop.migration",
322 "ignored Exception \"" << e.Message
323 << "\" while migrating from version \"" << m_aInfo.productname
324 << "\" data \"" << m_aInfo.userdata << "\"");
327 // prevent running the migration multiple times
328 setMigrationCompleted();
329 return result;
332 void MigrationImpl::refresh()
334 uno::Reference< XRefreshable >(
335 configuration::theDefaultProvider::get(comphelper::getProcessComponentContext()),
336 uno::UNO_QUERY_THROW)->refresh();
339 void MigrationImpl::setMigrationCompleted()
343 uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW);
344 aPropertySet->setPropertyValue("MigrationCompleted", uno::makeAny(sal_True));
345 uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
347 catch (...)
349 // fail silently
353 bool MigrationImpl::checkMigrationCompleted()
355 sal_Bool bMigrationCompleted = sal_False;
356 try {
357 uno::Reference< XPropertySet > aPropertySet(
358 getConfigAccess("org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
359 aPropertySet->getPropertyValue("MigrationCompleted") >>= bMigrationCompleted;
361 if( !bMigrationCompleted && getenv("SAL_DISABLE_USERMIGRATION" ) )
363 // migration prevented - fake it's success
364 setMigrationCompleted();
365 bMigrationCompleted = sal_True;
368 catch (const Exception&)
370 // just return false...
372 OSL_TRACE( "Migration %s", bMigrationCompleted ? "already completed" : "not done" );
374 return bMigrationCompleted;
377 static void insertSorted(migrations_available& rAvailableMigrations, supported_migration& aSupportedMigration)
379 bool bInserted( false );
380 migrations_available::iterator pIter = rAvailableMigrations.begin();
381 while ( !bInserted && pIter != rAvailableMigrations.end())
383 if ( pIter->nPriority < aSupportedMigration.nPriority )
385 rAvailableMigrations.insert(pIter, aSupportedMigration );
386 bInserted = true;
387 break; // i111193: insert invalidates iterator!
389 ++pIter;
391 if ( !bInserted )
392 rAvailableMigrations.push_back( aSupportedMigration );
395 bool MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigrations)
397 // get supported version names
398 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
399 uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
401 const OUString aVersionIdentifiers( "VersionIdentifiers" );
402 const OUString aPriorityIdentifier( "Priority" );
404 for (sal_Int32 i=0; i<seqSupportedVersions.getLength(); i++)
406 sal_Int32 nPriority( 0 );
407 uno::Sequence< OUString > seqVersions;
408 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(seqSupportedVersions[i]), uno::UNO_QUERY_THROW );
409 xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions;
410 xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority;
412 supported_migration aSupportedMigration;
413 aSupportedMigration.name = seqSupportedVersions[i];
414 aSupportedMigration.nPriority = nPriority;
415 for (sal_Int32 j=0; j<seqVersions.getLength(); j++)
416 aSupportedMigration.supported_versions.push_back(seqVersions[j].trim());
417 insertSorted( rAvailableMigrations, aSupportedMigration );
418 OSL_TRACE( " available migration '%s'\n",
419 OUStringToOString( aSupportedMigration.name, RTL_TEXTENCODING_ASCII_US ).getStr() );
422 return true;
425 migrations_vr MigrationImpl::readMigrationSteps(const OUString& rMigrationName)
427 // get migration access
428 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_QUERY_THROW);
429 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW );
431 // get migration description from from org.openoffice.Setup/Migration
432 // and build vector of migration steps
433 OUString aMigrationSteps( "MigrationSteps" );
434 uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(aMigrationSteps), uno::UNO_QUERY_THROW);
435 uno::Sequence< OUString > seqMigrations = theNameAccess->getElementNames();
436 uno::Reference< XNameAccess > tmpAccess;
437 uno::Reference< XNameAccess > tmpAccess2;
438 uno::Sequence< OUString > tmpSeq;
439 migrations_vr vrMigrations(new migrations_v);
440 for (sal_Int32 i = 0; i < seqMigrations.getLength(); i++)
442 // get current migration step
443 theNameAccess->getByName(seqMigrations[i]) >>= tmpAccess;
444 migration_step tmpStep;
445 tmpStep.name = seqMigrations[i];
447 // read included files from current step description
448 OUString aSeqEntry;
449 if (tmpAccess->getByName("IncludedFiles") >>= tmpSeq)
451 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
453 aSeqEntry = tmpSeq[j];
454 tmpStep.includeFiles.push_back(aSeqEntry);
458 // exluded files...
459 if (tmpAccess->getByName("ExcludedFiles") >>= tmpSeq)
461 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
462 tmpStep.excludeFiles.push_back(tmpSeq[j]);
465 // included nodes...
466 if (tmpAccess->getByName("IncludedNodes") >>= tmpSeq)
468 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
469 tmpStep.includeConfig.push_back(tmpSeq[j]);
472 // excluded nodes...
473 if (tmpAccess->getByName("ExcludedNodes") >>= tmpSeq)
475 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
476 tmpStep.excludeConfig.push_back(tmpSeq[j]);
479 // included extensions...
480 if (tmpAccess->getByName("IncludedExtensions") >>= tmpSeq)
482 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
483 tmpStep.includeExtensions.push_back(tmpSeq[j]);
486 // excluded extensions...
487 if (tmpAccess->getByName("ExcludedExtensions") >>= tmpSeq)
489 for (sal_Int32 j=0; j<tmpSeq.getLength(); j++)
491 aSeqEntry = tmpSeq[j];
492 tmpStep.excludeExtensions.push_back(aSeqEntry);
496 // generic service
497 tmpAccess->getByName("MigrationService") >>= tmpStep.service;
499 vrMigrations->push_back(tmpStep);
501 return vrMigrations;
504 static FileBase::RC _checkAndCreateDirectory(INetURLObject& dirURL)
506 FileBase::RC result = Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
507 if (result == FileBase::E_NOENT)
509 INetURLObject baseURL(dirURL);
510 baseURL.removeSegment();
511 _checkAndCreateDirectory(baseURL);
512 return Directory::create(dirURL.GetMainURL(INetURLObject::DECODE_TO_IURI));
513 } else
514 return result;
517 static const char XDG_CONFIG_PART[] = "/.config/";
519 #if defined UNX && ! defined MACOSX
520 OUString MigrationImpl::preXDGConfigDir(const OUString& rConfigDir)
522 OUString aPreXDGConfigPath;
523 const char* pXDGCfgHome = getenv("XDG_CONFIG_HOME");
525 // cater for XDG_CONFIG_HOME change
526 // If XDG_CONFIG_HOME is set then we;
527 // assume the user knows what they are doing ( room for improvement here, we could
528 // of course search the default config dir etc. also - but this is more complex,
529 // we would need to weigh results from the current config dir against matches in
530 // the 'old' config dir etc. ) - currently we just use the returned config dir.
531 // If XDG_CONFIG_HOME is NOT set;
532 // assume then we should now using the default $HOME/,config config location for
533 // our user profiles, however *all* previous libreoffice and openoffice.org
534 // configurations will be in the 'old' config directory and that's where we need
535 // to search - we convert the returned config dir to the 'old' dir
536 if ( !pXDGCfgHome && rConfigDir.endsWithAsciiL( XDG_CONFIG_PART, sizeof( XDG_CONFIG_PART ) - 1 ) )
537 // remove trailing '.config/' but leave the terminating '/'
538 aPreXDGConfigPath = rConfigDir.copy( 0, rConfigDir.getLength() - sizeof( XDG_CONFIG_PART ) + 2 );
539 else
540 aPreXDGConfigPath = rConfigDir;
542 // the application-specific config dir is not longer prefixed by '.' because it is hidden under ".config"
543 // we have to add the '.' for the pre-XDG directory names
544 aPreXDGConfigPath += ".";
546 return aPreXDGConfigPath;
548 #endif
550 void MigrationImpl::setInstallInfoIfExist(
551 install_info& aInfo,
552 const OUString& rConfigDir,
553 const OUString& rVersion)
555 OUString url(INetURLObject(rConfigDir).GetMainURL(INetURLObject::NO_DECODE));
556 osl::DirectoryItem item;
557 osl::FileStatus stat(osl_FileStatus_Mask_Type);
559 if (osl::DirectoryItem::get(url, item) == osl::FileBase::E_None
560 && item.getFileStatus(stat) == osl::FileBase::E_None
561 && stat.getFileType() == osl::FileStatus::Directory)
563 aInfo.userdata = url;
564 aInfo.productname = rVersion;
568 install_info MigrationImpl::findInstallation(const strings_v& rVersions)
571 OUString aTopConfigDir;
572 osl::Security().getConfigDir( aTopConfigDir );
573 if ( !aTopConfigDir.isEmpty() && aTopConfigDir[ aTopConfigDir.getLength()-1 ] != '/' )
574 aTopConfigDir += "/";
576 #if defined UNX && ! defined MACOSX
577 OUString aPreXDGTopConfigDir = preXDGConfigDir(aTopConfigDir);
578 #endif
580 install_info aInfo;
581 strings_v::const_iterator i_ver = rVersions.begin();
582 while (i_ver != rVersions.end())
584 OUString aVersion, aProfileName;
585 sal_Int32 nSeparatorIndex = (*i_ver).indexOf('=');
586 if ( nSeparatorIndex != -1 )
588 aVersion = (*i_ver).copy( 0, nSeparatorIndex );
589 aProfileName = (*i_ver).copy( nSeparatorIndex+1 );
592 if ( !aVersion.isEmpty() && !aProfileName.isEmpty() &&
593 ( aInfo.userdata.isEmpty() ||
594 aProfileName.equalsIgnoreAsciiCase(
595 utl::ConfigManager::getProductName() ) ) )
597 setInstallInfoIfExist(aInfo, aTopConfigDir + aProfileName, aVersion);
598 #if defined UNX && ! defined MACOSX
599 //try preXDG path if the new one does not exist
600 if ( aInfo.userdata.isEmpty())
601 setInstallInfoIfExist(aInfo, aPreXDGTopConfigDir + aProfileName, aVersion);
602 #endif
604 ++i_ver;
607 return aInfo;
610 sal_Int32 MigrationImpl::findPreferedMigrationProcess(const migrations_available& rAvailableMigrations)
612 sal_Int32 nIndex( -1 );
613 sal_Int32 i( 0 );
615 migrations_available::const_iterator rIter = rAvailableMigrations.begin();
616 while ( rIter != rAvailableMigrations.end() )
618 install_info aInstallInfo = findInstallation(rIter->supported_versions);
619 if (!aInstallInfo.productname.isEmpty() )
621 m_aInfo = aInstallInfo;
622 nIndex = i;
623 break;
625 ++i;
626 ++rIter;
629 OSL_TRACE( " preferred migration is from product '%s'\n",
630 OUStringToOString( m_aInfo.productname, RTL_TEXTENCODING_ASCII_US ).getStr() );
631 OSL_TRACE( " and settings directory '%s'\n",
632 OUStringToOString( m_aInfo.userdata, RTL_TEXTENCODING_ASCII_US ).getStr() );
634 return nIndex;
637 strings_vr MigrationImpl::applyPatterns(const strings_v& vSet, const strings_v& vPatterns) const
639 using namespace utl;
640 strings_vr vrResult(new strings_v);
641 strings_v::const_iterator i_set;
642 strings_v::const_iterator i_pat = vPatterns.begin();
643 while (i_pat != vPatterns.end())
645 // find matches for this pattern in input set
646 // and copy them to the result
647 SearchParam param(*i_pat, SearchParam::SRCH_REGEXP);
648 TextSearch ts(param, LANGUAGE_DONTKNOW);
649 i_set = vSet.begin();
650 sal_Int32 start = 0;
651 sal_Int32 end = 0;
652 while (i_set != vSet.end())
654 end = i_set->getLength();
655 if (ts.SearchForward(*i_set, &start, &end))
656 vrResult->push_back(*i_set);
657 ++i_set;
659 ++i_pat;
661 return vrResult;
664 strings_vr MigrationImpl::getAllFiles(const OUString& baseURL) const
666 using namespace osl;
667 strings_vr vrResult(new strings_v);
669 // get sub dirs
670 Directory dir(baseURL);
671 if (dir.open() == FileBase::E_None)
673 strings_v vSubDirs;
674 strings_vr vrSubResult;
676 // work through directory contents...
677 DirectoryItem item;
678 FileStatus fs(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL);
679 while (dir.getNextItem(item) == FileBase::E_None)
681 if (item.getFileStatus(fs) == FileBase::E_None)
683 if (fs.getFileType() == FileStatus::Directory)
684 vSubDirs.push_back(fs.getFileURL());
685 else
686 vrResult->push_back(fs.getFileURL());
690 // recurse subfolders
691 strings_v::const_iterator i = vSubDirs.begin();
692 while (i != vSubDirs.end())
694 vrSubResult = getAllFiles(*i);
695 vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end());
696 ++i;
699 return vrResult;
702 namespace {
704 // removes elements of vector 2 in vector 1
705 strings_v subtract(strings_v const & va, strings_v const & vb) {
706 strings_v a(va);
707 std::sort(a.begin(), a.end());
708 strings_v::iterator ae(std::unique(a.begin(), a.end()));
709 strings_v b(vb);
710 std::sort(b.begin(), b.end());
711 strings_v::iterator be(std::unique(b.begin(), b.end()));
712 strings_v c;
713 std::set_difference(a.begin(), ae, b.begin(), be, std::back_inserter(c));
714 return c;
719 strings_vr MigrationImpl::compileFileList()
722 strings_vr vrResult(new strings_v);
723 strings_vr vrInclude;
724 strings_vr vrExclude;
726 // get a list of all files:
727 strings_vr vrFiles = getAllFiles(m_aInfo.userdata);
729 // get a file list result for each migration step
730 migrations_v::const_iterator i_migr = m_vrMigrations->begin();
731 while (i_migr != m_vrMigrations->end())
733 vrInclude = applyPatterns(*vrFiles, i_migr->includeFiles);
734 vrExclude = applyPatterns(*vrFiles, i_migr->excludeFiles);
735 strings_v sub(subtract(*vrInclude, *vrExclude));
736 vrResult->insert(vrResult->end(), sub.begin(), sub.end());
737 ++i_migr;
739 return vrResult;
742 namespace {
744 struct componentParts {
745 std::set< OUString > includedPaths;
746 std::set< OUString > excludedPaths;
749 typedef std::map< OUString, componentParts > Components;
751 bool getComponent(OUString const & path, OUString * component) {
752 OSL_ASSERT(component != 0);
753 if (path.isEmpty() || path[0] != '/') {
754 OSL_TRACE(
755 ("configuration migration in/exclude path %s ignored (does not"
756 " start with slash)"),
757 OUStringToOString(path, RTL_TEXTENCODING_UTF8).getStr());
758 return false;
760 sal_Int32 i = path.indexOf('/', 1);
761 *component = i < 0 ? path.copy(1) : path.copy(1, i - 1);
762 return true;
765 uno::Sequence< OUString > setToSeq(std::set< OUString > const & set) {
766 std::set< OUString >::size_type n = set.size();
767 if (n > SAL_MAX_INT32) {
768 throw std::bad_alloc();
770 uno::Sequence< OUString > seq(static_cast< sal_Int32 >(n));
771 sal_Int32 i = 0;
772 for (std::set< OUString >::const_iterator j(set.begin());
773 j != set.end(); ++j)
775 seq[i++] = *j;
777 return seq;
782 void MigrationImpl::copyConfig() {
783 Components comps;
784 for (migrations_v::const_iterator i(m_vrMigrations->begin());
785 i != m_vrMigrations->end(); ++i)
787 for (strings_v::const_iterator j(i->includeConfig.begin());
788 j != i->includeConfig.end(); ++j)
790 OUString comp;
791 if (getComponent(*j, &comp)) {
792 comps[comp].includedPaths.insert(*j);
795 for (strings_v::const_iterator j(i->excludeConfig.begin());
796 j != i->excludeConfig.end(); ++j)
798 OUString comp;
799 if (getComponent(*j, &comp)) {
800 comps[comp].excludedPaths.insert(*j);
805 // check if the shared registrymodifications.xcu file exists
806 bool bRegistryModificationsXcuExists = false;
807 OUString regFilePath(m_aInfo.userdata);
808 regFilePath += "/user/registrymodifications.xcu";
809 File regFile(regFilePath);
810 ::osl::FileBase::RC nError = regFile.open(osl_File_OpenFlag_Read);
811 if ( nError == ::osl::FileBase::E_None ) {
812 bRegistryModificationsXcuExists = true;
813 regFile.close();
816 for (Components::const_iterator i(comps.begin()); i != comps.end(); ++i) {
817 if (!i->second.includedPaths.empty()) {
818 if (!bRegistryModificationsXcuExists) {
819 // shared registrymodifications.xcu does not exists
820 // the configuration is split in many registry files
821 // determine the file names from the first element in included paths
822 OUStringBuffer buf(m_aInfo.userdata);
823 buf.appendAscii("/user/registry/data");
824 sal_Int32 n = 0;
825 do {
826 OUString seg(i->first.getToken(0, '.', n));
827 OUString enc(
828 rtl::Uri::encode(
829 seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict,
830 RTL_TEXTENCODING_UTF8));
831 if (enc.isEmpty() && !seg.isEmpty()) {
832 OSL_TRACE(
833 ("configuration migration component %s ignored (cannot"
834 " be encoded as file path)"),
835 OUStringToOString(
836 i->first, RTL_TEXTENCODING_UTF8).getStr());
837 goto next;
839 buf.append('/');
840 buf.append(enc);
841 } while (n >= 0);
842 buf.appendAscii(".xcu");
843 regFilePath = buf.toString();
845 configuration::Update::get(
846 comphelper::getProcessComponentContext())->
847 insertModificationXcuFile(
848 regFilePath, setToSeq(i->second.includedPaths),
849 setToSeq(i->second.excludedPaths));
850 } else {
851 OSL_TRACE(
852 ("configuration migration component %s ignored (only excludes,"
853 " no includes)"),
854 OUStringToOString(
855 i->first, RTL_TEXTENCODING_UTF8).getStr());
857 next:;
861 uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
863 uno::Reference< XNameAccess > xNameAccess;
864 try{
865 OUString sAccessSrvc;
866 if (bUpdate)
867 sAccessSrvc = "com.sun.star.configuration.ConfigurationUpdateAccess";
868 else
869 sAccessSrvc = "com.sun.star.configuration.ConfigurationAccess";
871 OUString sConfigURL = OUString::createFromAscii(pPath);
873 uno::Reference< XMultiServiceFactory > theConfigProvider(
874 configuration::theDefaultProvider::get(
875 comphelper::getProcessComponentContext()));
877 // access the provider
878 uno::Sequence< uno::Any > theArgs(1);
879 theArgs[ 0 ] <<= sConfigURL;
880 xNameAccess = uno::Reference< XNameAccess > (
881 theConfigProvider->createInstanceWithArguments(
882 sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
884 catch (const com::sun::star::uno::Exception& e)
886 SAL_WARN(
887 "desktop.migration", "ignoring Exception \"" << e.Message << "\"");
889 return xNameAccess;
892 void MigrationImpl::copyFiles()
894 strings_v::const_iterator i_file = m_vrFileList->begin();
895 OUString localName;
896 OUString destName;
897 OUString userInstall;
898 utl::Bootstrap::PathStatus aStatus;
899 aStatus = utl::Bootstrap::locateUserInstallation(userInstall);
900 if (aStatus == utl::Bootstrap::PATH_EXISTS)
902 while (i_file != m_vrFileList->end())
904 // remove installation prefix from file
905 localName = i_file->copy(m_aInfo.userdata.getLength());
906 if (localName.endsWith( "/autocorr/acor_.dat"))
908 // Previous versions used an empty language tag for
909 // LANGUAGE_DONTKNOW with the "[All]" autocorrection entry.
910 // As of LibreOffice 4.0 it is 'und' for LANGUAGE_UNDETERMINED
911 // so the file name is "acor_und.dat".
912 localName = localName.copy( 0, localName.getLength() - 4) + "und.dat";
914 destName = userInstall + localName;
915 INetURLObject aURL(destName);
916 // check whether destination directory exists
917 aURL.removeSegment();
918 _checkAndCreateDirectory(aURL);
919 FileBase::RC copyResult = File::copy(*i_file, destName);
920 if (copyResult != FileBase::E_None)
922 OString msg("Cannot copy ");
923 msg += OUStringToOString(*i_file, RTL_TEXTENCODING_UTF8) + " to "
924 + OUStringToOString(destName, RTL_TEXTENCODING_UTF8);
925 OSL_FAIL(msg.getStr());
927 ++i_file;
930 else
932 OSL_FAIL("copyFiles: UserInstall does not exist");
936 void MigrationImpl::runServices()
938 // Build argument array
939 uno::Sequence< uno::Any > seqArguments(3);
940 seqArguments[0] = uno::makeAny(NamedValue("Productname",
941 uno::makeAny(m_aInfo.productname)));
942 seqArguments[1] = uno::makeAny(NamedValue("UserData",
943 uno::makeAny(m_aInfo.userdata)));
946 // create an instance of every migration service
947 // and execute the migration job
948 uno::Reference< XJob > xMigrationJob;
950 uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext());
951 migrations_v::const_iterator i_mig = m_vrMigrations->begin();
952 while (i_mig != m_vrMigrations->end())
954 if( !i_mig->service.isEmpty())
959 // set black list for extension migration
960 uno::Sequence< OUString > seqExtBlackList;
961 sal_uInt32 nSize = i_mig->excludeExtensions.size();
962 if ( nSize > 0 )
963 seqExtBlackList = comphelper::arrayToSequence< OUString >(
964 &i_mig->excludeExtensions[0], nSize );
965 seqArguments[2] = uno::makeAny(NamedValue("ExtensionBlackList",
966 uno::makeAny( seqExtBlackList )));
968 xMigrationJob = uno::Reference< XJob >(
969 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(i_mig->service, seqArguments, xContext),
970 uno::UNO_QUERY_THROW);
972 xMigrationJob->execute(uno::Sequence< NamedValue >());
976 catch (const Exception& e)
978 OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
979 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) + "\nMessage: ";
980 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
981 OSL_FAIL(aMsg.getStr());
983 catch (...)
985 OString aMsg("Execution of migration service failed (Exception caught).\nService: ");
986 aMsg += OUStringToOString(i_mig->service, RTL_TEXTENCODING_ASCII_US) +
987 "\nNo message available";
988 OSL_FAIL(aMsg.getStr());
992 ++i_mig;
996 ::std::vector< MigrationModuleInfo > MigrationImpl::dectectUIChangesForAllModules() const
998 ::std::vector< MigrationModuleInfo > vModulesInfo;
999 const OUString MENUBAR("menubar");
1000 const OUString TOOLBAR("toolbar");
1002 uno::Sequence< uno::Any > lArgs(2);
1003 lArgs[0] <<= m_aInfo.userdata + "/user/config/soffice.cfg/modules";
1004 lArgs[1] <<= embed::ElementModes::READ;
1006 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
1007 embed::FileSystemStorageFactory::create(comphelper::getProcessComponentContext()));
1008 uno::Reference< embed::XStorage > xModules;
1010 xModules = uno::Reference< embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
1011 if (!xModules.is())
1012 return vModulesInfo;
1014 uno::Reference< container::XNameAccess > xAccess = uno::Reference< container::XNameAccess >(xModules, uno::UNO_QUERY);
1015 uno::Sequence< OUString > lNames = xAccess->getElementNames();
1016 sal_Int32 nLength = lNames.getLength();
1017 for (sal_Int32 i=0; i<nLength; ++i)
1019 OUString sModuleShortName = lNames[i];
1020 uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ);
1021 if (xModule.is())
1023 MigrationModuleInfo aModuleInfo;
1025 uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ);
1026 if (xMenubar.is())
1028 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xMenubar, uno::UNO_QUERY);
1029 if (xNameAccess->getElementNames().getLength() > 0)
1031 aModuleInfo.sModuleShortName = sModuleShortName;
1032 aModuleInfo.bHasMenubar = sal_True;
1036 uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ);
1037 if (xToolbar.is())
1039 const OUString RESOURCEURL_CUSTOM_ELEMENT("custom_");
1040 sal_Int32 nCustomLen = 7;
1042 uno::Reference< container::XNameAccess > xNameAccess = uno::Reference< container::XNameAccess >(xToolbar, uno::UNO_QUERY);
1043 ::uno::Sequence< OUString > lToolbars = xNameAccess->getElementNames();
1044 for (sal_Int32 j=0; j<lToolbars.getLength(); ++j)
1046 OUString sToolbarName = lToolbars[j];
1047 if (sToolbarName.getLength()>=nCustomLen &&
1048 sToolbarName.copy(0, nCustomLen).equals(RESOURCEURL_CUSTOM_ELEMENT))
1049 continue;
1051 aModuleInfo.sModuleShortName = sModuleShortName;
1052 sal_Int32 nIndex = sToolbarName.lastIndexOf('.');
1053 if (nIndex > 0)
1055 OUString sExtension(sToolbarName.copy(nIndex));
1056 OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
1057 if (!sToolbarResourceName.isEmpty() && sExtension == ".xml")
1058 aModuleInfo.m_vToolbars.push_back(sToolbarResourceName);
1063 if (!aModuleInfo.sModuleShortName.isEmpty())
1064 vModulesInfo.push_back(aModuleInfo);
1068 return vModulesInfo;
1071 void MigrationImpl::compareOldAndNewConfig(const OUString& sParent,
1072 const uno::Reference< container::XIndexContainer >& xIndexOld,
1073 const uno::Reference< container::XIndexContainer >& xIndexNew,
1074 const OUString& sResourceURL)
1076 const OUString MENU_SEPARATOR(" | ");
1078 ::std::vector< MigrationItem > vOldItems;
1079 ::std::vector< MigrationItem > vNewItems;
1080 uno::Sequence< beans::PropertyValue > aProp;
1081 sal_Int32 nOldCount = xIndexOld->getCount();
1082 sal_Int32 nNewCount = xIndexNew->getCount();
1084 for (int n=0; n<nOldCount; ++n)
1086 MigrationItem aMigrationItem;
1087 if (xIndexOld->getByIndex(n) >>= aProp)
1089 for(int i=0; i<aProp.getLength(); ++i)
1091 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
1092 aProp[i].Value >>= aMigrationItem.m_sCommandURL;
1093 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
1094 aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
1097 if (!aMigrationItem.m_sCommandURL.isEmpty())
1098 vOldItems.push_back(aMigrationItem);
1102 for (int n=0; n<nNewCount; ++n)
1104 MigrationItem aMigrationItem;
1105 if (xIndexNew->getByIndex(n) >>= aProp)
1107 for(int i=0; i<aProp.getLength(); ++i)
1109 if ( aProp[i].Name == ITEM_DESCRIPTOR_COMMANDURL )
1110 aProp[i].Value >>= aMigrationItem.m_sCommandURL;
1111 else if ( aProp[i].Name == ITEM_DESCRIPTOR_CONTAINER )
1112 aProp[i].Value >>= aMigrationItem.m_xPopupMenu;
1115 if (!aMigrationItem.m_sCommandURL.isEmpty())
1116 vNewItems.push_back(aMigrationItem);
1120 ::std::vector< MigrationItem >::iterator it;
1122 OUString sSibling;
1123 for (it = vOldItems.begin(); it!=vOldItems.end(); ++it)
1125 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vNewItems.begin(), vNewItems.end(), *it);
1126 if (pFound != vNewItems.end() && it->m_xPopupMenu.is())
1128 OUString sName;
1129 if (!sParent.isEmpty())
1130 sName = sParent + MENU_SEPARATOR + it->m_sCommandURL;
1131 else
1132 sName = it->m_sCommandURL;
1133 compareOldAndNewConfig(sName, it->m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL);
1135 else if (pFound == vNewItems.end())
1137 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
1138 if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end())
1140 ::std::vector< MigrationItem > vMigrationItems;
1141 m_aOldVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
1142 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1144 else
1146 if (::std::find(m_aOldVersionItemsHashMap[sResourceURL].begin(), m_aOldVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].end())
1147 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1151 sSibling = it->m_sCommandURL;
1154 uno::Reference< container::XIndexContainer > xPopup;
1155 for (it = vNewItems.begin(); it!=vNewItems.end(); ++it)
1157 ::std::vector< MigrationItem >::iterator pFound = ::std::find(vOldItems.begin(), vOldItems.end(), *it);
1158 if (pFound != vOldItems.end() && it->m_xPopupMenu.is())
1160 OUString sName;
1161 if (!sParent.isEmpty())
1162 sName = sParent + MENU_SEPARATOR + it->m_sCommandURL;
1163 else
1164 sName = it->m_sCommandURL;
1165 compareOldAndNewConfig(sName, pFound->m_xPopupMenu, it->m_xPopupMenu, sResourceURL);
1167 else if (::std::find(vOldItems.begin(), vOldItems.end(), *it) == vOldItems.end())
1169 MigrationItem aMigrationItem(sParent, sSibling, it->m_sCommandURL, it->m_xPopupMenu);
1170 if (m_aNewVersionItemsHashMap.find(sResourceURL)==m_aNewVersionItemsHashMap.end())
1172 ::std::vector< MigrationItem > vMigrationItems;
1173 m_aNewVersionItemsHashMap.insert(MigrationHashMap::value_type(sResourceURL, vMigrationItems));
1174 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1176 else
1178 if (::std::find(m_aNewVersionItemsHashMap[sResourceURL].begin(), m_aNewVersionItemsHashMap[sResourceURL].end(), aMigrationItem)==m_aNewVersionItemsHashMap[sResourceURL].end())
1179 m_aNewVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
1185 void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurationManager >& xCfgManager,
1186 const uno::Reference< container::XIndexContainer>& xIndexContainer,
1187 const OUString& sModuleIdentifier,
1188 const OUString& sResourceURL)
1190 MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL);
1191 if (pFound==m_aOldVersionItemsHashMap.end())
1192 return;
1194 ::std::vector< MigrationItem >::iterator it;
1195 for (it=pFound->second.begin(); it!=pFound->second.end(); ++it)
1197 uno::Reference< container::XIndexContainer > xTemp = xIndexContainer;
1199 OUString sParentNodeName = it->m_sParentNodeName;
1200 sal_Int32 nIndex = 0;
1203 OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim();
1204 if (sToken.isEmpty())
1205 break;
1207 sal_Int32 nCount = xTemp->getCount();
1208 for (sal_Int32 i=0; i<nCount; ++i)
1210 OUString sCommandURL;
1211 OUString sLabel;
1212 uno::Reference< container::XIndexContainer > xChild;
1214 uno::Sequence< beans::PropertyValue > aPropSeq;
1215 xTemp->getByIndex(i) >>= aPropSeq;
1216 for (sal_Int32 j=0; j<aPropSeq.getLength(); ++j)
1218 OUString sPropName = aPropSeq[j].Name;
1219 if ( sPropName == ITEM_DESCRIPTOR_COMMANDURL )
1220 aPropSeq[j].Value >>= sCommandURL;
1221 else if ( sPropName == ITEM_DESCRIPTOR_LABEL )
1222 aPropSeq[j].Value >>= sLabel;
1223 else if ( sPropName == ITEM_DESCRIPTOR_CONTAINER )
1224 aPropSeq[j].Value >>= xChild;
1227 if (sCommandURL == sToken)
1229 xTemp = xChild;
1230 break;
1234 } while (nIndex>=0);
1236 if (nIndex == -1)
1238 uno::Sequence< beans::PropertyValue > aPropSeq(3);
1240 aPropSeq[0].Name = OUString(ITEM_DESCRIPTOR_COMMANDURL);
1241 aPropSeq[0].Value <<= it->m_sCommandURL;
1242 aPropSeq[1].Name = OUString(ITEM_DESCRIPTOR_LABEL);
1243 aPropSeq[1].Value <<= retrieveLabelFromCommand(it->m_sCommandURL, sModuleIdentifier);
1244 aPropSeq[2].Name = OUString(ITEM_DESCRIPTOR_CONTAINER);
1245 aPropSeq[2].Value <<= it->m_xPopupMenu;
1247 if (it->m_sPrevSibling.isEmpty())
1248 xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
1249 else if (!it->m_sPrevSibling.isEmpty())
1251 sal_Int32 nCount = xTemp->getCount();
1252 sal_Int32 i = 0;
1253 for (; i<nCount; ++i)
1255 OUString sCmd;
1256 uno::Sequence< beans::PropertyValue > aTempPropSeq;
1257 xTemp->getByIndex(i) >>= aTempPropSeq;
1258 for (sal_Int32 j=0; j<aTempPropSeq.getLength(); ++j)
1260 if ( aTempPropSeq[j].Name == ITEM_DESCRIPTOR_COMMANDURL )
1262 aTempPropSeq[j].Value >>= sCmd;
1263 break;
1267 if (sCmd.equals(it->m_sPrevSibling))
1268 break;
1271 xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
1276 uno::Reference< container::XIndexAccess > xIndexAccess(xIndexContainer, uno::UNO_QUERY);
1277 if (xIndexAccess.is())
1278 xCfgManager->replaceSettings(sResourceURL, xIndexAccess);
1280 uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY);
1281 if (xUIConfigurationPersistence.is())
1282 xUIConfigurationPersistence->store();
1285 uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(const OUString& sModuleShortName) const
1287 uno::Reference< ui::XUIConfigurationManager > xCfgManager;
1289 for (sal_Int32 i=0; i<m_lCfgManagerSeq.getLength(); ++i)
1291 if (m_lCfgManagerSeq[i].Name.equals(sModuleShortName))
1293 m_lCfgManagerSeq[i].Value >>= xCfgManager;
1294 break;
1298 return xCfgManager;
1301 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(const OUString& sModuleShortName) const
1303 uno::Reference< container::XIndexContainer > xNewMenuSettings;
1305 for (sal_Int32 i=0; i<m_lNewVersionMenubarSettingsSeq.getLength(); ++i)
1307 if (m_lNewVersionMenubarSettingsSeq[i].Name.equals(sModuleShortName))
1309 m_lNewVersionMenubarSettingsSeq[i].Value >>= xNewMenuSettings;
1310 break;
1314 return xNewMenuSettings;
1317 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(const OUString& sModuleShortName, const OUString& sToolbarName) const
1319 uno::Reference< container::XIndexContainer > xNewToolbarSettings;
1321 for (sal_Int32 i=0; i<m_lNewVersionToolbarSettingsSeq.getLength(); ++i)
1323 if (m_lNewVersionToolbarSettingsSeq[i].Name.equals(sModuleShortName))
1325 uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
1326 m_lNewVersionToolbarSettingsSeq[i].Value >>= lToolbarSettingsSeq;
1327 for (sal_Int32 j=0; j<lToolbarSettingsSeq.getLength(); ++j)
1329 if (lToolbarSettingsSeq[j].Name.equals(sToolbarName))
1331 lToolbarSettingsSeq[j].Value >>= xNewToolbarSettings;
1332 break;
1336 break;
1340 return xNewToolbarSettings;
1343 void NewVersionUIInfo::init(const ::std::vector< MigrationModuleInfo >& vModulesInfo)
1345 m_lCfgManagerSeq.realloc(vModulesInfo.size());
1346 m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size());
1347 m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
1349 const OUString sMenubarResourceURL("private:resource/menubar/menubar");
1350 const OUString sToolbarResourcePre("private:resource/toolbar/");
1352 uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = ui::ModuleUIConfigurationManagerSupplier::create( ::comphelper::getProcessComponentContext() );
1354 for (sal_uInt32 i=0; i<vModulesInfo.size(); ++i)
1356 OUString sModuleIdentifier = mapModuleShortNameToIdentifier(vModulesInfo[i].sModuleShortName);
1357 if (!sModuleIdentifier.isEmpty())
1359 uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier);
1360 m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName;
1361 m_lCfgManagerSeq[i].Value <<= xCfgManager;
1363 if (vModulesInfo[i].bHasMenubar)
1365 m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1366 m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL, sal_True);
1369 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
1370 if (nToolbars > 0)
1372 uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars);
1373 for (sal_Int32 j=0; j<nToolbars; ++j)
1375 OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
1376 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
1378 lPropSeq[j].Name = sToolbarName;
1379 lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL, sal_True);
1382 m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1383 m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq;
1389 } // namespace desktop
1391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */