summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cui/Library_cui.mk5
-rw-r--r--cui/UIConfig_cui.mk6
-rw-r--r--cui/source/dialogs/fileextcheckdlg.cxx55
-rw-r--r--cui/source/factory/dlgfact.cxx11
-rw-r--r--cui/source/factory/dlgfact.hxx6
-rw-r--r--cui/source/inc/fileextcheckdlg.hxx39
-rw-r--r--cui/source/options/optgdlg.cxx43
-rw-r--r--cui/source/options/optgdlg.hxx1
-rw-r--r--cui/uiconfig/ui/fileextcheckdialog.ui109
-rw-r--r--cui/uiconfig/ui/optgeneralpage.ui15
-rw-r--r--desktop/source/app/app.cxx10
-rw-r--r--include/vcl/abstdlg.hxx6
-rw-r--r--include/vcl/fileregistration.hxx21
-rw-r--r--officecfg/registry/data/org/openoffice/Office/Common.xcu3
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Common.xcs7
-rw-r--r--solenv/sanitizers/ui/cui.suppr1
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/inc/strings.hrc3
-rw-r--r--vcl/win/app/fileregistration.cxx198
19 files changed, 514 insertions, 26 deletions
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 <sal/config.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <vcl/fileregistration.hxx>
+
+#include <fileextcheckdlg.hxx>
+
+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<comphelper::ConfigurationChanges> 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 <tipofthedaydlg.hxx>
#include <toolbarmodedlg.hxx>
#include <DiagramDialog.hxx>
+#include <fileextcheckdlg.hxx>
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<DiagramDialog>(pParent, pDiagramData));
}
+#ifdef _WIN32
+VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateFileExtCheckDialog(weld::Window* pParent, const OUString& sTitle,
+ const OUString& sMsg)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(
+ std::make_unique<FileExtCheckDialog>(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<AbstractDiagramDialog> CreateDiagramDialog(
weld::Window* pParent,
std::shared_ptr<DiagramDataInterface> pDiagramData) override;
+
+#ifdef _WIN32
+ virtual VclPtr<VclAbstractDialog> 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 <sal/config.h>
+
+#include <vcl/weld.hxx>
+
+class FileExtCheckDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Label> m_pText;
+ std::unique_ptr<weld::CheckButton> m_pPerformCheck;
+ std::unique_ptr<weld::Button> 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 <svtools/imgdef.hxx>
#if defined(_WIN32)
-#include <o3tl/char16_t2wchar_t.hxx>
-#include <prewin.h>
-#include <shobjidl.h>
-#include <systools/win32/comtools.hxx>
-#include <postwin.h>
+#include <vcl/fileregistration.hxx>
#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<IApplicationAssociationRegistrationUI>().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<weld::Widget> m_xFileAssocFrame;
std::unique_ptr<weld::Button> m_xFileAssocBtn;
+ std::unique_ptr<weld::CheckButton> 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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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/.
+ *
+-->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="FileExtCheckDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="FileExtCheckDialog|Name"></property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <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="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkCheckButton" id="cbPerformCheck">
+ <property name="label" translatable="yes" context="FileExtCheck|Checkbox">_Perform check on startup</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="tooltip-text" translatable="yes" context="FileExtCheck|Checkbox_Tooltip">Enable the dialog again at Tools &gt; Options &gt; General</property>
+ <property name="use-underline">True</property>
+ <property name="active">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnCancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</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="btnOk">
+ <property name="label" translatable="yes" context="FileExtCheckDialog|Ok_Button">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="has-focus">True</property>
+ <property name="is-focus">True</property>
+ <property name="can-default">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="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </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>
+ <child>
+ <object class="GtkLabel" id="lbText">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="wrap">True</property>
+ <property name="width-chars">50</property>
+ <property name="max-width-chars">50</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-5">btnCancel</action-widget>
+ </action-widgets>
+ </object>
+</interface>
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 @@
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">12</property>
+ <property name="vexpand">True</property>
<child>
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
@@ -453,6 +454,20 @@
<property name="top_attach">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="cbPerformFileExtCheck">
+ <property name="label" translatable="yes" context="optgeneralpage|FileExtCheckCheckbox">Perform check for default file associations on start-up</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
</object>
</child>
<child type="label">
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 <windows.h>
+#include <vcl/fileregistration.hxx>
#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<AbstractDiagramDialog> CreateDiagramDialog(
weld::Window* pParent,
std::shared_ptr<DiagramDataInterface> pDiagramData) = 0;
+
+#ifdef _WIN32
+ virtual VclPtr<VclAbstractDialog>
+ 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 <sal/config.h>
+
+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 @@
<prop oor:name="FindReplaceRememberedSearches">
<value>10</value>
</prop>
+ <prop oor:name="PerformFileExtCheck">
+ <value install:module="wnt">true</value>
+ </prop>
</node>
<node oor:name="Save">
<node oor:name="ODF">
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 @@
</info>
<value>-1</value>
</prop>
+ <prop oor:name="PerformFileExtCheck" oor:type="xs:boolean" oor:nillable="false">
+ <!-- UIHints: Tools - Options - General -->
+ <info>
+ <desc>Determines whether the default file extension check is performed on startup.</desc>
+ </info>
+ <value>false</value>
+ </prop>
<prop oor:name="UseOpenCL" oor:type="xs:boolean" oor:nillable="false">
<info>
<desc>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 <sal/config.h>
+
+#include <comphelper/scopeguard.hxx>
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <vcl/abstdlg.hxx>
+#include <vcl/fileregistration.hxx>
+
+#include <strings.hrc>
+
+#include <prewin.h>
+#include <Shobjidl.h>
+#include <systools/win32/comtools.hxx>
+#include <versionhelpers.h>
+#include <postwin.h>
+
+#define MAX_LONG_PATH 32767
+
+namespace vcl::fileregistration
+{
+static void LaunchModernSettingsDialogDefaultApps()
+{
+ auto pIf = sal::systools::COMReference<IApplicationActivationManager>().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<IApplicationAssociationRegistration>& 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, &registeredApp);
+ 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<DWORD>(MAX_LONG_PATH * sizeof(WCHAR));
+ auto rc = RegGetValueW(HKEY_LOCAL_MACHINE, keyPath, nullptr, RRF_RT_REG_SZ, nullptr,
+ static_cast<PVOID>(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<IApplicationAssociationRegistrationUI>()
+ .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<IApplicationAssociationRegistration> pAAR = nullptr;
+ try
+ {
+ pAAR = sal::systools::COMReference<IApplicationAssociationRegistration>().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<OUString, OUString> formats = {
+ { ".odp", "LibreOffice.ImpressDocument.1" },
+ { ".odt", "LibreOffice.WriterDocument.1" },
+ { ".ods", "LibreOffice.CalcDocument.1" },
+ };
+ OUString aNonDefaults;
+ bool isNotDefault = false;
+
+ for (std::map<OUString, OUString>::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<VclAbstractDialog> 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: */