From 6a6cd129f34220fadf5d134a2dc2c1e368acbc4f Mon Sep 17 00:00:00 2001 From: Matt K Date: Thu, 25 Mar 2021 00:40:33 -0500 Subject: tdf#45735 New UI dialog at app startup to check default file formats On Windows only, and only on a non-admin installation, check on application startup whether the file formats ".ods", ".odt", and ".odp" are registered to be opened by LibreOffice by default. If any of the formats are not default, show a UI dialog informing the user which formats are not default and ask the user to set the defaults. If the user selects "OK" to set defaults then the Windows UI corresponding to the user's Windows version is opened for selecting defaults per program. There is also a checkbox on the dialog to select whether checking is performed on application startup. Also, in Tools -> Options -> General, add a UI checkbox for performing this check on application startup, and refactor the existing button "Windows Default apps" to use the same Windows UI Launch APIs. Change-Id: I5e7258d111ff7da8f68805e60405aec064ddcf7c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112370 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- cui/Library_cui.mk | 5 +- cui/UIConfig_cui.mk | 6 + cui/source/dialogs/fileextcheckdlg.cxx | 55 ++++++ cui/source/factory/dlgfact.cxx | 11 ++ cui/source/factory/dlgfact.hxx | 6 + cui/source/inc/fileextcheckdlg.hxx | 39 ++++ cui/source/options/optgdlg.cxx | 43 ++--- cui/source/options/optgdlg.hxx | 1 + cui/uiconfig/ui/fileextcheckdialog.ui | 109 ++++++++++++ cui/uiconfig/ui/optgeneralpage.ui | 15 ++ desktop/source/app/app.cxx | 10 ++ include/vcl/abstdlg.hxx | 6 + include/vcl/fileregistration.hxx | 21 +++ .../registry/data/org/openoffice/Office/Common.xcu | 3 + .../schema/org/openoffice/Office/Common.xcs | 7 + solenv/sanitizers/ui/cui.suppr | 1 + vcl/Library_vcl.mk | 1 + vcl/inc/strings.hrc | 3 + vcl/win/app/fileregistration.cxx | 198 +++++++++++++++++++++ 19 files changed, 514 insertions(+), 26 deletions(-) create mode 100644 cui/source/dialogs/fileextcheckdlg.cxx create mode 100644 cui/source/inc/fileextcheckdlg.hxx create mode 100644 cui/uiconfig/ui/fileextcheckdialog.ui create mode 100644 include/vcl/fileregistration.hxx create mode 100644 vcl/win/app/fileregistration.cxx diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index f2df06cc5f2c..d6fa68e0d194 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -85,7 +85,10 @@ ifeq ($(OS),WNT) $(eval $(call gb_Library_use_system_win32_libs,cui,\ advapi32 \ shlwapi \ - ole32 \ +)) + +$(eval $(call gb_Library_add_exception_objects,cui,\ + cui/source/dialogs/fileextcheckdlg \ )) endif diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk index 153d6fe98fda..ff3c718b21d6 100644 --- a/cui/UIConfig_cui.mk +++ b/cui/UIConfig_cui.mk @@ -9,6 +9,12 @@ $(eval $(call gb_UIConfig_UIConfig,cui)) +ifeq ($(OS),WNT) +$(eval $(call gb_UIConfig_add_uifiles,cui,\ + cui/uiconfig/ui/fileextcheckdialog \ +)) +endif + $(eval $(call gb_UIConfig_add_uifiles,cui,\ cui/uiconfig/ui/aboutdialog \ cui/uiconfig/ui/aboutconfigdialog\ diff --git a/cui/source/dialogs/fileextcheckdlg.cxx b/cui/source/dialogs/fileextcheckdlg.cxx new file mode 100644 index 000000000000..732f8367436a --- /dev/null +++ b/cui/source/dialogs/fileextcheckdlg.cxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include +#include + +#include + +FileExtCheckDialog::FileExtCheckDialog(weld::Window* pParent, const OUString& sTitle, + const OUString& sMsg) + : GenericDialogController(pParent, "cui/ui/fileextcheckdialog.ui", "FileExtCheckDialog") + , m_pText(m_xBuilder->weld_label("lbText")) + , m_pPerformCheck(m_xBuilder->weld_check_button("cbPerformCheck")) + , m_pOk(m_xBuilder->weld_button("btnOk")) +{ + m_pPerformCheck->set_active(true); + m_pOk->connect_clicked(LINK(this, FileExtCheckDialog, OnOkClick)); + m_xDialog->set_title(sTitle); + m_pText->set_label(sMsg); +} + +FileExtCheckDialog::~FileExtCheckDialog() +{ + std::shared_ptr xChanges( + comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::Misc::PerformFileExtCheck::set(m_pPerformCheck->get_active(), + xChanges); + xChanges->commit(); +} + +IMPL_LINK_NOARG(FileExtCheckDialog, OnOkClick, weld::Button&, void) +{ + vcl::fileregistration::LaunchRegistrationUI(); + FileExtCheckDialog::response(RET_OK); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index d371224ffa20..25f2c6f124af 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -90,6 +90,7 @@ #include #include #include +#include using namespace ::com::sun::star; using namespace ::com::sun::star::frame; @@ -1699,4 +1700,14 @@ AbstractDialogFactory_Impl::CreateDiagramDialog(weld::Window* pParent, std::shar std::make_unique(pParent, pDiagramData)); } +#ifdef _WIN32 +VclPtr +AbstractDialogFactory_Impl::CreateFileExtCheckDialog(weld::Window* pParent, const OUString& sTitle, + const OUString& sMsg) +{ + return VclPtr::Create( + std::make_unique(pParent, sTitle, sMsg)); +} +#endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx index 7d97167193b8..2d7afbe6f6a1 100644 --- a/cui/source/factory/dlgfact.hxx +++ b/cui/source/factory/dlgfact.hxx @@ -945,6 +945,12 @@ public: virtual VclPtr CreateDiagramDialog( weld::Window* pParent, std::shared_ptr pDiagramData) override; + +#ifdef _WIN32 + virtual VclPtr CreateFileExtCheckDialog(weld::Window* pParent, + const OUString& sTitle, + const OUString& sMsg) override; +#endif }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/inc/fileextcheckdlg.hxx b/cui/source/inc/fileextcheckdlg.hxx new file mode 100644 index 000000000000..968deae77177 --- /dev/null +++ b/cui/source/inc/fileextcheckdlg.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include + +#include + +class FileExtCheckDialog : public weld::GenericDialogController +{ +private: + std::unique_ptr m_pText; + std::unique_ptr m_pPerformCheck; + std::unique_ptr m_pOk; + + DECL_LINK(OnOkClick, weld::Button&, void); + +public: + FileExtCheckDialog(weld::Window* pWindow, const OUString& sTitle, const OUString& sMsg); + virtual ~FileExtCheckDialog() override; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx index 673815bb60ab..7ec04487d5c0 100644 --- a/cui/source/options/optgdlg.cxx +++ b/cui/source/options/optgdlg.cxx @@ -86,11 +86,7 @@ #include #if defined(_WIN32) -#include -#include -#include -#include -#include +#include #endif using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -177,6 +173,7 @@ OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* p #endif #if defined(_WIN32) , m_xFileAssocFrame(m_xBuilder->weld_widget("fileassoc")) + , m_xPerformFileExtCheck(m_xBuilder->weld_check_button("cbPerformFileExtCheck")) , m_xFileAssocBtn(m_xBuilder->weld_button("assocfiles")) #endif { @@ -288,6 +285,15 @@ bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet ) } #endif +#if defined(_WIN32) + if (m_xPerformFileExtCheck->get_state_changed_from_saved()) + { + officecfg::Office::Common::Misc::PerformFileExtCheck::set( + m_xPerformFileExtCheck->get_active(), batch); + bModified = true; + } +#endif + batch->commit(); if( m_xQuickLaunchCB->get_state_changed_from_saved()) @@ -347,6 +353,12 @@ void OfaMiscTabPage::Reset( const SfxItemSet* rSet ) } m_xQuickLaunchCB->save_state(); + +#if defined(_WIN32) + m_xPerformFileExtCheck->set_active( + officecfg::Office::Common::Misc::PerformFileExtCheck::get()); + m_xPerformFileExtCheck->save_state(); +#endif } IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void ) @@ -367,26 +379,7 @@ IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void ) #if defined(_WIN32) IMPL_STATIC_LINK_NOARG(OfaMiscTabPage, FileAssocClick, weld::Button&, void) { - const bool bUninit = SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)); - try - { - auto pIf - = sal::systools::COMReference().CoCreateInstance( - CLSID_ApplicationAssociationRegistrationUI, nullptr, CLSCTX_INPROC_SERVER); - - // LaunchAdvancedAssociationUI only works for applications registered under - // Software\RegisteredApplications. See scp2/source/ooo/registryitem_ooo.scp - const OUString expanded = Translate::ExpandVariables("%PRODUCTNAME %PRODUCTVERSION"); - // This will only show "To change your default apps, go to Settings > Apps > Default apps" - // on Win10; this is expected. At least this will self-document it to users. - pIf->LaunchAdvancedAssociationUI(o3tl::toW(expanded.getStr())); - } - catch (...) - { - // Just ignore any error here: this is not something we need to make sure to succeed - } - if (bUninit) - CoUninitialize(); + vcl::fileregistration::LaunchRegistrationUI(); } #endif diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx index 07d3cca86fb7..d9a55ced7fb1 100644 --- a/cui/source/options/optgdlg.hxx +++ b/cui/source/options/optgdlg.hxx @@ -52,6 +52,7 @@ private: #if defined(_WIN32) std::unique_ptr m_xFileAssocFrame; std::unique_ptr m_xFileAssocBtn; + std::unique_ptr m_xPerformFileExtCheck; #endif DECL_LINK(TwoFigureHdl, weld::SpinButton&, void); diff --git a/cui/uiconfig/ui/fileextcheckdialog.ui b/cui/uiconfig/ui/fileextcheckdialog.ui new file mode 100644 index 000000000000..c5661134ca20 --- /dev/null +++ b/cui/uiconfig/ui/fileextcheckdialog.ui @@ -0,0 +1,109 @@ + + + + + + False + 6 + + False + True + center-on-parent + dialog + + + False + vertical + 12 + + + False + True + end + + + _Perform check on startup + True + True + False + Enable the dialog again at Tools > Options > General + True + True + True + + + True + True + 0 + True + + + + + _Cancel + True + True + True + True + + + True + True + 1 + + + + + _OK + True + True + True + True + True + True + True + True + + + False + True + 2 + + + + + False + True + end + 0 + + + + + True + False + True + True + 50 + 50 + + + False + True + 0 + + + + + + btnCancel + + + diff --git a/cui/uiconfig/ui/optgeneralpage.ui b/cui/uiconfig/ui/optgeneralpage.ui index 3380a2f228af..5f502977f26e 100644 --- a/cui/uiconfig/ui/optgeneralpage.ui +++ b/cui/uiconfig/ui/optgeneralpage.ui @@ -15,6 +15,7 @@ False 6 12 + True True @@ -453,6 +454,20 @@ 0 + + + Perform check for default file associations on start-up + True + True + False + True + True + + + 0 + 1 + + diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index 90a98d0506b0..8b4d7b34f4d4 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -131,6 +131,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include +#include #endif #if defined(_WIN32) @@ -1893,6 +1894,15 @@ IMPL_LINK_NOARG(Desktop, OpenClients_Impl, void*, void) CloseSplashScreen(); CheckFirstRun( ); #ifdef _WIN32 + bool bDontShowDialogs + = Application::IsHeadlessModeEnabled(); // uitest.uicheck fails when the dialog is open + for (sal_uInt16 i = 0; !bDontShowDialogs && i < Application::GetCommandLineParamCount(); i++) + { + if (Application::GetCommandLineParam(i) == "--nologo") + bDontShowDialogs = true; + } + if (!bDontShowDialogs) + vcl::fileregistration::CheckFileExtRegistration(SfxGetpApp()->GetTopWindow()); // Registers a COM class factory of the service manager with the windows operating system. Reference< XMultiServiceFactory > xSMgr= comphelper::getProcessServiceFactory(); xSMgr->createInstance("com.sun.star.bridge.OleApplicationRegistration"); diff --git a/include/vcl/abstdlg.hxx b/include/vcl/abstdlg.hxx index 2a58f6af7355..52212f482253 100644 --- a/include/vcl/abstdlg.hxx +++ b/include/vcl/abstdlg.hxx @@ -180,6 +180,12 @@ public: virtual VclPtr CreateDiagramDialog( weld::Window* pParent, std::shared_ptr pDiagramData) = 0; + +#ifdef _WIN32 + virtual VclPtr + CreateFileExtCheckDialog(weld::Window* _pParent, const OUString& sTitle, const OUString& sMsg) + = 0; +#endif }; #endif diff --git a/include/vcl/fileregistration.hxx b/include/vcl/fileregistration.hxx new file mode 100644 index 000000000000..3dd16f728cc9 --- /dev/null +++ b/include/vcl/fileregistration.hxx @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include + +namespace vcl::fileregistration +{ +VCL_DLLPUBLIC void LaunchRegistrationUI(); + +VCL_DLLPUBLIC void CheckFileExtRegistration(weld::Window* pDialogParent); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/officecfg/registry/data/org/openoffice/Office/Common.xcu b/officecfg/registry/data/org/openoffice/Office/Common.xcu index 237348be96cb..2144d43a5454 100644 --- a/officecfg/registry/data/org/openoffice/Office/Common.xcu +++ b/officecfg/registry/data/org/openoffice/Office/Common.xcu @@ -467,6 +467,9 @@ 10 + + true + diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 5f51032addb5..91bf8142c72f 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -5665,6 +5665,13 @@ -1 + + + + Determines whether the default file extension check is performed on startup. + + false + Determines whether OpenCL can be used, when available, to speed up diff --git a/solenv/sanitizers/ui/cui.suppr b/solenv/sanitizers/ui/cui.suppr index f250aa945ab8..f7c838a8a349 100644 --- a/solenv/sanitizers/ui/cui.suppr +++ b/solenv/sanitizers/ui/cui.suppr @@ -117,6 +117,7 @@ cui/uiconfig/ui/iconchangedialog.ui://GtkLabel[@id='label1'] orphan-label cui/uiconfig/ui/iconselectordialog.ui://GtkLabel[@id='noteLabel'] orphan-label cui/uiconfig/ui/tipofthedaydialog.ui://GtkLabel[@id='lbTitle'] orphan-label cui/uiconfig/ui/tipofthedaydialog.ui://GtkLabel[@id='lbText'] orphan-label +cui/uiconfig/ui/fileextcheckdialog.ui://GtkLabel[@id='lbText'] orphan-label cui/uiconfig/ui/insertfloatingframe.ui://GtkLabel[@id='label6'] orphan-label cui/uiconfig/ui/insertfloatingframe.ui://GtkLabel[@id='label7'] orphan-label cui/uiconfig/ui/insertfloatingframe.ui://GtkLabel[@id='widthlabel'] orphan-label diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 4ffb346ca2e1..fba19b4e5fb3 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -749,6 +749,7 @@ ifeq ($(OS),WNT) $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/opengl/win/WinDeviceInfo \ vcl/source/app/salplug \ + vcl/win/app/fileregistration \ )) $(eval $(call gb_Library_use_system_win32_libs,vcl,\ diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc index 11b9268f2e1f..2acb7bf45e0c 100644 --- a/vcl/inc/strings.hrc +++ b/vcl/inc/strings.hrc @@ -135,6 +135,9 @@ #define STR_SEPARATOR NC_("STR_SEPARATOR", "Separator") +#define STR_FILEEXT_NONDEFAULT_ASK_TITLE NC_("STR_FILEEXT_NONDEFAULT_ASK_TITLE", "Default file formats not registered") +#define STR_FILEEXT_NONDEFAULT_ASK_MSG NC_("STR_FILEEXT_NONDEFAULT_ASK_MSG", "The following file formats are not registered to be opened by default in %PRODUCTNAME:\n$1\nSelect OK if you want to change default file format registrations.") + #define KEY_VERSION_CHECK NC_("KEY_VERSION_CHECK", "Warning: Not all of the imported EPS graphics could be saved at level1\nas some are at a higher level!") #endif // INCLUDED_VCL_INC_STRINGS_HRC diff --git a/vcl/win/app/fileregistration.cxx b/vcl/win/app/fileregistration.cxx new file mode 100644 index 000000000000..863e66d0a3b1 --- /dev/null +++ b/vcl/win/app/fileregistration.cxx @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#if !defined(NTDDI_VERSION) || NTDDI_VERSION < NTDDI_WIN8 +#define NTDDI_VERSION NTDDI_WIN8 // needed for IApplicationActivationManager +#endif + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define MAX_LONG_PATH 32767 + +namespace vcl::fileregistration +{ +static void LaunchModernSettingsDialogDefaultApps() +{ + auto pIf = sal::systools::COMReference().CoCreateInstance( + CLSID_ApplicationActivationManager, nullptr, CLSCTX_INPROC_SERVER); + + DWORD pid; + HRESULT hr = pIf->ActivateApplication(L"windows.immersivecontrolpanel_cw5n1h2txyewy" + L"!microsoft.windows.immersivecontrolpanel", + L"page=SettingsPageAppsDefaults", AO_NONE, &pid); + if (SUCCEEDED(hr)) + { + // Do not check error because we could at least open + // the "Default apps" setting. + pIf->ActivateApplication(L"windows.immersivecontrolpanel_cw5n1h2txyewy" + L"!microsoft.windows.immersivecontrolpanel", + L"page=SettingsPageAppsDefaults" + L"&target=SettingsPageAppsDefaultsDefaultAppsListView", + AO_NONE, &pid); + } +} + +static HRESULT +IsPathDefaultForClass(sal::systools::COMReference& pAAR, + LPCWSTR aClassName, LPCWSTR progID) +{ + // Make sure the Prog ID matches what we have + LPWSTR registeredApp; + HRESULT hr + = pAAR->QueryCurrentDefault(aClassName, AT_FILEEXTENSION, AL_EFFECTIVE, ®isteredApp); + if (FAILED(hr)) + { + return hr; + } + + if (!wcsnicmp(registeredApp, progID, wcslen(progID))) + hr = S_OK; + else + hr = S_FALSE; + + CoTaskMemFree(registeredApp); + + return hr; +} + +static bool IsDefaultAppInstalledInReg() +{ + const wchar_t* keyPath = L"SOFTWARE\\LibreOffice\\UNO\\InstallPath"; + + WCHAR szRegPath[MAX_LONG_PATH]; + DWORD cbData = static_cast(MAX_LONG_PATH * sizeof(WCHAR)); + auto rc = RegGetValueW(HKEY_LOCAL_MACHINE, keyPath, nullptr, RRF_RT_REG_SZ, nullptr, + static_cast(szRegPath), &cbData); + if (rc != ERROR_SUCCESS) + return false; + + WCHAR szProcPath[MAX_LONG_PATH]; + if (!GetModuleFileNameW(NULL, szProcPath, MAX_LONG_PATH)) + return false; + + WCHAR szFullProcPath[MAX_LONG_PATH]; + if (!GetFullPathNameW(szProcPath, MAX_LONG_PATH, szFullProcPath, NULL)) + return false; + + if (!GetLongPathNameW(szFullProcPath, szFullProcPath, MAX_LONG_PATH)) + return false; + + if (!GetLongPathNameW(szRegPath, szRegPath, MAX_LONG_PATH)) + return false; + + if (wcslen(szRegPath) > 0 && wcsstr(szFullProcPath, szRegPath) != NULL) + return true; + + return false; +} + +void LaunchRegistrationUI() +{ + const bool bUninit = SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)); + comphelper::ScopeGuard g([bUninit]() { + if (bUninit) + CoUninitialize(); + }); + + try + { + if (IsWindows10OrGreater()) + { + LaunchModernSettingsDialogDefaultApps(); + } + else + { + auto pIf = sal::systools::COMReference() + .CoCreateInstance(CLSID_ApplicationAssociationRegistrationUI, nullptr, + CLSCTX_INPROC_SERVER); + + // LaunchAdvancedAssociationUI only works for applications registered under + // Software\RegisteredApplications. See scp2/source/ooo/registryitem_ooo.scp + const OUString expanded = Translate::ExpandVariables("%PRODUCTNAME %PRODUCTVERSION"); + pIf->LaunchAdvancedAssociationUI(o3tl::toW(expanded.getStr())); + } + } + catch (...) + { + // Just ignore any error here: this is not something we need to make sure to succeed + } +} + +void CheckFileExtRegistration(weld::Window* pDialogParent) +{ + if (!officecfg::Office::Common::Misc::PerformFileExtCheck::get()) + return; + + if (!IsDefaultAppInstalledInReg()) + return; + + const bool bUninit = SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED)); + comphelper::ScopeGuard g([bUninit]() { + if (bUninit) + CoUninitialize(); + }); + sal::systools::COMReference pAAR = nullptr; + try + { + pAAR = sal::systools::COMReference().CoCreateInstance( + CLSID_ApplicationAssociationRegistration, nullptr, CLSCTX_INPROC_SERVER); + } + catch (...) + { + // Just return on any error here: this is not something we need to make sure to succeed + return; + } + + std::map formats = { + { ".odp", "LibreOffice.ImpressDocument.1" }, + { ".odt", "LibreOffice.WriterDocument.1" }, + { ".ods", "LibreOffice.CalcDocument.1" }, + }; + OUString aNonDefaults; + bool isNotDefault = false; + + for (std::map::iterator it = formats.begin(); it != formats.end(); it++) + { + if (IsPathDefaultForClass(pAAR, o3tl::toW(it->first.getStr()), + o3tl::toW(it->second.getStr())) + == S_FALSE) + { + isNotDefault = true; + aNonDefaults += it->first; + aNonDefaults += "\n"; + } + } + + if (isNotDefault) + { + OUString aMsg(VclResId(STR_FILEEXT_NONDEFAULT_ASK_MSG)); + aMsg = aMsg.replaceFirst("$1", aNonDefaults); + + VclAbstractDialogFactory* pFact = VclAbstractDialogFactory::Create(); + ScopedVclPtr pDlg(pFact->CreateFileExtCheckDialog( + pDialogParent, VclResId(STR_FILEEXT_NONDEFAULT_ASK_TITLE), aMsg)); + pDlg->Execute(); + } +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ -- cgit