1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
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>
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
;
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
)
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() ) {
93 ::uno::Sequence
< beans::PropertyValue
> aPropSeq
;
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
;
106 } catch (const container::NoSuchElementException
&) {
108 sal_Int32 nIndex
= sLabel
.indexOf(':');
109 if (nIndex
>=0 && nIndex
<= sLabel
.getLength()-1)
110 sLabel
= sLabel
.copy(nIndex
+1);
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";
165 bool MigrationImpl::alreadyMigrated()
167 OUString
const MIGRATION_STAMP_NAME("/MIGRATED4");
168 OUString aStr
= m_aInfo
.userdata
+ MIGRATION_STAMP_NAME
;
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
);
176 bool MigrationImpl::initializeMigration()
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
185 if (alreadyMigrated())
187 m_vrMigrations
= readMigrationSteps(m_vMigrationsAvailable
[nIndex
].name
);
190 bRet
= !m_aInfo
.userdata
.isEmpty();
193 SAL_INFO( "desktop.migration", "Migration " << ( bRet
? "needed" : "not required" ) );
198 void Migration::migrateSettingsIfNecessary()
202 if (! aImpl
.initializeMigration() )
205 bool bResult
= false;
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();
230 NewVersionUIInfo aNewVersionUIInfo
;
231 std::vector
< MigrationModuleInfo
> vModulesInfo
= dectectUIChangesForAllModules();
232 aNewVersionUIInfo
.init(vModulesInfo
);
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())
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
);
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();
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
286 // execute custom migration services from Setup.xcu
287 // and refresh the cache
289 uno::Reference
< XRefreshable
>(
290 configuration::theDefaultProvider::get(comphelper::getProcessComponentContext()),
291 uno::UNO_QUERY_THROW
)->refresh();
294 } catch (css::uno::Exception
& e
) {
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();
307 void MigrationImpl::setMigrationCompleted()
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();
318 bool MigrationImpl::checkMigrationCompleted()
320 bool bMigrationCompleted
= false;
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
);
347 break; // i111193: insert invalidates iterator!
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
<< "'" );
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
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
);
412 if (tmpAccess
->getByName("ExcludedFiles") >>= tmpSeq
) {
413 for (sal_Int32 j
=0; j
<tmpSeq
.getLength(); j
++)
414 tmpStep
.excludeFiles
.push_back(tmpSeq
[j
]);
418 if (tmpAccess
->getByName("IncludedNodes") >>= tmpSeq
) {
419 for (sal_Int32 j
=0; j
<tmpSeq
.getLength(); j
++)
420 tmpStep
.includeConfig
.push_back(tmpSeq
[j
]);
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
);
444 tmpAccess
->getByName("MigrationService") >>= tmpStep
.service
;
446 vrMigrations
->push_back(tmpStep
);
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
));
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 );
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
;
497 void MigrationImpl::setInstallInfoIfExist(
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
);
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
);
553 sal_Int32
MigrationImpl::findPreferredMigrationProcess(const migrations_available
& rAvailableMigrations
)
555 sal_Int32
nIndex( -1 );
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
;
570 SAL_INFO( "desktop.migration", " preferred migration is from product '" << m_aInfo
.productname
<< "'");
571 SAL_INFO( "desktop.migration", " and settings directory '" << m_aInfo
.userdata
<< "'");
576 strings_vr
MigrationImpl::applyPatterns(const strings_v
& vSet
, const strings_v
& vPatterns
)
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();
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
);
601 strings_vr
MigrationImpl::getAllFiles(const OUString
& baseURL
) const
603 strings_vr
vrResult(new strings_v
);
606 Directory
dir(baseURL
);
607 if (dir
.open() == FileBase::E_None
) {
609 strings_vr vrSubResult
;
611 // work through directory contents...
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());
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());
637 // removes elements of vector 2 in vector 1
638 strings_v
subtract(strings_v
const & va
, strings_v
const & vb
)
641 std::sort(a
.begin(), a
.end());
642 strings_v::iterator
ae(std::unique(a
.begin(), a
.end()));
644 std::sort(b
.begin(), b
.end());
645 strings_v::iterator
be(std::unique(b
.begin(), b
.end()));
647 std::set_difference(a
.begin(), ae
, b
.begin(), be
, std::back_inserter(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());
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)" );
692 sal_Int32 i
= path
.indexOf('/', 1);
693 *component
= i
< 0 ? path
.copy(1) : path
.copy(1, i
- 1);
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
));
705 for (std::set
< OUString
>::const_iterator
j(set
.begin());
706 j
!= set
.end(); ++j
) {
714 void MigrationImpl::copyConfig()
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
) {
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
) {
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;
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");
756 OUString
seg(i
->first
.getToken(0, '.', n
));
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)" );
769 regFilePath
= buf
.toString();
771 configuration::Update::get(
772 comphelper::getProcessComponentContext())->
773 insertModificationXcuFile(
774 regFilePath
, setToSeq(i
->second
.includedPaths
),
775 setToSeq(i
->second
.excludedPaths
));
777 SAL_INFO( "desktop.migration", "configuration migration component " << i
->first
<< " ignored (only excludes, no includes)" );
784 uno::Reference
< XNameAccess
> MigrationImpl::getConfigAccess(const sal_Char
* pPath
, bool bUpdate
)
786 uno::Reference
< XNameAccess
> xNameAccess
;
788 OUString sAccessSrvc
;
790 sAccessSrvc
= "com.sun.star.configuration.ConfigurationUpdateAccess";
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
;
804 theConfigProvider
->createInstanceWithArguments(
805 sAccessSrvc
, theArgs
), uno::UNO_QUERY_THROW
);
806 } catch (const css::uno::Exception
& e
) {
808 "desktop.migration", "ignoring Exception \"" << e
<< "\"");
813 void MigrationImpl::copyFiles()
815 strings_v::const_iterator i_file
= m_vrFileList
->begin();
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
);
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()) {
868 // set black list for extension migration
869 uno::Sequence
< OUString
> seqExtBlackList
;
870 sal_uInt32 nSize
= i_mig
->excludeExtensions
.size();
872 seqExtBlackList
= comphelper::arrayToSequence
< OUString
>(
873 &i_mig
->excludeExtensions
[0], nSize
);
874 seqArguments
[2] <<= NamedValue("ExtensionBlackList",
875 uno::makeAny( seqExtBlackList
));
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: "
887 << "\nMessage: " << e
);
889 SAL_WARN( "desktop", "Execution of migration service failed (Exception caught).\nService: "
890 << i_mig
->service
<< "\nNo message available");
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
);
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
);
923 MigrationModuleInfo aModuleInfo
;
925 uno::Reference
< embed::XStorage
> xMenubar
= xModule
->openStorageElement(MENUBAR
, embed::ElementModes::READ
);
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
);
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
)
947 aModuleInfo
.sModuleShortName
= sModuleShortName
;
948 sal_Int32 nIndex
= sToolbarName
.lastIndexOf('.');
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
);
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
;
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()) {
1016 if (!sParent
.isEmpty())
1017 sName
= sParent
+ MENU_SEPARATOR
+ it
->m_sCommandURL
;
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
);
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())
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;
1053 OUString sToken
= sParentNodeName
.getToken(0, '|', nIndex
).trim();
1054 if (sToken
.isEmpty())
1057 sal_Int32 nCount
= xTemp
->getCount();
1058 for (sal_Int32 i
=0; i
<nCount
; ++i
) {
1059 OUString sCommandURL
;
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
) {
1081 } while (nIndex
>=0);
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
));
1096 sal_Int32 nCount
= xTemp
->getCount();
1098 for (; i
<nCount
; ++i
) {
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
;
1109 if (sCmd
== it
->m_sPrevSibling
)
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
;
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
;
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
;
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: */