desktop/qa/data/ThemeDocument.docx             |binary
 desktop/qa/desktop_lib/test_desktop_lib.cxx    |   40 +++++++++++++++++++++++
 desktop/source/lib/init.cxx                    |    2 +
 docmodel/source/color/ComplexColorJSON.cxx     |   15 +++++---
 include/LibreOfficeKit/LibreOfficeKitEnums.h   |    9 ++++-
 include/docmodel/color/ComplexColorJSON.hxx    |    3 +
 include/svx/svdpage.hxx                        |    1 
 include/svx/theme/ThemeColorPaletteManager.hxx |    1 
 libreofficekit/source/gtk/lokdocview.cxx       |    1 
 sd/source/ui/inc/ViewShellBase.hxx             |    2 +
 sd/source/ui/view/ViewShellBase.cxx            |    5 ++
 svx/source/svdraw/svdpage.cxx                  |   19 +++++++++++
 svx/source/theme/ThemeColorPaletteManager.cxx  |   43 +++++++++++++++++++++++++
 sw/inc/view.hxx                                |    2 +
 sw/source/uibase/uiview/view.cxx               |   15 ++++++++
 15 files changed, 150 insertions(+), 8 deletions(-)

New commits:
commit e86a0236e69d76769b91f96d71fe852b91c5db6e
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sun Jun 4 20:57:19 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Mon Jun 5 13:06:57 2023 +0200

    lok: callback to send the updated theme palette when theme changes
    
    The callback sends the updated theme color palette when the theme
    changes or initially when the view is registered, so the client
    should always have the up-to-date theme color palette stored, so
    it can just show the color picker with the theme at any time without
    the need to call the server.
    
    Change-Id: I7cceccc46c2fad23ba89e6d3f3643e37f8dab292
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152589
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/desktop/qa/data/ThemeDocument.docx 
b/desktop/qa/data/ThemeDocument.docx
new file mode 100644
index 000000000000..4dbba883d9b6
Binary files /dev/null and b/desktop/qa/data/ThemeDocument.docx differ
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 74db478c09a3..b698cc5976b7 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -219,6 +219,7 @@ public:
     void testRenderSearchResult_CommonNode();
     void testNoDuplicateTableSelection();
     void testMultiViewTableSelection();
+    void testColorPaletteCallback();
     void testABI();
 
     CPPUNIT_TEST_SUITE(DesktopLOKTest);
@@ -291,6 +292,7 @@ public:
     CPPUNIT_TEST(testRenderSearchResult_CommonNode);
     CPPUNIT_TEST(testNoDuplicateTableSelection);
     CPPUNIT_TEST(testMultiViewTableSelection);
+    CPPUNIT_TEST(testColorPaletteCallback);
     CPPUNIT_TEST(testABI);
     CPPUNIT_TEST_SUITE_END();
 
@@ -2160,12 +2162,14 @@ class ViewCallback
 public:
     OString m_aCellFormula;
     int m_nTableSelectionCount;
+    int m_nColorPaletteCallbackCount = 0;
     bool m_bEmptyTableSelection;
     bool m_bTilesInvalidated;
     bool m_bZeroCursor;
     tools::Rectangle m_aOwnCursor;
     boost::property_tree::ptree m_aCommentCallbackResult;
     boost::property_tree::ptree m_aCallbackWindowResult;
+    boost::property_tree::ptree m_aColorPaletteCallbackResult;
     bool m_bWindowHidden;
 
     ViewCallback(LibLODocument_Impl* pDocument)
@@ -2245,6 +2249,14 @@ public:
             ++m_nTableSelectionCount;
         }
         break;
+        case LOK_CALLBACK_COLOR_PALETTES:
+        {
+            m_aColorPaletteCallbackResult.clear();
+            std::stringstream aStream(pPayload);
+            boost::property_tree::read_json(aStream, 
m_aColorPaletteCallbackResult);
+            ++m_nColorPaletteCallbackCount;
+        }
+        break;
         }
     }
 };
@@ -3525,6 +3537,34 @@ void DesktopLOKTest::testMultiViewTableSelection()
     CPPUNIT_ASSERT(!aView1.m_bEmptyTableSelection);
 }
 
+void DesktopLOKTest::testColorPaletteCallback()
+{
+    LibLODocument_Impl* pDocument = loadDoc("ThemeDocument.docx");
+
+    // Create view 1.
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    ViewCallback aView1(pDocument);
+    Scheduler::ProcessEventsToIdle();
+    {
+        CPPUNIT_ASSERT_EQUAL(1, aView1.m_nColorPaletteCallbackCount);
+        boost::property_tree::ptree aValues = 
aView1.m_aColorPaletteCallbackResult.get_child("ThemeColors");
+        CPPUNIT_ASSERT(!aValues.empty());
+        CPPUNIT_ASSERT_EQUAL(size_t(6), aValues.size());
+    }
+
+    // Create view 2.
+    pDocument->m_pDocumentClass->createView(pDocument);
+    pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
+    ViewCallback aView2(pDocument);
+    Scheduler::ProcessEventsToIdle();
+    {
+        CPPUNIT_ASSERT_EQUAL(1, aView2.m_nColorPaletteCallbackCount);
+        boost::property_tree::ptree aValues = 
aView1.m_aColorPaletteCallbackResult.get_child("ThemeColors");
+        CPPUNIT_ASSERT(!aValues.empty());
+        CPPUNIT_ASSERT_EQUAL(size_t(6), aValues.size());
+    }
+}
+
 namespace {
 
 constexpr size_t classOffset(int i)
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 13922571d9ce..52cd5411a7e5 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1816,6 +1816,7 @@ void CallbackFlushHandler::queue(const int type, 
CallbackData& aCallbackData)
         case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
         case LOK_CALLBACK_A11Y_CARET_CHANGED:
         case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+        case LOK_CALLBACK_COLOR_PALETTES:
         {
             const auto& pos = std::find(m_queue1.rbegin(), m_queue1.rend(), 
type);
             auto pos2 = toQueue2(pos);
@@ -1877,6 +1878,7 @@ void CallbackFlushHandler::queue(const int type, 
CallbackData& aCallbackData)
             case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
             case LOK_CALLBACK_A11Y_CARET_CHANGED:
             case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+            case LOK_CALLBACK_COLOR_PALETTES:
             {
                 if (removeAll(type))
                     SAL_INFO("lok", "Removed dups of [" << type << "]: [" << 
aCallbackData.getPayload() << "].");
diff --git a/docmodel/source/color/ComplexColorJSON.cxx 
b/docmodel/source/color/ComplexColorJSON.cxx
index d04e2c1e339b..db36f29e6a4e 100644
--- a/docmodel/source/color/ComplexColorJSON.cxx
+++ b/docmodel/source/color/ComplexColorJSON.cxx
@@ -12,7 +12,6 @@
 #include <sstream>
 #include <utility>
 #include <sal/log.hxx>
-#include <boost/property_tree/json_parser.hpp>
 
 namespace model::color
 {
@@ -57,10 +56,9 @@ bool convertFromJSON(OString const& rJsonString, 
model::ComplexColor& rComplexCo
     return true;
 }
 
-OString convertToJSON(model::ComplexColor const& rComplexColor)
+void convertToJSONTree(boost::property_tree::ptree& rTree, model::ComplexColor 
const& rComplexColor)
 {
-    boost::property_tree::ptree aTree;
-    aTree.put("ThemeIndex", sal_Int16(rComplexColor.getSchemeType()));
+    rTree.put("ThemeIndex", sal_Int16(rComplexColor.getSchemeType()));
 
     boost::property_tree::ptree aTransformationsList;
     for (auto const& rTransformation : rComplexColor.getTransformations())
@@ -91,10 +89,15 @@ OString convertToJSON(model::ComplexColor const& 
rComplexColor)
             aTransformationsList.push_back(std::make_pair("", aChild));
         }
     }
-    aTree.add_child("Transformations", aTransformationsList);
+    rTree.add_child("Transformations", aTransformationsList);
+}
+
+OString convertToJSON(model::ComplexColor const& rComplexColor)
+{
+    boost::property_tree::ptree aTree;
+    convertToJSONTree(aTree, rComplexColor);
     std::stringstream aStream;
     boost::property_tree::write_json(aStream, aTree);
-
     return OString(aStream.str());
 }
 
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 47b2d790738f..d6e46e96aee1 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -955,7 +955,12 @@ typedef enum
      *  }
      *  where [N1,N2] is the range of the text selection inside the focused 
paragraph.
      */
-    LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED = 64
+    LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED = 64,
+
+    /**
+     * Informs the LibreOfficeKit client that the color palettes have changed.
+    */
+    LOK_CALLBACK_COLOR_PALETTES = 65
 }
 LibreOfficeKitCallbackType;
 
@@ -1114,6 +1119,8 @@ static inline const char* lokCallbackTypeToString(int 
nType)
         return "LOK_CALLBACK_A11Y_CARET_CHANGED";
     case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
         return "LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED";
+    case LOK_CALLBACK_COLOR_PALETTES:
+        return "LOK_CALLBACK_COLOR_PALETTES";
     }
 
     assert(!"Unknown LibreOfficeKitCallbackType type.");
diff --git a/include/docmodel/color/ComplexColorJSON.hxx 
b/include/docmodel/color/ComplexColorJSON.hxx
index bf23e4f0565a..b4aa4bfb3354 100644
--- a/include/docmodel/color/ComplexColorJSON.hxx
+++ b/include/docmodel/color/ComplexColorJSON.hxx
@@ -12,10 +12,13 @@
 
 #include <docmodel/dllapi.h>
 #include <docmodel/color/ComplexColor.hxx>
+#include <boost/property_tree/json_parser.hpp>
 
 namespace model::color
 {
 DOCMODEL_DLLPUBLIC OString convertToJSON(model::ComplexColor const& 
rComplexColor);
+DOCMODEL_DLLPUBLIC void convertToJSONTree(boost::property_tree::ptree& rTree,
+                                          model::ComplexColor const& 
rComplexColor);
 DOCMODEL_DLLPUBLIC bool convertFromJSON(OString const& rJsonString,
                                         model::ComplexColor& rComplexColor);
 
diff --git a/include/svx/svdpage.hxx b/include/svx/svdpage.hxx
index 778e8c2ee327..6a65712719f1 100644
--- a/include/svx/svdpage.hxx
+++ b/include/svx/svdpage.hxx
@@ -327,6 +327,7 @@ private:
 
     SdrPageProperties& operator=(const SdrPageProperties& rCandidate) = delete;
 
+    void sendLOKitThemeChangedCallback();
 public:
     // construct/destruct
     SdrPageProperties(SdrPage& rSdrPage);
diff --git a/include/svx/theme/ThemeColorPaletteManager.hxx 
b/include/svx/theme/ThemeColorPaletteManager.hxx
index 14fbda39248b..d575c1038750 100644
--- a/include/svx/theme/ThemeColorPaletteManager.hxx
+++ b/include/svx/theme/ThemeColorPaletteManager.hxx
@@ -60,6 +60,7 @@ class SVXCORE_DLLPUBLIC ThemeColorPaletteManager final
 public:
     ThemeColorPaletteManager(std::shared_ptr<model::ColorSet> const& 
pColorSet);
     ThemePaletteCollection generate();
+    OString generateJSON();
 };
 
 } // end svx namespace
diff --git a/libreofficekit/source/gtk/lokdocview.cxx 
b/libreofficekit/source/gtk/lokdocview.cxx
index 6d810f2d1e3f..305ac5a477d2 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1491,6 +1491,7 @@ callback (gpointer pData)
     case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
     case LOK_CALLBACK_A11Y_CARET_CHANGED:
     case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+    case LOK_CALLBACK_COLOR_PALETTES:
     {
         // TODO: Implement me
         break;
diff --git a/sd/source/ui/inc/ViewShellBase.hxx 
b/sd/source/ui/inc/ViewShellBase.hxx
index ed80658d096c..7ef425416612 100644
--- a/sd/source/ui/inc/ViewShellBase.hxx
+++ b/sd/source/ui/inc/ViewShellBase.hxx
@@ -217,6 +217,8 @@ public:
     int getEditMode() const override;
     /// See SfxViewShell::setEditMode().
     void setEditMode(int nMode);
+    /// See SfxViewShell::afterCallbackRegistered().
+    void afterCallbackRegistered() override;
     /// See SfxViewShell::NotifyCursor().
     void NotifyCursor(SfxViewShell* pViewShell) const override;
 
diff --git a/sd/source/ui/view/ViewShellBase.cxx 
b/sd/source/ui/view/ViewShellBase.cxx
index 64d0950c366c..9099988969d8 100644
--- a/sd/source/ui/view/ViewShellBase.cxx
+++ b/sd/source/ui/view/ViewShellBase.cxx
@@ -1009,6 +1009,11 @@ void ViewShellBase::setEditMode(int nMode)
     }
 }
 
+void ViewShellBase::afterCallbackRegistered()
+{
+    // TODO: Add theme color palette changed callback
+}
+
 void ViewShellBase::NotifyCursor(SfxViewShell* pOtherShell) const
 {
     ViewShell* pThisShell = 
framework::FrameworkHelper::Instance(*const_cast<ViewShellBase*>(this))->GetViewShell(FrameworkHelper::msCenterPaneURL).get();
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
index f7df7c12a730..d165300292f7 100644
--- a/svx/source/svdraw/svdpage.cxx
+++ b/svx/source/svdraw/svdpage.cxx
@@ -30,6 +30,7 @@
 
 #include <tools/debug.hxx>
 #include <comphelper/diagnose_ex.hxx>
+#include <comphelper/lok.hxx>
 
 #include <svtools/colorcfg.hxx>
 #include <svx/svdetc.hxx>
@@ -46,6 +47,7 @@
 #include <svx/fmdpage.hxx>
 #include <svx/theme/ThemeColorChanger.hxx>
 #include <svx/ColorSets.hxx>
+#include <svx/theme/ThemeColorPaletteManager.hxx>
 
 #include <sdr/contact/viewcontactofsdrpage.hxx>
 #include <svx/sdr/contact/viewobjectcontact.hxx>
@@ -56,6 +58,8 @@
 #include <rtl/strbuf.hxx>
 #include <libxml/xmlwriter.h>
 #include <docmodel/theme/Theme.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include <com/sun/star/lang/IllegalArgumentException.hpp>
 
@@ -1201,6 +1205,7 @@ SdrPageProperties::SdrPageProperties(SdrPage& rSdrPage)
         {
             std::shared_ptr<model::ColorSet> pDefaultColorSet(new 
model::ColorSet(*pColorSet));
             mpTheme->setColorSet(pDefaultColorSet);
+            sendLOKitThemeChangedCallback();
         }
     }
 }
@@ -1273,8 +1278,13 @@ void SdrPageProperties::SetStyleSheet(SfxStyleSheet* 
pStyleSheet)
 
 void SdrPageProperties::SetTheme(std::shared_ptr<model::Theme> const& pTheme)
 {
+    if (mpTheme == pTheme)
+        return;
+
     mpTheme = pTheme;
 
+    sendLOKitThemeChangedCallback();
+
     if (mpTheme && mpTheme->getColorSet() && mpSdrPage->IsMasterPage())
     {
         SdrModel& rModel = mpSdrPage->getSdrModelFromSdrPage();
@@ -1293,6 +1303,15 @@ void 
SdrPageProperties::SetTheme(std::shared_ptr<model::Theme> const& pTheme)
     }
 }
 
+void SdrPageProperties::sendLOKitThemeChangedCallback()
+{
+    if (!comphelper::LibreOfficeKit::isActive())
+        return;
+
+    svx::ThemeColorPaletteManager aManager(mpTheme->getColorSet());
+    SfxLokHelper::notifyAllViews(LOK_CALLBACK_COLOR_PALETTES, 
aManager.generateJSON());
+}
+
 std::shared_ptr<model::Theme> const& SdrPageProperties::GetTheme() const
 {
     return mpTheme;
diff --git a/svx/source/theme/ThemeColorPaletteManager.cxx 
b/svx/source/theme/ThemeColorPaletteManager.cxx
index 82ebb38fb69a..c1fcc9fc0aa7 100644
--- a/svx/source/theme/ThemeColorPaletteManager.cxx
+++ b/svx/source/theme/ThemeColorPaletteManager.cxx
@@ -15,6 +15,8 @@
 #include <svx/dialmgr.hxx>
 #include <svx/strings.hrc>
 #include <docmodel/theme/ColorSet.hxx>
+#include <docmodel/color/ComplexColorJSON.hxx>
+#include <boost/property_tree/json_parser.hpp>
 
 #include <array>
 
@@ -125,6 +127,47 @@ svx::ThemePaletteCollection 
ThemeColorPaletteManager::generate()
     return aThemePaletteCollection;
 }
 
+OString ThemeColorPaletteManager::generateJSON()
+{
+    svx::ThemePaletteCollection aThemePaletteCollection = generate();
+
+    boost::property_tree::ptree aTree;
+    boost::property_tree::ptree aColorListTree;
+
+    for (size_t nEffect = 0; nEffect < 6; ++nEffect)
+    {
+        boost::property_tree::ptree aColorRowTree;
+        for (size_t nIndex = 0; nIndex < 12; ++nIndex)
+        {
+            auto const& rColorData = aThemePaletteCollection.maColors[nIndex];
+            auto const& rEffectData = rColorData.maEffects[nEffect];
+
+            boost::property_tree::ptree aColorTree;
+            aColorTree.put("Value", 
rEffectData.maColor.AsRGBHexString().toUtf8());
+            aColorTree.put("Name", rEffectData.maColorName.toUtf8());
+
+            model::ComplexColor aComplexColor;
+            aComplexColor.setSchemeColor(rColorData.meThemeColorType);
+            aComplexColor.addTransformation(
+                { model::TransformationType::LumMod, rEffectData.mnLumMod });
+            aComplexColor.addTransformation(
+                { model::TransformationType::LumMod, rEffectData.mnLumOff });
+            boost::property_tree::ptree aDataTree;
+            model::color::convertToJSONTree(aDataTree, aComplexColor);
+            aColorTree.add_child("Data", aDataTree);
+            aColorRowTree.push_back(std::make_pair("", aColorTree));
+        }
+        aColorListTree.push_back(std::make_pair("", aColorRowTree));
+    }
+
+    aTree.add_child("ThemeColors", aColorListTree);
+
+    std::stringstream aStream;
+    boost::property_tree::write_json(aStream, aTree);
+
+    return OString(aStream.str());
+}
+
 } // end svx namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx
index 60fe6fdc7303..89b5ad6f391b 100644
--- a/sw/inc/view.hxx
+++ b/sw/inc/view.hxx
@@ -670,6 +670,8 @@ public:
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
     void SetRedlineAuthor(const OUString& rAuthor);
     const OUString& GetRedlineAuthor() const;
+    /// See SfxViewShell::afterCallbackRegistered().
+    void afterCallbackRegistered() override;
     /// See SfxViewShell::NotifyCursor().
     void NotifyCursor(SfxViewShell* pViewShell) const override;
     void ShowUIElement(const OUString& sElementURL) const;
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index b035e53eb38f..dcd88c9e05d4 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <hintids.hxx>
 #include <comphelper/string.hxx>
+#include <comphelper/lok.hxx>
 #include <o3tl/any.hxx>
 #include <o3tl/string_view.hxx>
 #include <officecfg/Office/Common.hxx>
@@ -100,7 +101,7 @@
 #include <PostItMgr.hxx>
 #include <annotsh.hxx>
 #include <swruler.hxx>
-
+#include <svx/theme/ThemeColorPaletteManager.hxx>
 #include <com/sun/star/document/XDocumentProperties.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 
@@ -1177,6 +1178,18 @@ SwView::~SwView()
     m_pFormatClipboard.reset();
 }
 
+void SwView::afterCallbackRegistered()
+{
+    if (!comphelper::LibreOfficeKit::isActive())
+        return;
+    auto* pDocShell = GetDocShell();
+    if (pDocShell)
+    {
+        svx::ThemeColorPaletteManager aManager(pDocShell->GetThemeColors());
+        libreOfficeKitViewCallback(LOK_CALLBACK_COLOR_PALETTES, 
aManager.generateJSON());
+    }
+}
+
 SwDocShell* SwView::GetDocShell()
 {
     SfxObjectShell* pDocShell = GetViewFrame().GetObjectShell();

Reply via email to