Rebased ref, commits from common ancestor:
commit 2a2f53131c8dd906b549230ea211993c094efd66
Author:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
AuthorDate: Thu Nov 9 20:18:44 2023 +0300
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 13:37:53 2023 +0100

    Edit notes in child window
    
    These are the initial ui bits for testing the feature
    
    Change-Id: Ibc6e8a3f126c443453c5ecab52ba988a4f4f56e6

diff --git 
a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
index cca1b2ec38ae..618dbfa0d837 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
@@ -24,6 +24,14 @@
           <value xml:lang="en-US">S~lide</value>
         </prop>
       </node>
+      <node oor:name=".uno:NotesChildWindow" oor:op="replace">
+        <prop oor:name="Label" oor:type="xs:string">
+          <value xml:lang="en-US">Notes Panel</value>
+        </prop>
+        <prop oor:name="Properties" oor:type="xs:int">
+          <value>1</value>
+        </prop>
+      </node>
       <node oor:name=".uno:PageMenu" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
           <value xml:lang="en-US">~Page</value>
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 926dd86ee755..d7483cb77c25 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -232,6 +232,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
        sd/source/ui/dlg/AnimationChildWindow \
        sd/source/ui/dlg/LayerTabBar \
        sd/source/ui/dlg/NavigatorChildWindow \
+       sd/source/ui/dlg/NotesChildWindow \
        sd/source/ui/dlg/PaneChildWindows \
        sd/source/ui/dlg/PaneShells \
        sd/source/ui/dlg/SpellDialogChildWindow \
diff --git a/sd/inc/glob.hxx b/sd/inc/glob.hxx
index 6ecfc3fd39ce..8cdfcb18491b 100644
--- a/sd/inc/glob.hxx
+++ b/sd/inc/glob.hxx
@@ -39,6 +39,7 @@
 #define SD_IF_SDDRAWTABLEOBJECTBAR      SFX_INTERFACE_SD_START + 
SfxInterfaceId(27)
 #define SD_IF_SDTOOLPANELPANESHELL      SFX_INTERFACE_SD_START + 
SfxInterfaceId(29)
 #define SD_IF_SDTOOLPANELSHELL          SFX_INTERFACE_SD_START + 
SfxInterfaceId(30)
+#define SD_IF_SDNOTESCHILDWINDOWSHELL   SFX_INTERFACE_SD_START + 
SfxInterfaceId(31)
 
 
 // Object-Ids for StarDraw UserData
diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc
index 3e1ddd1542e7..ff7fca3f5447 100644
--- a/sd/inc/strings.hrc
+++ b/sd/inc/strings.hrc
@@ -263,6 +263,7 @@
 #define STR_UNDO_HANGULHANJACONVERSION                  
NC_("STR_UNDO_HANGULHANJACONVERSION", "Hangul/Hanja Conversion")
 #define STR_LEFT_PANE_IMPRESS_TITLE                     
NC_("STR_LEFT_PANE_IMPRESS_TITLE", "Slides")
 #define STR_LEFT_PANE_DRAW_TITLE                        
NC_("STR_LEFT_PANE_DRAW_TITLE", "Pages")
+#define STR_BOTTOM_NOTES_PANE_TITLE                     
NC_("STR_BOTTOM_NOTES_PANE_TITLE", "Notes")
 #define STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION        
NC_("STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION", "Preview not available")
 #define STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION    
NC_("STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION", "Preparing preview")
 #define STR_TASKPANEL_LAYOUT_MENU_TITLE                 
NC_("STR_TASKPANEL_LAYOUT_MENU_TITLE", "Layouts")
diff --git a/sd/source/ui/app/sddll.cxx b/sd/source/ui/app/sddll.cxx
index c195869b790e..c97a5d892a83 100644
--- a/sd/source/ui/app/sddll.cxx
+++ b/sd/source/ui/app/sddll.cxx
@@ -48,6 +48,7 @@
 #include <OutlineViewShell.hxx>
 #include <OutlineViewShellBase.hxx>
 #include <PaneChildWindows.hxx>
+#include <NotesChildWindow.hxx>
 #include <SpellDialogChildWindow.hxx>
 #include <SlideSorterViewShell.hxx>
 #include <SlideSorterViewShellBase.hxx>
@@ -166,6 +167,7 @@ void SdDLL::RegisterControllers(SdModule* pMod)
     ::sd::LeftPaneImpressChildWindow::RegisterChildWindow(false, pMod);
     ::sd::LeftPaneDrawChildWindow::RegisterChildWindow(false, pMod);
     ::sfx2::sidebar::SidebarChildWindow::RegisterChildWindow(false, pMod);
+    ::sd::NotesChildWindow::RegisterChildWindow(false, pMod);
     DevelopmentToolChildWindow::RegisterChildWindow(false, pMod);
 
     ::sd::SdNavigatorWrapper::RegisterChildWindow(false, pMod, 
SfxChildWindowFlags::NEVERHIDE);
diff --git a/sd/source/ui/dlg/NotesChildWindow.cxx 
b/sd/source/ui/dlg/NotesChildWindow.cxx
new file mode 100644
index 000000000000..ac26af12eb6b
--- /dev/null
+++ b/sd/source/ui/dlg/NotesChildWindow.cxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ */
+#include <NotesChildWindow.hxx>
+#include <titledockwin.hxx>
+#include <ViewShellBase.hxx>
+#include <framework/FrameworkHelper.hxx>
+#include <app.hrc>
+#include <strings.hrc>
+#include <sdresid.hxx>
+
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+
+namespace sd
+{
+SFX_IMPL_DOCKINGWINDOW_WITHID(NotesChildWindow, SID_NOTES_WINDOW);
+
+NotesChildWindow::NotesChildWindow(vcl::Window* pParentWindow, sal_uInt16 nId,
+                                   SfxBindings* pBindings, SfxChildWinInfo* 
pInfo)
+    : PaneChildWindow(pParentWindow, nId, pBindings, pInfo, 
STR_BOTTOM_NOTES_PANE_TITLE,
+                      SfxChildAlignment::RIGHT)
+{
+}
+
+} // end of namespace ::sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sd/source/ui/dlg/PaneChildWindows.cxx 
b/sd/source/ui/dlg/PaneChildWindows.cxx
index 320ce2a74b3d..72d9392f6f41 100644
--- a/sd/source/ui/dlg/PaneChildWindows.cxx
+++ b/sd/source/ui/dlg/PaneChildWindows.cxx
@@ -40,7 +40,8 @@ PaneChildWindow::PaneChildWindow (
     sal_uInt16 nId,
     SfxBindings* pBindings,
     SfxChildWinInfo* pInfo,
-    TranslateId pTitleBarResId)
+    TranslateId pTitleBarResId,
+    SfxChildAlignment eAlignment)
     : SfxChildWindow (pParentWindow, nId)
 {
     SetWindow( VclPtr<TitledDockingWindow>::Create(
@@ -48,7 +49,7 @@ PaneChildWindow::PaneChildWindow (
         this,
         pParentWindow,
         SdResId(pTitleBarResId)));
-    SetAlignment(SfxChildAlignment::LEFT);
+    SetAlignment(eAlignment);
     SfxDockingWindow* pDockingWindow = 
static_cast<SfxDockingWindow*>(GetWindow());
     pDockingWindow->EnableInput();
     pDockingWindow->Initialize(pInfo);
@@ -83,7 +84,8 @@ LeftPaneImpressChildWindow::LeftPaneImpressChildWindow (
         nId,
         pBindings,
         pInfo,
-        STR_LEFT_PANE_IMPRESS_TITLE)
+        STR_LEFT_PANE_IMPRESS_TITLE,
+        SfxChildAlignment::LEFT)
 {
 }
 
@@ -98,7 +100,8 @@ LeftPaneDrawChildWindow::LeftPaneDrawChildWindow (
         nId,
         pBindings,
         pInfo,
-        STR_LEFT_PANE_DRAW_TITLE)
+        STR_LEFT_PANE_DRAW_TITLE,
+        SfxChildAlignment::LEFT)
 {
 }
 
diff --git a/sd/source/ui/dlg/PaneShells.cxx b/sd/source/ui/dlg/PaneShells.cxx
index 77e411aaedc2..8f8140cf3411 100644
--- a/sd/source/ui/dlg/PaneShells.cxx
+++ b/sd/source/ui/dlg/PaneShells.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <PaneShells.hxx>
+#include <NotesChildWindow.hxx>
 
 #include <PaneChildWindows.hxx>
 
@@ -74,6 +75,30 @@ LeftDrawPaneShell::~LeftDrawPaneShell()
 {
 }
 
+//===== NotesChildWindowShell 
==================================================
+
+static SfxSlot aNotesChildWindowShellSlots_Impl[] =
+{
+    { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, 
nullptr, nullptr, 0, SfxDisableFlags::NONE, "" }
+};
+
+SFX_IMPL_INTERFACE(NotesChildWindowShell, SfxShell)
+
+void NotesChildWindowShell::InitInterface_Impl()
+{
+    
GetStaticInterface()->RegisterChildWindow(::sd::NotesChildWindow::GetChildWindowId());
+}
+
+
+NotesChildWindowShell::NotesChildWindowShell()
+{
+    SetName("NotesChildWindow");
+}
+
+NotesChildWindowShell::~NotesChildWindowShell()
+{
+}
+
 } // end of namespace ::sd
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.cxx 
b/sd/source/ui/framework/factories/BasicPaneFactory.cxx
index e112ac4c315a..ade1947f4d3c 100644
--- a/sd/source/ui/framework/factories/BasicPaneFactory.cxx
+++ b/sd/source/ui/framework/factories/BasicPaneFactory.cxx
@@ -25,6 +25,7 @@
 #include "ChildWindowPane.hxx"
 #include "FrameWindowPane.hxx"
 #include "FullScreenPane.hxx"
+#include "NotesChildWindow.hxx"
 
 #include <comphelper/servicehelper.hxx>
 #include <framework/FrameworkHelper.hxx>
@@ -46,7 +47,8 @@ namespace {
         CenterPaneId,
         FullScreenPaneId,
         LeftImpressPaneId,
-        LeftDrawPaneId
+        LeftDrawPaneId,
+        NotesChildWindowId
     };
 
     const sal_Int32 gnConfigurationUpdateStartEvent(0);
@@ -123,6 +125,11 @@ BasicPaneFactory::BasicPaneFactory (
             aDescriptor.mePaneId = LeftDrawPaneId;
             mpPaneContainer->push_back(aDescriptor);
             xCC->addResourceFactory(aDescriptor.msPaneURL, this);
+
+            aDescriptor.msPaneURL = FrameworkHelper::msNotesChildWindowURL;
+            aDescriptor.mePaneId = NotesChildWindowId;
+            mpPaneContainer->push_back(aDescriptor);
+            xCC->addResourceFactory(aDescriptor.msPaneURL, this);
         }
 
         // Register as configuration change listener.
@@ -223,6 +230,7 @@ Reference<XResource> SAL_CALL 
BasicPaneFactory::createResource (
 
             case LeftImpressPaneId:
             case LeftDrawPaneId:
+            case NotesChildWindowId:
                 xPane = CreateChildWindowPane(
                     rxPaneId,
                     *iDescriptor);
@@ -373,6 +381,11 @@ Reference<XResource> 
BasicPaneFactory::CreateChildWindowPane (
                 nChildWindowId = 
::sd::LeftPaneDrawChildWindow::GetChildWindowId();
                 break;
 
+            case NotesChildWindowId:
+                pShell.reset(new NotesChildWindowShell());
+                nChildWindowId = ::sd::NotesChildWindow::GetChildWindowId();
+                break;
+
             default:
                 break;
         }
diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx 
b/sd/source/ui/framework/factories/BasicViewFactory.cxx
index 3ea7e37f1f93..6572bdf30748 100644
--- a/sd/source/ui/framework/factories/BasicViewFactory.cxx
+++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx
@@ -426,6 +426,8 @@ bool BasicViewFactory::IsCacheable (const 
std::shared_ptr<ViewDescriptor>& rpDes
                 FrameworkHelper::msSlideSorterURL, 
FrameworkHelper::msLeftDrawPaneURL));
             tmp.push_back(FrameworkHelper::CreateResourceId(
                 FrameworkHelper::msSlideSorterURL, 
FrameworkHelper::msLeftImpressPaneURL));
+            tmp.push_back(FrameworkHelper::CreateResourceId(
+                FrameworkHelper::msNotesViewURL, 
FrameworkHelper::msNotesChildWindowURL));
             return tmp;
         }();
 
diff --git a/sd/source/ui/framework/module/ModuleController.cxx 
b/sd/source/ui/framework/module/ModuleController.cxx
index b064eefcdad7..09094a95a093 100644
--- a/sd/source/ui/framework/module/ModuleController.cxx
+++ b/sd/source/ui/framework/module/ModuleController.cxx
@@ -52,7 +52,8 @@ ModuleController::ModuleController(const 
rtl::Reference<::sd::DrawController>& r
         "com.sun.star.drawing.framework.BasicPaneFactory",
         { "private:resource/pane/CenterPane",
           "private:resource/pane/LeftImpressPane",
-          "private:resource/pane/LeftDrawPane" });
+          "private:resource/pane/LeftDrawPane",
+          "private:resource/pane/NotesChildWindow" });
     ProcessFactory(
         "com.sun.star.drawing.framework.BasicViewFactory",
         { "private:resource/view/ImpressView",
diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx 
b/sd/source/ui/framework/tools/FrameworkHelper.cxx
index 0a42649b1c85..4d73865aedc6 100644
--- a/sd/source/ui/framework/tools/FrameworkHelper.cxx
+++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx
@@ -175,6 +175,7 @@ const OUString FrameworkHelper::msCenterPaneURL( 
msPaneURLPrefix + "CenterPane")
 const OUString FrameworkHelper::msFullScreenPaneURL( msPaneURLPrefix + 
"FullScreenPane");
 const OUString FrameworkHelper::msLeftImpressPaneURL( msPaneURLPrefix + 
"LeftImpressPane");
 const OUString FrameworkHelper::msLeftDrawPaneURL( msPaneURLPrefix + 
"LeftDrawPane");
+const OUString FrameworkHelper::msNotesChildWindowURL( msPaneURLPrefix + 
"NotesChildWindow");
 
 // View URLs.
 
diff --git a/sd/source/ui/inc/NotesChildWindow.hxx 
b/sd/source/ui/inc/NotesChildWindow.hxx
new file mode 100644
index 000000000000..cec774cd04dd
--- /dev/null
+++ b/sd/source/ui/inc/NotesChildWindow.hxx
@@ -0,0 +1,29 @@
+/* -*- 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 <sfx2/dockwin.hxx>
+#include <sfx2/childwin.hxx>
+#include <unotools/resmgr.hxx>
+#include <PaneChildWindows.hxx>
+
+namespace sd
+{
+class NotesChildWindow final : public PaneChildWindow
+{
+public:
+    SFX_DECL_CHILDWINDOW_WITHID(NotesChildWindow);
+
+    NotesChildWindow(vcl::Window* pParentWindow, sal_uInt16 nId, SfxBindings* 
pBindings,
+                     SfxChildWinInfo* pInfo);
+};
+
+} // end of namespace ::sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sd/source/ui/inc/PaneChildWindows.hxx 
b/sd/source/ui/inc/PaneChildWindows.hxx
index f96ede468bac..4e0c7b718f42 100644
--- a/sd/source/ui/inc/PaneChildWindows.hxx
+++ b/sd/source/ui/inc/PaneChildWindows.hxx
@@ -34,7 +34,8 @@ public:
         sal_uInt16 nId,
         SfxBindings* pBindings,
         SfxChildWinInfo* pInfo,
-        TranslateId pTitleBarResId);
+        TranslateId pTitleBarResId,
+        SfxChildAlignment eAlignment);
     virtual ~PaneChildWindow() override;
 };
 
diff --git a/sd/source/ui/inc/PaneShells.hxx b/sd/source/ui/inc/PaneShells.hxx
index 73f24909c2fd..814888c6a2a6 100644
--- a/sd/source/ui/inc/PaneShells.hxx
+++ b/sd/source/ui/inc/PaneShells.hxx
@@ -58,6 +58,20 @@ public:
     virtual ~LeftDrawPaneShell() override;
 };
 
+class NotesChildWindowShell final : public SfxShell
+{
+public:
+    SFX_DECL_INTERFACE(SD_IF_SDNOTESCHILDWINDOWSHELL)
+
+private:
+    /// SfxInterface initializer.
+    static void InitInterface_Impl();
+
+public:
+    NotesChildWindowShell();
+    virtual ~NotesChildWindowShell() override;
+};
+
 } // end of namespace sd
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/inc/framework/FrameworkHelper.hxx 
b/sd/source/ui/inc/framework/FrameworkHelper.hxx
index 927b206b9edf..3ae8e0a55af8 100644
--- a/sd/source/ui/inc/framework/FrameworkHelper.hxx
+++ b/sd/source/ui/inc/framework/FrameworkHelper.hxx
@@ -61,6 +61,7 @@ public:
     static const OUString msFullScreenPaneURL;
     static const OUString msLeftImpressPaneURL;
     static const OUString msLeftDrawPaneURL;
+    static const OUString msNotesChildWindowURL;
 
     // URLs of frequently used views.
     static constexpr OUStringLiteral msViewURLPrefix = 
u"private:resource/view/";
diff --git a/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx 
b/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
index fb1ac2cf8236..ca05c1b4ee15 100644
--- a/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
+++ b/sd/source/ui/inc/framework/factories/BasicPaneFactory.hxx
@@ -48,6 +48,7 @@ typedef comphelper::WeakComponentImplHelper <
         private:resource/pane/FullScreenPane
         private:resource/pane/LeftImpressPane
         private:resource/pane/LeftDrawPane
+        private:resource/pane/NotesChildWindow
     There are two left panes because this is (seems to be) the only way to
     show different titles for the left pane in Draw and Impress.
 */
diff --git a/sd/source/ui/view/ViewShellBase.cxx 
b/sd/source/ui/view/ViewShellBase.cxx
index 9099988969d8..c1b7f33f4247 100644
--- a/sd/source/ui/view/ViewShellBase.cxx
+++ b/sd/source/ui/view/ViewShellBase.cxx
@@ -628,6 +628,11 @@ void ViewShellBase::Execute (SfxRequest& rRequest)
                 framework::FrameworkHelper::msSlideSorterURL);
             break;
 
+        case SID_NOTES_WINDOW:
+            mpImpl->SetPaneVisibility(rRequest, 
framework::FrameworkHelper::msNotesChildWindowURL,
+                                      
framework::FrameworkHelper::msNotesViewURL);
+            break;
+
         case SID_TOGGLE_TABBAR_VISIBILITY:
         {
             SdOptions* pOptions = 
SD_MOD()->GetSdOptions(GetDocument()->GetDocumentType());
@@ -1277,6 +1282,12 @@ void ViewShellBase::Implementation::GetSlotState 
(SfxItemSet& rSet)
                         bState = xConfiguration->hasResource(xResourceId);
                         break;
 
+                    case SID_NOTES_WINDOW:
+                        xResourceId = ResourceId::create(
+                            xContext, FrameworkHelper::msNotesChildWindowURL);
+                        bState = xConfiguration->hasResource(xResourceId);
+                        break;
+
                     case SID_DRAWINGMODE:
                     case SID_NORMAL_MULTI_PANE_GUI:
                     case SID_SLIDE_MASTER_MODE:
diff --git a/sd/source/ui/view/drvwshrg.cxx b/sd/source/ui/view/drvwshrg.cxx
index 792d5b833a54..9871db2e2de7 100644
--- a/sd/source/ui/view/drvwshrg.cxx
+++ b/sd/source/ui/view/drvwshrg.cxx
@@ -40,6 +40,7 @@
 #include <SpellDialogChildWindow.hxx>
 #include <GraphicViewShell.hxx>
 #include <AnimationChildWindow.hxx>
+#include <NotesChildWindow.hxx>
 
 using namespace sd;
 #define ShellClass_DrawViewShell
@@ -77,6 +78,7 @@ void DrawViewShell::InitInterface_Impl()
     GetStaticInterface()->RegisterChildWindow(
         sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
     
GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
+    
GetStaticInterface()->RegisterChildWindow(::sd::NotesChildWindow::GetChildWindowId());
 }
 
 // SdGraphicViewShell
@@ -103,6 +105,7 @@ void GraphicViewShell::InitInterface_Impl()
     GetStaticInterface()->RegisterChildWindow(
         sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
     
GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
+    
GetStaticInterface()->RegisterChildWindow(::sd::NotesChildWindow::GetChildWindowId());
 }
 
 } // end of namespace sd
diff --git a/sd/uiconfig/simpress/menubar/menubar.xml 
b/sd/uiconfig/simpress/menubar/menubar.xml
index 78489c56383e..ba1cc4868cc0 100644
--- a/sd/uiconfig/simpress/menubar/menubar.xml
+++ b/sd/uiconfig/simpress/menubar/menubar.xml
@@ -125,6 +125,7 @@
       <menu:menuitem menu:id=".uno:StatusBarVisible" menu:style="text"/>
       <menu:menuitem menu:id=".uno:LeftPaneImpress" menu:style="text"/>
       <menu:menuitem menu:id=".uno:ToggleTabBarVisibility" menu:style="text"/>
+      <menu:menuitem menu:id=".uno:NotesChildWindow" menu:style="text"/>
       <menu:menuseparator/>
       <menu:menuitem menu:id=".uno:ShowRuler"/>
       <menu:menu menu:id=".uno:GridMenu">
commit 9ec513d6346634c8ede37c0d58cf9e42928b87a0
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Mon Nov 6 18:48:37 2023 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 10:38:20 2023 +0100

    libcmis: fix regression setting wrong type of CURLOPT_SEEKFUNCTION
    
    Change-Id: I45421bbe13626aa843380e77f589e793328f99d4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159010
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 584c01394ff06072b11ef4bd4bffb9e7f2d31e81)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159031
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git 
a/external/libcmis/0003-HttpSession-fix-regression-setting-wrong-type-of-CUR.patch
 
b/external/libcmis/0003-HttpSession-fix-regression-setting-wrong-type-of-CUR.patch
new file mode 100644
index 000000000000..424fd9e0ea0f
--- /dev/null
+++ 
b/external/libcmis/0003-HttpSession-fix-regression-setting-wrong-type-of-CUR.patch
@@ -0,0 +1,81 @@
+From 3e6eb4cefd22498824247d91ab4c125deb3277da Mon Sep 17 00:00:00 2001
+From: Michael Stahl <michael.st...@allotropia.de>
+Date: Mon, 6 Nov 2023 18:41:37 +0100
+Subject: [PATCH 3/3] HttpSession: fix regression setting wrong type of
+ CURLOPT_SEEKFUNCTION
+
+(regression from commit 1b8a646b1d63bfa760d154dd7e51f6298d4a9899)
+---
+ src/libcmis/http-session.cxx | 28 +++++++++++++++++++++++++---
+ 1 file changed, 25 insertions(+), 3 deletions(-)
+
+diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx
+index 8787c50..d7b1a5e 100644
+--- a/src/libcmis/http-session.cxx
++++ b/src/libcmis/http-session.cxx
+@@ -31,6 +31,7 @@
+ #include <cctype>
+ #include <memory>
+ #include <string>
++#include <assert.h>
+ 
+ #include <libxml/parser.h>
+ #include <libxml/tree.h>
+@@ -110,6 +111,27 @@ namespace
+         return errCode;
+     }
+ 
++    int lcl_seekStream(void* data, curl_off_t offset, int origin)
++    {
++        std::ios_base::seekdir dir = {};
++        switch (origin)
++        {
++            case SEEK_SET: dir = std::ios_base::beg; break;
++            case SEEK_CUR: dir = std::ios_base::cur; break;
++            case SEEK_END: dir = std::ios_base::end; break;
++            default: assert(false); break;
++        }
++        istream& is = *(static_cast<istream*>(data));
++        is.clear();
++        is.seekg(offset, dir);
++        if (!is.good())
++        {
++            fprintf(stderr, "rewind failed\n");
++            return CURL_SEEKFUNC_FAIL;
++        }
++        return CURL_SEEKFUNC_OK;
++    }
++
+     template<typename T>
+     class ScopeGuard
+     {
+@@ -328,7 +350,7 @@ libcmis::HttpResponsePtr HttpSession::httpPatchRequest( 
string url, istream& is,
+     curl_easy_setopt( m_curlHandle, CURLOPT_UPLOAD, 1 );
+     curl_easy_setopt( m_curlHandle, CURLOPT_CUSTOMREQUEST, "PATCH" );
+ #if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && 
LIBCURL_VERSION_MINOR >= 85)
+-    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_ioctlStream );
++    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_seekStream );
+     curl_easy_setopt( m_curlHandle, CURLOPT_SEEKDATA, &isOriginal );
+ #else
+     curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLFUNCTION, lcl_ioctlStream );
+@@ -420,7 +442,7 @@ libcmis::HttpResponsePtr HttpSession::httpPutRequest( 
string url, istream& is, v
+     curl_easy_setopt( m_curlHandle, CURLOPT_READFUNCTION, lcl_readStream );
+     curl_easy_setopt( m_curlHandle, CURLOPT_UPLOAD, 1 );
+ #if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && 
LIBCURL_VERSION_MINOR >= 85)
+-    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_ioctlStream );
++    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_seekStream );
+     curl_easy_setopt( m_curlHandle, CURLOPT_SEEKDATA, &isOriginal );
+ #else
+     curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLFUNCTION, lcl_ioctlStream );
+@@ -513,7 +535,7 @@ libcmis::HttpResponsePtr HttpSession::httpPostRequest( 
const string& url, istrea
+     curl_easy_setopt( m_curlHandle, CURLOPT_READFUNCTION, lcl_readStream );
+     curl_easy_setopt( m_curlHandle, CURLOPT_POST, 1 );
+ #if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && 
LIBCURL_VERSION_MINOR >= 85)
+-    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_ioctlStream );
++    curl_easy_setopt( m_curlHandle, CURLOPT_SEEKFUNCTION, lcl_seekStream );
+     curl_easy_setopt( m_curlHandle, CURLOPT_SEEKDATA, &isOriginal );
+ #else
+     curl_easy_setopt( m_curlHandle, CURLOPT_IOCTLFUNCTION, lcl_ioctlStream );
+-- 
+2.41.0
+
diff --git a/external/libcmis/UnpackedTarball_libcmis.mk 
b/external/libcmis/UnpackedTarball_libcmis.mk
index 1ef846aa2b4b..1a1678e5a67c 100644
--- a/external/libcmis/UnpackedTarball_libcmis.mk
+++ b/external/libcmis/UnpackedTarball_libcmis.mk
@@ -16,6 +16,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1))
 $(eval $(call gb_UnpackedTarball_add_patches,libcmis,\
        external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch 
\
        
external/libcmis/0002-HttpSession-add-a-callback-that-can-be-used-to-confi.patch
 \
+       
external/libcmis/0003-HttpSession-fix-regression-setting-wrong-type-of-CUR.patch
 \
 ))
 
 # vim: set noet sw=4 ts=4:
commit e3b0b7c28efe2c5eb0efd6cd8c2863dc4f4ff6d2
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Mon Nov 6 14:43:12 2023 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 10:38:15 2023 +0100

    libcmis: HttpSession: add a callback that can be used to configure libcurl
    
    Change-Id: I6c2a3d1976f2256b21a3a306db7fbf04ca444c32
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159000
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 061e48e607291c2992c81d3073a8c41387c56996)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158907
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git 
a/external/libcmis/0002-HttpSession-add-a-callback-that-can-be-used-to-confi.patch
 
b/external/libcmis/0002-HttpSession-add-a-callback-that-can-be-used-to-confi.patch
new file mode 100644
index 000000000000..b47ee4d195b2
--- /dev/null
+++ 
b/external/libcmis/0002-HttpSession-add-a-callback-that-can-be-used-to-confi.patch
@@ -0,0 +1,142 @@
+From 94012ca5b669e71ea35508159f63576364736dc2 Mon Sep 17 00:00:00 2001
+From: Michael Stahl <michael.st...@allotropia.de>
+Date: Mon, 6 Nov 2023 14:18:59 +0100
+Subject: [PATCH 2/2] HttpSession: add a callback that can be used to configure
+ libcurl
+
+---
+ inc/libcmis/session-factory.hxx | 7 +++++++
+ src/libcmis/http-session.cxx    | 8 +++++++-
+ src/libcmis/http-session.hxx    | 8 +++++++-
+ src/libcmis/session-factory.cxx | 9 ++++++++-
+ 4 files changed, 29 insertions(+), 3 deletions(-)
+
+diff --git a/inc/libcmis/session-factory.hxx b/inc/libcmis/session-factory.hxx
+index 45abd8b..227ac4d 100644
+--- a/inc/libcmis/session-factory.hxx
++++ b/inc/libcmis/session-factory.hxx
+@@ -38,6 +38,9 @@
+ #include "libcmis/repository.hxx"
+ #include "libcmis/session.hxx"
+ 
++// needed for a callback type
++typedef void CURL;
++
+ namespace libcmis
+ {
+     /** This callback provides the OAuth2 code or NULL.
+@@ -80,6 +83,8 @@ namespace libcmis
+     };
+     typedef boost::shared_ptr< CertValidationHandler > 
CertValidationHandlerPtr;
+ 
++    typedef void(*CurlInitProtocolsFunction)(CURL *);
++
+     class LIBCMIS_API SessionFactory
+     {
+         private:
+@@ -109,6 +114,8 @@ namespace libcmis
+             static void setCertificateValidationHandler( 
CertValidationHandlerPtr handler ) { s_certValidationHandler = handler; }
+             static CertValidationHandlerPtr getCertificateValidationHandler( 
) { return s_certValidationHandler; }
+ 
++            static void 
setCurlInitProtocolsFunction(CurlInitProtocolsFunction);
++
+             static void setProxySettings( std::string proxy,
+                     std::string noProxy,
+                     std::string proxyUser,
+diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx
+index 9703427..8787c50 100644
+--- a/src/libcmis/http-session.cxx
++++ b/src/libcmis/http-session.cxx
+@@ -133,8 +133,10 @@ namespace
+ }
+ 
+ HttpSession::HttpSession( string username, string password, bool noSslCheck,
+-                          libcmis::OAuth2DataPtr oauth2, bool verbose ) :
++                          libcmis::OAuth2DataPtr oauth2, bool verbose,
++                          libcmis::CurlInitProtocolsFunction initProtocols) :
+     m_curlHandle( NULL ),
++    m_CurlInitProtocolsFunction(initProtocols),
+     m_no100Continue( false ),
+     m_oauth2Handler( NULL ),
+     m_username( username ),
+@@ -903,6 +905,10 @@ void HttpSession::initProtocols( )
+     curl_easy_setopt(m_curlHandle, CURLOPT_PROTOCOLS, protocols);
+     curl_easy_setopt(m_curlHandle, CURLOPT_REDIR_PROTOCOLS, protocols);
+ #endif
++    if (m_CurlInitProtocolsFunction)
++    {
++        (*m_CurlInitProtocolsFunction)(m_curlHandle);
++    }
+ }
+ 
+ const char* CurlException::what( ) const noexcept
+diff --git a/src/libcmis/http-session.hxx b/src/libcmis/http-session.hxx
+index 6c9ed1b..34223b2 100644
+--- a/src/libcmis/http-session.hxx
++++ b/src/libcmis/http-session.hxx
+@@ -43,6 +43,10 @@
+ 
+ class OAuth2Handler;
+ 
++namespace libcmis {
++    typedef void(*CurlInitProtocolsFunction)(CURL *);
++}
++
+ class CurlException : public std::exception
+ {
+     private:
+@@ -93,6 +97,7 @@ class HttpSession
+ {
+     protected:
+         CURL* m_curlHandle;
++        libcmis::CurlInitProtocolsFunction m_CurlInitProtocolsFunction = 
nullptr;
+     private:
+         bool  m_no100Continue;
+     protected:
+@@ -111,7 +116,8 @@ class HttpSession
+         HttpSession( std::string username, std::string password,
+                      bool noSslCheck = false,
+                      libcmis::OAuth2DataPtr oauth2 = libcmis::OAuth2DataPtr(),
+-                     bool verbose = false );
++                     bool verbose = false,
++                     libcmis::CurlInitProtocolsFunction = nullptr);
+ 
+         HttpSession( const HttpSession& copy );
+         virtual ~HttpSession( );
+diff --git a/src/libcmis/session-factory.cxx b/src/libcmis/session-factory.cxx
+index 1222473..47dc1c8 100644
+--- a/src/libcmis/session-factory.cxx
++++ b/src/libcmis/session-factory.cxx
+@@ -38,6 +38,7 @@ using namespace std;
+ 
+ namespace libcmis
+ {
++    CurlInitProtocolsFunction g_CurlInitProtocolsFunction = 0;
+     AuthProviderPtr SessionFactory::s_authProvider;
+     OAuth2AuthCodeProvider SessionFactory::s_oauth2AuthCodeProvider;
+ 
+@@ -48,6 +49,11 @@ namespace libcmis
+ 
+     CertValidationHandlerPtr SessionFactory::s_certValidationHandler;
+ 
++    void 
SessionFactory::setCurlInitProtocolsFunction(CurlInitProtocolsFunction const 
initProtocols)
++    {
++        g_CurlInitProtocolsFunction = initProtocols;
++    }
++
+     void SessionFactory::setProxySettings( string proxy, string noProxy,
+             string proxyUser, string proxyPass )
+     {
+@@ -81,7 +87,8 @@ namespace libcmis
+                 libcmis::HttpResponsePtr response;
+                 boost::shared_ptr< HttpSession> httpSession(
+                         new HttpSession( username, password,
+-                                         noSslCheck, oauth2, verbose ) );
++                                         noSslCheck, oauth2, verbose,
++                                         g_CurlInitProtocolsFunction) );
+ 
+                 try
+                 {
+-- 
+2.41.0
+
diff --git a/external/libcmis/UnpackedTarball_libcmis.mk 
b/external/libcmis/UnpackedTarball_libcmis.mk
index d7ecc207f10d..1ef846aa2b4b 100644
--- a/external/libcmis/UnpackedTarball_libcmis.mk
+++ b/external/libcmis/UnpackedTarball_libcmis.mk
@@ -15,6 +15,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1))
 
 $(eval $(call gb_UnpackedTarball_add_patches,libcmis,\
        external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch 
\
+       
external/libcmis/0002-HttpSession-add-a-callback-that-can-be-used-to-confi.patch
 \
 ))
 
 # vim: set noet sw=4 ts=4:
commit 1f6ae39011d77902623acfa442b3ecd7c4ed45d1
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Mon Nov 6 14:24:14 2023 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 10:38:09 2023 +0100

    libcmis: fix regression in HttpSession::initProtocols()
    
    Change-Id: I1d884945cc1f88a3abbf87c78227b56abf865c16
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158999
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 385aae6595fa467c73b6fdede5153d785c3ce138)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158906
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git 
a/external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch 
b/external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch
new file mode 100644
index 000000000000..8480913cdf20
--- /dev/null
+++ b/external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch
@@ -0,0 +1,31 @@
+From 5b9ed18e518a5214b4a1fb2766627c1d169b8d8c Mon Sep 17 00:00:00 2001
+From: Michael Stahl <michael.st...@allotropia.de>
+Date: Mon, 6 Nov 2023 13:33:05 +0100
+Subject: [PATCH 1/2] fix regression in  HttpSession::initProtocols()
+
+(regression from commit 1b8a646b1d63bfa760d154dd7e51f6298d4a9899)
+---
+ src/libcmis/http-session.cxx | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/libcmis/http-session.cxx b/src/libcmis/http-session.cxx
+index 3847a2c..9703427 100644
+--- a/src/libcmis/http-session.cxx
++++ b/src/libcmis/http-session.cxx
+@@ -894,11 +894,12 @@ catch ( const libcmis::Exception& e )
+ 
+ void HttpSession::initProtocols( )
+ {
+-    const unsigned long protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS;
+ #if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MAJOR == 7 && 
LIBCURL_VERSION_MINOR >= 85)
++    auto const protocols = "https,http";
+     curl_easy_setopt(m_curlHandle, CURLOPT_PROTOCOLS_STR, protocols);
+     curl_easy_setopt(m_curlHandle, CURLOPT_REDIR_PROTOCOLS_STR, protocols);
+ #else
++    const unsigned long protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS;
+     curl_easy_setopt(m_curlHandle, CURLOPT_PROTOCOLS, protocols);
+     curl_easy_setopt(m_curlHandle, CURLOPT_REDIR_PROTOCOLS, protocols);
+ #endif
+-- 
+2.41.0
+
diff --git a/external/libcmis/UnpackedTarball_libcmis.mk 
b/external/libcmis/UnpackedTarball_libcmis.mk
index 1c014d963401..d7ecc207f10d 100644
--- a/external/libcmis/UnpackedTarball_libcmis.mk
+++ b/external/libcmis/UnpackedTarball_libcmis.mk
@@ -13,4 +13,8 @@ $(eval $(call 
gb_UnpackedTarball_set_tarball,libcmis,$(LIBCMIS_TARBALL)))
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,libcmis,1))
 
+$(eval $(call gb_UnpackedTarball_add_patches,libcmis,\
+       external/libcmis/0001-fix-regression-in-HttpSession-initProtocols.patch 
\
+))
+
 # vim: set noet sw=4 ts=4:
commit 8a690465fc7df0f554252d437d0b50a9f5c0f7e7
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Fri Nov 3 14:20:07 2023 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 02:11:25 2023 +0100

    escape url passed to gstreamer
    
    Change-Id: I3c93ee34800cc8563370f75ef3ef6f8a9220e6ec
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158894
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit f41dcadf6492a6ffd32696d50f818e44355b9ad9)

diff --git a/avmedia/source/gstreamer/gstframegrabber.cxx 
b/avmedia/source/gstreamer/gstframegrabber.cxx
index 6f41511dc128..f8911ed7c9b3 100644
--- a/avmedia/source/gstreamer/gstframegrabber.cxx
+++ b/avmedia/source/gstreamer/gstframegrabber.cxx
@@ -50,11 +50,9 @@ void FrameGrabber::disposePipeline()
 
 FrameGrabber::FrameGrabber( std::u16string_view rURL )
 {
-    gchar *pPipelineStr;
-    pPipelineStr = g_strdup_printf(
-        "uridecodebin uri=%s ! videoconvert ! videoscale ! appsink "
-        "name=sink caps=\"video/x-raw,format=RGB,pixel-aspect-ratio=1/1\"",
-        OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+    const char pPipelineStr[] =
+        "uridecodebin name=source ! videoconvert ! videoscale ! appsink "
+        "name=sink caps=\"video/x-raw,format=RGB,pixel-aspect-ratio=1/1\"";
 
     GError *pError = nullptr;
     mpPipeline = gst_parse_launch( pPipelineStr, &pError );
@@ -65,6 +63,12 @@ FrameGrabber::FrameGrabber( std::u16string_view rURL )
     }
 
     if( mpPipeline ) {
+
+        if (GstElement *pUriDecode = gst_bin_get_by_name(GST_BIN(mpPipeline), 
"source"))
+            g_object_set(pUriDecode, "uri", OUStringToOString(rURL, 
RTL_TEXTENCODING_UTF8).getStr(), nullptr);
+        else
+            g_warning("Missing 'source' element in gstreamer pipeline");
+
         // pre-roll
         switch( gst_element_set_state( mpPipeline, GST_STATE_PAUSED ) ) {
         case GST_STATE_CHANGE_FAILURE:
commit dee219891fb19950a5ba0c55d3a6ddde2147bc5d
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Fri Nov 3 17:14:26 2023 +0000
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 02:10:50 2023 +0100

    add some protocols that don't make sense as floating frame targets
    
    Change-Id: Id900a5eef248731d1184c1df501a2cf7a2de7eb9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158910
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 11ebdfef16501c6d35c3e3d0d62507f706557c71)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158900
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit bab433911bdecb344f7ea94dbd00690241a08c54)

diff --git a/include/tools/urlobj.hxx b/include/tools/urlobj.hxx
index 9d6820ddf241..dfd658722826 100644
--- a/include/tools/urlobj.hxx
+++ b/include/tools/urlobj.hxx
@@ -915,6 +915,11 @@ public:
 
     void changeScheme(INetProtocol eTargetScheme);
 
+    // INetProtocol::Macro, INetProtocol::Uno, INetProtocol::Slot,
+    // vnd.sun.star.script, etc. All the types of URLs which shouldn't
+    // be accepted from an outside controlled source
+    bool IsExoticProtocol() const;
+
 private:
     // General Structure:
 
diff --git a/sfx2/source/doc/iframe.cxx b/sfx2/source/doc/iframe.cxx
index 507256aadf17..442913678e4c 100644
--- a/sfx2/source/doc/iframe.cxx
+++ b/sfx2/source/doc/iframe.cxx
@@ -169,8 +169,11 @@ sal_Bool SAL_CALL IFrameObject::load(
         xTrans->parseStrict( aTargetURL );
 
         INetURLObject aURLObject(aTargetURL.Complete);
-        if (aURLObject.GetProtocol() == INetProtocol::Macro || 
aURLObject.isSchemeEqualTo(u"vnd.sun.star.script"))
+        if (aURLObject.IsExoticProtocol())
+        {
+            SAL_WARN("sfx", "IFrameObject::load ignoring: " << 
aTargetURL.Complete);
             return false;
+        }
 
         uno::Reference<frame::XFramesSupplier> xParentFrame = 
xFrame->getCreator();
         SfxObjectShell* pDoc = SfxMacroLoader::GetObjectShell(xParentFrame);
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index ae5e07797bc0..cb749863e9fb 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -4880,4 +4880,12 @@ OUString INetURLObject::CutExtension()
         ? aTheExtension : OUString();
 }
 
+bool INetURLObject::IsExoticProtocol() const
+{
+    return m_eScheme == INetProtocol::Slot ||
+           m_eScheme == INetProtocol::Macro ||
+           m_eScheme == INetProtocol::Uno ||
+           isSchemeEqualTo(u"vnd.sun.star.script");
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 2221f551716d0b0747e5dd63cdb88142bf0664eb
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Nov 3 20:16:09 2023 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sun Nov 12 02:08:54 2023 +0100

    curl: mitigate migration to OpenSSL on Linux
    
    The problem is that curl 8.3.0 removed the NSS backend, so we now
    have no other choice than to use the bundled OpenSSL on Linux.
    
    Currently any curl https connection fails with:
    
      CurlSession.cxx:963: curl_easy_perform failed: (60) SSL certificate 
problem: unable to get local issuer certificate
    
    Apparently this requires manually telling curl which CA certificates to
    trust; there is a configure flag --with-ca-bundle but that is useless as
    it tries to load the file relative to whatever is the current working
    directory, and also did i mention that there are at least 3 different
    locations where a Linux system may store its system trusted CA
    certificates because ALL ABOUT CHOICE.
    
    So add a new header with an init function to try out various file
    locations listed in this nice blog article and call it from way too many
    places that independently use curl.
    
    
https://www.happyassassin.net/posts/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
    
    TODO: perhaps bundle a cacert.pem as a fallback in case the system chose
    to innovate by putting its certificates in yet another unexpected place
    
    (regression from commit c2930ebff82c4f7ffe8377ab82627131f8544226)
    
    Change-Id: Ibf1cc0069bc2ae011ecead9a4c2b455e94b01241
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158915
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 3fc632c0261c75fb4079a5305e814698e791f75c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159035
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    (cherry picked from commit f5ce7ad845c00af284065bb6691d38b62deb91d8)

diff --git a/desktop/source/app/updater.cxx b/desktop/source/app/updater.cxx
index 92f060b976e2..7ff6234b4555 100644
--- a/desktop/source/app/updater.cxx
+++ b/desktop/source/app/updater.cxx
@@ -37,6 +37,8 @@
 #include <orcus/json_document_tree.hpp>
 #include <orcus/config.hpp>
 #include <orcus/pstring.hpp>
+
+#include <curlinit.hxx>
 #include <comphelper/hash.hxx>
 
 #include <com/sun/star/container/XNameAccess.hpp>
@@ -546,6 +548,8 @@ std::string download_content(const OString& rURL, bool 
bFile, OUString& rHash)
     if (!curl)
         return std::string();
 
+    ::InitCurl_easy(curl.get());
+
     curl_easy_setopt(curl.get(), CURLOPT_URL, rURL.getStr());
     curl_easy_setopt(curl.get(), CURLOPT_USERAGENT, kUserAgent);
     bool bUseProxy = false;
diff --git a/desktop/source/minidump/minidump.cxx 
b/desktop/source/minidump/minidump.cxx
index 0bf20f2aa419..7fbb0884987d 100644
--- a/desktop/source/minidump/minidump.cxx
+++ b/desktop/source/minidump/minidump.cxx
@@ -17,6 +17,8 @@
 
 #include <curl/curl.h>
 
+#include <curlinit.hxx>
+
 #ifdef _WIN32
 #include <memory>
 #include <windows.h>
@@ -95,6 +97,8 @@ static bool uploadContent(std::map<std::string, std::string>& 
parameters, std::s
     if (!curl)
         return false;
 
+    ::InitCurl_easy(curl);
+
     std::string proxy, proxy_user_pwd, ca_certificate_file, file, url, version;
 
     getProperty("Proxy", proxy, parameters);
diff --git a/extensions/source/update/check/download.cxx 
b/extensions/source/update/check/download.cxx
index 8f090ed9b6dd..2124ee5a0512 100644
--- a/extensions/source/update/check/download.cxx
+++ b/extensions/source/update/check/download.cxx
@@ -23,6 +23,8 @@
 
 #include <curl/curl.h>
 
+#include <curlinit.hxx>
+
 #include <o3tl/string_view.hxx>
 #include <osl/diagnose.h>
 #include <osl/file.h>
@@ -222,6 +224,8 @@ static bool curl_run(std::u16string_view rURL, OutData& 
out, const OString& aPro
 
     if( nullptr != pCURL )
     {
+        ::InitCurl_easy(pCURL);
+
         out.curl = pCURL;
 
         OString aURL(OUStringToOString(rURL, RTL_TEXTENCODING_UTF8));
diff --git a/include/curlinit.hxx b/include/curlinit.hxx
new file mode 100644
index 000000000000..8b3a9968419d
--- /dev/null
+++ b/include/curlinit.hxx
@@ -0,0 +1,59 @@
+/* -*- 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 <curl/curl.h>
+
+#if defined(LINUX) && !defined(SYSTEM_CURL)
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+#include <unistd.h>
+
+static char const* GetCABundleFile()
+{
+    // try system ones first; inspired by:
+    // 
https://www.happyassassin.net/posts/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/
+    auto const candidates = {
+        "/etc/pki/tls/certs/ca-bundle.crt",
+        "/etc/pki/tls/certs/ca-bundle.trust.crt",
+        "/etc/ssl/certs/ca-certificates.crt",
+        "/var/lib/ca-certificates/ca-bundle.pem",
+    };
+    for (char const* const candidate : candidates)
+    {
+        if (access(candidate, R_OK) == 0)
+        {
+            return candidate;
+        }
+    }
+
+    throw css::uno::RuntimeException("no OpenSSL CA certificate bundle found");
+}
+
+static void InitCurl_easy(CURL* const pCURL)
+{
+    char const* const path = GetCABundleFile();
+    auto rc = curl_easy_setopt(pCURL, CURLOPT_CAINFO, path);
+    if (rc != CURLE_OK) // only if OOM?
+    {
+        throw css::uno::RuntimeException("CURLOPT_CAINFO failed");
+    }
+}
+
+#else
+
+static void InitCurl_easy(CURL* const)
+{
+    // these don't use OpenSSL so CAs work out of the box
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx 
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index 7152a6ff0880..c5062b84fbe7 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -41,6 +41,9 @@
 #include <boost/property_tree/json_parser.hpp>
 #include <algorithm>
 #include <string_view>
+
+#include <curlinit.hxx>
+
 #include <sal/log.hxx>
 #include <tools/color.hxx>
 #include <tools/long.hxx>
@@ -128,6 +131,8 @@ std::string makeHttpRequest_impl(std::u16string_view aURL, 
HTTP_METHOD method,
         return {}; // empty string
     }
 
+    ::InitCurl_easy(curl.get());
+
     // Same useragent string as in CurlSession 
(ucp/webdav-curl/CurlSession.cxx)
     curl_version_info_data const* const 
pVersion(curl_version_info(CURLVERSION_NOW));
     assert(pVersion);
diff --git a/linguistic/source/translate.cxx b/linguistic/source/translate.cxx
index 12f5491e2129..fdd95fca2988 100644
--- a/linguistic/source/translate.cxx
+++ b/linguistic/source/translate.cxx
@@ -4,6 +4,7 @@
 #include <rtl/string.h>
 #include <boost/property_tree/ptree.hpp>
 #include <boost/property_tree/json_parser.hpp>
+#include <curlinit.hxx>
 #include <vcl/htmltransferable.hxx>
 #include <tools/long.hxx>
 
@@ -16,6 +17,9 @@ OString Translate(const OString& rTargetLang, const OString& 
rAPIUrl, const OStr
 
     std::unique_ptr<CURL, std::function<void(CURL*)>> curl(curl_easy_init(),
                                                            [](CURL* p) { 
curl_easy_cleanup(p); });
+
+    ::InitCurl_easy(curl.get());
+
     (void)curl_easy_setopt(curl.get(), CURLOPT_URL, rAPIUrl.getStr());
     (void)curl_easy_setopt(curl.get(), CURLOPT_FAILONERROR, 1L);
     (void)curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, CURL_TIMEOUT);
diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx
index e68ccb8aafda..378a62f1ea56 100644
--- a/svl/source/crypto/cryptosign.cxx
+++ b/svl/source/crypto/cryptosign.cxx
@@ -15,6 +15,10 @@
 #include <svl/sigstruct.hxx>
 #include <config_crypto.h>
 
+#if USE_CRYPTO_NSS
+#include <curlinit.hxx>
+#endif
+
 #include <rtl/character.hxx>
 #include <rtl/strbuf.hxx>
 #include <rtl/string.hxx>
@@ -1086,6 +1090,8 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer)
             return false;
         }
 
+        ::InitCurl_easy(curl);
+
         SAL_INFO("svl.crypto", "Setting curl to verbose: " << 
(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) == CURLE_OK ? "OK" : "FAIL"));
 
         if ((rc = curl_easy_setopt(curl, CURLOPT_URL, 
OUStringToOString(m_aSignTSA, RTL_TEXTENCODING_UTF8).getStr())) != CURLE_OK)
diff --git a/ucb/source/ucp/cmis/cmis_content.cxx 
b/ucb/source/ucp/cmis/cmis_content.cxx
index a9781c233054..52c4769e474b 100644
--- a/ucb/source/ucp/cmis/cmis_content.cxx
+++ b/ucb/source/ucp/cmis/cmis_content.cxx
@@ -56,6 +56,8 @@
 #include <ucbhelper/proxydecider.hxx>
 #include <ucbhelper/macros.hxx>
 #include <sax/tools/converter.hxx>
+#include <curlinit.hxx>
+
 #include <utility>
 
 #include "auth_provider.hxx"
@@ -335,6 +337,9 @@ namespace cmis
                     new CertValidationHandler( xEnv, m_xContext, 
aBindingUrl.GetHost( ) ) );
             libcmis::SessionFactory::setCertificateValidationHandler( 
certHandler );
 
+            // init libcurl callback
+            
libcmis::SessionFactory::setCurlInitProtocolsFunction(&::InitCurl_easy);
+
             // Get the auth credentials
             AuthProvider aAuthProvider(xEnv, 
m_xIdentifier->getContentIdentifier(), m_aURL.getBindingUrl());
             AuthProvider::setXEnv( xEnv );
diff --git a/ucb/source/ucp/ftp/ftploaderthread.cxx 
b/ucb/source/ucp/ftp/ftploaderthread.cxx
index f5ebfe36cdda..91130fc1bc9c 100644
--- a/ucb/source/ucp/ftp/ftploaderthread.cxx
+++ b/ucb/source/ucp/ftp/ftploaderthread.cxx
@@ -25,6 +25,8 @@
 #include "ftploaderthread.hxx"
 #include "curl.hxx"
 
+#include <curlinit.hxx>
+
 using namespace ftp;
 
 
@@ -75,6 +77,8 @@ CURL* FTPLoaderThread::handle() {
     if(!ret) {
         ret = curl_easy_init();
         if (ret != nullptr) {
+            ::InitCurl_easy(ret);
+
             // Make sure curl is not internally using environment variables 
like
             // "ftp_proxy":
             if (curl_easy_setopt(ret, CURLOPT_PROXY, "") != CURLE_OK) {
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx 
b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index ac924beb2e17..f046395a668e 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -35,6 +35,7 @@
 #include <rtl/uri.hxx>
 #include <rtl/strbuf.hxx>
 #include <rtl/ustrbuf.hxx>
+#include <curlinit.hxx>
 #include <config_version.h>
 
 #include <map>
@@ -680,6 +681,7 @@ 
CurlSession::CurlSession(uno::Reference<uno::XComponentContext> xContext,
     assert(rc == CURLE_OK);
     rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HEADERFUNCTION, 
&header_callback);
     assert(rc == CURLE_OK);
+    ::InitCurl_easy(m_pCurl.get());
     // tdf#149921 by default, with schannel (WNT) connection fails if 
revocation
     // lists cannot be checked; try to limit the checking to when revocation
     // lists can actually be retrieved (usually not the case for self-signed 
CA)

Reply via email to