[Libreoffice-commits] core.git: include/LibreOfficeKit libreofficekit/source sw/inc sw/source

Pranav Kant pranavk at collabora.co.uk
Fri Jan 27 11:50:53 UTC 2017


 include/LibreOfficeKit/LibreOfficeKitEnums.h |   26 ++++
 libreofficekit/source/gtk/lokdocview.cxx     |    4 
 sw/inc/PostItMgr.hxx                         |    2 
 sw/source/uibase/docvw/PostItMgr.cxx         |  158 +++++++++++++++++++++------
 4 files changed, 154 insertions(+), 36 deletions(-)

New commits:
commit 5f5073a84518e4a8660e0153c2e218fb75a85ec4
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Jan 24 14:07:45 2017 +0530

    lok: Implement new callbacks for comment notifications
    
    Change-Id: I298183b295c68c4a39cb1f6fffe4b89b4eaee0f3
    Reviewed-on: https://gerrit.libreoffice.org/33469
    Reviewed-by: pranavk <pranavk at collabora.co.uk>
    Tested-by: pranavk <pranavk at collabora.co.uk>

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index f3dccd0..8a59b4c 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -467,6 +467,32 @@ typedef enum
      * - 'action' is 'Modify'.
      */
     LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED = 31,
+
+    /**
+     * There is some change in comments in the document
+     *
+     * The payload example:
+     * {
+     *     "comment": {
+     *         "action": "Add",
+     *         "id": "11",
+     *         "parent": "4",
+     *         "author": "Unknown Author",
+     *         "text": "",
+     *         "dateTime": "2016-08-18T13:13:00",
+     *         "anchorPos": "4529, 3906",
+     *         "textRange": "1418, 3906, 3111, 919"
+     *     }
+     * }
+     *
+     * The format is the same as an entry of
+     * lok::Document::getCommandValues('.uno:ViewAnnotations'), extra
+     * fields:
+     *
+     * - 'action' can be 'Add', 'Remove' or 'Modify' depending on whether
+     *    comment has been added, removed or modified.
+     */
+    LOK_CALLBACK_COMMENT = 32
 }
 LibreOfficeKitCallbackType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index c9c32af..1cd2c05 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -426,6 +426,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED";
     case LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED:
         return "LOK_CALLBACK_REDLINE_TABLE_ENTRY_MODIFIED";
+    case LOK_CALLBACK_COMMENT:
+        return "LOK_CALLBACK_COMMENT";
     }
     g_assert(false);
     return nullptr;
@@ -1395,6 +1397,8 @@ callback (gpointer pData)
     {
         break;
     }
+    case LOK_CALLBACK_COMMENT:
+        break;
     default:
         g_assert(false);
         break;
diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx
index 68887aa..97448fd 100644
--- a/sw/inc/PostItMgr.hxx
+++ b/sw/inc/PostItMgr.hxx
@@ -186,7 +186,7 @@ class SwPostItMgr: public SfxListener
 
         sw::sidebarwindows::SwSidebarWin* GetSidebarWin(const SfxBroadcaster* pBroadcaster) const;
 
-        void            InsertItem( SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus);
+        SwSidebarItem*  InsertItem( SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus);
         void            RemoveItem( SfxBroadcaster* pBroadcast );
 
     public:
diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx
index d169a89..43b1b55 100644
--- a/sw/source/uibase/docvw/PostItMgr.cxx
+++ b/sw/source/uibase/docvw/PostItMgr.cxx
@@ -17,11 +17,13 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <boost/property_tree/json_parser.hpp>
+
 #include "PostItMgr.hxx"
 #include <postithelper.hxx>
 
-#include <SidebarWin.hxx>
 #include <AnnotationWin.hxx>
+#include <SidebarWin.hxx>
 #include <frmsidebarwincontainer.hxx>
 #include <accmap.hxx>
 
@@ -53,6 +55,7 @@
 #include <docary.hxx>
 #include <SwRewriter.hxx>
 #include <tools/color.hxx>
+#include <unotools/datetime.hxx>
 
 #include <swmodule.hxx>
 #include <annotation.hrc>
@@ -75,6 +78,8 @@
 #include <i18nlangtag/mslangid.hxx>
 #include <i18nlangtag/lang.h>
 #include <comphelper/lok.hxx>
+#include <comphelper/string.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include "annotsh.hxx"
 #include "swabstdlg.hxx"
@@ -94,37 +99,89 @@
 
 using namespace sw::sidebarwindows;
 
-bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b)
-{
-    // sort by anchor position
-    SwPosition aPosAnchorA = a->GetAnchorPosition();
-    SwPosition aPosAnchorB = b->GetAnchorPosition();
+namespace {
 
-    bool aAnchorAInFooter = false;
-    bool aAnchorBInFooter = false;
+    enum class CommentNotificationType { Add, Remove, Modify };
 
-    // is the anchor placed in Footnote or the Footer?
-    if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() )
-        aAnchorAInFooter = true;
-    if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() )
-        aAnchorBInFooter = true;
+    bool comp_pos(const SwSidebarItem* a, const SwSidebarItem* b)
+    {
+        // sort by anchor position
+        SwPosition aPosAnchorA = a->GetAnchorPosition();
+        SwPosition aPosAnchorB = b->GetAnchorPosition();
 
-    // fdo#34800
-    // if AnchorA is in footnote, and AnchorB isn't
-    // we do not want to change over the position
-    if( aAnchorAInFooter && !aAnchorBInFooter )
-        return false;
-    // if aAnchorA is not placed in a footnote, and aAnchorB is
-    // force a change over
-    else if( !aAnchorAInFooter && aAnchorBInFooter )
-        return true;
-    // If neither or both are in the footer, compare the positions.
-    // Since footnotes are in Inserts section of nodes array and footers
-    // in Autotext section, all footnotes precede any footers so no need
-    // to check that.
-    else
-        return aPosAnchorA < aPosAnchorB;
-}
+        bool aAnchorAInFooter = false;
+        bool aAnchorBInFooter = false;
+
+        // is the anchor placed in Footnote or the Footer?
+        if( aPosAnchorA.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorA.nNode.GetNode().FindFooterStartNode() )
+            aAnchorAInFooter = true;
+        if( aPosAnchorB.nNode.GetNode().FindFootnoteStartNode() || aPosAnchorB.nNode.GetNode().FindFooterStartNode() )
+            aAnchorBInFooter = true;
+
+        // fdo#34800
+        // if AnchorA is in footnote, and AnchorB isn't
+        // we do not want to change over the position
+        if( aAnchorAInFooter && !aAnchorBInFooter )
+            return false;
+        // if aAnchorA is not placed in a footnote, and aAnchorB is
+        // force a change over
+        else if( !aAnchorAInFooter && aAnchorBInFooter )
+            return true;
+        // If neither or both are in the footer, compare the positions.
+        // Since footnotes are in Inserts section of nodes array and footers
+        // in Autotext section, all footnotes precede any footers so no need
+        // to check that.
+        else
+            return aPosAnchorA < aPosAnchorB;
+    }
+
+    /// Emits LOK notification about one addition/removal/change of a comment
+    void lcl_CommentNotification(const SwView* pView, const CommentNotificationType nType, const SwSidebarItem* pItem, const sal_uInt32 nPostItId)
+    {
+        if (!comphelper::LibreOfficeKit::isActive())
+            return;
+
+        boost::property_tree::ptree aAnnotation;
+        aAnnotation.put("action", (nType == CommentNotificationType::Add ? "Add" :
+                                   (nType == CommentNotificationType::Remove ? "Remove" :
+                                    (nType == CommentNotificationType::Modify ? "Modify" : "???"))));
+        aAnnotation.put("id", nPostItId);
+        if (nType != CommentNotificationType::Remove && pItem != nullptr)
+        {
+            sw::annotation::SwAnnotationWin* pWin = static_cast<sw::annotation::SwAnnotationWin*>((pItem)->pPostIt.get());
+
+            const SwPostItField* pField = pWin->GetPostItField();
+            const std::string aAnchorPos = std::to_string(pWin->GetAnchorPos().X()) + ", " + std::to_string(pWin->GetAnchorPos().Y());
+            std::vector<OString> aRects;
+            for (const basegfx::B2DRange& aRange : pWin->GetAnnotationTextRanges())
+            {
+                const SwRect rect(aRange.getMinX(), aRange.getMinY(), aRange.getWidth(), aRange.getHeight());
+                aRects.push_back(rect.SVRect().toString());
+            }
+            const OString sRects = comphelper::string::join("; ", aRects);
+
+            aAnnotation.put("id", pField->GetPostItId());
+            aAnnotation.put("reply", pWin->IsFollow());
+            aAnnotation.put("author", pField->GetPar1().toUtf8().getStr());
+            aAnnotation.put("text", pField->GetPar2().toUtf8().getStr());
+            aAnnotation.put("dateTime", utl::toISO8601(pField->GetDateTime().GetUNODateTime()));
+            aAnnotation.put("anchorPos", aAnchorPos.c_str());
+            aAnnotation.put("textRange", sRects.getStr());
+        }
+
+        boost::property_tree::ptree aTree;
+        aTree.add_child("comment", aAnnotation);
+        std::stringstream aStream;
+        boost::property_tree::write_json(aStream, aTree);
+        std::string aPayload = aStream.str();
+
+        if (pView)
+        {
+            pView->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload.c_str());
+        }
+    }
+
+} // anonymous namespace
 
 SwPostItMgr::SwPostItMgr(SwView* pView)
     : mpView(pView)
@@ -216,21 +273,27 @@ void SwPostItMgr::CheckForRemovedPostIts()
     }
 }
 
-void SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus)
+SwSidebarItem* SwPostItMgr::InsertItem(SfxBroadcaster* pItem, bool bCheckExistance, bool bFocus)
 {
+    SwSidebarItem* pAnnotationItem = nullptr;
     if (bCheckExistance)
     {
         for(std::list<SwSidebarItem*>::iterator i = mvPostItFields.begin(); i != mvPostItFields.end() ; ++i)
         {
             if ( (*i)->GetBroadCaster() == pItem )
-                return;
+                return pAnnotationItem;
         }
     }
     mbLayout = bFocus;
+
     if (dynamic_cast< const SwFormatField *>( pItem ) !=  nullptr)
-        mvPostItFields.push_back(new SwAnnotationItem(static_cast<SwFormatField&>(*pItem), bFocus) );
+    {
+        pAnnotationItem = new SwAnnotationItem(static_cast<SwFormatField&>(*pItem), bFocus);
+        mvPostItFields.push_back(pAnnotationItem);
+    }
     OSL_ENSURE(dynamic_cast< const SwFormatField *>( pItem ) !=  nullptr,"Mgr::InsertItem: seems like new stuff was added");
     StartListening(*pItem);
+    return pAnnotationItem;
 }
 
 void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast )
@@ -282,9 +345,22 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
                 if ( pField->IsFieldInDoc() )
                 {
                     bool bEmpty = !HasNotes();
-                    InsertItem( pField, true, false );
+                    SwSidebarItem* pItem = InsertItem( pField, true, false );
+
                     if (bEmpty && !mvPostItFields.empty())
                         PrepareView(true);
+
+                    // If LOK has disabled tiled annotations, emit annotation callbacks
+                    if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
+                    {
+                        CalcRects();
+                        Show();
+
+                        if (pItem && pItem->pPostIt)
+                        {
+                            lcl_CommentNotification(mpView, CommentNotificationType::Add, pItem, 0);
+                        }
+                    }
                 }
                 else
                 {
@@ -302,6 +378,13 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
                         break;
                     }
                     RemoveItem(pField);
+
+                    // If LOK has disabled tiled annotations, emit annotation callbacks
+                    if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
+                    {
+                        SwPostItField* pPostItField = static_cast<SwPostItField*>(pField->GetField());
+                        lcl_CommentNotification(mpView, CommentNotificationType::Remove, nullptr, pPostItField->GetPostItId());
+                    }
                 }
                 break;
             }
@@ -313,7 +396,7 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
             }
             case SwFormatFieldHintWhich::CHANGED:
             {
-                        SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC);
+                SwFormatField* pFormatField = dynamic_cast<SwFormatField*>(&rBC);
                 for(std::list<SwSidebarItem*>::iterator i = mvPostItFields.begin(); i != mvPostItFields.end() ; ++i)
                 {
                     if ( pFormatField == (*i)->GetBroadCaster() )
@@ -323,6 +406,12 @@ void SwPostItMgr::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
                             (*i)->pPostIt->SetPostItText();
                             mbLayout = true;
                         }
+
+                        // If LOK has disabled tiled annotations, emit annotation callbacks
+                        if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
+                        {
+                            lcl_CommentNotification(mpView, CommentNotificationType::Modify, *i, 0);
+                        }
                         break;
                     }
                 }
@@ -458,7 +547,6 @@ bool SwPostItMgr::CalcRects()
                 bRepair = true;
                 continue;
             }
-
             const SwRect aOldAnchorRect( pItem->maLayoutInfo.mPosition );
             const SwPostItHelper::SwLayoutStatus eOldLayoutStatus = pItem->mLayoutStatus;
             const sal_uLong nOldStartNodeIdx( pItem->maLayoutInfo.mnStartNodeIdx );


More information about the Libreoffice-commits mailing list