35 #include <rtl/uri.hxx>
39 #include <osl/file.hxx>
40 #include <osl/security.hxx>
43 #include <com/sun/star/configuration/Update.hpp>
44 #include <com/sun/star/configuration/theDefaultProvider.hpp>
45 #include <com/sun/star/task/XJob.hpp>
46 #include <com/sun/star/beans/NamedValue.hpp>
47 #include <com/sun/star/beans/XPropertySet.hpp>
48 #include <com/sun/star/util/XRefreshable.hpp>
49 #include <com/sun/star/util/XChangesBatch.hpp>
50 #include <com/sun/star/embed/ElementModes.hpp>
51 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
52 #include <com/sun/star/embed/XStorage.hpp>
53 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
54 #include <com/sun/star/ui/UIConfigurationManager.hpp>
55 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
65 using com::sun::star::uno::Exception;
80 if ( sShortName ==
u"StartModule" )
81 sIdentifier =
"com.sun.star.frame.StartModule";
83 else if ( sShortName ==
u"swriter" )
84 sIdentifier =
"com.sun.star.text.TextDocument";
86 else if ( sShortName ==
u"scalc" )
87 sIdentifier =
"com.sun.star.sheet.SpreadsheetDocument";
89 else if ( sShortName ==
u"sdraw" )
90 sIdentifier =
"com.sun.star.drawing.DrawingDocument";
92 else if ( sShortName ==
u"simpress" )
93 sIdentifier =
"com.sun.star.presentation.PresentationDocument";
95 else if ( sShortName ==
u"smath" )
96 sIdentifier =
"com.sun.star.formula.FormulaProperties";
98 else if ( sShortName ==
u"schart" )
99 sIdentifier =
"com.sun.star.chart2.ChartDocument";
101 else if ( sShortName ==
u"BasicIDE" )
102 sIdentifier =
"com.sun.star.script.BasicIDE";
104 else if ( sShortName ==
u"dbapp" )
105 sIdentifier =
"com.sun.star.sdb.OfficeDatabaseDocument";
107 else if ( sShortName ==
u"sglobal" )
108 sIdentifier =
"com.sun.star.text.GlobalDocument";
110 else if ( sShortName ==
u"sweb" )
111 sIdentifier =
"com.sun.star.text.WebDocument";
113 else if ( sShortName ==
u"swxform" )
114 sIdentifier =
"com.sun.star.xforms.XMLFormDocument";
116 else if ( sShortName ==
u"sbibliography" )
117 sIdentifier =
"com.sun.star.frame.Bibliography";
122 bool MigrationImpl::alreadyMigrated()
124 OUString
aStr = m_aInfo.userdata +
"/MIGRATED4";
127 bool bRet = aFile.open (osl_File_OpenFlag_Write | osl_File_OpenFlag_Create | osl_File_OpenFlag_NoLock) == FileBase::E_EXIST;
128 SAL_INFO(
"desktop.migration",
"File '" << aStr <<
"' exists? " << bRet );
132 bool MigrationImpl::initializeMigration()
136 if (!checkMigrationCompleted()) {
137 readAvailableMigrations(m_vMigrationsAvailable);
138 sal_Int32
nIndex = findPreferredMigrationProcess(m_vMigrationsAvailable);
141 if (alreadyMigrated())
143 m_vrMigrations = readMigrationSteps(m_vMigrationsAvailable[nIndex].
name);
146 bRet = !m_aInfo.userdata.isEmpty();
149 SAL_INFO(
"desktop.migration",
"Migration " << ( bRet ?
"needed" :
"not required" ) );
154 void Migration::migrateSettingsIfNecessary()
161 bool bResult =
false;
167 OSL_ENSURE(bResult,
"Migration has not been successful");
170 MigrationImpl::MigrationImpl()
174 MigrationImpl::~MigrationImpl()
179 bool MigrationImpl::doMigration()
182 m_vrFileList = compileFileList();
187 std::vector< MigrationModuleInfo > vModulesInfo = detectUIChangesForAllModules();
188 aNewVersionUIInfo.
init(vModulesInfo);
192 const OUString sMenubarResourceURL(
"private:resource/menubar/menubar");
193 const OUString sToolbarResourcePre(
"private:resource/toolbar/");
196 if (sModuleIdentifier.isEmpty())
200 OUString aOldCfgDataPath = m_aInfo.userdata +
"/user/config/soffice.cfg/modules/" +
i.sModuleShortName;
201 uno::Sequence< uno::Any > lArgs {uno::makeAny(aOldCfgDataPath), uno::makeAny(embed::ElementModes::READ)};
205 uno::Reference< embed::XStorage > xModules(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
208 if ( xModules.is() ) {
209 xOldCfgManager->setStorage( xModules );
210 xOldCfgManager->reload();
213 uno::Reference< ui::XUIConfigurationManager > xCfgManager = aNewVersionUIInfo.
getConfigManager(
i.sModuleShortName);
216 uno::Reference< container::XIndexContainer > xOldVersionMenuSettings(xOldCfgManager->getSettings(sMenubarResourceURL,
true), uno::UNO_QUERY);
217 uno::Reference< container::XIndexContainer > xNewVersionMenuSettings = aNewVersionUIInfo.
getNewMenubarSettings(
i.sModuleShortName);
218 compareOldAndNewConfig(OUString(), xOldVersionMenuSettings, xNewVersionMenuSettings, sMenubarResourceURL);
219 mergeOldToNewVersion(xCfgManager, xNewVersionMenuSettings, sModuleIdentifier, sMenubarResourceURL);
222 sal_Int32 nToolbars =
i.m_vToolbars.size();
224 for (sal_Int32 j=0; j<nToolbars; ++j) {
225 OUString sToolbarName =
i.m_vToolbars[j];
226 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
228 uno::Reference< container::XIndexContainer > xOldVersionToolbarSettings(xOldCfgManager->getSettings(sToolbarResourceURL,
true), uno::UNO_QUERY);
229 uno::Reference< container::XIndexContainer > xNewVersionToolbarSettings = aNewVersionUIInfo.
getNewToolbarSettings(
i.sModuleShortName, sToolbarName);
230 compareOldAndNewConfig(OUString(), xOldVersionToolbarSettings, xNewVersionToolbarSettings, sToolbarResourceURL);
231 mergeOldToNewVersion(xCfgManager, xNewVersionToolbarSettings, sModuleIdentifier, sToolbarResourceURL);
235 m_aOldVersionItemsHashMap.clear();
244 uno::Reference< XRefreshable >(
246 uno::UNO_QUERY_THROW)->refresh();
249 }
catch (
const css::uno::Exception &) {
252 "ignored Exception while migrating from version \"" << m_aInfo.productname
253 <<
"\" data \"" << m_aInfo.userdata <<
"\"");
257 setMigrationCompleted();
261 void MigrationImpl::setMigrationCompleted()
264 uno::Reference< XPropertySet > aPropertySet(getConfigAccess(
"org.openoffice.Setup/Office",
true), uno::UNO_QUERY_THROW);
265 aPropertySet->setPropertyValue(
"MigrationCompleted", uno::makeAny(
true));
266 uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges();
272 bool MigrationImpl::checkMigrationCompleted()
274 bool bMigrationCompleted =
false;
276 uno::Reference< XPropertySet > aPropertySet(
277 getConfigAccess(
"org.openoffice.Setup/Office"), uno::UNO_QUERY_THROW);
278 aPropertySet->getPropertyValue(
"MigrationCompleted") >>= bMigrationCompleted;
280 if( !bMigrationCompleted && getenv(
"SAL_DISABLE_USERMIGRATION" ) ) {
282 setMigrationCompleted();
283 bMigrationCompleted =
true;
288 SAL_INFO(
"desktop.migration",
"Migration " << ( bMigrationCompleted ?
"already completed" :
"not done" ) );
290 return bMigrationCompleted;
295 migrations_available::iterator pIter = std::find_if(rAvailableMigrations.begin(), rAvailableMigrations.end(),
297 if (pIter != rAvailableMigrations.end())
298 rAvailableMigrations.insert(pIter, aSupportedMigration );
300 rAvailableMigrations.push_back( aSupportedMigration );
306 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess(
"org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_SET_THROW);
307 const uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames();
309 const OUString aVersionIdentifiers(
"VersionIdentifiers" );
310 const OUString aPriorityIdentifier(
"Priority" );
312 for (OUString
const & supportedVersion :seqSupportedVersions) {
313 sal_Int32 nPriority( 0 );
314 uno::Sequence< OUString > seqVersions;
315 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(supportedVersion), uno::UNO_QUERY_THROW );
316 xMigrationData->getByName( aVersionIdentifiers ) >>= seqVersions;
317 xMigrationData->getByName( aPriorityIdentifier ) >>= nPriority;
320 aSupportedMigration.
name = supportedVersion;
321 aSupportedMigration.
nPriority = nPriority;
322 for (OUString
const & s : std::as_const(seqVersions))
324 insertSorted( rAvailableMigrations, aSupportedMigration );
325 SAL_INFO(
"desktop.migration",
" available migration '" << aSupportedMigration.
name <<
"'" );
329 migrations_vr MigrationImpl::readMigrationSteps(
const OUString& rMigrationName)
332 uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess(
"org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_SET_THROW);
333 uno::Reference< XNameAccess > xMigrationData( aMigrationAccess->getByName(rMigrationName), uno::UNO_QUERY_THROW );
337 uno::Reference< XNameAccess > theNameAccess(xMigrationData->getByName(
"MigrationSteps"), uno::UNO_QUERY_THROW);
338 uno::Reference< XNameAccess > tmpAccess;
339 uno::Sequence< OUString > tmpSeq;
341 const css::uno::Sequence<OUString> aMigrationSteps = theNameAccess->getElementNames();
342 for (
const OUString& rMigrationStep : aMigrationSteps) {
344 theNameAccess->getByName(rMigrationStep) >>= tmpAccess;
348 if (tmpAccess->getByName(
"IncludedFiles") >>= tmpSeq) {
349 for (
const OUString& rSeqEntry : std::as_const(tmpSeq))
354 if (tmpAccess->getByName(
"ExcludedFiles") >>= tmpSeq) {
355 for (
const OUString& rSeqEntry : std::as_const(tmpSeq))
360 if (tmpAccess->getByName(
"IncludedNodes") >>= tmpSeq) {
361 for (
const OUString& rSeqEntry : std::as_const(tmpSeq))
366 if (tmpAccess->getByName(
"ExcludedNodes") >>= tmpSeq) {
367 for (
const OUString& rSeqEntry : std::as_const(tmpSeq))
372 if (tmpAccess->getByName(
"ExcludedExtensions") >>= tmpSeq) {
373 for (
const OUString& rSeqEntry : std::as_const(tmpSeq))
378 tmpAccess->getByName(
"MigrationService") >>= tmpStep.
service;
380 vrMigrations->push_back(tmpStep);
388 if (result == FileBase::E_NOENT) {
397 #if defined UNX && ! defined MACOSX
401 OUString MigrationImpl::preXDGConfigDir(
const OUString& rConfigDir)
403 OUString aPreXDGConfigPath;
404 const char* pXDGCfgHome = getenv(
"XDG_CONFIG_HOME");
417 if ( !pXDGCfgHome && rConfigDir.endsWith( XDG_CONFIG_PART ) )
419 aPreXDGConfigPath = rConfigDir.copy( 0, rConfigDir.getLength() -
sizeof(
XDG_CONFIG_PART ) + 2 );
421 aPreXDGConfigPath = rConfigDir;
425 aPreXDGConfigPath +=
".";
427 return aPreXDGConfigPath;
431 void MigrationImpl::setInstallInfoIfExist(
433 const OUString& rConfigDir,
434 const OUString& rVersion)
437 osl::DirectoryItem item;
438 osl::FileStatus stat(osl_FileStatus_Mask_Type);
440 if (osl::DirectoryItem::get(url, item) == osl::FileBase::E_None
441 && item.getFileStatus(stat) == osl::FileBase::E_None
442 && stat.getFileType() == osl::FileStatus::Directory) {
451 OUString aTopConfigDir;
452 osl::Security().getConfigDir( aTopConfigDir );
453 if ( !aTopConfigDir.isEmpty() && aTopConfigDir[ aTopConfigDir.getLength()-1 ] !=
'/' )
454 aTopConfigDir +=
"/";
456 #if defined UNX && ! defined MACOSX
457 OUString aPreXDGTopConfigDir = preXDGConfigDir(aTopConfigDir);
461 for (
auto const& elem : rVersions)
463 OUString aVersion, aProfileName;
464 sal_Int32 nSeparatorIndex = elem.indexOf(
'=');
465 if ( nSeparatorIndex != -1 ) {
466 aVersion = elem.copy( 0, nSeparatorIndex );
467 aProfileName = elem.copy( nSeparatorIndex+1 );
470 if ( !aVersion.isEmpty() && !aProfileName.isEmpty() &&
472 aProfileName.equalsIgnoreAsciiCase(
474 setInstallInfoIfExist(aInfo, aTopConfigDir + aProfileName, aVersion);
475 #if defined UNX && ! defined MACOSX
478 setInstallInfoIfExist(aInfo, aPreXDGTopConfigDir + aProfileName, aVersion);
491 for (
auto const& availableMigration : rAvailableMigrations)
493 install_info aInstallInfo = findInstallation(availableMigration.supported_versions);
495 m_aInfo = aInstallInfo;
502 SAL_INFO(
"desktop.migration",
" preferred migration is from product '" << m_aInfo.productname <<
"'");
503 SAL_INFO(
"desktop.migration",
" and settings directory '" << m_aInfo.userdata <<
"'");
512 for (
auto const& pattern : vPatterns)
516 SearchParam param(pattern, SearchParam::SearchType::Regexp);
520 for (
auto const& elem : vSet)
522 end = elem.getLength();
524 vrResult->push_back(elem);
530 strings_vr MigrationImpl::getAllFiles(
const OUString& baseURL)
const
535 Directory dir(baseURL);
536 if (dir.open() == FileBase::E_None) {
542 FileStatus fs(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileURL);
543 while (dir.getNextItem(item) == FileBase::E_None) {
544 if (item.getFileStatus(fs) == FileBase::E_None) {
545 if (fs.getFileType() == FileStatus::Directory)
546 vSubDirs.push_back(fs.getFileURL());
548 vrResult->push_back(fs.getFileURL());
553 for (
auto const& subDir : vSubDirs)
555 vrSubResult = getAllFiles(subDir);
556 vrResult->insert(vrResult->end(), vrSubResult->begin(), vrSubResult->end());
569 std::sort(
a.begin(),
a.end());
570 strings_v::iterator ae(std::unique(
a.begin(),
a.end()));
572 std::sort(b.begin(), b.end());
573 strings_v::iterator be(std::unique(b.begin(), b.end()));
575 std::set_difference(
a.begin(), ae, b.begin(), be, std::back_inserter(c));
589 strings_vr vrFiles = getAllFiles(m_aInfo.userdata);
592 for (
auto const& rMigration : *m_vrMigrations)
594 vrInclude = applyPatterns(*vrFiles, rMigration.includeFiles);
595 vrExclude = applyPatterns(*vrFiles, rMigration.excludeFiles);
596 strings_v sub(subtract(*vrInclude, *vrExclude));
597 vrResult->insert(vrResult->end(), sub.begin(), sub.end());
605 struct componentParts {
610 typedef std::map< OUString, componentParts >
Components;
612 bool getComponent(OUString
const & path, OUString * component)
614 OSL_ASSERT(component !=
nullptr);
615 if (path.isEmpty() || path[0] !=
'/') {
616 SAL_INFO(
"desktop.migration",
"configuration migration in/exclude path " << path <<
" ignored (does not start with slash)" );
619 sal_Int32
i = path.indexOf(
'/', 1);
620 *component = i < 0 ? path.copy(1) : path.copy(1, i - 1);
626 void MigrationImpl::copyConfig()
629 for (
auto const& rMigrationStep : *m_vrMigrations) {
630 for (
const OUString& rIncludePath : rMigrationStep.includeConfig) {
632 if (getComponent(rIncludePath, &comp)) {
633 comps[comp].includedPaths.insert(rIncludePath);
636 for (
const OUString& rExcludePath : rMigrationStep.excludeConfig) {
638 if (getComponent(rExcludePath, &comp)) {
639 comps[comp].excludedPaths.insert(rExcludePath);
645 bool bRegistryModificationsXcuExists =
false;
646 OUString regFilePath = m_aInfo.userdata +
"/user/registrymodifications.xcu";
647 File regFile(regFilePath);
648 ::osl::FileBase::RC nError = regFile.open(osl_File_OpenFlag_Read);
649 if ( nError == ::osl::FileBase::E_None ) {
650 bRegistryModificationsXcuExists =
true;
654 for (
auto const&
comp : comps)
656 if (!
comp.second.includedPaths.empty()) {
657 if (!bRegistryModificationsXcuExists) {
661 OUStringBuffer buf(m_aInfo.userdata);
662 buf.append(
"/user/registry/data");
665 OUString seg(
comp.first.getToken(0,
'.', n));
668 seg, rtl_UriCharClassPchar, rtl_UriEncodeStrict,
669 RTL_TEXTENCODING_UTF8));
670 if (enc.isEmpty() && !seg.isEmpty()) {
671 SAL_INFO(
"desktop.migration",
"configuration migration component " <<
comp.first <<
" ignored (cannot be encoded as file path)" );
678 regFilePath = buf.toString();
680 configuration::Update::get(
682 insertModificationXcuFile(
687 SAL_INFO(
"desktop.migration",
"configuration migration component " <<
comp.first <<
" ignored (only excludes, no includes)" );
694 uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(
const char* pPath,
bool bUpdate)
696 uno::Reference< XNameAccess > xNameAccess;
700 sAccessSrvc =
"com.sun.star.configuration.ConfigurationUpdateAccess";
702 sAccessSrvc =
"com.sun.star.configuration.ConfigurationAccess";
704 OUString sConfigURL = OUString::createFromAscii(pPath);
706 uno::Reference< XMultiServiceFactory > theConfigProvider(
707 configuration::theDefaultProvider::get(
711 uno::Sequence< uno::Any > theArgs {uno::makeAny(sConfigURL)};
713 theConfigProvider->createInstanceWithArguments(
714 sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW );
715 }
catch (
const css::uno::Exception&) {
721 void MigrationImpl::copyFiles()
725 OUString userInstall;
729 for (
auto const& rFile : *m_vrFileList)
732 localName = rFile.copy(m_aInfo.userdata.getLength());
733 if (localName.endsWith(
"/autocorr/acor_.dat")) {
738 localName = OUString::Concat(localName.subView( 0, localName.getLength() - 4)) +
"und.dat";
740 destName = userInstall + localName;
745 FileBase::RC copyResult = File::copy(rFile, destName);
746 if (copyResult != FileBase::E_None) {
747 SAL_WARN(
"desktop",
"Cannot copy " << rFile <<
" to " << destName);
751 OSL_FAIL(
"copyFiles: UserInstall does not exist");
755 void MigrationImpl::runServices()
758 uno::Sequence< uno::Any > seqArguments(3);
759 seqArguments[0] <<= NamedValue(
"Productname",
760 uno::makeAny(m_aInfo.productname));
761 seqArguments[1] <<= NamedValue(
"UserData",
762 uno::makeAny(m_aInfo.userdata));
767 uno::Reference< XJob > xMigrationJob;
770 for (
auto const& rMigration : *m_vrMigrations)
772 if( !rMigration.service.isEmpty()) {
776 uno::Sequence< OUString > seqExtDenyList;
777 sal_uInt32 nSize = rMigration.excludeExtensions.size();
779 seqExtDenyList = comphelper::arrayToSequence< OUString >(
780 rMigration.excludeExtensions.data(), nSize );
781 seqArguments[2] <<= NamedValue(
"ExtensionDenyList",
782 uno::makeAny( seqExtDenyList ));
785 xContext->getServiceManager()->createInstanceWithArgumentsAndContext(rMigration.service, seqArguments, xContext),
786 uno::UNO_QUERY_THROW);
788 xMigrationJob->execute(uno::Sequence< NamedValue >());
793 << rMigration.service);
795 SAL_WARN(
"desktop",
"Execution of migration service failed (Exception caught).\nService: "
796 << rMigration.service <<
"\nNo message available");
803 std::vector< MigrationModuleInfo > MigrationImpl::detectUIChangesForAllModules()
const
805 std::vector< MigrationModuleInfo > vModulesInfo;
806 const OUString MENUBAR(
"menubar");
807 const OUString TOOLBAR(
"toolbar");
809 uno::Sequence< uno::Any > lArgs {uno::makeAny(m_aInfo.userdata +
"/user/config/soffice.cfg/modules"),
810 uno::makeAny(embed::ElementModes::READ)};
812 uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
814 uno::Reference< embed::XStorage > xModules;
816 xModules.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY);
820 uno::Sequence< OUString > lNames = xModules->getElementNames();
821 sal_Int32
nLength = lNames.getLength();
822 for (sal_Int32 i=0; i<nLength; ++i) {
823 OUString sModuleShortName = lNames[i];
824 uno::Reference< embed::XStorage > xModule = xModules->openStorageElement(sModuleShortName, embed::ElementModes::READ);
828 uno::Reference< embed::XStorage > xMenubar = xModule->openStorageElement(MENUBAR, embed::ElementModes::READ);
830 if (xMenubar->getElementNames().hasElements()) {
836 uno::Reference< embed::XStorage > xToolbar = xModule->openStorageElement(TOOLBAR, embed::ElementModes::READ);
838 const ::uno::Sequence< OUString > lToolbars = xToolbar->getElementNames();
839 for (OUString
const & sToolbarName : lToolbars) {
840 if (sToolbarName.startsWith(
"custom_"))
844 sal_Int32
nIndex = sToolbarName.lastIndexOf(
'.');
846 OUString sExtension(sToolbarName.copy(nIndex));
847 OUString sToolbarResourceName(sToolbarName.copy(0, nIndex));
848 if (!sToolbarResourceName.isEmpty() && sExtension ==
".xml")
849 aModuleInfo.
m_vToolbars.push_back(sToolbarResourceName);
855 vModulesInfo.push_back(aModuleInfo);
862 void MigrationImpl::compareOldAndNewConfig(
const OUString& sParent,
863 const uno::Reference< container::XIndexContainer >& xIndexOld,
864 const uno::Reference< container::XIndexContainer >& xIndexNew,
865 const OUString& sResourceURL)
867 const OUString MENU_SEPARATOR(
" | ");
869 std::vector< MigrationItem > vOldItems;
870 std::vector< MigrationItem > vNewItems;
871 uno::Sequence< beans::PropertyValue > aProps;
872 sal_Int32 nOldCount = xIndexOld->getCount();
873 sal_Int32 nNewCount = xIndexNew->getCount();
875 for (
int n=0;
n<nOldCount; ++
n) {
877 if (xIndexOld->getByIndex(
n) >>= aProps) {
878 for(beans::PropertyValue
const & prop : std::as_const(aProps)) {
879 if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
881 else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER )
886 vOldItems.push_back(aMigrationItem);
890 for (
int n=0;
n<nNewCount; ++
n) {
892 if (xIndexNew->getByIndex(
n) >>= aProps) {
893 for(beans::PropertyValue
const & prop : std::as_const(aProps)) {
894 if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL )
896 else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER )
901 vNewItems.push_back(aMigrationItem);
906 for (
auto const& oldItem : vOldItems)
908 std::vector< MigrationItem >::iterator pFound = std::find(vNewItems.begin(), vNewItems.end(), oldItem);
909 if (pFound != vNewItems.end() && oldItem.m_xPopupMenu.is()) {
911 if (!sParent.isEmpty())
912 sName = sParent + MENU_SEPARATOR + oldItem.m_sCommandURL;
914 sName = oldItem.m_sCommandURL;
915 compareOldAndNewConfig(sName, oldItem.m_xPopupMenu, pFound->m_xPopupMenu, sResourceURL);
916 }
else if (pFound == vNewItems.end()) {
917 MigrationItem aMigrationItem(sParent, sSibling, oldItem.m_sCommandURL, oldItem.m_xPopupMenu);
918 if (m_aOldVersionItemsHashMap.find(sResourceURL)==m_aOldVersionItemsHashMap.end()) {
919 std::vector< MigrationItem > vMigrationItems;
920 m_aOldVersionItemsHashMap.emplace(sResourceURL, vMigrationItems);
921 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
923 if (std::find(m_aOldVersionItemsHashMap[sResourceURL].
begin(), m_aOldVersionItemsHashMap[sResourceURL].
end(), aMigrationItem)==m_aOldVersionItemsHashMap[sResourceURL].
end())
924 m_aOldVersionItemsHashMap[sResourceURL].push_back(aMigrationItem);
928 sSibling = oldItem.m_sCommandURL;
932 void MigrationImpl::mergeOldToNewVersion(
const uno::Reference< ui::XUIConfigurationManager >& xCfgManager,
933 const uno::Reference< container::XIndexContainer>& xIndexContainer,
934 const OUString& sModuleIdentifier,
935 const OUString& sResourceURL)
937 MigrationHashMap::iterator pFound = m_aOldVersionItemsHashMap.find(sResourceURL);
938 if (pFound==m_aOldVersionItemsHashMap.end())
941 for (
auto const& elem : pFound->second)
943 uno::Reference< container::XIndexContainer > xTemp = xIndexContainer;
945 OUString sParentNodeName = elem.m_sParentNodeName;
948 OUString sToken = sParentNodeName.getToken(0,
'|', nIndex).trim();
949 if (sToken.isEmpty())
952 sal_Int32
nCount = xTemp->getCount();
953 for (sal_Int32 i=0; i<nCount; ++i) {
954 OUString sCommandURL;
956 uno::Reference< container::XIndexContainer > xChild;
958 uno::Sequence< beans::PropertyValue > aPropSeq;
959 xTemp->getByIndex(i) >>= aPropSeq;
960 for (beans::PropertyValue
const & prop : std::as_const(aPropSeq)) {
961 OUString sPropName = prop.Name;
962 if ( sPropName == ITEM_DESCRIPTOR_COMMANDURL )
963 prop.Value >>= sCommandURL;
964 else if ( sPropName == ITEM_DESCRIPTOR_LABEL )
965 prop.Value >>= sLabel;
966 else if ( sPropName == ITEM_DESCRIPTOR_CONTAINER )
967 prop.Value >>= xChild;
970 if (sCommandURL == sToken) {
976 }
while (nIndex >= 0);
980 uno::Sequence< beans::PropertyValue > aPropSeq {
981 beans::PropertyValue(ITEM_DESCRIPTOR_COMMANDURL, 0, uno::makeAny(elem.m_sCommandURL), beans::PropertyState_DIRECT_VALUE),
983 beans::PropertyValue(ITEM_DESCRIPTOR_CONTAINER, 0, uno::makeAny(elem.m_xPopupMenu), beans::PropertyState_DIRECT_VALUE)
986 if (elem.m_sPrevSibling.isEmpty())
987 xTemp->insertByIndex(0, uno::makeAny(aPropSeq));
989 sal_Int32
nCount = xTemp->getCount();
991 for (; i<nCount; ++i) {
993 uno::Sequence< beans::PropertyValue > aTempPropSeq;
994 xTemp->getByIndex(i) >>= aTempPropSeq;
995 for (beans::PropertyValue
const & prop : std::as_const(aTempPropSeq)) {
996 if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL ) {
1002 if (sCmd == elem.m_sPrevSibling)
1006 xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq));
1011 if (xIndexContainer.is())
1012 xCfgManager->replaceSettings(sResourceURL, xIndexContainer);
1014 uno::Reference< ui::XUIConfigurationPersistence > xUIConfigurationPersistence(xCfgManager, uno::UNO_QUERY);
1015 if (xUIConfigurationPersistence.is())
1016 xUIConfigurationPersistence->store();
1019 uno::Reference< ui::XUIConfigurationManager > NewVersionUIInfo::getConfigManager(std::u16string_view sModuleShortName)
const
1021 uno::Reference< ui::XUIConfigurationManager > xCfgManager;
1023 for (
const css::beans::PropertyValue& rProp : m_lCfgManagerSeq) {
1024 if (rProp.Name == sModuleShortName) {
1025 rProp.Value >>= xCfgManager;
1033 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewMenubarSettings(std::u16string_view sModuleShortName)
const
1035 uno::Reference< container::XIndexContainer > xNewMenuSettings;
1037 for (
auto const & prop : m_lNewVersionMenubarSettingsSeq) {
1038 if (prop.Name == sModuleShortName) {
1039 prop.Value >>= xNewMenuSettings;
1044 return xNewMenuSettings;
1047 uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSettings(std::u16string_view sModuleShortName, std::u16string_view sToolbarName)
const
1049 uno::Reference< container::XIndexContainer > xNewToolbarSettings;
1051 for (
auto const & newProp : m_lNewVersionToolbarSettingsSeq) {
1052 if (newProp.Name == sModuleShortName) {
1053 uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq;
1054 newProp.Value >>= lToolbarSettingsSeq;
1055 for (
auto const & prop : std::as_const(lToolbarSettingsSeq)) {
1056 if (prop.Name == sToolbarName) {
1057 prop.Value >>= xNewToolbarSettings;
1066 return xNewToolbarSettings;
1069 void NewVersionUIInfo::init(
const std::vector< MigrationModuleInfo >& vModulesInfo)
1071 m_lCfgManagerSeq.resize(vModulesInfo.size());
1072 m_lNewVersionMenubarSettingsSeq.realloc(vModulesInfo.size());
1073 m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size());
1075 const OUString sMenubarResourceURL(
"private:resource/menubar/menubar");
1076 const OUString sToolbarResourcePre(
"private:resource/toolbar/");
1080 for (
size_t i=0; i<vModulesInfo.size(); ++i) {
1082 if (!sModuleIdentifier.isEmpty()) {
1083 uno::Reference< ui::XUIConfigurationManager > xCfgManager = xModuleCfgSupplier->getUIConfigurationManager(sModuleIdentifier);
1084 m_lCfgManagerSeq[i].Name = vModulesInfo[i].sModuleShortName;
1085 m_lCfgManagerSeq[i].Value <<= xCfgManager;
1087 if (vModulesInfo[i].bHasMenubar) {
1088 m_lNewVersionMenubarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1089 m_lNewVersionMenubarSettingsSeq[i].Value <<= xCfgManager->getSettings(sMenubarResourceURL,
true);
1092 sal_Int32 nToolbars = vModulesInfo[i].m_vToolbars.size();
1093 if (nToolbars > 0) {
1094 uno::Sequence< beans::PropertyValue > lPropSeq(nToolbars);
1095 for (sal_Int32 j=0; j<nToolbars; ++j) {
1096 OUString sToolbarName = vModulesInfo[i].m_vToolbars[j];
1097 OUString sToolbarResourceURL = sToolbarResourcePre + sToolbarName;
1099 lPropSeq[j].Name = sToolbarName;
1100 lPropSeq[j].Value <<= xCfgManager->getSettings(sToolbarResourceURL,
true);
1103 m_lNewVersionToolbarSettingsSeq[i].Name = vModulesInfo[i].sModuleShortName;
1104 m_lNewVersionToolbarSettingsSeq[i].Value <<= lPropSeq;
std::unique_ptr< strings_v > strings_vr
static PathStatus locateUserInstallation(OUString &_rURL)
void init(const std::vector< MigrationModuleInfo > &vModulesInfo)
bool initializeMigration()
std::set< OUString > excludedPaths
OUString GetLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
strings_v supported_versions
std::vector< OUString > m_vToolbars
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
OUString sModuleShortName
constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL
css::uno::Reference< css::container::XIndexContainer > m_xPopupMenu
constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL
css::uno::Reference< css::container::XIndexContainer > getNewToolbarSettings(std::u16string_view sModuleShortName, std::u16string_view sToolbarName) const
information for the UI elements to be migrated for one module
PropertiesInfo aProperties
enumrange< T >::Iterator begin(enumrange< T >)
static void insertSorted(migrations_available &rAvailableMigrations, supported_migration const &aSupportedMigration)
std::vector< supported_migration > migrations_available
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
#define TOOLS_WARN_EXCEPTION(area, stream)
css::uno::Reference< css::container::XIndexContainer > getNewMenubarSettings(std::u16string_view sModuleShortName) const
static OUString getProductName()
#define LANGUAGE_DONTKNOW
strings_v excludeExtensions
const char XDG_CONFIG_PART[]
enumrange< T >::Iterator end(enumrange< T >)
constexpr OUStringLiteral sAccessSrvc
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
static uno::Reference< css::uno::XComponentContext > xContext
get the information before copying the ui configuration files of old version to new version ...
std::vector< uno::Reference< sheet::XSpreadsheetDocument > > Components
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Reference< css::ui::XUIConfigurationManager > getConfigManager(std::u16string_view sModuleShortName) const
static OUString mapModuleShortNameToIdentifier(std::u16string_view sShortName)
#define SAL_INFO(area, stream)
Reference< XComponentContext > getProcessComponentContext()
std::set< OUString > includedPaths
std::vector< migration_step > migrations_v
#define SAL_WARN(area, stream)
static FileBase::RC _checkAndCreateDirectory(INetURLObject const &dirURL)
constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER
std::vector< OUString > strings_v
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
std::unique_ptr< migrations_v > migrations_vr