[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.1' - 18 commits - desktop/CppunitTest_desktop_lib.mk desktop/inc desktop/qa desktop/source editeng/source include/editeng include/LibreOfficeKit include/sfx2 include/svx include/vcl ios/experimental libreofficekit/qa libreofficekit/README libreofficekit/source sc/source sd/qa sfx2/sdi sfx2/source sw/inc sw/qa sw/source test/Package_unittest.mk test/user-template

Ashod Nakashian ashod.nakashian at collabora.co.uk
Sun Jun 19 16:42:15 UTC 2016


 desktop/CppunitTest_desktop_lib.mk                                             |    5 
 desktop/inc/lib/init.hxx                                                       |   74 ++
 desktop/qa/desktop_lib/test_desktop_lib.cxx                                    |  344 +++++++++-
 desktop/source/lib/init.cxx                                                    |   80 ++
 desktop/source/lib/lokandroid.cxx                                              |    2 
 editeng/source/editeng/impedit.hxx                                             |    1 
 include/LibreOfficeKit/LibreOfficeKit.h                                        |   21 
 include/LibreOfficeKit/LibreOfficeKit.hxx                                      |   30 
 include/LibreOfficeKit/LibreOfficeKitEnums.h                                   |    4 
 include/LibreOfficeKit/LibreOfficeKitTypes.h                                   |    4 
 include/editeng/editview.hxx                                                   |    1 
 include/editeng/outliner.hxx                                                   |    1 
 include/sfx2/objsh.hxx                                                         |    1 
 include/sfx2/viewsh.hxx                                                        |    1 
 include/svx/svdmodel.hxx                                                       |    1 
 include/vcl/ITiledRenderable.hxx                                               |    1 
 ios/experimental/TiledLibreOffice/TiledLibreOffice/AppDelegate.m               |    1 
 ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.h                 |    1 
 ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m                 |    1 
 ios/experimental/TiledLibreOffice/TiledLibreOffice/View.m                      |    1 
 libreofficekit/README                                                          |    2 
 libreofficekit/qa/tilebench/tilebench.cxx                                      |    2 
 libreofficekit/qa/unit/tiledrendering.cxx                                      |    1 
 libreofficekit/source/gtk/lokdocview.cxx                                       |    1 
 sc/source/ui/view/gridwin.cxx                                                  |    1 
 sc/source/ui/view/gridwin4.cxx                                                 |    1 
 sd/qa/unit/tiledrendering/tiledrendering.cxx                                   |    1 
 sfx2/sdi/sfx.sdi                                                               |    2 
 sfx2/source/control/bindings.cxx                                               |    4 
 sfx2/source/control/unoctitm.cxx                                               |   25 
 sfx2/source/menu/mnumgr.cxx                                                    |    8 
 sw/inc/PostItMgr.hxx                                                           |    1 
 sw/inc/docsh.hxx                                                               |    1 
 sw/inc/viewsh.hxx                                                              |    1 
 sw/qa/extras/tiledrendering/tiledrendering.cxx                                 |    6 
 sw/source/core/crsr/swcrsr.cxx                                                 |    3 
 sw/source/core/crsr/viscrs.cxx                                                 |    4 
 sw/source/core/layout/trvlfrm.cxx                                              |    3 
 sw/source/core/view/viewimp.cxx                                                |    5 
 sw/source/uibase/dochdl/swdtflvr.cxx                                           |   12 
 sw/source/uibase/docvw/SidebarScrollBar.cxx                                    |    1 
 sw/source/uibase/docvw/SidebarWin.cxx                                          |    2 
 sw/source/uibase/docvw/edtwin.cxx                                              |   18 
 sw/source/uibase/inc/swdtflvr.hxx                                              |    6 
 sw/source/uibase/inc/wrtsh.hxx                                                 |    2 
 sw/source/uibase/shells/basesh.cxx                                             |    8 
 sw/source/uibase/uno/unotxdoc.cxx                                              |    1 
 sw/source/uibase/wrtsh/wrtsh1.cxx                                              |    8 
 sw/source/uibase/wrtsh/wrtsh2.cxx                                              |    3 
 test/Package_unittest.mk                                                       |    3 
 test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml    |   40 +
 test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml |   49 +
 test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml  |   53 +
 53 files changed, 762 insertions(+), 91 deletions(-)

New commits:
commit 3dc777d4d630c6a869afd9bae0615f35221ed773
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Tue May 24 21:24:34 2016 -0400

    bccu#1811 - Writer comment focusing / selection / cursor issue
    
    Partially based on fd205e40c58aa749fbe458d74ca0c2373a1017dc
    which caused make desktop.check to fail when viewsh.?xx
    changes were included, so left them out.
    
    Reviewed-on: https://gerrit.libreoffice.org/25421
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 0d7920952a8748e3e2f02f7b27d624598d974006)
    
    Change-Id: I5b4576d2385c1812f358a2434b87c8ca62024430

diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index ed9cf71..c51bd74 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -168,6 +168,7 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload)
 
 void SwTiledRenderingTest::testRegisterCallback()
 {
+    comphelper::LibreOfficeKit::setActive();
     SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
     pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this);
     SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
@@ -178,6 +179,7 @@ void SwTiledRenderingTest::testRegisterCallback()
     CPPUNIT_ASSERT(!m_aInvalidation.IsEmpty());
     Rectangle aTopLeft(0, 0, 256*15, 256*15); // 1 px = 15 twips, assuming 96 DPI.
     CPPUNIT_ASSERT(m_aInvalidation.IsOver(aTopLeft));
+    comphelper::LibreOfficeKit::setActive(false);
 }
 
 void SwTiledRenderingTest::testPostKeyEvent()
@@ -197,6 +199,7 @@ void SwTiledRenderingTest::testPostKeyEvent()
 
 void SwTiledRenderingTest::testPostMouseEvent()
 {
+    comphelper::LibreOfficeKit::setActive();
     SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
     SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
     pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, /*bBasicCall=*/false);
@@ -210,6 +213,7 @@ void SwTiledRenderingTest::testPostMouseEvent()
     pXTextDocument->postMouseEvent(LOK_MOUSEEVENT_MOUSEBUTTONUP, aStart.getX(), aStart.getY(), 1);
     // The new cursor position must be before the first word.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pShellCursor->GetPoint()->nContent.GetIndex());
+    comphelper::LibreOfficeKit::setActive(false);
 }
 
 void SwTiledRenderingTest::testSetTextSelection()
@@ -436,6 +440,7 @@ void SwTiledRenderingTest::testSearchTextFrameWrapAround()
 
 void SwTiledRenderingTest::testDocumentSizeChanged()
 {
+    comphelper::LibreOfficeKit::setActive();
     // Get the current document size.
     SwXTextDocument* pXTextDocument = createDoc("2-pages.odt");
     pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this);
@@ -449,6 +454,7 @@ void SwTiledRenderingTest::testDocumentSizeChanged()
     CPPUNIT_ASSERT_EQUAL(aSize.getWidth(), m_aDocumentSize.getWidth());
     // Document height should be smaller now.
     CPPUNIT_ASSERT(aSize.getHeight() > m_aDocumentSize.getHeight());
+    comphelper::LibreOfficeKit::setActive(false);
 }
 
 void SwTiledRenderingTest::testSearchAll()
diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index 6d759be..de2417f 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -52,6 +52,7 @@
 #include <redline.hxx>
 #include <txatbase.hxx>
 #include <memory>
+#include <comphelper/lok.hxx>
 
 using namespace ::com::sun::star::i18n;
 
@@ -1379,7 +1380,7 @@ bool SwCursor::SelectWordWT( SwViewShell* pViewShell, sal_Int16 nWordType, const
                                 nWordType,
                                 bForward ));
 
-            if (pViewShell->isTiledRendering() && aBndry.startPos == aBndry.endPos && nPtPos > 0)
+            if (comphelper::LibreOfficeKit::isActive() && aBndry.startPos == aBndry.endPos && nPtPos > 0)
             {
                 // nPtPos is the end of the paragraph, select the last word then.
                 --nPtPos;
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 28f540d..e25b334 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -92,7 +92,7 @@ void SwVisibleCursor::Show()
         m_bIsVisible = true;
 
         // display at all?
-        if( m_pCursorShell->VisArea().IsOver( m_pCursorShell->m_aCharRect ) || m_pCursorShell->isTiledRendering() )
+        if( m_pCursorShell->VisArea().IsOver( m_pCursorShell->m_aCharRect ) || comphelper::LibreOfficeKit::isActive() )
             _SetPosAndShow();
     }
 }
@@ -757,7 +757,7 @@ void SwShellTableCursor::FillRects()
 
     bool bStart = true;
     SwRegionRects aReg( GetShell()->VisArea() );
-    if (GetShell()->isTiledRendering())
+    if (comphelper::LibreOfficeKit::isActive())
         aReg = GetShell()->getIDocumentLayoutAccess().GetCurrentLayout()->Frame();
     SwNodes& rNds = GetDoc()->GetNodes();
     SwFrame* pEndFrame = nullptr;
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index aa86732..c955254 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -47,6 +47,7 @@
 
 #include <cfloat>
 #include <swselectionlist.hxx>
+#include <comphelper/lok.hxx>
 
 namespace {
     bool lcl_GetCursorOfst_Objects( const SwPageFrame* pPageFrame, bool bSearchBackground,
@@ -2020,7 +2021,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor)
 
     bool bIgnoreVisArea = true;
     if (pSh)
-        bIgnoreVisArea = pSh->GetViewOptions()->IsPDFExport() || pSh->isTiledRendering();
+        bIgnoreVisArea = pSh->GetViewOptions()->IsPDFExport() || comphelper::LibreOfficeKit::isActive();
 
     // #i12836# enhanced pdf
     SwRegionRects aRegion( !bIgnoreVisArea ?
diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx
index d84ffa9..7d6017c 100644
--- a/sw/source/core/view/viewimp.cxx
+++ b/sw/source/core/view/viewimp.cxx
@@ -35,6 +35,7 @@
 #include <pagepreviewlayout.hxx>
 #include <comcore.hrc>
 #include <svx/svdundo.hxx>
+#include <comphelper/lok.hxx>
 #include <IDocumentLayoutAccess.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <IDocumentDeviceAccess.hxx>
@@ -132,13 +133,13 @@ void SwViewShellImp::DelRegion()
 bool SwViewShellImp::AddPaintRect( const SwRect &rRect )
 {
     // In case of tiled rendering the visual area is the last painted tile -> not interesting.
-    if ( rRect.IsOver( m_pShell->VisArea() ) || m_pShell->isTiledRendering() )
+    if ( rRect.IsOver( m_pShell->VisArea() ) || comphelper::LibreOfficeKit::isActive() )
     {
         if ( !m_pRegion )
         {
             // In case of normal rendering, this makes sure only visible rectangles are painted.
             // Otherwise get the rectangle of the full document, so all paint rectangles are invalidated.
-            const SwRect& rArea = m_pShell->isTiledRendering() ? m_pShell->GetLayout()->Frame() : m_pShell->VisArea();
+            const SwRect& rArea = comphelper::LibreOfficeKit::isActive() ? m_pShell->GetLayout()->Frame() : m_pShell->VisArea();
             m_pRegion = new SwRegionRects( rArea );
         }
         (*m_pRegion) -= rRect;
diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx
index 8e9ef75..3340e01 100644
--- a/sw/source/uibase/docvw/SidebarWin.cxx
+++ b/sw/source/uibase/docvw/SidebarWin.cxx
@@ -618,7 +618,7 @@ void SwSidebarWin::InitControls()
         LibreOfficeKitCallback pCallback = nullptr;
         void* pData = nullptr;
         pDrawModel->getLibreOfficeKitCallback(pCallback, pData);
-        mpOutlinerView->setTiledRendering(comphelper::LibreOfficeKit::isActive());
+        mpOutlinerView->setTiledRendering(true);
         mpOutlinerView->registerLibreOfficeKitCallback(pCallback, pData, pDrawModel);
     }
 
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 48ccdf2..69ec7c583 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3321,7 +3321,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                             {
                             case nsSelectionType::SEL_GRF:
                                 RstMBDownFlags();
-                                if (!rSh.isTiledRendering())
+                                if (!comphelper::LibreOfficeKit::isActive())
                                 {
                                     GetView().GetViewFrame()->GetBindings().Execute(
                                         FN_FORMAT_GRAFIC_DLG, nullptr, 0,
@@ -3340,7 +3340,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
 
                             case nsSelectionType::SEL_FRM:
                                 RstMBDownFlags();
-                                if (!rSh.isTiledRendering())
+                                if (!comphelper::LibreOfficeKit::isActive())
                                 {
                                     GetView().GetViewFrame()->GetBindings().Execute(
                                         FN_FORMAT_FRAME_DLG, nullptr, 0,
@@ -3359,7 +3359,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
 
                         // if the cursor position was corrected or if a Fly
                         // was selected in ReadOnlyMode, no word selection, except when tiled rendering.
-                        if ((!g_bValidCursorPos || rSh.IsFrameSelected()) && !rSh.isTiledRendering())
+                        if ((!g_bValidCursorPos || rSh.IsFrameSelected()) && !comphelper::LibreOfficeKit::isActive())
                             return;
 
                         SwField *pField;
@@ -3411,7 +3411,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
                         }
                         else
                         {
-                            if (!rSh.SelWrd(&aDocPos) && rSh.isTiledRendering())
+                            if (!rSh.SelWrd(&aDocPos) && comphelper::LibreOfficeKit::isActive())
                                 // Double click did not select any word: try to
                                 // select the current cell in case we are in a
                                 // table.
@@ -3814,7 +3814,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
     }
 
     const Point aOldPt( rSh.VisArea().Pos() );
-    const bool bInsWin = rSh.VisArea().IsInside( aDocPt ) || rSh.isTiledRendering();
+    const bool bInsWin = rSh.VisArea().IsInside( aDocPt ) || comphelper::LibreOfficeKit::isActive();
 
     if( m_pShadCursor && !bInsWin )
         delete m_pShadCursor, m_pShadCursor = nullptr;
@@ -4918,7 +4918,7 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt)
     if (bCallBase)
         Window::MouseButtonUp(rMEvt);
 
-    if (pSdrView && rMEvt.GetClicks() == 1 && rSh.isTiledRendering())
+    if (pSdrView && rMEvt.GetClicks() == 1 && comphelper::LibreOfficeKit::isActive())
     {
         // When tiled rendering, single click on a shape text starts editing already.
         SdrViewEvent aViewEvent;
@@ -6328,7 +6328,7 @@ void SwEditWin::LogicInvalidate(const Rectangle* pRectangle)
 void SwEditWin::LogicMouseButtonDown(const MouseEvent& rMouseEvent)
 {
     // When we're not doing tiled rendering, then positions must be passed as pixels.
-    assert(m_rView.GetWrtShell().isTiledRendering());
+    assert(comphelper::LibreOfficeKit::isActive());
 
     Point aPoint = GetPointerPosPixel();
     SetLastMousePos(rMouseEvent.GetPosPixel());
@@ -6341,7 +6341,7 @@ void SwEditWin::LogicMouseButtonDown(const MouseEvent& rMouseEvent)
 void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
 {
     // When we're not doing tiled rendering, then positions must be passed as pixels.
-    assert(m_rView.GetWrtShell().isTiledRendering());
+    assert(comphelper::LibreOfficeKit::isActive());
 
     Point aPoint = GetPointerPosPixel();
     SetLastMousePos(rMouseEvent.GetPosPixel());
@@ -6354,7 +6354,7 @@ void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
 void SwEditWin::LogicMouseMove(const MouseEvent& rMouseEvent)
 {
     // When we're not doing tiled rendering, then positions must be passed as pixels.
-    assert(m_rView.GetWrtShell().isTiledRendering());
+    assert(comphelper::LibreOfficeKit::isActive());
 
     Point aPoint = GetPointerPosPixel();
     SetLastMousePos(rMouseEvent.GetPosPixel());
diff --git a/sw/source/uibase/wrtsh/wrtsh2.cxx b/sw/source/uibase/wrtsh/wrtsh2.cxx
index 1f88e46..b4ceabf 100644
--- a/sw/source/uibase/wrtsh/wrtsh2.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh2.cxx
@@ -67,6 +67,7 @@
 #include <memory>
 
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <comphelper/lok.hxx>
 
 void SwWrtShell::Insert(SwField &rField)
 {
@@ -472,7 +473,7 @@ void LoadURL( SwViewShell& rVSh, const OUString& rURL, sal_uInt16 nFilter,
         return;
 
     // We are doing tiledRendering, let the client handles the URL loading.
-    if (rVSh.isTiledRendering())
+    if (comphelper::LibreOfficeKit::isActive())
     {
         rVSh.libreOfficeKitCallback(LOK_CALLBACK_HYPERLINK_CLICKED, rURL.toUtf8().getStr());
         return;
commit a4e64ca050ddbc489f7fe98acae84fa5272112ea
Author: Henry Castro <hcastro at collabora.com>
Date:   Fri May 27 16:38:47 2016 -0400

    lok: add uno command AssignLayout
    
    Change-Id: I959d1a57945a3b5aa3f2c273c4b885ed5f628f6e
    (cherry picked from commit b0c0d4eff911a1d2619c0cac5a0e86220d9747ab)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index a67d3bf..65447f0 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -794,7 +794,8 @@ static void doc_iniUnoCommands ()
         OUString(".uno:EntireRow"),
         OUString(".uno:EntireColumn"),
         OUString(".uno:EntireCell"),
-        OUString(".uno:MergeCells")
+        OUString(".uno:MergeCells"),
+        OUString(".uno:AssignLayout")
     };
 
     util::URL aCommandURL;
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index d9179e1..af314f5 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1140,6 +1140,12 @@ void SfxDispatchController_Impl::InterceptLOKStateChangeEvent(const SfxObjectShe
     {
         aBuffer.append(OUString::boolean(aEvent.IsEnabled));
     }
+    else if (aEvent.FeatureURL.Path == "AssignLayout")
+    {
+        sal_Int32 nLayout = 0;
+        aEvent.State >>= nLayout;
+        aBuffer.append(nLayout);
+    }
     else
     {
         return;
commit a1fc1453ef22ef01fca3c45a3040c74560d7168c
Author: Pranav Kant <pranavk at collabora.com>
Date:   Tue May 24 16:52:27 2016 +0530

    lok context menu: Remove disabled items (set enabled to false)
    
    Change-Id: I18a95cc53f9e79eab257baa4d7b23853cb05e039
    (cherry picked from commit 7e4711e642f6b085698a0d2912b0381cb7a2c9c3)

diff --git a/sfx2/source/menu/mnumgr.cxx b/sfx2/source/menu/mnumgr.cxx
index 1797ccc..c465279 100644
--- a/sfx2/source/menu/mnumgr.cxx
+++ b/sfx2/source/menu/mnumgr.cxx
@@ -469,6 +469,8 @@ void SfxPopupMenuManager::ExecutePopup( const ResId& rResId, SfxViewFrame* pFram
             pSVMenu = static_cast<PopupMenu*>( pMenu );
         }
 
+        SfxPopupMenuManager aPop( pSVMenu, pFrame->GetBindings() );
+        aPop.RemoveDisabledEntries();
         if (comphelper::LibreOfficeKit::isActive())
         {
             boost::property_tree::ptree aMenu = fillPopupMenu(pSVMenu);
@@ -481,11 +483,7 @@ void SfxPopupMenuManager::ExecutePopup( const ResId& rResId, SfxViewFrame* pFram
             objSh->libreOfficeKitCallback(LOK_CALLBACK_CONTEXT_MENU, aStream.str().c_str());
         }
         else
-        {
-            SfxPopupMenuManager aPop( pSVMenu, pFrame->GetBindings() );
-            aPop.RemoveDisabledEntries();
             aPop.Execute( rPoint, pWindow );
-        }
 
         // #i112646 avoid crash when context menu is closed.
         // the (manually inserted) sub-menu needs to be destroyed before
commit 626a20c792456fef73d2bd81749aac21be92f0d3
Author: Pranav Kant <pranavk at collabora.com>
Date:   Mon May 23 13:32:47 2016 +0530

    lok: Subcribe to more uno commands for state change
    
    Change-Id: Id2870b176de4163fbe01e4ac380b4981d3187d90
    (cherry picked from commit ddcbda3c48acab14928b91756836ca44543720c3)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 410081b..a67d3bf 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -777,7 +777,24 @@ static void doc_iniUnoCommands ()
         OUString(".uno:Redo"),
         OUString(".uno:InsertPage"),
         OUString(".uno:DeletePage"),
-        OUString(".uno:DuplicatePage")
+        OUString(".uno:DuplicatePage"),
+        OUString(".uno:Cut"),
+        OUString(".uno:Copy"),
+        OUString(".uno:Paste"),
+        OUString(".uno:SelectAll"),
+        OUString(".uno:InsertAnnotation"),
+        OUString(".uno:InsertRowsBefore"),
+        OUString(".uno:InsertRowsAfter"),
+        OUString(".uno:InsertColumnsBefore"),
+        OUString(".uno:InsertColumnsAfter"),
+        OUString(".uno:DeleteRows"),
+        OUString(".uno:DeleteColumns"),
+        OUString(".uno:DeleteTable"),
+        OUString(".uno:SelectTable"),
+        OUString(".uno:EntireRow"),
+        OUString(".uno:EntireColumn"),
+        OUString(".uno:EntireCell"),
+        OUString(".uno:MergeCells")
     };
 
     util::URL aCommandURL;
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 13dd5b5..d9179e1 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1113,7 +1113,24 @@ void SfxDispatchController_Impl::InterceptLOKStateChangeEvent(const SfxObjectShe
         aBuffer.append(nColor);
     }
     else if (aEvent.FeatureURL.Path == "Undo" ||
-             aEvent.FeatureURL.Path == "Redo")
+             aEvent.FeatureURL.Path == "Redo" ||
+             aEvent.FeatureURL.Path == "Cut" ||
+             aEvent.FeatureURL.Path == "Copy" ||
+             aEvent.FeatureURL.Path == "Paste" ||
+             aEvent.FeatureURL.Path == "SelectAll" ||
+             aEvent.FeatureURL.Path == "InsertAnnotation" ||
+             aEvent.FeatureURL.Path == "InsertRowsBefore" ||
+             aEvent.FeatureURL.Path == "InsertRowsAfter" ||
+             aEvent.FeatureURL.Path == "InsertColumnsBefore" ||
+             aEvent.FeatureURL.Path == "InsertColumnsAfter" ||
+             aEvent.FeatureURL.Path == "DeleteRows" ||
+             aEvent.FeatureURL.Path == "DeleteColumns" ||
+             aEvent.FeatureURL.Path == "DeleteTable" ||
+             aEvent.FeatureURL.Path == "SelectTable" ||
+             aEvent.FeatureURL.Path == "EntireRow" ||
+             aEvent.FeatureURL.Path == "EntireColumn" ||
+             aEvent.FeatureURL.Path == "EntireCell" ||
+             aEvent.FeatureURL.Path == "MergeCells")
     {
         aBuffer.append(aEvent.IsEnabled ? OUString("enabled") : OUString("disabled"));
     }
commit 7ef3e05ea35d0160e2f985ceb9680070063de290
Author: Pranav Kant <pranavk at collabora.com>
Date:   Mon May 16 17:14:55 2016 +0530

    lok context menu: Include uno commands for submenus too
    
    Change-Id: I4ba49ba94a3270a5d53754320e5fbd49e3f5c848
    (cherry picked from commit 96744275f4ead236e666a2c39037300c4924f771)

diff --git a/sfx2/source/menu/mnumgr.cxx b/sfx2/source/menu/mnumgr.cxx
index 7ea4dd8..1797ccc 100644
--- a/sfx2/source/menu/mnumgr.cxx
+++ b/sfx2/source/menu/mnumgr.cxx
@@ -383,6 +383,8 @@ namespace {
                         continue;
 
                     aItemTree.put("type", "menu");
+                    if (!aCommandURL.isEmpty())
+                        aItemTree.put("command", aCommandURL.toUtf8().getStr());
                     aItemTree.push_back(std::make_pair("menu", aSubmenu));
                 }
                 else
commit 25dcfb998903b50c5ceb2b0047e8370dccd02c98
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun May 8 12:02:54 2016 -0400

    LOK: drop identical invalidation notifications
    
    And drop duplicate GRAPHIC_SELECTION notifications.
    
    Change-Id: I0c372efa9a58620e24cea219d82479cdc9dff359
    Reviewed-on: https://gerrit.libreoffice.org/24771
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 7cdfe080432f69c2247cc7ff28316b653bd654ff)

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index ec0b501..7344b28 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -43,6 +43,7 @@ namespace desktop {
             m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_START, "NIL");
             m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, "NIL");
             m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
+            m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
             m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
             m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
             m_states.emplace(LOK_CALLBACK_MOUSE_POINTER, "NIL");
@@ -85,7 +86,6 @@ namespace desktop {
                 return;
             }
 
-
             const std::string payload(data ? data : "(nil)");
             std::unique_lock<std::mutex> lock(m_mutex);
 
@@ -124,13 +124,14 @@ namespace desktop {
                 case LOK_CALLBACK_TEXT_SELECTION_START:
                 case LOK_CALLBACK_TEXT_SELECTION_END:
                 case LOK_CALLBACK_TEXT_SELECTION:
+                case LOK_CALLBACK_GRAPHIC_SELECTION:
                 case LOK_CALLBACK_MOUSE_POINTER:
                 case LOK_CALLBACK_CELL_CURSOR:
                 case LOK_CALLBACK_CELL_FORMULA:
                 case LOK_CALLBACK_CURSOR_VISIBLE:
                 case LOK_CALLBACK_SET_PART:
                 case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
-                    removeAllButLast(type);
+                    removeAllButLast(type, false);
                 break;
 
                 // These come with rects, so drop earlier
@@ -139,10 +140,15 @@ namespace desktop {
                 case LOK_CALLBACK_INVALIDATE_TILES:
                     if (payload.empty())
                     {
-                        // Invalidating everything means previous
+                        // Invalidating everything means previously
                         // invalidated tiles can be dropped.
-                        removeAllButLast(type);
+                        removeAllButLast(type, false);
+                    }
+                    else
+                    {
+                        removeAllButLast(type, true);
                     }
+
                 break;
             }
 
@@ -171,23 +177,26 @@ namespace desktop {
             }
         }
 
-        void removeAllButLast(const int type)
+        void removeAllButLast(const int type, const bool identical)
         {
             int i = m_queue.size() - 1;
+            std::string payload;
             for (; i >= 0; --i)
             {
                 if (m_queue[i].first == type)
                 {
-                    //SAL_WARN("idle", "Found [" + std::to_string(type) + "] at " + std::to_string(i));
+                    payload = m_queue[i].second;
+                    //SAL_WARN("idle", "Found [" + std::to_string(type) + "] at " + std::to_string(i) + ": [" + payload + "].");
                     break;
                 }
             }
 
             for (--i; i >= 0; --i)
             {
-                if (m_queue[i].first == type)
+                if (m_queue[i].first == type &&
+                    (!identical || m_queue[i].second == payload))
                 {
-                    //SAL_WARN("idle", "Removing [" + std::to_string(type) + "] at " + std::to_string(i));
+                    //SAL_WARN("idle", "Removing [" + std::to_string(type) + "] at " + std::to_string(i) + ": " + m_queue[i].second + "].");
                     m_queue.erase(m_queue.begin() + i);
                 }
             }
commit 039c54e51c8ce99494dbe10abb9aa43575852cab
Author: Pranav Kant <pranavk at collabora.com>
Date:   Fri Apr 8 20:08:38 2016 +0530

    lok context menu: unit test
    
    Reviewed-on: https://gerrit.libreoffice.org/23985
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: pranavk <pranavk at collabora.com>
    (cherry picked from commit d76b1b5b06c064938986c0b921b8d537fdf8bf4c)
    
    Change-Id: I244fbf4b98368c7c0d66cdd865e1243639727026
    Reviewed-on: https://gerrit.libreoffice.org/24732
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit c01a98e42c2cc2e130c738d0656f7446aea2e119)

diff --git a/test/Package_unittest.mk b/test/Package_unittest.mk
index 77c4593..8001731 100644
--- a/test/Package_unittest.mk
+++ b/test/Package_unittest.mk
@@ -21,5 +21,8 @@ $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/sta
 $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autotext/en-US/crdbus50.bau,user/autotext/en-US/crdbus50.bau))
 $(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/.dummy,empty-directory-dummy))
 $(eval $(call gb_Package_add_file,test_unittest,unittest/user/autocorr/acor_en-US.dat,user/autocorr/acor_fr.dat))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml,user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml,user/config/soffice.cfg/modules/swriter/popupmenu/text.xml))
+$(eval $(call gb_Package_add_file,test_unittest,unittest/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml,user/config/soffice.cfg/modules/simpress/popupmenu/page.xml))
 
 # vim: set noet sw=4 ts=4:
diff --git a/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml
new file mode 100644
index 0000000..57ecd28
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/scalc/popupmenu/cell.xml
@@ -0,0 +1,40 @@
+<?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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+  <menu:menuitem menu:id=".uno:Cut"/>
+  <menu:menuitem menu:id=".uno:Copy"/>
+  <menu:menuitem menu:id=".uno:Paste"/>
+  <menu:menuitem menu:id=".uno:PasteSpecial"/>
+  <menu:menu menu:id=".uno:PasteOnly">
+    <menu:menupopup>
+      <menu:menuitem menu:id=".uno:PasteOnlyText"/>
+      <menu:menuitem menu:id=".uno:PasteOnlyValue"/>
+      <menu:menuitem menu:id=".uno:PasteOnlyFormula"/>
+    </menu:menupopup>
+  </menu:menu>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:ResetAttributes"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:FormatCellDialog"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:InsertCell"/>
+  <menu:menuitem menu:id=".uno:DeleteCell"/>
+  <menu:menuitem menu:id=".uno:Delete"/>
+  <menu:menuitem menu:id=".uno:MergeCells"/>
+  <menu:menuitem menu:id=".uno:SplitCell"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:InsertAnnotation"/>
+  <menu:menuitem menu:id=".uno:EditAnnotation"/>
+  <menu:menuitem menu:id=".uno:DeleteNote"/>
+  <menu:menuitem menu:id=".uno:ShowNote"/>
+  <menu:menuitem menu:id=".uno:HideNote"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:DataSelect"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml b/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml
new file mode 100644
index 0000000..02ff497
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/simpress/popupmenu/page.xml
@@ -0,0 +1,49 @@
+<?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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+  <menu:menuitem menu:id=".uno:Cut"/>
+  <menu:menuitem menu:id=".uno:Copy"/>
+  <menu:menuitem menu:id=".uno:Paste"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:SlideSetup"/>
+  <menu:menuitem menu:id=".uno:SelectBackground"/>
+  <menu:menuitem menu:id=".uno:SaveBackground"/>
+  <menu:menu menu:id=".uno:SlideFeaturesMenu">
+    <menu:menupopup>
+      <menu:menuitem menu:id=".uno:HideSlide"/>
+      <menu:menuitem menu:id=".uno:ShowSlide"/>
+      <menu:menuseparator/>
+      <menu:menuitem menu:id=".uno:DisplayMasterBackground"/>
+      <menu:menuitem menu:id=".uno:DisplayMasterObjects"/>
+      <menu:menuitem menu:id=".uno:MasterLayouts"/>
+      <menu:menuseparator/>
+      <menu:menuitem menu:id=".uno:PresentationLayout"/>
+    </menu:menupopup>
+  </menu:menu>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:ShowRuler"/>
+  <menu:menu menu:id=".uno:GridMenu">
+    <menu:menupopup>
+      <menu:menuitem menu:id=".uno:GridVisible"/>
+      <menu:menuitem menu:id=".uno:GridUse"/>
+      <menu:menuitem menu:id=".uno:GridFront"/>
+    </menu:menupopup>
+  </menu:menu>
+  <menu:menu menu:id=".uno:SnapLinesMenu">
+    <menu:menupopup>
+      <menu:menuitem menu:id=".uno:HelplinesVisible"/>
+      <menu:menuitem menu:id=".uno:HelplinesUse"/>
+      <menu:menuitem menu:id=".uno:HelplinesFront"/>
+    </menu:menupopup>
+  </menu:menu>
+  <menu:menuitem menu:id=".uno:CapturePoint"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:LeaveGroup"/>
+</menu:menupopup>
diff --git a/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml b/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml
new file mode 100644
index 0000000..a6a6021
--- /dev/null
+++ b/test/user-template/user/config/soffice.cfg/modules/swriter/popupmenu/text.xml
@@ -0,0 +1,53 @@
+<?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/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+  <menu:menuitem menu:id=".uno:Cut"/>
+  <menu:menuitem menu:id=".uno:Copy"/>
+  <menu:menuitem menu:id=".uno:Paste"/>
+  <menu:menu menu:id=".uno:PasteSpecialMenu">
+    <menu:menupopup>
+      <menu:menuitem menu:id=".uno:PasteUnformatted"/>
+      <menu:menuitem menu:id=".uno:PasteSpecial"/>
+    </menu:menupopup>
+  </menu:menu>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:NumberingStart"/>
+  <menu:menuitem menu:id=".uno:ContinueNumbering"/>
+  <menu:menuitem menu:id=".uno:IncrementLevel"/>
+  <menu:menuitem menu:id=".uno:DecrementLevel"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:FontDialog"/>
+  <menu:menuitem menu:id=".uno:ParagraphDialog"/>
+  <menu:menuitem menu:id=".uno:OutlineBullet"/>
+  <menu:menuitem menu:id=".uno:PageDialog"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:UpdateCurIndex"/>
+  <menu:menuitem menu:id=".uno:EditCurIndex"/>
+  <menu:menuitem menu:id=".uno:RemoveTableOf"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:FieldDialog"/>
+  <menu:menuitem menu:id=".uno:EditFootnote"/>
+  <menu:menuitem menu:id=".uno:IndexEntryDialog"/>
+  <menu:menuitem menu:id=".uno:AuthoritiesEntryDialog"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:AcceptTrackedChange"/>
+  <menu:menuitem menu:id=".uno:RejectTrackedChange"/>
+  <menu:menuitem menu:id=".uno:NextTrackedChange"/>
+  <menu:menuitem menu:id=".uno:PreviousTrackedChange"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:EditStyle"/>
+  <menu:menuseparator/>
+  <menu:menuitem menu:id=".uno:OpenHyperlinkOnCursor"/>
+  <menu:menuitem menu:id=".uno:EditHyperlink"/>
+  <menu:menuitem menu:id=".uno:CopyHyperlinkLocation"/>
+  <menu:menuitem menu:id=".uno:RemoveHyperlink"/>
+  <menu:menuitem menu:id=".uno:OpenSmartTagMenuOnCursor"/>
+  <menu:menuitem menu:id=".uno:ThesaurusFromContext"/>
+</menu:menupopup>
commit 6c6399f91e6633cf7309704d79e13cdd1dfc77d9
Author: Andras Timar <andras.timar at collabora.com>
Date:   Sun Jun 19 17:24:00 2016 +0200

    fix/merge desktop unit tests
    
    Change-Id: Ic46b8fb79cd66e2f004fe826cbc036db37e48bbd

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index d6b18e1..9ab6fbd 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -14,7 +14,6 @@
 #include <com/sun/star/awt/Key.hpp>
 #include <com/sun/star/awt/XReschedule.hpp>
 #include <com/sun/star/awt/Toolkit.hpp>
-#include <basebmp/bitmapdevice.hxx>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/util/XModifiable.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
@@ -30,6 +29,7 @@
 #include <svl/srchitem.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <unotools/tempfile.hxx>
+#include <vcl/svapp.hxx>
 
 #include <lib/init.hxx>
 
@@ -86,7 +86,11 @@ public:
     void testWriterComments();
     void testModifiedStatus();
     void testSheetOperations();
+    void testContextMenuCalc();
+    void testContextMenuWriter();
+    void testContextMenuImpress();
     void testNotificationCompression();
+
     CPPUNIT_TEST_SUITE(DesktopLOKTest);
     CPPUNIT_TEST(testGetStyles);
     CPPUNIT_TEST(testGetFonts);
@@ -107,6 +111,9 @@ public:
     CPPUNIT_TEST(testWriterComments);
     CPPUNIT_TEST(testModifiedStatus);
     CPPUNIT_TEST(testSheetOperations);
+    CPPUNIT_TEST(testContextMenuCalc);
+    CPPUNIT_TEST(testContextMenuWriter);
+    CPPUNIT_TEST(testContextMenuImpress);
     CPPUNIT_TEST(testNotificationCompression);
     CPPUNIT_TEST_SUITE_END();
 
@@ -124,6 +131,10 @@ public:
     // for testModifiedStatus
     osl::Condition m_aStateChangedCondition;
     bool m_bModified;
+
+    // for testContextMenu{Calc, Writer}
+    osl::Condition m_aContextMenuCondition;
+    boost::property_tree::ptree m_aContextMenuResult;
 };
 
 LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType)
@@ -211,6 +222,14 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload)
         }
     }
     break;
+    case LOK_CALLBACK_CONTEXT_MENU:
+    {
+        m_aContextMenuResult.clear();
+        std::stringstream aStream(pPayload);
+        boost::property_tree::read_json(aStream, m_aContextMenuResult);
+        m_aContextMenuCondition.set();
+    }
+    break;
     }
 }
 
@@ -336,6 +355,7 @@ void DesktopLOKTest::testSearchCalc()
         {"SearchItem.Backward", uno::makeAny(false)},
         {"SearchItem.Command", uno::makeAny(static_cast<sal_uInt16>(SvxSearchCmd::FIND_ALL))},
     }));
+
     comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
     Scheduler::ProcessEventsToIdle();
 
@@ -386,9 +406,7 @@ void DesktopLOKTest::testPaintTile()
     LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
     int nCanvasWidth = 100;
     int nCanvasHeight = 300;
-    sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(basebmp::Format::ThirtyTwoBitTcMaskBGRA,
-                                                               nCanvasWidth);
-    std::vector<unsigned char> aBuffer(nStride * nCanvasHeight);
+    std::vector<unsigned char> aBuffer(nCanvasWidth * nCanvasHeight * 4);
     int nTilePosX = 0;
     int nTilePosY = 0;
     int nTileWidth = 1000;
@@ -449,7 +467,6 @@ void DesktopLOKTest::testPasteWriterJPEG()
 {
     comphelper::LibreOfficeKit::setActive();
     LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
-    OString aText("hello");
 
     OUString aFileURL;
     createFileURL(OUString::createFromAscii("paste.jpg"), aFileURL);
@@ -623,7 +640,7 @@ void DesktopLOKTest::testCommandResult()
     m_aCommandResultCondition.reset();
     pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", nullptr, true);
     Scheduler::ProcessEventsToIdle();
-    m_aCommandResultCondition.wait(aTimeValue);
+    m_aCommandResultCondition.wait(&aTimeValue);
 
     CPPUNIT_ASSERT(m_aCommandResult.isEmpty());
 
@@ -633,7 +650,7 @@ void DesktopLOKTest::testCommandResult()
     m_aCommandResultCondition.reset();
     pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", nullptr, true);
     Scheduler::ProcessEventsToIdle();
-    m_aCommandResultCondition.wait(aTimeValue);
+    m_aCommandResultCondition.wait(&aTimeValue);
 
     boost::property_tree::ptree aTree;
     std::stringstream aStream(m_aCommandResult.getStr());
@@ -656,7 +673,8 @@ void DesktopLOKTest::testWriterComments()
     m_aCommandResultCondition.reset();
     pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", nullptr, true);
     Scheduler::ProcessEventsToIdle();
-    m_aCommandResultCondition.wait(aTimeValue);
+
+    m_aCommandResultCondition.wait(&aTimeValue);
     CPPUNIT_ASSERT(!m_aCommandResult.isEmpty());
     xToolkit->reschedule();
 
@@ -696,6 +714,7 @@ void DesktopLOKTest::testModifiedStatus()
     m_bModified = false;
     m_aStateChangedCondition.reset();
     pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
+    Scheduler::ProcessEventsToIdle();
     TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max
     m_aStateChangedCondition.wait(&aTimeValue);
     Scheduler::ProcessEventsToIdle();
@@ -709,6 +728,7 @@ void DesktopLOKTest::testModifiedStatus()
     utl::TempFile aTempFile;
     aTempFile.EnableKillingFile();
     CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", "TakeOwnership"));
+    Scheduler::ProcessEventsToIdle();
     m_aStateChangedCondition.wait(&aTimeValue);
     Scheduler::ProcessEventsToIdle();
 
@@ -718,6 +738,7 @@ void DesktopLOKTest::testModifiedStatus()
     // Modify the document again
     m_aStateChangedCondition.reset();
     pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
+    Scheduler::ProcessEventsToIdle();
     m_aStateChangedCondition.wait(&aTimeValue);
     Scheduler::ProcessEventsToIdle();
 
@@ -785,44 +806,207 @@ void DesktopLOKTest::testNotificationCompression()
     std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(callbackCompressionTest, &notifs));
 
     handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // 0
-    handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // 1
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // Superseeded.
     handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // Should be dropped.
-    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // 2
+    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // Superseeded.
     handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // Should be dropped.
-    handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // 3
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // Superseeded.
+    handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 2
+    handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:Bold"); // 3
     handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 4
-    handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:Bold"); // 5
-    handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 6
-    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // 7
+    handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"); // 5
+    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // 6
     handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_MOUSE_POINTER, "text"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15 25 15 10"); // Superseeded.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15 25 15 10"); // Superseeded.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // Superseedd.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15 25 15 10"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15 25 15 10"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // 7
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_START, "15 25 15 10"); // 8
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION_END, "15 25 15 10"); // 9
+    handler->queue(LOK_CALLBACK_CELL_CURSOR, "15 25 15 10"); // 10
+    handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""); // 11
+    handler->queue(LOK_CALLBACK_CELL_CURSOR, "15 25 15 10"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"); // 12
+    handler->queue(LOK_CALLBACK_SET_PART, "1"); // 13
+    handler->queue(LOK_CALLBACK_CURSOR_VISIBLE, ""); // Should be dropped.
+    handler->queue(LOK_CALLBACK_CELL_FORMULA, "blah"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_SET_PART, "1"); // Should be dropped.
+
+    Scheduler::ProcessEventsToIdle();
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(13), notifs.size());
+
+    size_t i = 0;
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(".uno:Bold"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_MOUSE_POINTER, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("text"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION_START, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION_END, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_CELL_CURSOR, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_CURSOR_VISIBLE, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_CELL_FORMULA, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("blah"), std::get<1>(notifs[i++]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_SET_PART, (int)std::get<0>(notifs[i]));
+    CPPUNIT_ASSERT_EQUAL(std::string("1"), std::get<1>(notifs[i++]));
+}
+
+namespace {
+
+    void verifyContextMenuStructure(boost::property_tree::ptree& aRoot)
+    {
+        for (const auto& aItemPair: aRoot)
+        {
+            // This is an array, so no key
+            CPPUNIT_ASSERT_EQUAL(std::string(aItemPair.first.data()), std::string(""));
+
+            boost::property_tree::ptree aItemValue = aItemPair.second;
+            boost::optional<boost::property_tree::ptree&> aText = aItemValue.get_child_optional("text");
+            boost::optional<boost::property_tree::ptree&> aType = aItemValue.get_child_optional("type");
+            boost::optional<boost::property_tree::ptree&> aCommand = aItemValue.get_child_optional("command");
+            boost::optional<boost::property_tree::ptree&> aSubmenu = aItemValue.get_child_optional("menu");
+            boost::optional<boost::property_tree::ptree&> aEnabled = aItemValue.get_child_optional("enabled");
+            boost::optional<boost::property_tree::ptree&> aChecktype = aItemValue.get_child_optional("checktype");
+            boost::optional<boost::property_tree::ptree&> aChecked = aItemValue.get_child_optional("checked");
+
+            // type is omnipresent
+            CPPUNIT_ASSERT( aType );
+
+            // seperator doesn't have any other attribs
+            if ( aType.get().data() == "separator" )
+            {
+                CPPUNIT_ASSERT( !aText && !aCommand && !aSubmenu && !aEnabled && !aChecktype && !aChecked );
+            }
+            else if ( aType.get().data() == "command" )
+            {
+                CPPUNIT_ASSERT( aCommand && aText );
+            }
+            else if ( aType.get().data() == "menu")
+            {
+                CPPUNIT_ASSERT( aSubmenu && aText );
+                verifyContextMenuStructure( aSubmenu.get() );
+            }
+
+            if ( aChecktype )
+            {
+                CPPUNIT_ASSERT( aChecktype.get().data() == "radio" ||
+                                aChecktype.get().data() == "checkmark" ||
+                                aChecktype.get().data() == "auto" );
+
+                CPPUNIT_ASSERT( aChecked &&
+                                ( aChecked.get().data() == "true" || aChecked.get().data() == "false" ) );
+            }
+        }
 
-    flushTimers();
+    }
 
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(8), notifs.size());
+} // end anonymous namespace
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, (int)std::get<0>(notifs[0]));
-    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[0]));
+void DesktopLOKTest::testContextMenuCalc()
+{
+    comphelper::LibreOfficeKit::setActive();
+    LibLODocument_Impl* pDocument = loadDoc("sheets.ods", LOK_DOCTYPE_SPREADSHEET);
+    pDocument->pClass->initializeForRendering(pDocument, nullptr);
+    pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION, (int)std::get<0>(notifs[1]));
-    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[1]));
+    // Values in twips
+    int row5 = 1150;
+    int col1 = 1100;
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[2]));
-    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[2]));
+    pDocument->pClass->postMouseEvent(pDocument,
+                                      LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+                                      col1, row5,
+                                      1, 4, 0);
+    Scheduler::ProcessEventsToIdle();
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION, (int)std::get<0>(notifs[3]));
-    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[3]));
+    TimeValue aTimeValue = {2 , 0}; // 2 seconds max
+    m_aContextMenuCondition.wait(&aTimeValue);
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[4]));
-    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[4]));
+    CPPUNIT_ASSERT( !m_aContextMenuResult.empty() );
+    boost::optional<boost::property_tree::ptree&> aMenu = m_aContextMenuResult.get_child_optional("menu");
+    CPPUNIT_ASSERT( aMenu );
+    verifyContextMenuStructure( aMenu.get() );
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[5]));
-    CPPUNIT_ASSERT_EQUAL(std::string(".uno:Bold"), std::get<1>(notifs[5]));
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
+void DesktopLOKTest::testContextMenuWriter()
+{
+    comphelper::LibreOfficeKit::setActive();
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt", LOK_DOCTYPE_TEXT);
+    pDocument->pClass->initializeForRendering(pDocument, nullptr);
+    pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[6]));
-    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[6]));
+    Point aRandomPoint(1150, 1100);
+    pDocument->pClass->postMouseEvent(pDocument,
+                                      LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+                                      aRandomPoint.X(), aRandomPoint.Y(),
+                                      1, 4, 0);
+    Scheduler::ProcessEventsToIdle();
 
-    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[7]));
-    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[7]));
+    TimeValue aTimeValue = {2 , 0}; // 2 seconds max
+    m_aContextMenuCondition.wait(&aTimeValue);
+
+    CPPUNIT_ASSERT( !m_aContextMenuResult.empty() );
+    boost::optional<boost::property_tree::ptree&> aMenu = m_aContextMenuResult.get_child_optional("menu");
+    CPPUNIT_ASSERT( aMenu );
+    verifyContextMenuStructure( aMenu.get() );
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
+void DesktopLOKTest::testContextMenuImpress()
+{
+    comphelper::LibreOfficeKit::setActive();
+    LibLODocument_Impl* pDocument = loadDoc("blank_presentation.odp", LOK_DOCTYPE_PRESENTATION);
+    pDocument->pClass->initializeForRendering(pDocument, nullptr);
+    pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
+
+    Point aRandomPoint(1150, 1100);
+    pDocument->pClass->postMouseEvent(pDocument,
+                                      LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+                                      aRandomPoint.X(), aRandomPoint.Y(),
+                                      1, 4, 0);
+    Scheduler::ProcessEventsToIdle();
+
+    TimeValue aTimeValue = {2 , 0}; // 2 seconds max
+    m_aContextMenuCondition.wait(&aTimeValue);
+
+    CPPUNIT_ASSERT( !m_aContextMenuResult.empty() );
+    boost::optional<boost::property_tree::ptree&> aMenu = m_aContextMenuResult.get_child_optional("menu");
+    CPPUNIT_ASSERT( aMenu );
+    verifyContextMenuStructure( aMenu.get() );
+
+    comphelper::LibreOfficeKit::setActive(false);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
commit a1b8274ca5f674e9c5a17c72eb81e2f64d88e763
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat May 7 16:31:38 2016 -0400

    LOK: SAL_WARN for each removed event is unnecessary
    
    Change-Id: If5e4c7b8751ae4eeb278475fb00118e32c6bb565
    Reviewed-on: https://gerrit.libreoffice.org/24730
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit a6dfeca2bcfae4e935009699678f956132a9bd4f)

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index e2b169e..ec0b501 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -178,7 +178,7 @@ namespace desktop {
             {
                 if (m_queue[i].first == type)
                 {
-                    SAL_WARN("idle", "Found [" + std::to_string(type) + "] at " + std::to_string(i));
+                    //SAL_WARN("idle", "Found [" + std::to_string(type) + "] at " + std::to_string(i));
                     break;
                 }
             }
@@ -187,7 +187,7 @@ namespace desktop {
             {
                 if (m_queue[i].first == type)
                 {
-                    SAL_WARN("idle", "Removing [" + std::to_string(type) + "] at " + std::to_string(i));
+                    //SAL_WARN("idle", "Removing [" + std::to_string(type) + "] at " + std::to_string(i));
                     m_queue.erase(m_queue.begin() + i);
                 }
             }
commit a61ca650e21de3bd896bc6f9abce1481425fb29a
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jan 28 13:31:52 2016 +0100

    sw: add AnchorType parameter to .uno:Paste
    
    Which allows not hardcoding as-char for LOK.
    
    (cherry picked from commit 552361aaad740e55fcfa7993b4111aba354f863f)
    
    Change-Id: I3b2987abbaf1f259c614b7b2a8709f15048d362d

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index a83ed39..d6b18e1 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -467,6 +467,17 @@ void DesktopLOKTest::testPasteWriterJPEG()
     // This was text::TextContentAnchorType_AT_PARAGRAPH.
     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, xShape->getPropertyValue("AnchorType").get<text::TextContentAnchorType>());
 
+    // Delete the pasted picture, and paste again with a custom anchor type.
+    uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY)->dispose();
+    uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
+    {
+        {"AnchorType", uno::makeAny(static_cast<sal_uInt16>(text::TextContentAnchorType_AT_CHARACTER))},
+    }));
+    comphelper::dispatchCommand(".uno:Paste", aPropertyValues);
+    xShape.set(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+    // This was text::TextContentAnchorType_AS_CHARACTER, AnchorType argument was ignored.
+    CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, xShape->getPropertyValue("AnchorType").get<text::TextContentAnchorType>());
+
     comphelper::LibreOfficeKit::setActive(false);
 }
 
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 7d078a3..410081b 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -33,6 +33,7 @@
 #include <comphelper/processfactory.hxx>
 #include <comphelper/string.hxx>
 #include <comphelper/scopeguard.hxx>
+#include <comphelper/propertysequence.hxx>
 
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
@@ -50,6 +51,7 @@
 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
 
 #include <editeng/fontitem.hxx>
 #include <editeng/flstitem.hxx>
@@ -1330,7 +1332,10 @@ static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, cons
         return false;
     }
 
-    uno::Sequence<beans::PropertyValue> aPropertyValues;
+    uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
+    {
+        {"AnchorType", uno::makeAny(static_cast<sal_uInt16>(text::TextContentAnchorType_AS_CHARACTER))},
+    }));
     if (!comphelper::dispatchCommand(".uno:Paste", aPropertyValues))
     {
         gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command";
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index 8c3bad6..e1753da 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -4159,7 +4159,7 @@ SfxBoolItem PartWindow SID_PARTWIN
 
 
 SfxVoidItem Paste SID_PASTE
-()
+(SfxUInt16Item AnchorType FN_PARAM_1)
 [
     /* flags: */
     AutoUpdate = FALSE,
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index 15d6fcd..8921410 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -1133,7 +1133,7 @@ bool SwTransferable::IsPaste( const SwWrtShell& rSh,
     return bIsPaste;
 }
 
-bool SwTransferable::Paste( SwWrtShell& rSh, TransferableDataHelper& rData )
+bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, sal_uInt16 nAnchorType)
 {
     sal_uInt16 nEventAction, nAction=0;
     SotExchangeDest nDestination = SwTransferable::GetSotDestination( rSh );
@@ -1174,7 +1174,7 @@ bool SwTransferable::Paste( SwWrtShell& rSh, TransferableDataHelper& rData )
 
     return EXCHG_INOUT_ACTION_NONE != nAction &&
             SwTransferable::PasteData( rData, rSh, nAction, nFormat,
-                                        nDestination, false, false );
+                                        nDestination, false, false, nullptr, 0, false, nAnchorType );
 }
 
 bool SwTransferable::PasteData( TransferableDataHelper& rData,
@@ -1182,7 +1182,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData,
                             SotExchangeDest nDestination, bool bIsPasteFormat,
                             bool bIsDefault,
                             const Point* pPt, sal_Int8 nDropAction,
-                            bool bPasteSelection )
+                            bool bPasteSelection, sal_uInt16 nAnchorType )
 {
     SwWait aWait( *rSh.GetView().GetDocShell(), false );
     std::unique_ptr<SwTrnsfrActionAndUndo> pAction;
@@ -1515,7 +1515,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData,
         case EXCHG_OUT_ACTION_INSERT_GRAPH:
             bRet = SwTransferable::_PasteGrf( rData, rSh, nFormat,
                                                 SwPasteSdr::Insert, pPt,
-                                                nActionFlags, nDropAction, bNeedToSelectBeforePaste);
+                                                nActionFlags, nDropAction, bNeedToSelectBeforePaste, nAnchorType );
             break;
 
         case EXCHG_OUT_ACTION_REPLACE_DRAWOBJ:
@@ -2258,7 +2258,7 @@ bool SwTransferable::_PasteSdrFormat(  TransferableDataHelper& rData,
 
 bool SwTransferable::_PasteGrf( TransferableDataHelper& rData, SwWrtShell& rSh,
                                 SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point* pPt,
-                                sal_uInt8 nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste)
+                                sal_uInt8 nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, sal_uInt16 nAnchorType )
 {
     bool bRet = false;
 
@@ -2366,7 +2366,7 @@ bool SwTransferable::_PasteGrf( TransferableDataHelper& rData, SwWrtShell& rSh,
             case SwPasteSdr::Insert:
             {
                 SwTransferable::SetSelInShell( rSh, false, pPt );
-                rSh.Insert( sURL, aEmptyOUStr, aGraphic );
+                rSh.Insert( sURL, aEmptyOUStr, aGraphic, nullptr, false, nAnchorType );
                 break;
             }
 
diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx
index 73452d9..76c3709 100644
--- a/sw/source/uibase/inc/swdtflvr.hxx
+++ b/sw/source/uibase/inc/swdtflvr.hxx
@@ -105,7 +105,7 @@ class SW_DLLPUBLIC SwTransferable : public TransferableHelper
 
     static bool _PasteGrf( TransferableDataHelper& rData, SwWrtShell& rSh,
                                 SotClipboardFormatId nFormat, SwPasteSdr nAction, const Point* pPt,
-                                sal_uInt8 nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste);
+                                sal_uInt8 nActionFlags, sal_Int8 nDropAction, bool bNeedToSelectBeforePaste, sal_uInt16 nAnchorType = 0 );
 
     static bool _PasteImageMap( TransferableDataHelper& rData,
                                     SwWrtShell& rSh );
@@ -168,13 +168,13 @@ public:
 
     // paste - methods and helper methods for the paste
     static bool IsPaste( const SwWrtShell&, const TransferableDataHelper& );
-    static bool Paste( SwWrtShell&, TransferableDataHelper& );
+    static bool Paste( SwWrtShell&, TransferableDataHelper&, sal_uInt16 nAnchorType = 0 );
     static bool PasteData( TransferableDataHelper& rData,
                           SwWrtShell& rSh, sal_uInt16 nAction, SotClipboardFormatId nFormat,
                           SotExchangeDest nDestination, bool bIsPasteFormat,
                           bool bIsDefault,
                           const Point* pDDPos = nullptr, sal_Int8 nDropAction = 0,
-                          bool bPasteSelection = false );
+                          bool bPasteSelection = false, sal_uInt16 nAnchorType = 0 );
 
     static bool IsPasteSpecial( const SwWrtShell& rWrtShell,
                                 const TransferableDataHelper& );
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index d5fd881..1b98bd6 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -291,7 +291,7 @@ typedef bool (SwWrtShell:: *FNSimpleMove)();
     // graphic
     void    Insert( const OUString &rPath, const OUString &rFilter,
                     const Graphic &, SwFlyFrameAttrMgr * = nullptr,
-                    bool bRule = false );
+                    bool bRule = false, sal_uInt16 nAnchorType = 0 );
 
     void    InsertByWord( const OUString & );
     void    InsertPageBreak(const OUString *pPageDesc = nullptr, const ::boost::optional<sal_uInt16>& rPgNum = boost::none);
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index f6d6b75..06e3f88 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -284,7 +284,13 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq)
                     // Temporary variables, because the shell could already be
                     // destroyed after the paste.
                     SwView* pView = &rView;
-                    SwTransferable::Paste( rSh, aDataHelper );
+
+                    const SfxUInt16Item* pAnchorType = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
+                    if (pAnchorType)
+                        SwTransferable::Paste(rSh, aDataHelper, pAnchorType->GetValue());
+                    else
+                        SwTransferable::Paste(rSh, aDataHelper);
+
                     if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
                         rSh.EnterSelFrameMode();
                     pView->AttrChangedNotify( &rSh );
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index c10e6ff..90ce1e1 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -241,7 +241,7 @@ void SwWrtShell::Insert( const OUString &rStr )
 
 void SwWrtShell::Insert( const OUString &rPath, const OUString &rFilter,
                          const Graphic &rGrf, SwFlyFrameAttrMgr *pFrameMgr,
-                         bool bRule )
+                         bool bRule, sal_uInt16 nAnchorType )
 {
     ResetCursorStack();
     if ( !CanInsert() )
@@ -277,9 +277,9 @@ void SwWrtShell::Insert( const OUString &rPath, const OUString &rFilter,
         // These must be removed explicitly for the optimal size.
         pFrameMgr->DelAttr(RES_FRM_SIZE);
 
-        if (comphelper::LibreOfficeKit::isActive())
-            // LOK: anchor inserted images as-char by default.
-            pFrameMgr->SetAnchor(FLY_AS_CHAR);
+        if (nAnchorType != 0)
+            // Something other than at-para was requested.
+            pFrameMgr->SetAnchor(static_cast<RndStdIds>(nAnchorType));
     }
     else
     {
commit 91a056e0f9279ac297cd9432e789c848b032b1fd
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Apr 7 08:43:14 2016 +0200

    CppunitTest_desktop_lib: avoid #include "../..." style include
    
    Change-Id: Ib5ce0dee00c9306f89ad4b43af4b34e604147a1c
    (cherry picked from commit 04216006ee038232067bcf74d67b14e8918063f2)
    Reviewed-on: https://gerrit.libreoffice.org/24728
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 2c0e7371e5c353d803d87b96328ea92f2c6a3216)

diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk
index 75418be..b47c61f 100644
--- a/desktop/CppunitTest_desktop_lib.mk
+++ b/desktop/CppunitTest_desktop_lib.mk
@@ -34,6 +34,11 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_lib, \
 
 $(eval $(call gb_CppunitTest_use_external,desktop_lib,boost_headers))
 
+$(eval $(call gb_CppunitTest_set_include,desktop_lib,\
+    -I$(SRCDIR)/desktop/inc \
+    $$(INCLUDE) \
+))
+
 $(eval $(call gb_CppunitTest_use_api,desktop_lib,\
 	offapi \
 	udkapi \
diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 7527fbe..a83ed39 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -31,7 +31,7 @@
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <unotools/tempfile.hxx>
 
-#include "../../inc/lib/init.hxx"
+#include <lib/init.hxx>
 
 using namespace com::sun::star;
 using namespace desktop;
commit 97f5b6c5f17b64aa9da0cc73ab0253147d21d9fc
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sat Apr 23 09:21:00 2016 -0400

    Test desktop notification compression
    
    Reviewed-on: https://gerrit.libreoffice.org/24314
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit bb52a54aa49cbb75820f8ddbfc8e9e94b63281cd)
    
    Change-Id: Ibb9a62bb5e1500a068c24346d6d433012a1bc7dd

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index f419609..7527fbe 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -86,6 +86,7 @@ public:
     void testWriterComments();
     void testModifiedStatus();
     void testSheetOperations();
+    void testNotificationCompression();
     CPPUNIT_TEST_SUITE(DesktopLOKTest);
     CPPUNIT_TEST(testGetStyles);
     CPPUNIT_TEST(testGetFonts);
@@ -106,6 +107,7 @@ public:
     CPPUNIT_TEST(testWriterComments);
     CPPUNIT_TEST(testModifiedStatus);
     CPPUNIT_TEST(testSheetOperations);
+    CPPUNIT_TEST(testNotificationCompression);
     CPPUNIT_TEST_SUITE_END();
 
     uno::Reference<lang::XComponent> mxComponent;
@@ -760,6 +762,58 @@ void DesktopLOKTest::testSheetOperations()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+static void callbackCompressionTest(const int type, const char* payload, void* data)
+{
+    std::vector<std::tuple<int, std::string>>* notifs = reinterpret_cast<std::vector<std::tuple<int, std::string>>*>(data);
+    notifs->emplace_back(type, std::string(payload ? payload : "(nil)"));
+}
+
+void DesktopLOKTest::testNotificationCompression()
+{
+    std::vector<std::tuple<int, std::string>> notifs;
+    std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(callbackCompressionTest, &notifs));
+
+    handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // 0
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // 1
+    handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""); // Should be dropped.
+    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // 2
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15 25 15 10"); // Should be dropped.
+    handler->queue(LOK_CALLBACK_TEXT_SELECTION, ""); // 3
+    handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 4
+    handler->queue(LOK_CALLBACK_STATE_CHANGED, ".uno:Bold"); // 5
+    handler->queue(LOK_CALLBACK_STATE_CHANGED, ""); // 6
+    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // 7
+    handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15 25 15 10"); // Should be dropped.
+
+    flushTimers();
+
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(8), notifs.size());
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, (int)std::get<0>(notifs[0]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[0]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION, (int)std::get<0>(notifs[1]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[1]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[2]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[2]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_TEXT_SELECTION, (int)std::get<0>(notifs[3]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[3]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[4]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[4]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[5]));
+    CPPUNIT_ASSERT_EQUAL(std::string(".uno:Bold"), std::get<1>(notifs[5]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_STATE_CHANGED, (int)std::get<0>(notifs[6]));
+    CPPUNIT_ASSERT_EQUAL(std::string(""), std::get<1>(notifs[6]));
+
+    CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[7]));
+    CPPUNIT_ASSERT_EQUAL(std::string("15 25 15 10"), std::get<1>(notifs[7]));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 3916cec5b7384318de659d6bfb57c44b33206a41
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Thu Feb 11 14:34:07 2016 +0100

    lok: Extend the StatusModified unit test with Save As.
    
    (cherry picked from commit cfa9404319ac5310dc772b3b4a9a3d05721e6940)
    (cherry picked from commit c0dfafab6459ef06ada37ea7ed5c7ebd59388057)
    
    Change-Id: Ie9bbce6892fe1dcf55e23028e68037f996d7c71f
    ad6bb5ba62d114ca760c4215aa8eec872c5d181b
    Reviewed-on: https://gerrit.libreoffice.org/24726
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    
    (cherry picked from commit 6afeaee7055bdadf22e2935203cfc99b63172215)

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index d76b655..f419609 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -679,10 +679,10 @@ void DesktopLOKTest::testModifiedStatus()
     pDocument->pClass->initializeForRendering(pDocument, nullptr);
     pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
 
-    // Set the document as modified.
+    // Type "t" and check that the document was set as modified
+    m_bModified = false;
     m_aStateChangedCondition.reset();
-    uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY);
-    xModifiable->setModified(true);
+    pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
     TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max
     m_aStateChangedCondition.wait(&aTimeValue);
     Scheduler::ProcessEventsToIdle();
@@ -690,6 +690,41 @@ void DesktopLOKTest::testModifiedStatus()
     // This was false, there was no callback about the modified status change.
     CPPUNIT_ASSERT(m_bModified);
 
+    // Perform SaveAs with "TakeOwnership" option set, and check that the
+    // modification state was reset
+    m_aStateChangedCondition.reset();
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", "TakeOwnership"));
+    m_aStateChangedCondition.wait(&aTimeValue);
+    Scheduler::ProcessEventsToIdle();
+
+    // There was no callback about the modified status change.
+    CPPUNIT_ASSERT(!m_bModified);
+
+    // Modify the document again
+    m_aStateChangedCondition.reset();
+    pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
+    m_aStateChangedCondition.wait(&aTimeValue);
+    Scheduler::ProcessEventsToIdle();
+
+    // There was no callback about the modified status change.
+    CPPUNIT_ASSERT(m_bModified);
+
+    /*
+    // TODO: move this to a test where LOK is fully bootstrapped, so that we can
+    // get back the notification about ".uno:Save" too
+    // Now perform a normal "Save", and check the modified state was reset
+    // again
+    m_aStateChangedCondition.reset();
+    pDocument->pClass->postUnoCommand(pDocument, ".uno:Save", nullptr, false);
+    m_aStateChangedCondition.wait(&aTimeValue);
+    Scheduler::ProcessEventsToIdle();
+
+    // There was no callback about the modified status change.
+    CPPUNIT_ASSERT(!m_bModified);
+    */
+
     comphelper::LibreOfficeKit::setActive(false);
 }
 
commit f0d46143f4637304110d6b5a79532c20ec9bcd62
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Jan 19 16:30:59 2016 +0100

    CppunitTest_desktop_lib: add ModifiedStatus callback testcase
    
    (cherry picked from commit cdf08b3aa74bb32ea18b583a9c0c41b91d7819ac)
    
    Reviewed-on: https://gerrit.libreoffice.org/24725
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit e32607559b48523215a8524504fc6faa893c342a)
    
    Change-Id: Ieb7e808ebc7619c3a4a013cad776eeefd6163e22

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 2ad43c0..d76b655 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -16,6 +16,7 @@
 #include <com/sun/star/awt/Toolkit.hpp>
 #include <basebmp/bitmapdevice.hxx>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
 #include <com/sun/star/text/TextContentAnchorType.hpp>
 #include <boost/property_tree/json_parser.hpp>
 #include <comphelper/processfactory.hxx>
@@ -40,7 +41,8 @@ class DesktopLOKTest : public UnoApiTest
 public:
     DesktopLOKTest() : UnoApiTest("/desktop/qa/data/"),
     m_nSelectionBeforeSearchResult(0),
-    m_nSelectionAfterSearchResult(0)
+    m_nSelectionAfterSearchResult(0),
+    m_bModified(false)
     {
     }
 
@@ -82,8 +84,8 @@ public:
     void testCellCursor();
     void testCommandResult();
     void testWriterComments();
+    void testModifiedStatus();
     void testSheetOperations();
-
     CPPUNIT_TEST_SUITE(DesktopLOKTest);
     CPPUNIT_TEST(testGetStyles);
     CPPUNIT_TEST(testGetFonts);
@@ -102,6 +104,7 @@ public:
     CPPUNIT_TEST(testCellCursor);
     CPPUNIT_TEST(testCommandResult);
     CPPUNIT_TEST(testWriterComments);
+    CPPUNIT_TEST(testModifiedStatus);
     CPPUNIT_TEST(testSheetOperations);
     CPPUNIT_TEST_SUITE_END();
 
@@ -115,6 +118,10 @@ public:
     // for testCommandResult
     osl::Condition m_aCommandResultCondition;
     OString m_aCommandResult;
+
+    // for testModifiedStatus
+    osl::Condition m_aStateChangedCondition;
+    bool m_bModified;
 };
 
 LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType)
@@ -191,6 +198,17 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload)
         m_aCommandResultCondition.set();
     }
     break;
+    case LOK_CALLBACK_STATE_CHANGED:
+    {
+        OString aPayload(pPayload);
+        OString aPrefix(".uno:ModifiedStatus=");
+        if (aPayload.startsWith(aPrefix))
+        {
+            m_bModified = aPayload.copy(aPrefix.getLength()).toBoolean();
+            m_aStateChangedCondition.set();
+        }
+    }
+    break;
     }
 }
 
@@ -653,6 +671,28 @@ void DesktopLOKTest::testWriterComments()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+void DesktopLOKTest::testModifiedStatus()
+{
+    LibLibreOffice_Impl aOffice;
+    comphelper::LibreOfficeKit::setActive();
+    LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
+    pDocument->pClass->initializeForRendering(pDocument, nullptr);
+    pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
+
+    // Set the document as modified.
+    m_aStateChangedCondition.reset();
+    uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY);
+    xModifiable->setModified(true);
+    TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max
+    m_aStateChangedCondition.wait(&aTimeValue);
+    Scheduler::ProcessEventsToIdle();
+
+    // This was false, there was no callback about the modified status change.
+    CPPUNIT_ASSERT(m_bModified);
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 void DesktopLOKTest::testSheetOperations()
 {
     comphelper::LibreOfficeKit::setActive(true);
diff --git a/sfx2/source/control/bindings.cxx b/sfx2/source/control/bindings.cxx
index 5d13693..1b90500 100644
--- a/sfx2/source/control/bindings.cxx
+++ b/sfx2/source/control/bindings.cxx
@@ -1587,7 +1587,9 @@ bool SfxBindings::NextJob_Impl(Timer * pTimer)
     }
 
     // if possible Update all server / happens in its own time slice
-    if ( pImp->bMsgDirty )
+    // but process all events at once when unit testing, for reliability reasons
+    static bool bTest = getenv("LO_TESTNAME");
+    if ( pImp->bMsgDirty && !bTest )
     {
         UpdateSlotServer_Impl();
         return false;
commit f6a784c6cd9825f0b83f6a0166f07a87db2fa646
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Mon Dec 7 09:25:42 2015 +0100

    Let LIBO_INTERNAL_ONLY imply LOK_USE_UNSTABLE_API
    
    (cherry picked from commit 958b9a7fbdd58fdce762021917155c58fbb90d18)
    
    Reviewed-on: https://gerrit.libreoffice.org/24722
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit dfc2c194cf28c364328c9fcb484d56c51dba3e76)
    
    Change-Id: Ifbed5e534ba79d32b7188bb7fb7108338b6e124d

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 76bcdbd..7d078a3 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -16,7 +16,6 @@
 #include <memory>
 #include <boost/property_tree/json_parser.hpp>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx
index 9f15796..c9181a9 100644
--- a/desktop/source/lib/lokandroid.cxx
+++ b/desktop/source/lib/lokandroid.cxx
@@ -17,8 +17,6 @@
 
 #include <osl/detail/android-bootstrap.h>
 
-#define LOK_USE_UNSTABLE_API
-
 #include <LibreOfficeKit/LibreOfficeKit.h>
 
 /* LibreOfficeKit */
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index ca05b3b..b71b0b1 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -55,7 +55,6 @@
 
 #include <i18nlangtag/lang.h>
 #include <rtl/ref.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 #include <boost/noncopyable.hpp>
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 9f604a3..68ae432 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -12,7 +12,7 @@
 
 #include <stddef.h>
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 // the unstable API needs C99's bool
 #include <stdbool.h>
 #include <stdint.h>
@@ -58,7 +58,7 @@ struct _LibreOfficeKitClass
                                                         const char* pOptions);
     void (*freeError) (char* pFree);
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
     void (*registerCallback) (LibreOfficeKit* pThis,
                               LibreOfficeKitCallback pCallback,
                               void* pData);
@@ -95,7 +95,7 @@ struct _LibreOfficeKitDocumentClass
                    const char* pFormat,
                    const char* pFilterOptions);
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
     /// @see lok::Document::getDocumentType().
     int (*getDocumentType) (LibreOfficeKitDocument* pThis);
 
@@ -239,7 +239,7 @@ struct _LibreOfficeKitDocumentClass
                            const int nTileWidth,
                            const int nTileHeight);
 
-#endif // LOK_USE_UNSTABLE_API
+#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
 #ifdef __cplusplus
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 4660739b..a417581 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -62,7 +62,7 @@ public:
     /// Gives access to the underlying C pointer.
     inline LibreOfficeKitDocument *get() { return mpDoc; }
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
     /**
      * Get document type.
      *
@@ -435,7 +435,7 @@ public:
                                             nTileWidth, nTileHeight);
     }
 
-#endif // LOK_USE_UNSTABLE_API
+#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
 /// The lok::Office class represents one started LibreOfficeKit instance.
@@ -488,7 +488,8 @@ public:
         mpThis->pClass->freeError(pFree);
     }
 
-#ifdef LOK_USE_UNSTABLE_API
+
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
     /**
      * Returns details of filter types.
      *
@@ -541,7 +542,7 @@ public:
     {
         mpThis->pClass->setDocumentPassword(mpThis, pURL, pPassword);
     }
-#endif // LOK_USE_UNSTABLE_API
+#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
 /// Factory method to create a lok::Office instance.
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index c1d8508..7543ff7 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -15,7 +15,7 @@ extern "C"
 {
 #endif
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 typedef enum
 {
   LOK_DOCTYPE_TEXT,
@@ -362,7 +362,7 @@ typedef enum
 }
 LibreOfficeKitSetGraphicSelectionType;
 
-#endif // LOK_USE_UNSTABLE_API
+#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 
 #ifdef __cplusplus
 }
diff --git a/include/LibreOfficeKit/LibreOfficeKitTypes.h b/include/LibreOfficeKit/LibreOfficeKitTypes.h
index 338f8b8..3383944 100644
--- a/include/LibreOfficeKit/LibreOfficeKitTypes.h
+++ b/include/LibreOfficeKit/LibreOfficeKitTypes.h
@@ -17,9 +17,9 @@ extern "C"
 {
 #endif
 
-#ifdef LOK_USE_UNSTABLE_API
+#if defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 typedef void (*LibreOfficeKitCallback)(int nType, const char* pPayload, void* pData);
-#endif // LOK_USE_UNSTABLE_API
+#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 
 #ifdef __cplusplus
 }
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 485d8d4..4918315 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -30,7 +30,6 @@
 #include <vcl/cursor.hxx>
 #include <editeng/editstat.hxx>
 #include <svl/languageoptions.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 class EditEngine;
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 0a5b54e..0d3d80c 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -38,7 +38,6 @@
 
 #include <svtools/grfmgr.hxx>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 #include <vector>
 
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 0c32922..90e2f57 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -53,7 +53,6 @@
 #include <o3tl/typed_flags_set.hxx>
 #include <functional>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 class SbxValue;
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 86323a9..b333196 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -39,7 +39,6 @@
 #include <o3tl/typed_flags_set.hxx>
 #include <vcl/vclptr.hxx>
 #include <sfx2/tabdlg.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 #include <functional>
 
diff --git a/include/svx/svdmodel.hxx b/include/svx/svdmodel.hxx
index 20b057a..caf354b 100644
--- a/include/svx/svdmodel.hxx
+++ b/include/svx/svdmodel.hxx
@@ -38,7 +38,6 @@
 #include <svx/xtable.hxx>
 #include <svx/pageitem.hxx>
 #include <vcl/field.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 class OutputDevice;
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 94902bf..be087a5 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -11,7 +11,6 @@
 #ifndef INCLUDED_VCL_ITILEDRENDERABLE_HXX
 #define INCLUDED_VCL_ITILEDRENDERABLE_HXX
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 #include <tools/gen.hxx>
 #include <vcl/pointr.hxx>
diff --git a/ios/experimental/TiledLibreOffice/TiledLibreOffice/AppDelegate.m b/ios/experimental/TiledLibreOffice/TiledLibreOffice/AppDelegate.m
index 652496c..bcf4e22 100644
--- a/ios/experimental/TiledLibreOffice/TiledLibreOffice/AppDelegate.m
+++ b/ios/experimental/TiledLibreOffice/TiledLibreOffice/AppDelegate.m
@@ -6,7 +6,6 @@
 // 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/.
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitInit.h>
 
 #import "AppDelegate.h"
diff --git a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.h b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.h
index d0d20c3..0e5bc8a 100644
--- a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.h
+++ b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.h
@@ -8,7 +8,6 @@
 
 #import <UIKit/UIKit.h>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
 
 @interface TiledView : UIView
diff --git a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
index 9809f08..de0d975 100644
--- a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
+++ b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
@@ -8,7 +8,6 @@
 
 #include <CoreText/CoreText.h>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
 
 #import "View.h"
diff --git a/ios/experimental/TiledLibreOffice/TiledLibreOffice/View.m b/ios/experimental/TiledLibreOffice/TiledLibreOffice/View.m
index 33690e1..f553a5a 100644
--- a/ios/experimental/TiledLibreOffice/TiledLibreOffice/View.m
+++ b/ios/experimental/TiledLibreOffice/TiledLibreOffice/View.m
@@ -6,7 +6,6 @@
 // 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/.
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
 
 #import "View.h"
diff --git a/libreofficekit/README b/libreofficekit/README
index 669cb80..7e5f8e9 100644
--- a/libreofficekit/README
+++ b/libreofficekit/README
@@ -33,7 +33,7 @@ To use LOK Tiled Rendering you will need the following before the LOK includes:
 
 (This must be define before ANY LOK header, i.e. including the Init header.)
 
-Currently only bitmap-buffer rendering is supported, with a 32-bit RGBA
+Currently only bitmap-buffer rendering is supported, with a 32-bit BGRA
 colourspace (further alternatives could feasibly be implemented as needed).
 Scanlines are ordered top-down (whereas LibreOffice will internally default
 to bottom-up).
diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index 20777de..b4912b1 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -14,8 +14,6 @@
 #include <vector>
 #include <osl/time.h>
 
-#define LOK_USE_UNSTABLE_API
-
 #include <LibreOfficeKit/LibreOfficeKitInit.h>
 #include <LibreOfficeKit/LibreOfficeKit.hxx>
 
diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx
index c2e1425..e28fece 100644
--- a/libreofficekit/qa/unit/tiledrendering.cxx
+++ b/libreofficekit/qa/unit/tiledrendering.cxx
@@ -21,7 +21,6 @@
 
 #include <config_options.h>
     // see use of ENABLE_RUNTIME_OPTIMIZATIONS in LibreOfficeKintInit.h
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitInit.h>
 #include <LibreOfficeKit/LibreOfficeKit.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index d2655e4..289188c 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -17,7 +17,6 @@
 #include <boost/property_tree/json_parser.hpp>
 
 #include <com/sun/star/awt/Key.hpp>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKit.h>
 #include <LibreOfficeKit/LibreOfficeKitInit.h>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index d19d90d..8982dbd 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -136,7 +136,6 @@
 #include <svx/sdr/overlay/overlayselection.hxx>
 #include <comphelper/string.hxx>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
 
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 2aec1cb..6244efd 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -29,7 +29,6 @@
 #include <sfx2/printer.hxx>
 #include <vcl/settings.hxx>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include <svx/svdview.hxx>
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 5e7acf1..88c3ce6 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -11,7 +11,6 @@
 #include <unotest/macros_test.hxx>
 #include <test/xmltesttools.hxx>
 #include <boost/property_tree/json_parser.hpp>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <com/sun/star/frame/Desktop.hpp>
 #include <comphelper/dispatchcommand.hxx>
diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx
index d4f21ca..b4f96a6 100644
--- a/sw/inc/PostItMgr.hxx
+++ b/sw/inc/PostItMgr.hxx
@@ -34,7 +34,6 @@
 #include <SidebarWindowsTypes.hxx>
 #include <svl/lstner.hxx>
 #include <vcl/vclptr.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 class OutputDevice;
diff --git a/sw/inc/docsh.hxx b/sw/inc/docsh.hxx
index 52fe098..e3367d1 100644
--- a/sw/inc/docsh.hxx
+++ b/sw/inc/docsh.hxx
@@ -29,7 +29,6 @@
 
 #include <svl/lstner.hxx>
 #include <svtools/embedhlp.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 #include <sfx2/StyleManager.hxx>
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 6cd2bf5..179a6fd 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -31,7 +31,6 @@
 #include <vcl/print.hxx>
 #include <vcl/vclptr.hxx>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitTypes.h>
 
 namespace com { namespace sun { namespace star { namespace accessibility {
diff --git a/sw/source/uibase/docvw/SidebarScrollBar.cxx b/sw/source/uibase/docvw/SidebarScrollBar.cxx
index 9e2c299..7ad9b93 100644
--- a/sw/source/uibase/docvw/SidebarScrollBar.cxx
+++ b/sw/source/uibase/docvw/SidebarScrollBar.cxx
@@ -9,7 +9,6 @@
 
 #include <SidebarScrollBar.hxx>
 
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 
 #include <SidebarWin.hxx>
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 1cd8593..ea64df0 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -29,7 +29,6 @@
 #include <sfx2/printer.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
 #include <toolkit/awt/vclxdevice.hxx>
-#define LOK_USE_UNSTABLE_API
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <cmdid.h>
 #include <swtypes.hxx>
commit 9420cefcb43fca6e0c40c16351e1eefc8f4e9552
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Fri May 6 11:01:42 2016 -0400

    Don't change part on text documents to paint tiles
    
    Change-Id: Icb5fb46cbc9d2f72c814cf9f1f166382493d403f
    Reviewed-on: https://gerrit.libreoffice.org/24702
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit aadab5f4a72e38ccc8bbe9b7811d2cdcaa00124c)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 1948143..76bcdbd 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1067,15 +1067,21 @@ void doc_paintPartTile(LibreOfficeKitDocument* pThis,
     pDocument->mpCallbackFlushHandler->setPartTilePainting(true);
     try
     {
-        const int nOrigPart = doc_getPart(pThis);
-        if (nPart != nOrigPart)
+        // Text documents have a single coordinate system; don't change part.
+        int nOrigPart = 0;
+        const bool isText = (doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT);
+        if (!isText)
         {
-            doc_setPart(pThis, nPart);
+            nOrigPart = doc_getPart(pThis);
+            if (nPart != nOrigPart)
+            {
+                doc_setPart(pThis, nPart);
+            }
         }
 
         doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
 
-        if (nPart != nOrigPart)
+        if (!isText && nPart != nOrigPart)
         {
             doc_setPart(pThis, nOrigPart);
         }
commit a2ff63c5044cdc75658ea2a87b2410922e6b136f
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Fri May 6 08:16:00 2016 -0400

    Allow painting for arbitrary part
    
    Painting should not cause any state changes, but
    to paint a tile on a different part than the current
    has to change the document, which sends notifications
    to all clients.
    
    A new API, paintPartTile, allows for painting tiles
    on any part without sending change of part notifications.
    
    Furthermore, because we block notifications during this
    operation, no tile invalidation is issued due to
    changing of the part.
    
    One issue remains in the cases when the LO Core
    resets the cursor position internally and we resume
    editing after painting, the cursor might be at the top
    of the page. This needs fixing separately.
    
    Change-Id: If19bd1c90ecad4d5ed5e8d09513741b7994fa6e5
    Reviewed-on: https://gerrit.libreoffice.org/24698
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit 7f6a0f656ddb2312c3d78091fce663a36ef6e1db)

diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index 1e3774c..e2b169e 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -33,7 +33,8 @@ namespace desktop {
         explicit CallbackFlushHandler(LibreOfficeKitCallback pCallback, void* pData)
             : Idle( "lokit timer callback" ),
               m_pCallback(pCallback),
-              m_pData(pData)
+              m_pData(pData),
+              m_bPartTilePainting(false)
         {
             SetPriority(SchedulerPriority::POST_PAINT);
 
@@ -78,6 +79,13 @@ namespace desktop {
 
         void queue(const int type, const char* data)
         {
+            if (m_bPartTilePainting)
+            {
+                // We drop notifications when this is set.
+                return;
+            }
+
+
             const std::string payload(data ? data : "(nil)");
             std::unique_lock<std::mutex> lock(m_mutex);
 
@@ -145,6 +153,9 @@ namespace desktop {
             }
         }
 
+        void setPartTilePainting(const bool bPartPainting) { m_bPartTilePainting = bPartPainting; }
+        bool isPartTilePainting() const { return m_bPartTilePainting; }
+
     private:
         void flush()
         {
@@ -187,6 +198,7 @@ namespace desktop {
         std::map<int, std::string> m_states;
         LibreOfficeKitCallback m_pCallback;
         void *m_pData;
+        bool m_bPartTilePainting;
         std::mutex m_mutex;
     };
 
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 10125a2..1948143 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -323,6 +323,12 @@ void        doc_paintTile(LibreOfficeKitDocument* pThis,
                           const int nCanvasWidth, const int nCanvasHeight,
                           const int nTilePosX, const int nTilePosY,
                           const int nTileWidth, const int nTileHeight);
+void        doc_paintPartTile(LibreOfficeKitDocument* pThis,
+                              unsigned char* pBuffer,
+                              const int nPart,
+                              const int nCanvasWidth, const int nCanvasHeight,
+                              const int nTilePosX, const int nTilePosY,
+                              const int nTileWidth, const int nTileHeight);
 static int doc_getTileMode(LibreOfficeKitDocument* pThis);
 static void doc_getDocumentSize(LibreOfficeKitDocument* pThis,
                                 long* pWidth,
@@ -401,6 +407,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
         m_pDocumentClass->getPartName = doc_getPartName;
         m_pDocumentClass->setPartMode = doc_setPartMode;
         m_pDocumentClass->paintTile = doc_paintTile;
+        m_pDocumentClass->paintPartTile = doc_paintPartTile;
         m_pDocumentClass->getTileMode = doc_getTileMode;
         m_pDocumentClass->getDocumentSize = doc_getDocumentSize;
         m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
@@ -1042,6 +1049,45 @@ void doc_paintTile(LibreOfficeKitDocument* pThis,
 #endif
 }
 
+
+void doc_paintPartTile(LibreOfficeKitDocument* pThis,
+                       unsigned char* pBuffer,
+                       const int nPart,
+                       const int nCanvasWidth, const int nCanvasHeight,
+                       const int nTilePosX, const int nTilePosY,
+                       const int nTileWidth, const int nTileHeight)
+{
+    SAL_INFO( "lok.tiledrendering", "paintPartTile: painting @ " << nPart << " ["
+               << nTileWidth << "x" << nTileHeight << "]@("
+               << nTilePosX << ", " << nTilePosY << ") to ["
+               << nCanvasWidth << "x" << nCanvasHeight << "]px" );
+
+    // Disable callbacks while we are painting.
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+    pDocument->mpCallbackFlushHandler->setPartTilePainting(true);
+    try
+    {
+        const int nOrigPart = doc_getPart(pThis);
+        if (nPart != nOrigPart)
+        {
+            doc_setPart(pThis, nPart);
+        }
+
+        doc_paintTile(pThis, pBuffer, nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
+
+        if (nPart != nOrigPart)
+        {
+            doc_setPart(pThis, nOrigPart);
+        }
+    }
+    catch (const std::exception& exception)
+    {
+        // Nothing to do but restore the PartTilePainting flag.
+    }
+
+    pDocument->mpCallbackFlushHandler->setPartTilePainting(false);
+}
+
 static int doc_getTileMode(LibreOfficeKitDocument* /*pThis*/)
 {
     return LOK_TILEMODE_BGRA;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index be833db..9f604a3 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -226,6 +226,19 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::getPartHash().
     char* (*getPartHash) (LibreOfficeKitDocument* pThis,
                           int nPart);
+
+    /// Paints a tile from a specific part.
+    /// @see lok::Document::paintTile().
+    void (*paintPartTile) (LibreOfficeKitDocument* pThis,
+                           unsigned char* pBuffer,
+                           const int nPart,
+                           const int nCanvasWidth,

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list