summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--comphelper/source/misc/backupfilehelper.cxx261
-rw-r--r--desktop/source/app/app.cxx64
-rw-r--r--desktop/uiconfig/ui/querytrytorestoreconfigurationdialog.ui37
-rw-r--r--include/comphelper/backupfilehelper.hxx23
-rw-r--r--instsetoo_native/CustomTarget_setup.mk4
-rw-r--r--svx/source/dialog/SafeModeDialog.cxx102
-rw-r--r--svx/source/dialog/SafeModeDialog.hxx14
-rw-r--r--svx/uiconfig/ui/safemodedialog.ui155
8 files changed, 470 insertions, 190 deletions
diff --git a/comphelper/source/misc/backupfilehelper.cxx b/comphelper/source/misc/backupfilehelper.cxx
index 518a5e954b00..dd0c1ef3100b 100644
--- a/comphelper/source/misc/backupfilehelper.cxx
+++ b/comphelper/source/misc/backupfilehelper.cxx
@@ -225,6 +225,18 @@ namespace
return false;
}
+ bool dirExists(const OUString& rDirURL)
+ {
+ if (!rDirURL.isEmpty())
+ {
+ osl::Directory aDirectory(rDirURL);
+
+ return (osl::FileBase::E_None == aDirectory.open());
+ }
+
+ return false;
+ }
+
void scanDirsAndFiles(
const OUString& rDirURL,
std::set< OUString >& rDirs,
@@ -269,6 +281,39 @@ namespace
}
}
}
+
+ bool deleteDirRecursively(const OUString& rDirURL)
+ {
+ std::set< OUString > aDirs;
+ std::set< std::pair< OUString, OUString > > aFiles;
+
+ scanDirsAndFiles(
+ rDirURL,
+ aDirs,
+ aFiles);
+
+ for (const auto& dir : aDirs)
+ {
+ const OUString aNewDirURL(rDirURL + "/" + dir);
+
+ deleteDirRecursively(aNewDirURL);
+ }
+
+ for (const auto& file : aFiles)
+ {
+ OUString aNewFileURL(rDirURL + "/" + file.first);
+
+ if (!file.second.isEmpty())
+ {
+ aNewFileURL += ".";
+ aNewFileURL += file.second;
+ }
+
+ osl::File::remove(aNewFileURL);
+ }
+
+ return osl::FileBase::E_None == osl::Directory::remove(rDirURL);
+ }
}
namespace
@@ -434,6 +479,11 @@ namespace
return true;
}
+
+ bool isEnabled() const
+ {
+ return REGISTERED == meState;
+ }
};
typedef ::std::vector< ExtensionInfoEntry > ExtensionInfoEntryVector;
@@ -578,6 +628,91 @@ namespace
return bRetval;
}
+
+ bool areThereEnabledExtensions() const
+ {
+ for (const auto& a : maEntries)
+ {
+ if (a.isEnabled())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static void disableAll()
+ {
+ // create content from current extension configuration
+ uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< deployment::XExtensionManager > m_xExtensionManager = deployment::ExtensionManager::get(xContext);
+
+ try
+ {
+ xAllPackages = m_xExtensionManager->getAllExtensions(uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >());
+ }
+ catch (const deployment::DeploymentException &)
+ {
+ return;
+ }
+ catch (const ucb::CommandFailedException &)
+ {
+ return;
+ }
+ catch (const ucb::CommandAbortedException &)
+ {
+ return;
+ }
+ catch (const lang::IllegalArgumentException & e)
+ {
+ throw uno::RuntimeException(e.Message, e.Context);
+ }
+
+ for (sal_Int32 i = 0; i < xAllPackages.getLength(); ++i)
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
+
+ for (sal_Int32 j = 0; j < xPackageList.getLength(); ++j)
+ {
+ uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
+
+ if (xPackage.is())
+ {
+ const beans::Optional< beans::Ambiguous< sal_Bool > > option(
+ xPackage->isRegistered(uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >()));
+ bool bEnabled(false);
+
+ if (option.IsPresent)
+ {
+ ::beans::Ambiguous< sal_Bool > const& reg = option.Value;
+
+ if (!reg.IsAmbiguous)
+ {
+ bEnabled = reg.Value;
+ }
+ }
+
+ if (bEnabled)
+ {
+ try
+ {
+ m_xExtensionManager->disableExtension(
+ xPackage,
+ uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >());
+ }
+ catch (const ::ucb::CommandAbortedException &)
+ {
+ }
+ }
+ }
+ }
+ }
+ }
};
}
@@ -1272,7 +1407,7 @@ namespace comphelper
maDirs(),
maFiles(),
mnNumBackups(2),
- mnMode(0),
+ mnMode(1),
mbActive(false),
mbExtensions(true),
mbCompress(true)
@@ -1386,12 +1521,20 @@ namespace comphelper
maUserConfigBaseURL,
aPackURL);
}
+ }
- // Try Push of ExtensionInfo
- if (mbExtensions)
- {
- bDidPush |= tryPush_extensionInfo(aPackURL);
- }
+ return bDidPush;
+ }
+
+ bool BackupFileHelper::tryPushExtensionInfo()
+ {
+ bool bDidPush(false);
+
+ if (mbActive && mbExtensions)
+ {
+ const OUString aPackURL(getPackURL());
+
+ bDidPush = tryPush_extensionInfo(aPackURL);
}
return bDidPush;
@@ -1417,12 +1560,20 @@ namespace comphelper
maUserConfigBaseURL,
aPackURL);
}
+ }
- // try for ExtensionInfo
- if (mbExtensions)
- {
- bPopPossible |= isPopPossible_extensionInfo(aPackURL);
- }
+ return bPopPossible;
+ }
+
+ bool BackupFileHelper::isPopPossibleExtensionInfo()
+ {
+ bool bPopPossible(false);
+
+ if (mbActive && mbExtensions)
+ {
+ const OUString aPackURL(getPackURL());
+
+ bPopPossible = isPopPossible_extensionInfo(aPackURL);
}
return bPopPossible;
@@ -1449,11 +1600,25 @@ namespace comphelper
aPackURL);
}
- // try for ExtensionInfo
- if (mbExtensions)
+ if (bDidPop)
{
- bDidPop |= tryPop_extensionInfo(aPackURL);
+ // try removal of evtl. empty directory
+ osl::Directory::remove(aPackURL);
}
+ }
+
+ return bDidPop;
+ }
+
+ bool BackupFileHelper::tryPopExtensionInfo()
+ {
+ bool bDidPop(false);
+
+ if (mbActive && mbExtensions)
+ {
+ const OUString aPackURL(getPackURL());
+
+ bDidPop = tryPop_extensionInfo(aPackURL);
if (bDidPop)
{
@@ -1465,6 +1630,53 @@ namespace comphelper
return bDidPop;
}
+ bool BackupFileHelper::isTryDisableAllExtensionsPossible()
+ {
+ // return true if there is an eabled extension that can be disabled
+ ExtensionInfo aCurrentExtensionInfo;
+
+ aCurrentExtensionInfo.createCurrent();
+ return aCurrentExtensionInfo.areThereEnabledExtensions();
+ }
+
+ void BackupFileHelper::tryDisableAllExtensions()
+ {
+ // disable all still enabled extensions. No need to
+ // createCurrent() again, just do it now
+ ExtensionInfo::disableAll();
+ }
+
+ bool BackupFileHelper::isTryResetCustomizationsPossible()
+ {
+ // return true if not all of the customization selection dirs are deleted
+ return
+ dirExists(maUserConfigBaseURL + "/config") || // UI config stuff
+ dirExists(maUserConfigBaseURL + "/registry") || // most of the registry stuff
+ dirExists(maUserConfigBaseURL + "/psprint") || // not really needed, can be abandoned
+ dirExists(maUserConfigBaseURL + "/store") || // not really needed, can be abandoned
+ dirExists(maUserConfigBaseURL + "/temp") || // not really needed, can be abandoned
+ dirExists(maUserConfigBaseURL + "/pack") || // own backup dir
+ fileExists(maUserConfigBaseURL + "/registrymodifications.xcu"); // personal registry stuff
+ }
+
+ void BackupFileHelper::tryResetCustomizations()
+ {
+ // delete all of the customization selection dirs
+ deleteDirRecursively(maUserConfigBaseURL + "/config");
+ deleteDirRecursively(maUserConfigBaseURL + "/registry");
+ deleteDirRecursively(maUserConfigBaseURL + "/psprint");
+ deleteDirRecursively(maUserConfigBaseURL + "/store");
+ deleteDirRecursively(maUserConfigBaseURL + "/temp");
+ deleteDirRecursively(maUserConfigBaseURL + "/pack");
+ osl::File::remove(maUserConfigBaseURL + "/registrymodifications.xcu");
+ }
+
+ void BackupFileHelper::tryResetUserProfile()
+ {
+ // completely delete the current UserProfile
+ deleteDirRecursively(maUserConfigBaseURL);
+ }
+
/////////////////// helpers ///////////////////////
const rtl::OUString BackupFileHelper::getPackURL() const
@@ -1839,25 +2051,29 @@ namespace comphelper
return;
}
+ // Information about the configuration and the role/purpose of directories in
+ // the UserConfiguration is taken from: https://wiki.documentfoundation.org/UserProfile
+
// fill dir and file info list to work with dependent on work mode
switch (mnMode)
{
case 0:
{
- // add registrymodifications (the orig file in maInitialBaseURL)
+ // simple mode: add just registrymodifications
+ // (the orig file in maInitialBaseURL)
maFiles.insert(std::pair< OUString, OUString >(maRegModName, maExt));
break;
}
case 1:
{
- // add registrymodifications (the orig file in maInitialBaseURL)
- maFiles.insert(std::pair< OUString, OUString >(maRegModName, maExt));
-
- // Add a selection of dirs containing User-Defined and thus
- // valuable configuration information (see https://wiki.documentfoundation.org/UserProfile).
+ // defined mode: Add a selection of dirs containing User-Defined and thus
+ // valuable configuration information.
// This is clearly discussable in every single point and may be adapted/corrected
// over time. Main focus is to secure User-Defined/adapted values
+ // add registrymodifications (the orig file in maInitialBaseURL)
+ maFiles.insert(std::pair< OUString, OUString >(maRegModName, maExt));
+
// User-defined substitution table (Tools/AutoCorrect)
maDirs.insert("autocorr");
@@ -1891,6 +2107,7 @@ namespace comphelper
// Questionable - where and how is Extension stuff held and how
// does this interact with enabled/disabled states which are extra handled?
// Keep out of business until deeper evaluated
+ //
// maDirs.insert("extensions");
// maDirs.insert("uno-packages");
break;
@@ -1913,6 +2130,10 @@ namespace comphelper
// not really needed, can be abandoned
maDirs.erase("temp");
+
+ // exclude own backup dir to avoid recursion
+ maDirs.erase("pack");
+
break;
}
}
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index cd3fbfa96326..6be6d6139bfa 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -951,64 +951,23 @@ void Desktop::HandleBootstrapErrors(
}
else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
{
- bool bFireOriginalError(true);
- comphelper::BackupFileHelper aBackupFileHelper;
-
- // crerate BackupFileHelper and check if active and if pop is possible
- if (aBackupFileHelper.isPopPossible())
- {
- // for linux (and probably others?) we need to instantiate XDesktop2
- // to be able to open a *.ui-file based dialog, so do this here locally.
- // does no harm on win, so better always do this (in error case only anyways)
- Reference< XComponentContext > xLocalContext = ::comphelper::getProcessComponentContext();
- Reference< XDesktop2 > xDesktop = css::frame::Desktop::create(xLocalContext);
-
- ScopedVclPtrInstance< MessageDialog > aQueryShouldRestore(
- Application::GetDefDialogParent(),
- "QueryTryToRestoreConfigurationDialog",
- "desktop/ui/querytrytorestoreconfigurationdialog.ui");
-
- if (aQueryShouldRestore.get())
- {
- if (!aErrorMessage.isEmpty())
- {
- OUString aPrimaryText(aQueryShouldRestore->get_primary_text());
-
- aPrimaryText += "\n(\"" + aErrorMessage + "\")";
- aQueryShouldRestore->set_primary_text(aPrimaryText);
- }
-
- if (RET_YES == aQueryShouldRestore->Execute())
- {
- aBackupFileHelper.tryPop();
- bFireOriginalError = false;
- }
- }
- }
-
// set flag at BackupFileHelper to be able to know if _exit was called and
// actions are executed after this. This method we are in will not return,
// but end up in a _exit() call
comphelper::BackupFileHelper::setExitWasCalled();
- if (bFireOriginalError)
- {
- OUString msg(
- GetMsgString(
- STR_CONFIG_ERR_ACCESS_GENERAL,
- ("A general error occurred while accessing your central"
- " configuration.")));
- if (!aErrorMessage.isEmpty()) {
- msg += "\n(\"" + aErrorMessage + "\")";
- }
- FatalError(MakeStartupErrorMessage(msg));
- }
- else
- {
- // Already presented all information to the user.
- // just do what FatalError does at it's end
- _exit(EXITHELPER_FATAL_ERROR);
+ // enter safe mode, too
+ sfx2::SafeMode::putFlag();
+
+ OUString msg(
+ GetMsgString(
+ STR_CONFIG_ERR_ACCESS_GENERAL,
+ ("A general error occurred while accessing your central"
+ " configuration. SafeMode is initiated.")));
+ if (!aErrorMessage.isEmpty()) {
+ msg += "\n(\"" + aErrorMessage + "\")";
}
+ FatalError(MakeStartupErrorMessage(msg));
}
else if ( aBootstrapError == BE_USERINSTALL_FAILED )
{
@@ -1824,6 +1783,7 @@ int Desktop::doShutdown()
comphelper::BackupFileHelper aBackupFileHelper;
aBackupFileHelper.tryPush();
+ aBackupFileHelper.tryPushExtensionInfo();
}
// The acceptors in the AcceptorMap must be released (in DeregisterServices)
diff --git a/desktop/uiconfig/ui/querytrytorestoreconfigurationdialog.ui b/desktop/uiconfig/ui/querytrytorestoreconfigurationdialog.ui
deleted file mode 100644
index 4c332d1889d6..000000000000
--- a/desktop/uiconfig/ui/querytrytorestoreconfigurationdialog.ui
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <!-- interface-requires gtk+ 3.0 -->
- <object class="GtkMessageDialog" id="QueryTryToRestoreConfigurationDialog">
- <property name="can_focus">False</property>
- <property name="border_width">6</property>
- <property name="title" translatable="yes">LibreOffice Startup: General Configuration Error</property>
- <property name="resizable">False</property>
- <property name="type_hint">dialog</property>
- <property name="skip_taskbar_hint">True</property>
- <property name="message_type">question</property>
- <property name="buttons">yes-no</property>
- <property name="text" translatable="yes">A general error occurred during startup while accessing the central configuration.</property>
- <property name="secondary_text" translatable="yes">A Backup of your configuration was detected. Restoring the configuration might solve this problem, but is not guaranteed to work. A restart of the Program is needed.
-
-Do you want to restore the configuration?</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="messagedialog-vbox5">
- <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="messagedialog-action_area5">
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff --git a/include/comphelper/backupfilehelper.hxx b/include/comphelper/backupfilehelper.hxx
index b1913f901822..24978c7a8706 100644
--- a/include/comphelper/backupfilehelper.hxx
+++ b/include/comphelper/backupfilehelper.hxx
@@ -106,15 +106,21 @@ namespace comphelper
*
* @return bool
* returns true if a new backup was actually created
+ *
+ * tryPushExtensionInfo is the specialized version for ExtensionInfo
*/
bool tryPush();
+ bool tryPushExtensionInfo();
/** finds out if a restore is possible
*
* @return bool
* returns true if a restore to an older backup is possible
+ *
+ * isPopPossibleExtensionInfo is the specialized version for ExtensionInfo
*/
bool isPopPossible();
+ bool isPopPossibleExtensionInfo();
/** tries to execute a restore. Will overwrite the base file
* in that case and take one version off the 'stack' of copies.
@@ -123,8 +129,25 @@ namespace comphelper
*
* @return bool
* returns true if a restore was actually created
+ *
+ * tryPopExtensionInfo is the specialized version for ExtensionInfo
*/
bool tryPop();
+ bool tryPopExtensionInfo();
+
+ /** tries to iterate the extensions and to disable all of them
+ */
+ static bool isTryDisableAllExtensionsPossible();
+ static void tryDisableAllExtensions();
+
+ /** resets User-Customizations like Settings and UserInterface modifications
+ */
+ bool isTryResetCustomizationsPossible();
+ void tryResetCustomizations();
+
+ /** resets the whole UserProfile
+ */
+ void tryResetUserProfile();
private:
// internal helper methods
diff --git a/instsetoo_native/CustomTarget_setup.mk b/instsetoo_native/CustomTarget_setup.mk
index 5ce472632cdf..2b9429c3c9f6 100644
--- a/instsetoo_native/CustomTarget_setup.mk
+++ b/instsetoo_native/CustomTarget_setup.mk
@@ -108,7 +108,7 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
# SecureUserConfig : boolean - switches securing on/off - default false
# SecureUserConfigCompress : boolean - defines if backup data will be compressed - default true
# SecureUserConfigNumCopies : integer - defines how many compressed copies of saved content will be kept - default 2
-# SecureUserConfigMode: integer - defines what to secure, default is 0
+# SecureUserConfigMode: integer - defines what to secure, default is 1
# 0 : only registrymodifications.xcu
# 1 : a selected amount of user-defined configs
# 2 : everything in the user config directory
@@ -131,7 +131,7 @@ $(call gb_CustomTarget_get_workdir,instsetoo_native/setup)/$(call gb_Helper_get_
&& echo 'SecureUserConfig=true' \
&& echo 'SecureUserConfigCompress=true' \
&& echo 'SecureUserConfigNumCopies=2' \
- && echo 'SecureUserConfigMode=0' \
+ && echo 'SecureUserConfigMode=1' \
&& echo 'SecureUserConfigExtensions=true' \
) > $@
diff --git a/svx/source/dialog/SafeModeDialog.cxx b/svx/source/dialog/SafeModeDialog.cxx
index 53d99119e51d..a2e6ca2c3cfa 100644
--- a/svx/source/dialog/SafeModeDialog.cxx
+++ b/svx/source/dialog/SafeModeDialog.cxx
@@ -22,26 +22,63 @@
using namespace css;
-SafeModeDialog::SafeModeDialog(vcl::Window* pParent):
- Dialog(pParent, "SafeModeDialog", "svx/ui/safemodedialog.ui")
+SafeModeDialog::SafeModeDialog(vcl::Window* pParent)
+: Dialog(pParent, "SafeModeDialog", "svx/ui/safemodedialog.ui"),
+
+ mpBtnContinue(),
+ mpBtnQuit(),
+ mpBtnRestart(),
+
+ mpCBCheckProfilesafeConfig(),
+ mpCBCheckProfilesafeExtensions(),
+ mpCBDisableAllExtensions(),
+ mpCBResetCustomizations(),
+ mpCBResetWholeUserProfile(),
+
+ maBackupFileHelper()
{
get(mpBtnContinue, "btn_continue");
get(mpBtnQuit, "btn_quit");
get(mpBtnRestart, "btn_restart");
- get(mpCBCustomizations, "check_customizations");
- get(mpCBExtensions, "check_extensions");
- get(mpCBFull, "check_full");
+
+ get(mpCBCheckProfilesafeConfig, "check_profilesafe_config");
+ get(mpCBCheckProfilesafeExtensions, "check_profilesafe_extensions");
+ get(mpCBDisableAllExtensions, "check_disable_all_extensions");
+ get(mpCBResetCustomizations, "check_reset_customizations");
+ get(mpCBResetWholeUserProfile, "check_reset_whole_userprofile");
mpBtnContinue->SetClickHdl(LINK(this, SafeModeDialog, BtnHdl));
mpBtnQuit->SetClickHdl(LINK(this, SafeModeDialog, BtnHdl));
mpBtnRestart->SetClickHdl(LINK(this, SafeModeDialog, BtnHdl));
- mpCBCustomizations->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
- mpCBExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
- mpCBFull->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
+ mpCBCheckProfilesafeConfig->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
+ mpCBCheckProfilesafeExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
+ mpCBDisableAllExtensions->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
+ mpCBResetCustomizations->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
+ mpCBResetWholeUserProfile->SetToggleHdl(LINK(this, SafeModeDialog, CheckBoxHdl));
// Disable restart btn until some checkbox is active
mpBtnRestart->Disable();
+
+ if (!maBackupFileHelper.isPopPossible())
+ {
+ mpCBCheckProfilesafeConfig->Disable();
+ }
+
+ if (!maBackupFileHelper.isPopPossibleExtensionInfo())
+ {
+ mpCBCheckProfilesafeExtensions->Disable();
+ }
+
+ if (comphelper::BackupFileHelper::isTryDisableAllExtensionsPossible())
+ {
+ mpCBDisableAllExtensions->Disable();
+ }
+
+ if (maBackupFileHelper.isTryResetCustomizationsPossible())
+ {
+ mpCBResetCustomizations->Disable();
+ }
}
SafeModeDialog::~SafeModeDialog()
@@ -54,9 +91,12 @@ void SafeModeDialog::dispose()
mpBtnContinue.clear();
mpBtnQuit.clear();
mpBtnRestart.clear();
- mpCBCustomizations.clear();
- mpCBExtensions.clear();
- mpCBFull.clear();
+
+ mpCBCheckProfilesafeConfig.clear();
+ mpCBCheckProfilesafeExtensions.clear();
+ mpCBDisableAllExtensions.clear();
+ mpCBResetCustomizations.clear();
+ mpCBResetWholeUserProfile.clear();
Dialog::dispose();
}
@@ -80,7 +120,37 @@ void SafeModeDialog::terminateOffice()
void SafeModeDialog::applyChanges()
{
- // TODO: Apply apply changes
+ if (mpCBCheckProfilesafeConfig->IsChecked())
+ {
+ // reset UserConfiguration to last known working state
+ // ProfileSafeMode/BackupFileHelper
+ maBackupFileHelper.tryPop();
+ }
+
+ if (mpCBCheckProfilesafeExtensions->IsChecked())
+ {
+ // reset State of installed Extensions to last known working state
+ // ProfileSafeMode/BackupFileHelper
+ maBackupFileHelper.tryPopExtensionInfo();
+ }
+
+ if (mpCBDisableAllExtensions->IsChecked())
+ {
+ // Disable all extensions
+ comphelper::BackupFileHelper::tryDisableAllExtensions();
+ }
+
+ if (mpCBResetCustomizations->IsChecked())
+ {
+ // Reset customizations (Settings and UserInterface modifications)
+ maBackupFileHelper.tryResetCustomizations();
+ }
+
+ if (mpCBResetWholeUserProfile->IsChecked())
+ {
+ // Reset the whole UserProfile
+ maBackupFileHelper.tryResetUserProfile();
+ }
// Then restart
css::task::OfficeRestartManager::get(comphelper::getProcessComponentContext())->requestRestart(
@@ -106,7 +176,13 @@ IMPL_LINK(SafeModeDialog, BtnHdl, Button*, pBtn, void)
IMPL_LINK(SafeModeDialog, CheckBoxHdl, CheckBox&, /*pCheckBox*/, void)
{
- bool bEnable = mpCBCustomizations->IsChecked() || mpCBExtensions->IsChecked() || mpCBFull->IsChecked();
+ const bool bEnable(
+ mpCBCheckProfilesafeConfig->IsChecked() ||
+ mpCBCheckProfilesafeExtensions->IsChecked() ||
+ mpCBDisableAllExtensions->IsChecked() ||
+ mpCBResetCustomizations->IsChecked() ||
+ mpCBResetWholeUserProfile->IsChecked());
+
mpBtnRestart->Enable(bEnable);
}
diff --git a/svx/source/dialog/SafeModeDialog.hxx b/svx/source/dialog/SafeModeDialog.hxx
index dd0036ef7e19..6f2e4af6d600 100644
--- a/svx/source/dialog/SafeModeDialog.hxx
+++ b/svx/source/dialog/SafeModeDialog.hxx
@@ -15,6 +15,7 @@
#include <vcl/fixed.hxx>
#include <vcl/edit.hxx>
#include <vcl/vclmedit.hxx>
+#include <comphelper/backupfilehelper.hxx>
class SafeModeDialog : public Dialog
{
@@ -34,12 +35,17 @@ private:
VclPtr<Button> mpBtnQuit;
VclPtr<Button> mpBtnRestart;
- VclPtr<CheckBox> mpCBExtensions;
- VclPtr<CheckBox> mpCBCustomizations;
- VclPtr<CheckBox> mpCBFull;
+ VclPtr<CheckBox> mpCBCheckProfilesafeConfig;
+ VclPtr<CheckBox> mpCBCheckProfilesafeExtensions;
+ VclPtr<CheckBox> mpCBDisableAllExtensions;
+ VclPtr<CheckBox> mpCBResetCustomizations;
+ VclPtr<CheckBox> mpCBResetWholeUserProfile;
+
+ // local BackupFileHelper for handling possible restores
+ comphelper::BackupFileHelper maBackupFileHelper;
static void terminateOffice();
- static void applyChanges();
+ void applyChanges();
DECL_LINK(CheckBoxHdl, CheckBox&, void);
DECL_LINK(BtnHdl, Button*, void);
diff --git a/svx/uiconfig/ui/safemodedialog.ui b/svx/uiconfig/ui/safemodedialog.ui
index 8ac77b2c7400..a1a352addc47 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,123 +13,153 @@
<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">
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="layout_style">end</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>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkButton" id="btn_continue">
- <property name="label" translatable="yes">_Continue in Safe Mode</property>
+ <object class="GtkCheckButton" id="check_profilesafe_config">
+ <property name="label" translatable="yes">Reset UserConfiguration to last known working state</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>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</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>
+ <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="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</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>
+ <object class="GtkCheckButton" id="check_disable_all_extensions">
+ <property name="label" translatable="yes">Disable all extensions</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="check_reset_customizations">
+ <property name="label" translatable="yes">Reset customizations (Settings and User Interface modifications)</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">3</property>
</packing>
</child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</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="label" translatable="yes">%PRODUCTNAME is now running in Safe Mode, which temporarily disables your custom settings and extensions.
-
-You can make some or all these changes permanent:</property>
- <property name="wrap">True</property>
- <property name="xalign">0</property>
- <property name="yalign">0</property>
+ <child>
+ <object class="GtkCheckButton" id="check_reset_whole_userprofile">
+ <property name="label" translatable="yes">Reset the whole User Profile</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">4</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkBox" id="box1">
- <property name="visible">True</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <property name="layout_style">end</property>
<child>
- <object class="GtkCheckButton" id="check_extensions">
- <property name="label" translatable="yes">Disable all extensions</property>
+ <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="receives_default">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">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">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="check_customizations">
- <property name="label" translatable="yes">Reset customizations (Settings and User Interface modifications)</property>
+ <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">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="check_full">
- <property name="label" translatable="yes">Reset the whole User Profile</property>
+ <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">False</property>
- <property name="xalign">0</property>
- <property name="draw_indicator">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
</object>
<packing>
- <property name="expand">False</property>
+ <property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
@@ -137,8 +167,9 @@ You can make some or all these changes permanent:</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">4</property>
</packing>
</child>
</object>