diff options
Diffstat (limited to 'desktop/source/migration/migration.cxx')
-rw-r--r-- | desktop/source/migration/migration.cxx | 202 |
1 files changed, 154 insertions, 48 deletions
diff --git a/desktop/source/migration/migration.cxx b/desktop/source/migration/migration.cxx index 7d3b272973be..d6b52c806367 100644 --- a/desktop/source/migration/migration.cxx +++ b/desktop/source/migration/migration.cxx @@ -34,14 +34,16 @@ #include <unotools/bootstrap.hxx> #include <rtl/uri.hxx> #include <i18nlangtag/lang.h> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/urlobj.hxx> +#include <officecfg/Office/UI.hxx> #include <osl/file.hxx> #include <osl/security.hxx> #include <unotools/configmgr.hxx> #include <com/sun/star/configuration/Update.hpp> #include <com/sun/star/configuration/theDefaultProvider.hpp> +#include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/task/XJob.hpp> #include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -68,9 +70,9 @@ using namespace com::sun::star; namespace desktop { -constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL"; -constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer"; -constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL = u"Label"; +constexpr OUString ITEM_DESCRIPTOR_COMMANDURL = u"CommandURL"_ustr; +constexpr OUString ITEM_DESCRIPTOR_CONTAINER = u"ItemDescriptorContainer"_ustr; +constexpr OUString ITEM_DESCRIPTOR_LABEL = u"Label"_ustr; static OUString mapModuleShortNameToIdentifier(std::u16string_view sShortName) { @@ -188,8 +190,8 @@ bool MigrationImpl::doMigration() copyFiles(); - static const OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar"); - static const OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/"); + static constexpr OUString sMenubarResourceURL(u"private:resource/menubar/menubar"_ustr); + static constexpr OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/"); for (MigrationModuleInfo & i : vModulesInfo) { OUString sModuleIdentifier = mapModuleShortNameToIdentifier(i.sModuleShortName); if (sModuleIdentifier.isEmpty()) @@ -197,7 +199,7 @@ bool MigrationImpl::doMigration() OUString aOldCfgDataPath = m_aInfo.userdata + "/user/config/soffice.cfg/modules/" + i.sModuleShortName; - uno::Sequence< uno::Any > lArgs {uno::makeAny(aOldCfgDataPath), uno::makeAny(embed::ElementModes::READ)}; + uno::Sequence< uno::Any > lArgs {uno::Any(aOldCfgDataPath), uno::Any(embed::ElementModes::READ)}; uno::Reference< uno::XComponentContext > xContext(comphelper::getProcessComponentContext()); uno::Reference< lang::XSingleServiceFactory > xStorageFactory(embed::FileSystemStorageFactory::create(xContext)); @@ -261,7 +263,7 @@ void MigrationImpl::setMigrationCompleted() { try { uno::Reference< XPropertySet > aPropertySet(getConfigAccess("org.openoffice.Setup/Office", true), uno::UNO_QUERY_THROW); - aPropertySet->setPropertyValue("MigrationCompleted", uno::makeAny(true)); + aPropertySet->setPropertyValue("MigrationCompleted", uno::Any(true)); uno::Reference< XChangesBatch >(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges(); } catch (...) { // fail silently @@ -305,8 +307,8 @@ void MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigr uno::Reference< XNameAccess > aMigrationAccess(getConfigAccess("org.openoffice.Setup/Migration/SupportedVersions"), uno::UNO_SET_THROW); const uno::Sequence< OUString > seqSupportedVersions = aMigrationAccess->getElementNames(); - static const OUStringLiteral aVersionIdentifiers( u"VersionIdentifiers" ); - static const OUStringLiteral aPriorityIdentifier( u"Priority" ); + static constexpr OUStringLiteral aVersionIdentifiers( u"VersionIdentifiers" ); + static constexpr OUStringLiteral aPriorityIdentifier( u"Priority" ); for (OUString const & supportedVersion :seqSupportedVersions) { sal_Int32 nPriority( 0 ); @@ -318,7 +320,7 @@ void MigrationImpl::readAvailableMigrations(migrations_available& rAvailableMigr supported_migration aSupportedMigration; aSupportedMigration.name = supportedVersion; aSupportedMigration.nPriority = nPriority; - for (OUString const & s : std::as_const(seqVersions)) + for (OUString const& s : seqVersions) aSupportedMigration.supported_versions.push_back(s.trim()); insertSorted( rAvailableMigrations, aSupportedMigration ); SAL_INFO( "desktop.migration", " available migration '" << aSupportedMigration.name << "'" ); @@ -345,31 +347,31 @@ migrations_vr MigrationImpl::readMigrationSteps(const OUString& rMigrationName) // read included files from current step description if (tmpAccess->getByName("IncludedFiles") >>= tmpSeq) { - for (const OUString& rSeqEntry : std::as_const(tmpSeq)) + for (const OUString& rSeqEntry : tmpSeq) tmpStep.includeFiles.push_back(rSeqEntry); } // excluded files... if (tmpAccess->getByName("ExcludedFiles") >>= tmpSeq) { - for (const OUString& rSeqEntry : std::as_const(tmpSeq)) + for (const OUString& rSeqEntry : tmpSeq) tmpStep.excludeFiles.push_back(rSeqEntry); } // included nodes... if (tmpAccess->getByName("IncludedNodes") >>= tmpSeq) { - for (const OUString& rSeqEntry : std::as_const(tmpSeq)) + for (const OUString& rSeqEntry : tmpSeq) tmpStep.includeConfig.push_back(rSeqEntry); } // excluded nodes... if (tmpAccess->getByName("ExcludedNodes") >>= tmpSeq) { - for (const OUString& rSeqEntry : std::as_const(tmpSeq)) + for (const OUString& rSeqEntry : tmpSeq) tmpStep.excludeConfig.push_back(rSeqEntry); } // excluded extensions... if (tmpAccess->getByName("ExcludedExtensions") >>= tmpSeq) { - for (const OUString& rSeqEntry : std::as_const(tmpSeq)) + for (const OUString& rSeqEntry : tmpSeq) tmpStep.excludeExtensions.push_back(rSeqEntry); } @@ -429,7 +431,7 @@ OUString MigrationImpl::preXDGConfigDir(const OUString& rConfigDir) void MigrationImpl::setInstallInfoIfExist( install_info& aInfo, - const OUString& rConfigDir, + std::u16string_view rConfigDir, const OUString& rVersion) { OUString url(INetURLObject(rConfigDir).GetMainURL(INetURLObject::DecodeMechanism::NONE)); @@ -470,11 +472,11 @@ install_info MigrationImpl::findInstallation(const strings_v& rVersions) ( aInfo.userdata.isEmpty() || aProfileName.equalsIgnoreAsciiCase( utl::ConfigManager::getProductName() ) ) ) { - setInstallInfoIfExist(aInfo, aTopConfigDir + aProfileName, aVersion); + setInstallInfoIfExist(aInfo, Concat2View(aTopConfigDir + aProfileName), aVersion); #if defined UNX && ! defined MACOSX //try preXDG path if the new one does not exist if ( aInfo.userdata.isEmpty()) - setInstallInfoIfExist(aInfo, aPreXDGTopConfigDir + aProfileName, aVersion); + setInstallInfoIfExist(aInfo, Concat2View(aPreXDGTopConfigDir + aProfileName), aVersion); #endif } } @@ -616,6 +618,55 @@ bool getComponent(OUString const & path, OUString * component) return true; } +void renameMigratedSetElementTo( + css::uno::Reference<css::container::XNameContainer> const & set, OUString const & currentName, + OUString const & migratedName) +{ + // To avoid unexpected data loss, the code is careful to only rename from currentName to + // migratedName in the expected case where the currentName element exists and the migratedName + // element doesn't exist: + bool const hasCurrent = set->hasByName(currentName); + bool const hasMigrated = set->hasByName(migratedName); + if (hasCurrent && !hasMigrated) { + auto const elem = set->getByName(currentName); + set->removeByName(currentName); + set->insertByName(migratedName, elem); + } else { + SAL_INFO_IF(!hasCurrent, "desktop.migration", "unexpectedly missing " << currentName); + SAL_INFO_IF(hasMigrated, "desktop.migration", "unexpectedly present " << migratedName); + } +} + +void renameMigratedSetElementBack( + css::uno::Reference<css::container::XNameContainer> const & set, OUString const & currentName, + OUString const & migratedName) +{ + // To avoid unexpected data loss, the code is careful to ensure that in the end a currentName + // element exists, creating it from a template if the migratedName element had unexpectedly gone + // missing: + bool const hasMigrated = set->hasByName(migratedName); + css::uno::Any elem; + if (hasMigrated) { + elem = set->getByName(migratedName); + set->removeByName(migratedName); + } else { + SAL_INFO("desktop.migration", "unexpected loss of " << migratedName); + elem <<= css::uno::Reference<css::lang::XSingleServiceFactory>( + set, css::uno::UNO_QUERY_THROW)->createInstance(); + } + if (set->hasByName(currentName)) { + SAL_INFO("desktop.migration", "unexpected reappearance of " << currentName); + if (hasMigrated) { + SAL_INFO( + "desktop.migration", + "reappeared " << currentName << " overwritten with " << migratedName); + set->replaceByName(currentName, elem); + } + } else { + set->insertByName(currentName, elem); + } +} + } void MigrationImpl::copyConfig() @@ -646,6 +697,30 @@ void MigrationImpl::copyConfig() regFile.close(); } + // If the to-be-migrated data contains modifications of + // /org.openoffice.Office.UI/ColorScheme/ColorSchemes set elements named after the migrated + // product name, those modifications must instead be made to the corresponding set elements + // named after the current product name. However, if the current configuration data does not + // contain those old-named set elements at all, their modification data would silently be + // ignored by css.configuration.XUpdate::insertModificationXcuFile. So temporarily rename any + // new-named set elements to their old-named counterparts here, and rename them back again down + // below after importing the migrated data: + OUString sProductName = utl::ConfigManager::getProductName(); + OUString sProductNameDark = sProductName + " Dark"; + OUString sMigratedProductName = m_aInfo.productname; + // remove version number from the end of product name if there’s one + if (isdigit(sMigratedProductName[sMigratedProductName.getLength() - 1])) + sMigratedProductName = (sMigratedProductName.copy(0, m_aInfo.productname.getLength() - 1)).trim(); + OUString sMigratedProductNameDark = sMigratedProductName + " Dark"; + auto const tempRename = sMigratedProductName != sProductName; + if (tempRename) { + auto const batch = comphelper::ConfigurationChanges::create(); + auto const schemes = officecfg::Office::UI::ColorScheme::ColorSchemes::get(batch); + renameMigratedSetElementTo(schemes, sProductName, sMigratedProductName); + renameMigratedSetElementTo(schemes, sProductNameDark, sMigratedProductNameDark); + batch->commit(); + } + for (auto const& comp : comps) { if (!comp.second.includedPaths.empty()) { @@ -653,8 +728,8 @@ void MigrationImpl::copyConfig() // shared registrymodifications.xcu does not exists // the configuration is split in many registry files // determine the file names from the first element in included paths - OUStringBuffer buf(m_aInfo.userdata); - buf.append("/user/registry/data"); + OUStringBuffer buf(m_aInfo.userdata + + "/user/registry/data"); sal_Int32 n = 0; do { OUString seg(comp.first.getToken(0, '.', n)); @@ -666,8 +741,7 @@ void MigrationImpl::copyConfig() SAL_INFO( "desktop.migration", "configuration migration component " << comp.first << " ignored (cannot be encoded as file path)" ); goto next; } - buf.append('/'); - buf.append(enc); + buf.append("/" + enc); } while (n >= 0); buf.append(".xcu"); regFilePath = buf.makeStringAndClear(); @@ -678,12 +752,44 @@ void MigrationImpl::copyConfig() regFilePath, comphelper::containerToSequence(comp.second.includedPaths), comphelper::containerToSequence(comp.second.excludedPaths)); + } else { SAL_INFO( "desktop.migration", "configuration migration component " << comp.first << " ignored (only excludes, no includes)" ); } next: ; } + if (tempRename) { + auto const batch = comphelper::ConfigurationChanges::create(); + auto const schemes = officecfg::Office::UI::ColorScheme::ColorSchemes::get(batch); + renameMigratedSetElementBack(schemes, sProductName, sMigratedProductName); + renameMigratedSetElementBack(schemes, sProductNameDark, sMigratedProductNameDark); + batch->commit(); + } + // checking the migrated (product name related) color scheme name, and replace it to the current version scheme name + try + { + OUString sMigratedColorScheme; + uno::Reference<XPropertySet> aPropertySet( + getConfigAccess("org.openoffice.Office.UI/ColorScheme", true), uno::UNO_QUERY_THROW); + if (aPropertySet->getPropertyValue("CurrentColorScheme") >>= sMigratedColorScheme) + { + if (sMigratedColorScheme.equals(sMigratedProductName)) + { + aPropertySet->setPropertyValue("CurrentColorScheme", + uno::Any(sProductName)); + uno::Reference<XChangesBatch>(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges(); + } + else if (sMigratedColorScheme.equals(sMigratedProductNameDark)) + { + aPropertySet->setPropertyValue("CurrentColorScheme", + uno::Any(sProductNameDark)); + uno::Reference<XChangesBatch>(aPropertySet, uno::UNO_QUERY_THROW)->commitChanges(); + } + } + } catch (const Exception&) { + // fail silently... + } } uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const char* pPath, bool bUpdate) @@ -703,7 +809,7 @@ uno::Reference< XNameAccess > MigrationImpl::getConfigAccess(const char* pPath, comphelper::getProcessComponentContext())); // access the provider - uno::Sequence< uno::Any > theArgs {uno::makeAny(sConfigURL)}; + uno::Sequence< uno::Any > theArgs {uno::Any(sConfigURL)}; xNameAccess.set( theConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), uno::UNO_QUERY_THROW ); @@ -753,9 +859,9 @@ void MigrationImpl::runServices() uno::Sequence< uno::Any > seqArguments(3); auto pseqArguments = seqArguments.getArray(); pseqArguments[0] <<= NamedValue("Productname", - uno::makeAny(m_aInfo.productname)); + uno::Any(m_aInfo.productname)); pseqArguments[1] <<= NamedValue("UserData", - uno::makeAny(m_aInfo.userdata)); + uno::Any(m_aInfo.userdata)); // create an instance of every migration service @@ -775,7 +881,7 @@ void MigrationImpl::runServices() seqExtDenyList = comphelper::arrayToSequence< OUString >( rMigration.excludeExtensions.data(), nSize ); pseqArguments[2] <<= NamedValue("ExtensionDenyList", - uno::makeAny( seqExtDenyList )); + uno::Any( seqExtDenyList )); xMigrationJob.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(rMigration.service, seqArguments, xContext), @@ -799,11 +905,11 @@ void MigrationImpl::runServices() std::vector< MigrationModuleInfo > MigrationImpl::detectUIChangesForAllModules() const { std::vector< MigrationModuleInfo > vModulesInfo; - static const OUStringLiteral MENUBAR(u"menubar"); - static const OUStringLiteral TOOLBAR(u"toolbar"); + static constexpr OUStringLiteral MENUBAR(u"menubar"); + static constexpr OUStringLiteral TOOLBAR(u"toolbar"); - uno::Sequence< uno::Any > lArgs {uno::makeAny(m_aInfo.userdata + "/user/config/soffice.cfg/modules"), - uno::makeAny(embed::ElementModes::READ)}; + uno::Sequence< uno::Any > lArgs {uno::Any(m_aInfo.userdata + "/user/config/soffice.cfg/modules"), + uno::Any(embed::ElementModes::READ)}; uno::Reference< lang::XSingleServiceFactory > xStorageFactory( embed::FileSystemStorageFactory::create(comphelper::getProcessComponentContext())); @@ -839,9 +945,9 @@ std::vector< MigrationModuleInfo > MigrationImpl::detectUIChangesForAllModules() aModuleInfo.sModuleShortName = sModuleShortName; sal_Int32 nIndex = sToolbarName.lastIndexOf('.'); if (nIndex > 0) { - OUString sExtension(sToolbarName.copy(nIndex)); + std::u16string_view sExtension(sToolbarName.subView(nIndex)); OUString sToolbarResourceName(sToolbarName.copy(0, nIndex)); - if (!sToolbarResourceName.isEmpty() && sExtension == ".xml") + if (!sToolbarResourceName.isEmpty() && sExtension == u".xml") aModuleInfo.m_vToolbars.push_back(sToolbarResourceName); } } @@ -860,7 +966,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent, const uno::Reference< container::XIndexContainer >& xIndexNew, const OUString& sResourceURL) { - static const OUStringLiteral MENU_SEPARATOR(u" | "); + static constexpr OUStringLiteral MENU_SEPARATOR(u" | "); std::vector< MigrationItem > vOldItems; std::vector< MigrationItem > vNewItems; @@ -871,7 +977,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent, for (int n=0; n<nOldCount; ++n) { MigrationItem aMigrationItem; if (xIndexOld->getByIndex(n) >>= aProps) { - for(beans::PropertyValue const & prop : std::as_const(aProps)) { + for(beans::PropertyValue const & prop : aProps) { if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL ) prop.Value >>= aMigrationItem.m_sCommandURL; else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER ) @@ -886,7 +992,7 @@ void MigrationImpl::compareOldAndNewConfig(const OUString& sParent, for (int n=0; n<nNewCount; ++n) { MigrationItem aMigrationItem; if (xIndexNew->getByIndex(n) >>= aProps) { - for(beans::PropertyValue const & prop : std::as_const(aProps)) { + for(beans::PropertyValue const & prop : aProps) { if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL ) prop.Value >>= aMigrationItem.m_sCommandURL; else if ( prop.Name == ITEM_DESCRIPTOR_CONTAINER ) @@ -941,8 +1047,8 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat OUString sParentNodeName = elem.m_sParentNodeName; sal_Int32 nIndex = 0; do { - OUString sToken = sParentNodeName.getToken(0, '|', nIndex).trim(); - if (sToken.isEmpty()) + std::u16string_view sToken( o3tl::trim(o3tl::getToken(sParentNodeName, 0, '|', nIndex)) ); + if (sToken.empty()) break; sal_Int32 nCount = xTemp->getCount(); @@ -953,7 +1059,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat uno::Sequence< beans::PropertyValue > aPropSeq; xTemp->getByIndex(i) >>= aPropSeq; - for (beans::PropertyValue const & prop : std::as_const(aPropSeq)) { + for (beans::PropertyValue const & prop : aPropSeq) { OUString sPropName = prop.Name; if ( sPropName == ITEM_DESCRIPTOR_COMMANDURL ) prop.Value >>= sCommandURL; @@ -974,13 +1080,13 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat if (nIndex == -1) { auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(elem.m_sCommandURL, sModuleIdentifier); uno::Sequence< beans::PropertyValue > aPropSeq { - beans::PropertyValue(ITEM_DESCRIPTOR_COMMANDURL, 0, uno::makeAny(elem.m_sCommandURL), beans::PropertyState_DIRECT_VALUE), - beans::PropertyValue(ITEM_DESCRIPTOR_LABEL, 0, uno::makeAny(vcl::CommandInfoProvider::GetLabelForCommand(aProperties)), beans::PropertyState_DIRECT_VALUE), - beans::PropertyValue(ITEM_DESCRIPTOR_CONTAINER, 0, uno::makeAny(elem.m_xPopupMenu), beans::PropertyState_DIRECT_VALUE) + beans::PropertyValue(ITEM_DESCRIPTOR_COMMANDURL, 0, uno::Any(elem.m_sCommandURL), beans::PropertyState_DIRECT_VALUE), + beans::PropertyValue(ITEM_DESCRIPTOR_LABEL, 0, uno::Any(vcl::CommandInfoProvider::GetLabelForCommand(aProperties)), beans::PropertyState_DIRECT_VALUE), + beans::PropertyValue(ITEM_DESCRIPTOR_CONTAINER, 0, uno::Any(elem.m_xPopupMenu), beans::PropertyState_DIRECT_VALUE) }; if (elem.m_sPrevSibling.isEmpty()) - xTemp->insertByIndex(0, uno::makeAny(aPropSeq)); + xTemp->insertByIndex(0, uno::Any(aPropSeq)); else { sal_Int32 nCount = xTemp->getCount(); sal_Int32 i = 0; @@ -988,7 +1094,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat OUString sCmd; uno::Sequence< beans::PropertyValue > aTempPropSeq; xTemp->getByIndex(i) >>= aTempPropSeq; - for (beans::PropertyValue const & prop : std::as_const(aTempPropSeq)) { + for (beans::PropertyValue const & prop : aTempPropSeq) { if ( prop.Name == ITEM_DESCRIPTOR_COMMANDURL ) { prop.Value >>= sCmd; break; @@ -999,7 +1105,7 @@ void MigrationImpl::mergeOldToNewVersion(const uno::Reference< ui::XUIConfigurat break; } - xTemp->insertByIndex(i+1, uno::makeAny(aPropSeq)); + xTemp->insertByIndex(i+1, uno::Any(aPropSeq)); } } } @@ -1048,7 +1154,7 @@ uno::Reference< container::XIndexContainer > NewVersionUIInfo::getNewToolbarSett if (newProp.Name == sModuleShortName) { uno::Sequence< beans::PropertyValue > lToolbarSettingsSeq; newProp.Value >>= lToolbarSettingsSeq; - for (auto const & prop : std::as_const(lToolbarSettingsSeq)) { + for (auto const & prop : lToolbarSettingsSeq) { if (prop.Name == sToolbarName) { prop.Value >>= xNewToolbarSettings; break; @@ -1070,8 +1176,8 @@ void NewVersionUIInfo::init(const std::vector< MigrationModuleInfo >& vModulesIn m_lNewVersionToolbarSettingsSeq.realloc(vModulesInfo.size()); auto p_lNewVersionToolbarSettingsSeq = m_lNewVersionToolbarSettingsSeq.getArray(); - static const OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar"); - static const OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/"); + static constexpr OUStringLiteral sMenubarResourceURL(u"private:resource/menubar/menubar"); + static constexpr OUStringLiteral sToolbarResourcePre(u"private:resource/toolbar/"); uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier = ui::theModuleUIConfigurationManagerSupplier::get( ::comphelper::getProcessComponentContext() ); |