diff options
-rw-r--r-- | comphelper/source/misc/backupfilehelper.cxx | 160 | ||||
-rw-r--r-- | include/comphelper/backupfilehelper.hxx | 13 | ||||
-rw-r--r-- | svx/source/dialog/SafeModeDialog.cxx | 34 | ||||
-rw-r--r-- | svx/source/dialog/SafeModeDialog.hxx | 2 | ||||
-rw-r--r-- | svx/uiconfig/ui/safemodedialog.ui | 162 |
5 files changed, 267 insertions, 104 deletions
diff --git a/comphelper/source/misc/backupfilehelper.cxx b/comphelper/source/misc/backupfilehelper.cxx index 4da90b47f743..dd0af8d6709a 100644 --- a/comphelper/source/misc/backupfilehelper.cxx +++ b/comphelper/source/misc/backupfilehelper.cxx @@ -688,7 +688,9 @@ namespace } public: - void createUsingExtensionRegistryEntriesFromXML(const OUString& rUserConfigWorkURL) + void createUsingExtensionRegistryEntriesFromXML( + const OUString& rUserConfigWorkURL, + bool bUser) { // This is looked up for 'user' in the user|shared|bundled deployed Extensions, // only the user ones seem to be able to be de/activated. The ones for user are in @@ -697,13 +699,15 @@ namespace // in safe mode by deleting the uno_packages directory and the shared|bundled // ones by deleting the extensions directory. const OUString aRegPath("/registry/com.sun.star.comp.deployment.bundle.PackageRegistryBackend/backenddb.xml"); - const OUString aUnoPackagReg(rUserConfigWorkURL + "/uno_packages/cache" + aRegPath); + const OUString aExtensionsReg(rUserConfigWorkURL + "/extensions/shared" + aRegPath); + const OUString aUnoPackageReg(rUserConfigWorkURL + "/uno_packages/cache" + aRegPath); + const OUString aPath(bUser ? aUnoPackageReg : aExtensionsReg); - if (fileExists(aUnoPackagReg)) + if (fileExists(aPath)) { uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext(); uno::Reference< xml::dom::XDocumentBuilder > xBuilder(xml::dom::DocumentBuilder::create(xContext)); - uno::Reference< xml::dom::XDocument > aDocument = xBuilder->parseURI(aUnoPackagReg); + uno::Reference< xml::dom::XDocument > aDocument = xBuilder->parseURI(aPath); if (aDocument.is()) { @@ -1911,20 +1915,6 @@ namespace comphelper return bPopPossible; } - bool BackupFileHelper::isPopPossibleExtensionInfo() - { - bool bPopPossible(false); - - if (mbActive && mbExtensions) - { - const OUString aPackURL(getPackURL()); - - bPopPossible = isPopPossible_extensionInfo(aPackURL); - } - - return bPopPossible; - } - bool BackupFileHelper::tryPop() { bool bDidPop(false); @@ -1956,6 +1946,20 @@ namespace comphelper return bDidPop; } + bool BackupFileHelper::isPopPossibleExtensionInfo() + { + bool bPopPossible(false); + + if (mbActive && mbExtensions) + { + const OUString aPackURL(getPackURL()); + + bPopPossible = isPopPossible_extensionInfo(aPackURL); + } + + return bPopPossible; + } + bool BackupFileHelper::tryPopExtensionInfo() { bool bDidPop(false); @@ -1983,7 +1987,7 @@ namespace comphelper // extensions are not loaded from XExtensionManager class ExtensionInfo aExtensionInfo; - aExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL); + aExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL, true); return aExtensionInfo.areThereEnabledExtensions(); } @@ -1997,7 +2001,7 @@ namespace comphelper const ExtensionInfoEntryVector aToBeEnabled; ExtensionInfoEntryVector aToBeDisabled; - aCurrentExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL); + aCurrentExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL, true); const ExtensionInfoEntryVector& rCurrentVector = aCurrentExtensionInfo.getExtensionInfoEntryVector(); @@ -2012,29 +2016,109 @@ namespace comphelper ExtensionInfo::changeEnableDisableStateInXML(maUserConfigWorkURL, aToBeEnabled, aToBeDisabled); } + bool BackupFileHelper::isTryDeinstallUserExtensionsPossible() + { + // check if there are User Extensions installed. + class ExtensionInfo aExtensionInfo; + + aExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL, true); + + return !aExtensionInfo.getExtensionInfoEntryVector().empty(); + } + + void BackupFileHelper::tryDeinstallUserExtensions() + { + // delete User Extension installs + deleteDirRecursively(maUserConfigWorkURL + "/uno_packages"); + } + + bool BackupFileHelper::isTryDeinstallAllExtensionsPossible() + { + // check if there are other Extensions installed (shared|bundled). + class ExtensionInfo aExtensionInfo; + + aExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL, false); + + return !aExtensionInfo.getExtensionInfoEntryVector().empty(); + } + + void BackupFileHelper::tryDeinstallAllExtensions() + { + // delete other Extension installs (shared|bundled) + deleteDirRecursively(maUserConfigWorkURL + "/extensions"); + } + + const std::vector< OUString >& BackupFileHelper::getCustomizationDirNames() + { + static std::vector< OUString > aDirNames; + + if (aDirNames.empty()) + { + aDirNames.push_back("config"); // UI config stuff + aDirNames.push_back("registry"); // most of the registry stuff + aDirNames.push_back("psprint"); // not really needed, can be abandoned + aDirNames.push_back("store"); // not really needed, can be abandoned + aDirNames.push_back("temp"); // not really needed, can be abandoned + aDirNames.push_back("pack"); // own backup dir + } + + return aDirNames; + } + + const std::vector< OUString >& BackupFileHelper::getCustomizationFileNames() + { + static std::vector< OUString > aFileNames; + + if (aFileNames.empty()) + { + aFileNames.push_back("registrymodifications.xcu"); // personal registry stuff + } + + return aFileNames; + } + bool BackupFileHelper::isTryResetCustomizationsPossible() { - // return true if not all of the customization selection dirs are deleted - return - dirExists(maUserConfigWorkURL + "/config") || // UI config stuff - dirExists(maUserConfigWorkURL + "/registry") || // most of the registry stuff - dirExists(maUserConfigWorkURL + "/psprint") || // not really needed, can be abandoned - dirExists(maUserConfigWorkURL + "/store") || // not really needed, can be abandoned - dirExists(maUserConfigWorkURL + "/temp") || // not really needed, can be abandoned - dirExists(maUserConfigWorkURL + "/pack") || // own backup dir - fileExists(maUserConfigWorkURL + "/registrymodifications.xcu"); // personal registry stuff + // return true if not all of the customization selection dirs or files are deleted + const std::vector< OUString >& rDirs = getCustomizationDirNames(); + + for (const auto& a : rDirs) + { + if (dirExists(maUserConfigWorkURL + "/" + a)) + { + return true; + } + } + + const std::vector< OUString >& rFiles = getCustomizationFileNames(); + + for (const auto& b : rFiles) + { + if (fileExists(maUserConfigWorkURL + "/" + b)) + { + return true; + } + } + + return false; } void BackupFileHelper::tryResetCustomizations() { // delete all of the customization selection dirs - deleteDirRecursively(maUserConfigWorkURL + "/config"); - deleteDirRecursively(maUserConfigWorkURL + "/registry"); - deleteDirRecursively(maUserConfigWorkURL + "/psprint"); - deleteDirRecursively(maUserConfigWorkURL + "/store"); - deleteDirRecursively(maUserConfigWorkURL + "/temp"); - deleteDirRecursively(maUserConfigWorkURL + "/pack"); - osl::File::remove(maUserConfigWorkURL + "/registrymodifications.xcu"); + const std::vector< OUString >& rDirs = getCustomizationDirNames(); + + for (const auto& a : rDirs) + { + deleteDirRecursively(maUserConfigWorkURL + "/" + a); + } + + const std::vector< OUString >& rFiles = getCustomizationFileNames(); + + for (const auto& b : rFiles) + { + osl::File::remove(maUserConfigWorkURL + "/" + b); + } } void BackupFileHelper::tryResetUserProfile() @@ -2379,7 +2463,7 @@ namespace comphelper // get current extension info, but from XML config files ExtensionInfo aCurrentExtensionInfo; - aCurrentExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL); + aCurrentExtensionInfo.createUsingExtensionRegistryEntriesFromXML(maUserConfigWorkURL, true); // now we have loaded last_working (aLoadedExtensionInfo) and // current (aCurrentExtensionInfo) ExtensionInfo and may react on @@ -2412,7 +2496,7 @@ namespace comphelper { aToBeDisabled.push_back(rCurrentInfo); } - else if (!bCurrentEnabled && !bLoadedEnabled) + else if (!bCurrentEnabled && bLoadedEnabled) { aToBeEnabled.push_back(rCurrentInfo); } diff --git a/include/comphelper/backupfilehelper.hxx b/include/comphelper/backupfilehelper.hxx index b8250eed1941..8d2161626af2 100644 --- a/include/comphelper/backupfilehelper.hxx +++ b/include/comphelper/backupfilehelper.hxx @@ -17,6 +17,7 @@ #include <osl/file.hxx> #include <memory> #include <set> +#include <vector> namespace comphelper { @@ -156,6 +157,16 @@ namespace comphelper static bool isTryDisableAllExtensionsPossible(); static void tryDisableAllExtensions(); + /** Deinstall all User Extensions (installed for User only) + */ + static bool isTryDeinstallUserExtensionsPossible(); + static void tryDeinstallUserExtensions(); + + /** Deinstall all Extensions (user|shared|bundled) + */ + static bool isTryDeinstallAllExtensionsPossible(); + static void tryDeinstallAllExtensions(); + /** resets User-Customizations like Settings and UserInterface modifications */ static bool isTryResetCustomizationsPossible(); @@ -168,6 +179,8 @@ namespace comphelper private: // internal helper methods static const rtl::OUString getPackURL(); + static const std::vector< OUString >& getCustomizationDirNames(); + static const std::vector< OUString >& getCustomizationFileNames(); // file push helpers bool tryPush_Files(const std::set< OUString >& rDirs, const std::set< std::pair< OUString, OUString > >& rFiles, const OUString& rSourceURL, const OUString& rTargetURL); diff --git a/svx/source/dialog/SafeModeDialog.cxx b/svx/source/dialog/SafeModeDialog.cxx index 2782edb26c19..fe337815fde5 100644 --- a/svx/source/dialog/SafeModeDialog.cxx +++ b/svx/source/dialog/SafeModeDialog.cxx @@ -40,6 +40,8 @@ SafeModeDialog::SafeModeDialog(vcl::Window* pParent) mpCBCheckProfilesafeConfig(), mpCBCheckProfilesafeExtensions(), mpCBDisableAllExtensions(), + mpCBDeinstallUserExtensions(), + mpCBDeinstallAllExtensions(), mpCBResetCustomizations(), mpCBResetWholeUserProfile(), @@ -52,6 +54,8 @@ SafeModeDialog::SafeModeDialog(vcl::Window* pParent) get(mpCBCheckProfilesafeConfig, "check_profilesafe_config"); get(mpCBCheckProfilesafeExtensions, "check_profilesafe_extensions"); get(mpCBDisableAllExtensions, "check_disable_all_extensions"); + get(mpCBDeinstallUserExtensions, "check_deinstall_user_extensions"); + get(mpCBDeinstallAllExtensions, "check_deinstall_all_extensions"); get(mpCBResetCustomizations, "check_reset_customizations"); get(mpCBResetWholeUserProfile, "check_reset_whole_userprofile"); @@ -64,6 +68,8 @@ SafeModeDialog::SafeModeDialog(vcl::Window* pParent) mpCBCheckProfilesafeConfig->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); mpCBCheckProfilesafeExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); mpCBDisableAllExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); + mpCBDeinstallUserExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); + mpCBDeinstallAllExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); mpCBResetCustomizations->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); mpCBResetWholeUserProfile->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl)); @@ -87,11 +93,23 @@ SafeModeDialog::SafeModeDialog(vcl::Window* pParent) mpCBDisableAllExtensions->Disable(); } + if (!comphelper::BackupFileHelper::isTryDeinstallUserExtensionsPossible()) + { + mpCBDeinstallUserExtensions->Disable(); + } + + if (!comphelper::BackupFileHelper::isTryDeinstallAllExtensionsPossible()) + { + mpCBDeinstallAllExtensions->Disable(); + } + if (!comphelper::BackupFileHelper::isTryResetCustomizationsPossible()) { mpCBResetCustomizations->Disable(); } + // no disabe of mpCBResetWholeUserProfile, always possible (as last choice) + // Set URL for help button (module=safemode) OUString sURL("http://hub.libreoffice.org/send-feedback/?LOversion=" + utl::ConfigManager::getAboutBoxProductVersion() + "&LOlocale=" + utl::ConfigManager::getLocale() + "&LOmodule=safemode"); @@ -112,6 +130,8 @@ void SafeModeDialog::dispose() mpCBCheckProfilesafeConfig.clear(); mpCBCheckProfilesafeExtensions.clear(); mpCBDisableAllExtensions.clear(); + mpCBDeinstallUserExtensions.clear(); + mpCBDeinstallAllExtensions.clear(); mpCBResetCustomizations.clear(); mpCBResetWholeUserProfile.clear(); @@ -150,6 +170,18 @@ void SafeModeDialog::applyChanges() comphelper::BackupFileHelper::tryDisableAllExtensions(); } + if (mpCBDeinstallUserExtensions->IsChecked()) + { + // Deinstall all User Extensions (installed for User only) + comphelper::BackupFileHelper::tryDeinstallUserExtensions(); + } + + if (mpCBDeinstallAllExtensions->IsChecked()) + { + // Deinstall all Extensions (user|shared|bundled) + comphelper::BackupFileHelper::tryDeinstallAllExtensions(); + } + if (mpCBResetCustomizations->IsChecked()) { // Reset customizations (Settings and UserInterface modifications) @@ -215,6 +247,8 @@ IMPL_LINK(SafeModeDialog, CheckBoxHdl, CheckBox*, /*pCheckBox*/ ) mpCBCheckProfilesafeConfig->IsChecked() || mpCBCheckProfilesafeExtensions->IsChecked() || mpCBDisableAllExtensions->IsChecked() || + mpCBDeinstallUserExtensions->IsChecked() || + mpCBDeinstallAllExtensions->IsChecked() || mpCBResetCustomizations->IsChecked() || mpCBResetWholeUserProfile->IsChecked()); diff --git a/svx/source/dialog/SafeModeDialog.hxx b/svx/source/dialog/SafeModeDialog.hxx index c1c8d62dbc2b..760573655cf8 100644 --- a/svx/source/dialog/SafeModeDialog.hxx +++ b/svx/source/dialog/SafeModeDialog.hxx @@ -39,6 +39,8 @@ private: VclPtr<CheckBox> mpCBCheckProfilesafeConfig; VclPtr<CheckBox> mpCBCheckProfilesafeExtensions; VclPtr<CheckBox> mpCBDisableAllExtensions; + VclPtr<CheckBox> mpCBDeinstallUserExtensions; + VclPtr<CheckBox> mpCBDeinstallAllExtensions; VclPtr<CheckBox> mpCBResetCustomizations; VclPtr<CheckBox> mpCBResetWholeUserProfile; diff --git a/svx/uiconfig/ui/safemodedialog.ui b/svx/uiconfig/ui/safemodedialog.ui index cfc7e0fcc568..54bbb1e0c7d7 100644 --- a/svx/uiconfig/ui/safemodedialog.ui +++ b/svx/uiconfig/ui/safemodedialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.16.1 --> <interface> <requires lib="gtk+" version="3.12"/> <object class="GtkDialog" id="SafeModeDialog"> @@ -13,71 +13,16 @@ <property name="can_focus">False</property> <property name="orientation">vertical</property> <property name="spacing">12</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area1"> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="btn_continue"> - <property name="label" translatable="yes">_Continue in Safe Mode</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_default">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="btn_quit"> - <property name="label" translatable="yes">_Quit</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="btn_restart"> - <property name="label" translatable="yes">_Make Changes and Restart</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">end</property> - <property name="position">4</property> - </packing> - </child> <child> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="yalign">0</property> <property name="label" translatable="yes">%PRODUCTNAME is now running in Safe Mode. You can make one or more of the following changes to return to a working state. The offered possible changes get more radical from top to bottom, so it is recommended to try them thoroughly one after the other.</property> <property name="wrap">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> </object> <packing> <property name="expand">False</property> @@ -92,7 +37,7 @@ The offered possible changes get more radical from top to bottom, so it is recom <property name="orientation">vertical</property> <child> <object class="GtkCheckButton" id="check_profilesafe_config"> - <property name="label" translatable="yes">Reset UserConfiguration to last known working state</property> + <property name="label" translatable="yes">Restore UserConfiguration to last known working state from backup</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -107,7 +52,7 @@ The offered possible changes get more radical from top to bottom, so it is recom </child> <child> <object class="GtkCheckButton" id="check_profilesafe_extensions"> - <property name="label" translatable="yes">Reset State of installed Extensions to last known working state</property> + <property name="label" translatable="yes">Restore enable/disable State of installed User Extensions to last known working state</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -122,7 +67,7 @@ The offered possible changes get more radical from top to bottom, so it is recom </child> <child> <object class="GtkCheckButton" id="check_disable_all_extensions"> - <property name="label" translatable="yes">Disable all extensions</property> + <property name="label" translatable="yes">Disable all User Extensions</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -136,8 +81,8 @@ The offered possible changes get more radical from top to bottom, so it is recom </packing> </child> <child> - <object class="GtkCheckButton" id="check_reset_customizations"> - <property name="label" translatable="yes">Reset customizations (Settings and User Interface modifications)</property> + <object class="GtkCheckButton" id="check_deinstall_user_extensions"> + <property name="label" translatable="yes">Deinstall all User Extensions</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -151,8 +96,8 @@ The offered possible changes get more radical from top to bottom, so it is recom </packing> </child> <child> - <object class="GtkCheckButton" id="check_reset_whole_userprofile"> - <property name="label" translatable="yes">Reset the whole User Profile</property> + <object class="GtkCheckButton" id="check_deinstall_all_extensions"> + <property name="label" translatable="yes">Deinstall all Extensions (including shared and bundled)</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -165,6 +110,36 @@ The offered possible changes get more radical from top to bottom, so it is recom <property name="position">4</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="check_reset_customizations"> + <property name="label" translatable="yes">Reset User Customizations (Settings, User Interface modifications, AutoCorrect, AutoText, etc.)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="check_reset_whole_userprofile"> + <property name="label" translatable="yes">Reset the whole User Profile to initial state after Installation</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">6</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> @@ -186,10 +161,10 @@ The offered possible changes get more radical from top to bottom, so it is recom <object class="GtkLabel" id="label3"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="xalign">0</property> <property name="label" translatable="yes">If you experience problems that are not resolved by using the Safe Mode, visit the following link to get help or report a bug. You can also include the relevant parts of your User Profile. Beware that it might contain personal data.</property> - <property name="xalign">0</property> </object> <packing> <property name="expand">False</property> @@ -228,6 +203,61 @@ You can also include the relevant parts of your User Profile. Beware that it mig <property name="position">3</property> </packing> </child> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area1"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="btn_continue"> + <property name="label" translatable="yes">_Continue in Safe Mode</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_default">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="btn_quit"> + <property name="label" translatable="yes">_Quit</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="btn_restart"> + <property name="label" translatable="yes">_Make Changes and Restart</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack_type">end</property> + <property name="position">4</property> + </packing> + </child> </object> </child> </object> |