[Libreoffice-commits] core.git: Branch 'feature/gsoc-tiled-rendering' - 170 commits - accessibility/inc accessibility/source avmedia/source basctl/source basic/qa bin/find-unused-defines.awk chart2/Library_chartcontroller.mk chart2/source chart2/uiconfig codemaker/source comphelper/source compilerplugins/clang configmgr/source configure.ac cui/source dbaccess/source desktop/source desktop/test desktop/win32 distro-configs/LibreOfficeLinux.conf download.lst drawinglayer/source editeng/source embeddedobj/source extensions/source external/firebird external/libvisio extras/source filter/source fpicker/source fpicker/uiconfig framework/source helpcontent2 i18npool/inc icon-themes/breeze icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/tango include/basebmp include/basegfx include/comphelper include/editeng include/filter include/LibreOfficeKit include/linguistic include/o3tl include/rtl include/sfx2 include/svtools include/svx include/tools include/unotools include/vcl instsetoo _native/inc_common libreofficekit/qa libreofficekit/source linguistic/source lotuswordpro/source o3tl/CppunitTest_o3tl_tests.mk o3tl/qa offapi/com offapi/UnoApi_offapi.mk officecfg/registry oox/source pyuno/source readlicense_oo/license registry/source reportdesign/source rsc/inc rsc/source sal/osl sc/inc scp2/source sc/qa sc/source sc/uiconfig sd/inc sd/source sd/uiconfig setup_native/source sfx2/Library_sfx.mk sfx2/source shell/inc sot/qa sot/source starmath/inc starmath/source stoc/source svtools/inc svtools/source svx/Library_svx.mk svx/source svx/uiconfig sw/CppunitTest_sw_uiwriter.mk sw/inc sw/qa sw/source sw/uiconfig toolkit/source ucb/source unotools/source vcl/inc vcl/opengl vcl/source vcl/unx vcl/workben wizards/source writerfilter/source

Pranav Kant pranavk at gnome.org
Sun Jul 26 04:47:04 PDT 2015


Rebased ref, commits from common ancestor:
commit 9288722eb8aecd3cc307f771d2f3fbfb762ef11c
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sat Jul 25 21:21:34 2015 +0530

    lokdocview: Cannot use same GTask object for all calls.
    
    Change-Id: I875d49a9e4360659087ae70456edefb15bc57b20

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 60bdbd4..825eb10 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -475,12 +475,15 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle)
     aStart.y = aRectanglePixels.x / nTileSizePixels;
     aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
     aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
-    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
     for (int i = aStart.x; i < aEnd.x; i++)
+    {
         for (int j = aStart.y; j < aEnd.y; j++)
+        {
+            GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
             priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task);
-
-    g_object_unref(task);
+            g_object_unref(task);
+        }
+    }
 }
 
 static gboolean
commit cb46d767e170521de5596de5d423847147aee5df
Author: Pranav Kant <pranavk at gnome.org>
Date:   Fri Jul 24 01:10:42 2015 +0530

    Use thread pool for LOK call: paintTile()
    
    Change-Id: I45e94248013277affa11e91439fbc16995b8ed8e

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 2259d5b..60bdbd4 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -135,16 +135,6 @@ enum
     PROP_CAN_ZOOM_OUT
 };
 
-enum
-{
-    LOK_LOAD_DOC,
-    LOK_POST_COMMAND,
-    LOK_SET_EDIT,
-    LOK_SET_PARTMODE,
-    LOK_SET_PART,
-    LOK_POST_KEY
-};
-
 static guint doc_view_signals[LAST_SIGNAL] = { 0 };
 
 static void lok_doc_view_initable_iface_init (GInitableIface *iface);
@@ -161,7 +151,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA,
 #pragma GCC diagnostic pop
 #endif
 
-static GThreadPool* lokThreadPool;
+GThreadPool* lokThreadPool;
 
 /// Helper struct used to pass the data from soffice thread -> main thread.
 struct CallbackData
@@ -176,50 +166,6 @@ struct CallbackData
           m_pDocView(pDocView) {}
 };
 
-/**
-   A struct that we use to store the data about the LOK call.
-
-   Object of this type is passed with all the LOK calls,
-   so that they can be idenitified. Additionally, it also contains
-   the data that LOK call needs.
-*/
-struct LOEvent
-{
-    /// To identify the type of LOK call
-    int m_nType;
-    const gchar* m_pCommand;
-    const gchar* m_pArguments;
-    gchar* m_pPath;
-    gboolean m_bEdit;
-    int m_nPartMode;
-    int m_nPart;
-    int m_nKeyEvent;
-    int m_nCharCode;
-    int m_nKeyCode;
-
-
-    /// Constructor to easily instantiate an object for LOK call of `type' type.
-    LOEvent(int type)
-        : m_nType(type) {}
-
-    LOEvent(int type, const gchar* pCommand, const gchar* pArguments)
-        : m_nType(type),
-          m_pCommand(pCommand),
-          m_pArguments(pArguments) {}
-
-    LOEvent(int type, const gchar* pPath)
-        : m_nType(type)
-    {
-        m_pPath = g_strdup(pPath);
-    }
-
-    LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode)
-        : m_nType(type),
-          m_nKeyEvent(nKeyEvent),
-          m_nCharCode(nCharCode),
-          m_nKeyCode(nKeyCode) {}
-};
-
 static void
 payloadToSize(const char* pPayload, long& rWidth, long& rHeight)
 {
@@ -529,10 +475,12 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle)
     aStart.y = aRectanglePixels.x / nTileSizePixels;
     aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
     aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
-
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
     for (int i = aStart.x; i < aEnd.x; i++)
         for (int j = aStart.y; j < aEnd.y; j++)
-            priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom);
+            priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task);
+
+    g_object_unref(task);
 }
 
 static gboolean
@@ -753,13 +701,6 @@ renderGraphicHandle(LOKDocView* pDocView,
     }
 }
 
-static void
-renderDocumentCallback(GObject* source_object, GAsyncResult*, gpointer)
-{
-    LOKDocView* pDocView = LOK_DOC_VIEW(source_object);
-    gtk_widget_queue_draw(GTK_WIDGET(pDocView));
-}
-
 static gboolean
 renderDocument(LOKDocView* pDocView, cairo_t* pCairo)
 {
@@ -808,14 +749,14 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo)
 
             if (bPaint)
             {
-                GTask* task = g_task_new(pDocView, NULL, renderDocumentCallback, NULL);
+                GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
                 Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task);
-
                 GdkPixbuf* pPixBuf = currentTile.getBuffer();
                 gdk_cairo_set_source_pixbuf (pCairo, pPixBuf,
                                              twipToPixel(aTileRectangleTwips.x, priv->m_fZoom),
                                              twipToPixel(aTileRectangleTwips.y, priv->m_fZoom));
                 cairo_paint(pCairo);
+                g_object_unref(task);
             }
         }
     }
@@ -1212,6 +1153,52 @@ lok_doc_view_post_command_in_thread (gpointer data)
 }
 
 static void
+paintTileInThread (gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+    TileBuffer& buffer = priv->m_aTileBuffer;
+    int index = pLOEvent->m_nX * buffer.m_nWidth + pLOEvent->m_nY;
+    if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() &&
+        buffer.m_mTiles[index].valid)
+        return;
+
+    GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels);
+    if (!pPixBuf)
+    {
+        g_info ("Error allocating memory to pixbuf");
+        return;
+    }
+
+    unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
+    GdkRectangle aTileRectangle;
+    aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nY;
+    aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nX;
+
+    g_test_timer_start();
+    priv->m_pDocument->pClass->paintTile(priv->m_pDocument,
+                                         pBuffer,
+                                         nTileSizePixels, nTileSizePixels,
+                                         aTileRectangle.x, aTileRectangle.y,
+                                         pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom),
+                                         pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom));
+
+    double elapsedTime = g_test_timer_elapsed();
+    g_info ("Rendered (%d, %d) in %f seconds",
+            pLOEvent->m_nX,
+            pLOEvent->m_nY,
+            elapsedTime);
+
+    //create a mapping for it
+    buffer.m_mTiles[index].setPixbuf(pPixBuf);
+    buffer.m_mTiles[index].valid = true;
+    gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+}
+
+
+static void
 lokThreadFunc(gpointer data, gpointer /*user_data*/)
 {
     GTask* task = G_TASK(data);
@@ -1237,6 +1224,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
     case LOK_POST_KEY:
         postKeyEventInThread(task);
         break;
+    case LOK_PAINT_TILE:
+        paintTileInThread(task);
+        break;
     }
 
     g_object_unref(task);
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
index d488f8b..a8594fc 100644
--- a/libreofficekit/source/gtk/tilebuffer.cxx
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -13,6 +13,8 @@
 #define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__)
 #endif
 
+extern GThreadPool* lokThreadPool;
+
 /* ------------------
    Utility functions
    ------------------
@@ -27,42 +29,6 @@ float twipToPixel(float fInput, float zoom)
     return fInput / 1440.0f * DPI * zoom;
 }
 
-static void getTileFunc(GTask*, gpointer, gpointer task_data, GCancellable*)
-{
-    GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels);
-    GetTileCallbackData* pCallback = static_cast<GetTileCallbackData*>(task_data);
-    TileBuffer* buffer = pCallback->m_pBuffer;
-    int index = pCallback->m_nX * buffer->m_nWidth + pCallback->m_nY;
-    if (!pPixBuf)
-    {
-        g_info ("Error allocating memory to pixbuf");
-        return;
-    }
-
-    unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
-    GdkRectangle aTileRectangle;
-    aTileRectangle.x = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nY;
-    aTileRectangle.y = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nX;
-
-    g_test_timer_start();
-    buffer->m_pLOKDocument->pClass->paintTile(buffer->m_pLOKDocument,
-                                      pBuffer,
-                                      nTileSizePixels, nTileSizePixels,
-                                      aTileRectangle.x, aTileRectangle.y,
-                                      pixelToTwip(nTileSizePixels, pCallback->m_fZoom),
-                                      pixelToTwip(nTileSizePixels, pCallback->m_fZoom));
-
-    double elapsedTime = g_test_timer_elapsed();
-    g_info ("Rendered (%d, %d) in %f seconds",
-            pCallback->m_nX,
-            pCallback->m_nY,
-            elapsedTime);
-
-    //create a mapping for it
-    buffer->m_mTiles[index].setPixbuf(pPixBuf);
-    buffer->m_mTiles[index].valid = true;
-}
-
 /* ----------------------------
    Tile class member functions
    ----------------------------
@@ -96,17 +62,17 @@ void TileBuffer::resetAllTiles()
     }
 }
 
-void TileBuffer::setInvalid(int x, int y, float fZoom)
+void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task)
 {
     int index = x * m_nWidth + y;
     g_info("Setting tile invalid (%d, %d)", x, y);
     if (m_mTiles.find(index) != m_mTiles.end())
     {
         m_mTiles[index].valid = false;
-        GTask* task = g_task_new(this, NULL, NULL, NULL);
-        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, fZoom, this);
-        g_task_set_task_data(task, pCallback, g_free);
-        g_task_run_in_thread(task, getTileFunc);
+
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, fZoom);
+        g_task_set_task_data(task, pLOEvent, g_free);
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
     }
 }
 
@@ -116,17 +82,16 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task)
 
     if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid)
     {
-        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this);
-        g_task_set_task_data(task, pCallback, g_free);
-        g_task_run_in_thread(task, getTileFunc);
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom);
+        g_task_set_task_data(task, pLOEvent, g_free);
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
         return m_mTiles[index];
     }
     else if(m_mTiles.find(index) == m_mTiles.end())
     {
-        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this);
-        g_task_set_task_data(task, pCallback, g_free);
-        g_info ("running in thread new tile");
-        g_task_run_in_thread(task, getTileFunc);
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom);
+        g_task_set_task_data(task, pLOEvent, g_free);
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
         return m_DummyTile;
     }
 
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 40fb2ab..f23b023 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -107,7 +107,7 @@ class TileBuffer
 
        @return the tile at the mentioned position (x, y)
      */
-    Tile& getTile(int x, int y, float aZoom, GTask*);
+    Tile& getTile(int x, int y, float aZoom, GTask* task);
     /// Destroys all the tiles in the tile buffer; also frees the memory allocated
     /// for all the Tile objects.
     void resetAllTiles();
@@ -118,8 +118,7 @@ class TileBuffer
        @param x the position of tile along x-axis
        @param y the position of tile along y-axis
      */
-    void setInvalid(int x, int y, float zoom);
-
+    void setInvalid(int x, int y, float zoom, GTask* task);
 
     /// Contains the reference to the LOK Document that this tile buffer is for.
     LibreOfficeKitDocument *m_pLOKDocument;
@@ -131,26 +130,70 @@ class TileBuffer
     Tile m_DummyTile;
 };
 
+enum
+{
+    LOK_LOAD_DOC,
+    LOK_POST_COMMAND,
+    LOK_SET_EDIT,
+    LOK_SET_PARTMODE,
+    LOK_SET_PART,
+    LOK_POST_KEY,
+    LOK_PAINT_TILE
+};
+
 /**
-   Helper struct used to pass the data from main thread to spawned threads.
-   Spawned threads are responsible for calling paintTile, and store the result
-   in tile buffer.
+   A struct that we use to store the data about the LOK call.
+
+   Object of this type is passed with all the LOK calls,
+   so that they can be idenitified. Additionally, it also contains
+   the data that LOK call needs.
 */
-struct GetTileCallbackData
+struct LOEvent
 {
+    /// To identify the type of LOK call
+    int m_nType;
+    const gchar* m_pCommand;
+    const gchar* m_pArguments;
+    gchar* m_pPath;
+    gboolean m_bEdit;
+    int m_nPartMode;
+    int m_nPart;
+    int m_nKeyEvent;
+    int m_nCharCode;
+    int m_nKeyCode;
+
     int m_nX;
     int m_nY;
     float m_fZoom;
-    TileBuffer* m_pBuffer;
 
-    GetTileCallbackData(int x, int y, float zoom, TileBuffer* buffer)
-        : m_nX(x),
+    /// Constructor to easily instantiate an object for LOK call of `type' type.
+    LOEvent(int type)
+        : m_nType(type) {}
+
+    LOEvent(int type, const gchar* pCommand, const gchar* pArguments)
+        : m_nType(type),
+          m_pCommand(pCommand),
+          m_pArguments(pArguments) {}
+
+    LOEvent(int type, const gchar* pPath)
+        : m_nType(type)
+    {
+        m_pPath = g_strdup(pPath);
+    }
+
+    LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode)
+        : m_nType(type),
+          m_nKeyEvent(nKeyEvent),
+          m_nCharCode(nCharCode),
+          m_nKeyCode(nKeyCode) {}
+
+    LOEvent(int type, int x, int y, float zoom)
+        : m_nType(type),
+          m_nX(x),
           m_nY(y),
-          m_fZoom(zoom),
-          m_pBuffer(buffer) { }
+          m_fZoom(zoom) {}
 };
 
-
 #endif // INCLUDED_TILEBUFFER_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 00fc69e2a65c2c3217569b95432f6b6968c9b780
Author: Pranav Kant <pranavk at gnome.org>
Date:   Wed Jul 22 20:25:36 2015 +0530

    lokdocview, tilebuffer: Add DOxygen comments
    
    Change-Id: I27377f0a758729a7877cfc6a56ea1b4bb3d1c3c9

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 0e51b13..2259d5b 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -36,6 +36,7 @@
 // Number of handles around a graphic selection.
 #define GRAPHIC_HANDLE_COUNT 8
 
+/// Private struct used by this GObject type
 struct _LOKDocViewPrivate
 {
     gchar* m_aLOPath;
@@ -162,6 +163,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA,
 
 static GThreadPool* lokThreadPool;
 
+/// Helper struct used to pass the data from soffice thread -> main thread.
 struct CallbackData
 {
     int m_nType;
@@ -174,8 +176,16 @@ struct CallbackData
           m_pDocView(pDocView) {}
 };
 
+/**
+   A struct that we use to store the data about the LOK call.
+
+   Object of this type is passed with all the LOK calls,
+   so that they can be idenitified. Additionally, it also contains
+   the data that LOK call needs.
+*/
 struct LOEvent
 {
+    /// To identify the type of LOK call
     int m_nType;
     const gchar* m_pCommand;
     const gchar* m_pArguments;
@@ -187,6 +197,8 @@ struct LOEvent
     int m_nCharCode;
     int m_nKeyCode;
 
+
+    /// Constructor to easily instantiate an object for LOK call of `type' type.
     LOEvent(int type)
         : m_nType(type) {}
 
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 50de72d..40fb2ab 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -131,6 +131,11 @@ class TileBuffer
     Tile m_DummyTile;
 };
 
+/**
+   Helper struct used to pass the data from main thread to spawned threads.
+   Spawned threads are responsible for calling paintTile, and store the result
+   in tile buffer.
+*/
 struct GetTileCallbackData
 {
     int m_nX;
commit 2a92ed5adbd76f79211b0efa68d1ccda9bca04e2
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 19 01:03:56 2015 +0530

    lokdocview: Make paintTile() async
    
    Change-Id: I57db9e3adf26996e6e1e105b8b95f53e88e7760f

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 8054c8e..0e51b13 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -520,7 +520,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle)
 
     for (int i = aStart.x; i < aEnd.x; i++)
         for (int j = aStart.y; j < aEnd.y; j++)
-            priv->m_aTileBuffer.setInvalid(i, j);
+            priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom);
 }
 
 static gboolean
@@ -741,6 +741,12 @@ renderGraphicHandle(LOKDocView* pDocView,
     }
 }
 
+static void
+renderDocumentCallback(GObject* source_object, GAsyncResult*, gpointer)
+{
+    LOKDocView* pDocView = LOK_DOC_VIEW(source_object);
+    gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+}
 
 static gboolean
 renderDocument(LOKDocView* pDocView, cairo_t* pCairo)
@@ -790,7 +796,9 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo)
 
             if (bPaint)
             {
-                Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom);
+                GTask* task = g_task_new(pDocView, NULL, renderDocumentCallback, NULL);
+                Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task);
+
                 GdkPixbuf* pPixBuf = currentTile.getBuffer();
                 gdk_cairo_set_source_pixbuf (pCairo, pPixBuf,
                                              twipToPixel(aTileRectangleTwips.x, priv->m_fZoom),
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
index 60aa16f..d488f8b 100644
--- a/libreofficekit/source/gtk/tilebuffer.cxx
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -27,6 +27,42 @@ float twipToPixel(float fInput, float zoom)
     return fInput / 1440.0f * DPI * zoom;
 }
 
+static void getTileFunc(GTask*, gpointer, gpointer task_data, GCancellable*)
+{
+    GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels);
+    GetTileCallbackData* pCallback = static_cast<GetTileCallbackData*>(task_data);
+    TileBuffer* buffer = pCallback->m_pBuffer;
+    int index = pCallback->m_nX * buffer->m_nWidth + pCallback->m_nY;
+    if (!pPixBuf)
+    {
+        g_info ("Error allocating memory to pixbuf");
+        return;
+    }
+
+    unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
+    GdkRectangle aTileRectangle;
+    aTileRectangle.x = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nY;
+    aTileRectangle.y = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nX;
+
+    g_test_timer_start();
+    buffer->m_pLOKDocument->pClass->paintTile(buffer->m_pLOKDocument,
+                                      pBuffer,
+                                      nTileSizePixels, nTileSizePixels,
+                                      aTileRectangle.x, aTileRectangle.y,
+                                      pixelToTwip(nTileSizePixels, pCallback->m_fZoom),
+                                      pixelToTwip(nTileSizePixels, pCallback->m_fZoom));
+
+    double elapsedTime = g_test_timer_elapsed();
+    g_info ("Rendered (%d, %d) in %f seconds",
+            pCallback->m_nX,
+            pCallback->m_nY,
+            elapsedTime);
+
+    //create a mapping for it
+    buffer->m_mTiles[index].setPixbuf(pPixBuf);
+    buffer->m_mTiles[index].valid = true;
+}
+
 /* ----------------------------
    Tile class member functions
    ----------------------------
@@ -56,55 +92,42 @@ void TileBuffer::resetAllTiles()
     std::map<int, Tile>::iterator it = m_mTiles.begin();
     for (; it != m_mTiles.end(); ++it)
     {
-        it->second.release();
+        it->second.valid = false;
     }
-    m_mTiles.clear();
 }
 
-void TileBuffer::setInvalid(int x, int y)
+void TileBuffer::setInvalid(int x, int y, float fZoom)
 {
     int index = x * m_nWidth + y;
     g_info("Setting tile invalid (%d, %d)", x, y);
     if (m_mTiles.find(index) != m_mTiles.end())
     {
         m_mTiles[index].valid = false;
-        m_mTiles[index].release();
-        m_mTiles.erase(index);
+        GTask* task = g_task_new(this, NULL, NULL, NULL);
+        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, fZoom, this);
+        g_task_set_task_data(task, pCallback, g_free);
+        g_task_run_in_thread(task, getTileFunc);
     }
 }
 
-Tile& TileBuffer::getTile(int x, int y, float aZoom)
+Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task)
 {
     int index = x * m_nWidth + y;
-    if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid)
-    {
 
-        GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels);
-        if (!pPixBuf)
-        {
-            g_info ("Error allocating memory to pixbuf");
-            return m_mTiles[index];
-        }
-
-        unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
-        GdkRectangle aTileRectangle;
-        aTileRectangle.x = pixelToTwip(nTileSizePixels, aZoom) * y;
-        aTileRectangle.y = pixelToTwip(nTileSizePixels, aZoom) * x;
-
-        g_test_timer_start();
-        m_pLOKDocument->pClass->paintTile(m_pLOKDocument,
-                                          pBuffer,
-                                          nTileSizePixels, nTileSizePixels,
-                                          aTileRectangle.x, aTileRectangle.y,
-                                          pixelToTwip(nTileSizePixels, aZoom),
-                                          pixelToTwip(nTileSizePixels, aZoom));
-
-        double elapsedTime = g_test_timer_elapsed();
-        g_info ("Rendered (%d, %d) in %f seconds", x, y, elapsedTime);
-
-        //create a mapping for it
-        m_mTiles[index].setPixbuf(pPixBuf);
-        m_mTiles[index].valid = true;
+    if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid)
+    {
+        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this);
+        g_task_set_task_data(task, pCallback, g_free);
+        g_task_run_in_thread(task, getTileFunc);
+        return m_mTiles[index];
+    }
+    else if(m_mTiles.find(index) == m_mTiles.end())
+    {
+        GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this);
+        g_task_set_task_data(task, pCallback, g_free);
+        g_info ("running in thread new tile");
+        g_task_run_in_thread(task, getTileFunc);
+        return m_DummyTile;
     }
 
     return m_mTiles[index];
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 6e6c0be..50de72d 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -86,7 +86,10 @@ class TileBuffer
             int columns)
      : m_pLOKDocument(document)
         , m_nWidth(columns)
-    {  }
+    {
+        GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels);
+        m_DummyTile.setPixbuf(pPixBuf);
+    }
 
     ~TileBuffer() {}
 
@@ -104,7 +107,7 @@ class TileBuffer
 
        @return the tile at the mentioned position (x, y)
      */
-    Tile& getTile(int x, int y, float aZoom);
+    Tile& getTile(int x, int y, float aZoom, GTask*);
     /// Destroys all the tiles in the tile buffer; also frees the memory allocated
     /// for all the Tile objects.
     void resetAllTiles();
@@ -115,17 +118,34 @@ class TileBuffer
        @param x the position of tile along x-axis
        @param y the position of tile along y-axis
      */
-    void setInvalid(int x, int y);
+    void setInvalid(int x, int y, float zoom);
+
 
- private:
     /// Contains the reference to the LOK Document that this tile buffer is for.
     LibreOfficeKitDocument *m_pLOKDocument;
     /// Stores all the tiles cached by this tile buffer.
     std::map<int, Tile> m_mTiles;
     /// Width of the current tile buffer (number of columns)
     int m_nWidth;
+    /// Dummy tile
+    Tile m_DummyTile;
 };
 
+struct GetTileCallbackData
+{
+    int m_nX;
+    int m_nY;
+    float m_fZoom;
+    TileBuffer* m_pBuffer;
+
+    GetTileCallbackData(int x, int y, float zoom, TileBuffer* buffer)
+        : m_nX(x),
+          m_nY(y),
+          m_fZoom(zoom),
+          m_pBuffer(buffer) { }
+};
+
+
 #endif // INCLUDED_TILEBUFFER_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 4c7f88498d989dbaf1022f1632b6363e7fb12ac8
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 12 23:22:51 2015 +0530

    lokdocview: Use a thread pool for most LOK calls
    
    This is a thread pool with just single thread because LOK is
    single threaded; using multiple threads in this case would be
    useless.
    
    Primary reason we are using a thread pool here is to avoid the
    overhead in spawning a new thread for each LOK call.
    
    Change-Id: Ibbfdb7cb0a8ef9f07bcc659e65ce8997716aa245

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 3f56f08..02789ad 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -81,8 +81,8 @@ gboolean                       lok_doc_view_get_edit               (LOKDocView*
 
 /// Posts the .uno: command to the LibreOfficeKit.
 void                           lok_doc_view_post_command           (LOKDocView* pDocView,
-                                                                    const char* pCommand,
-                                                                    const char* pArguments);
+                                                                    const gchar* pCommand,
+                                                                    const gchar* pArguments);
 
 float                          lok_doc_view_pixel_to_twip          (LOKDocView* pDocView,
                                                                     float fInput);
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 5517dc4..8054c8e 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -134,6 +134,16 @@ enum
     PROP_CAN_ZOOM_OUT
 };
 
+enum
+{
+    LOK_LOAD_DOC,
+    LOK_POST_COMMAND,
+    LOK_SET_EDIT,
+    LOK_SET_PARTMODE,
+    LOK_SET_PART,
+    LOK_POST_KEY
+};
+
 static guint doc_view_signals[LAST_SIGNAL] = { 0 };
 
 static void lok_doc_view_initable_iface_init (GInitableIface *iface);
@@ -150,6 +160,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA,
 #pragma GCC diagnostic pop
 #endif
 
+static GThreadPool* lokThreadPool;
 
 struct CallbackData
 {
@@ -163,6 +174,40 @@ struct CallbackData
           m_pDocView(pDocView) {}
 };
 
+struct LOEvent
+{
+    int m_nType;
+    const gchar* m_pCommand;
+    const gchar* m_pArguments;
+    gchar* m_pPath;
+    gboolean m_bEdit;
+    int m_nPartMode;
+    int m_nPart;
+    int m_nKeyEvent;
+    int m_nCharCode;
+    int m_nKeyCode;
+
+    LOEvent(int type)
+        : m_nType(type) {}
+
+    LOEvent(int type, const gchar* pCommand, const gchar* pArguments)
+        : m_nType(type),
+          m_pCommand(pCommand),
+          m_pArguments(pArguments) {}
+
+    LOEvent(int type, const gchar* pPath)
+        : m_nType(type)
+    {
+        m_pPath = g_strdup(pPath);
+    }
+
+    LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode)
+        : m_nType(type),
+          m_nKeyEvent(nKeyEvent),
+          m_nCharCode(nCharCode),
+          m_nKeyCode(nKeyCode) {}
+};
+
 static void
 payloadToSize(const char* pPayload, long& rWidth, long& rHeight)
 {
@@ -225,6 +270,20 @@ isEmptyRectangle(const GdkRectangle& rRectangle)
     return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0;
 }
 
+static void
+postKeyEventInThread(gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+
+    priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument,
+                                            pLOEvent->m_nKeyEvent,
+                                            pLOEvent->m_nCharCode,
+                                            pLOEvent->m_nKeyCode);
+}
+
 static gboolean
 signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
 {
@@ -281,10 +340,23 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
     if (pEvent->state & GDK_SHIFT_MASK)
         nKeyCode |= KEY_SHIFT;
 
+
     if (pEvent->type == GDK_KEY_RELEASE)
-        priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode);
+    {
+        GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode);
+        g_task_set_task_data(task, pLOEvent, g_free);
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+        g_object_unref(task);
+    }
     else
-        priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode);
+    {
+        GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode);
+        g_task_set_task_data(task, pLOEvent, g_free);
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+        g_object_unref(task);
+    }
 
     return FALSE;
 }
@@ -1013,6 +1085,143 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
     return FALSE;
 }
 
+static void
+lok_doc_view_open_document_in_thread (gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+
+    if ( priv->m_pDocument )
+    {
+        priv->m_pDocument->pClass->destroy( priv->m_pDocument );
+        priv->m_pDocument = 0;
+    }
+
+    priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView);
+    priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath );
+    if ( !priv->m_pDocument )
+    {
+        // FIXME: should have a GError parameter and populate it.
+        char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice );
+        fprintf( stderr, "Error opening document '%s'\n", pError );
+        g_task_return_new_error(task, 0, 0, pError);
+    }
+    else
+    {
+        priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument);
+        priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView);
+        priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips);
+        g_timeout_add(600, handleTimeout, pDocView);
+
+        float zoom = priv->m_fZoom;
+        long nDocumentWidthTwips = priv->m_nDocumentWidthTwips;
+        long nDocumentHeightTwips = priv->m_nDocumentHeightTwips;
+        long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom);
+        long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom);
+        // Total number of columns in this document.
+        guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
+
+
+        priv->m_aTileBuffer = TileBuffer(priv->m_pDocument,
+                                         nColumns);
+        gtk_widget_set_size_request(GTK_WIDGET(pDocView),
+                                    nDocumentWidthPixels,
+                                    nDocumentHeightPixels);
+        gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE);
+        gtk_widget_grab_focus(GTK_WIDGET(pDocView));
+        g_task_return_boolean (task, true);
+    }
+}
+
+static void
+lok_doc_view_set_part_in_thread(gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+    int nPart = pLOEvent->m_nPart;
+
+    priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart );
+}
+
+static void
+lok_doc_view_set_partmode_in_thread(gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+    int nPartMode = pLOEvent->m_nPartMode;
+
+    priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode );
+}
+
+static void
+lok_doc_view_set_edit_in_thread(gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+    gboolean bWasEdit = priv->m_bEdit;
+    gboolean bEdit = pLOEvent->m_bEdit;
+
+    if (!priv->m_bEdit && bEdit)
+        g_info("lok_doc_view_set_edit: entering edit mode");
+    else if (priv->m_bEdit && !bEdit)
+    {
+        g_info("lok_doc_view_set_edit: leaving edit mode");
+        priv->m_pDocument->pClass->resetSelection(priv->m_pDocument);
+    }
+    priv->m_bEdit = bEdit;
+    g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit);
+    gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+}
+
+static void
+lok_doc_view_post_command_in_thread (gpointer data)
+{
+    GTask* task = G_TASK(data);
+    LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+
+    priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments);
+}
+
+static void
+lokThreadFunc(gpointer data, gpointer /*user_data*/)
+{
+    GTask* task = G_TASK(data);
+    LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
+
+    switch (pLOEvent->m_nType)
+    {
+    case LOK_LOAD_DOC:
+        lok_doc_view_open_document_in_thread (task);
+        break;
+    case LOK_POST_COMMAND:
+        lok_doc_view_post_command_in_thread (task);
+        break;
+    case LOK_SET_EDIT:
+        lok_doc_view_set_edit_in_thread(task);
+        break;
+    case LOK_SET_PART:
+        lok_doc_view_set_part_in_thread(task);
+        break;
+    case LOK_SET_PARTMODE:
+        lok_doc_view_set_partmode_in_thread(task);
+        break;
+    case LOK_POST_KEY:
+        postKeyEventInThread(task);
+        break;
+    }
+
+    g_object_unref(task);
+}
+
 static void lok_doc_view_init (LOKDocView* pDocView)
 {
     LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
@@ -1392,6 +1601,12 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
                      g_cclosure_marshal_VOID__STRING,
                      G_TYPE_NONE, 1,
                      G_TYPE_STRING);
+
+    lokThreadPool = g_thread_pool_new(lokThreadFunc,
+                                      NULL,
+                                      1,
+                                      FALSE,
+                                      NULL);
 }
 
 /**
@@ -1423,60 +1638,13 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr
     GTask* task = G_TASK(res);
 
     g_return_val_if_fail(g_task_is_valid(res, pDocView), false);
-    //FIXME: make source_tag workx
+    //FIXME: make source_tag work
     //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL);
     g_return_val_if_fail(error == NULL || *error == NULL, false);
 
     return g_task_propagate_boolean(task, error);
 }
 
-static void
-lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer /*task_data*/, GCancellable* /*cancellable*/)
-{
-    LOKDocView* pDocView = LOK_DOC_VIEW(source_object);
-    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
-
-    if ( priv->m_pDocument )
-    {
-        priv->m_pDocument->pClass->destroy( priv->m_pDocument );
-        priv->m_pDocument = 0;
-    }
-
-    priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView);
-    priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath );
-    if ( !priv->m_pDocument )
-    {
-        // FIXME: should have a GError parameter and populate it.
-        char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice );
-        fprintf( stderr, "Error opening document '%s'\n", pError );
-        g_task_return_new_error(task, 0, 0, pError);
-    }
-    else
-    {
-        priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument);
-        priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView);
-        priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips);
-        g_timeout_add(600, handleTimeout, pDocView);
-
-        float zoom = priv->m_fZoom;
-        long nDocumentWidthTwips = priv->m_nDocumentWidthTwips;
-        long nDocumentHeightTwips = priv->m_nDocumentHeightTwips;
-        long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom);
-        long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom);
-        // Total number of columns in this document.
-        guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
-
-
-        priv->m_aTileBuffer = TileBuffer(priv->m_pDocument,
-                                         nColumns);
-        gtk_widget_set_size_request(GTK_WIDGET(pDocView),
-                                    nDocumentWidthPixels,
-                                    nDocumentHeightPixels);
-        gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE);
-        gtk_widget_grab_focus(GTK_WIDGET(pDocView));
-        g_task_return_boolean (task, true);
-    }
-}
 
 /**
  * lok_doc_view_open_document:
@@ -1492,15 +1660,13 @@ lok_doc_view_open_document (LOKDocView* pDocView,
                             GAsyncReadyCallback callback,
                             gpointer userdata)
 {
-    GTask *task;
+    GTask* task = g_task_new(pDocView, cancellable, callback, userdata);
+    LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC, pPath);
     LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
     priv->m_aDocPath = g_strdup(pPath);
+    g_task_set_task_data(task, pLOEvent, g_free);
 
-    task = g_task_new(pDocView, cancellable, callback, userdata);
-    // FIXME: Use source_tag to check the task.
-    //g_task_set_source_tag(task, lok_doc_view_open_document);
-
-    g_task_run_in_thread(task, lok_doc_view_open_document_func);
+    g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
     g_object_unref(task);
 }
 
@@ -1572,8 +1738,13 @@ lok_doc_view_get_part (LOKDocView* pDocView)
 SAL_DLLPUBLIC_EXPORT void
 lok_doc_view_set_part (LOKDocView* pDocView, int nPart)
 {
-    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
-    priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart );
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+    LOEvent* pLOEvent = new LOEvent(LOK_SET_PART);
+    pLOEvent->m_nPart = nPart;
+    g_task_set_task_data(task, pLOEvent, g_free);
+
+    g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+    g_object_unref(task);
 }
 
 SAL_DLLPUBLIC_EXPORT char*
@@ -1587,8 +1758,13 @@ SAL_DLLPUBLIC_EXPORT void
 lok_doc_view_set_partmode(LOKDocView* pDocView,
                           int nPartMode)
 {
-    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
-    priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode );
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+    LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE);
+    pLOEvent->m_nPartMode = nPartMode;
+    g_task_set_task_data(task, pLOEvent, g_free);
+
+    g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+    g_object_unref(task);
 }
 
 SAL_DLLPUBLIC_EXPORT void
@@ -1610,19 +1786,13 @@ SAL_DLLPUBLIC_EXPORT void
 lok_doc_view_set_edit(LOKDocView* pDocView,
                       gboolean bEdit)
 {
-    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
-    gboolean bWasEdit = priv->m_bEdit;
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+    LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT);
+    pLOEvent->m_bEdit = bEdit;
+    g_task_set_task_data(task, pLOEvent, g_free);
 
-    if (!priv->m_bEdit && bEdit)
-        g_info("lok_doc_view_set_edit: entering edit mode");
-    else if (priv->m_bEdit && !bEdit)
-    {
-        g_info("lok_doc_view_set_edit: leaving edit mode");
-        priv->m_pDocument->pClass->resetSelection(priv->m_pDocument);
-    }
-    priv->m_bEdit = bEdit;
-    g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit);
-    gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+    g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+    g_object_unref(task);
 }
 
 /**
@@ -1648,11 +1818,16 @@ lok_doc_view_get_edit (LOKDocView* pDocView)
 */
 SAL_DLLPUBLIC_EXPORT void
 lok_doc_view_post_command (LOKDocView* pDocView,
-                           const char* pCommand,
-                           const char* pArguments)
+                           const gchar* pCommand,
+                           const gchar* pArguments)
 {
-    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
-    priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pCommand, pArguments);
+
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+    LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND, pCommand, pArguments);
+    g_task_set_task_data(task, pLOEvent, g_free);
+
+    g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+    g_object_unref(task);
 }
 
 /**
commit aaa117ae095c9bc74d3711b2bb73207aeea5b2da
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sat Jul 11 21:29:53 2015 +0530

    gtktiledviewer: Fill whole statusbar with progressbar
    
    We don't have anything yet to put in statusbar. Let progressbar
    fill the whole width of statusbar for now.
    
    Change-Id: I4cd8745e997a0d2b917bc5baf358b097174d0df9

diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index e8091a7..46d3176 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -370,6 +370,11 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ )
     }
 }
 
+static void removeChildrenFromStatusbar(GtkWidget* children, gpointer)
+{
+    gtk_container_remove(GTK_CONTAINER(pStatusBar), children);
+}
+
 static void populatePartModeSelector( GtkComboBoxText* pSelector )
 {
     gtk_combo_box_text_append_text( pSelector, "Standard" );
@@ -577,8 +582,10 @@ int main( int argc, char* argv[] )
     g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar);
 
     pStatusBar = gtk_statusbar_new ();
+    gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, NULL);
     gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar);
     gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar);
+    gtk_widget_set_hexpand(pProgressBar, true);
 
     gtk_widget_show_all( pWindow );
     // Hide the findbar by default.
commit 102ce3b80d6a602a256a4f7da75f471046502cc9
Author: Pranav Kant <pranavk at gnome.org>
Date:   Tue Jul 7 21:16:45 2015 +0530

    lokdocview: Emit load-changed signal showing load progress
    
    Change-Id: I69b4c05d12c0c0b2ca6b7d1ad76ed74cc1f4346a

diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index a208051..e8091a7 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -30,6 +30,7 @@ static int help()
 }
 
 static GtkWidget* pDocView;
+static GtkWidget* pStatusBar;
 static GtkToolItem* pEnableEditing;
 static GtkToolItem* pBold;
 static GtkToolItem* pItalic;
@@ -286,6 +287,12 @@ static void signalCommand(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer
     }
 }
 
+static void loadChanged(LOKDocView* /*pLOKDocView*/, gdouble fValue, gpointer pData)
+{
+    GtkWidget* pProgressBar = GTK_WIDGET (pData);
+    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(pProgressBar), fValue);
+}
+
 /// LOKDocView found no search matches -> set the search label accordingly.
 static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpointer /*pData*/)
 {
@@ -403,6 +410,8 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo
 
     focusChain = g_list_append( focusChain, pDocView1 );
     gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain );
+
+    gtk_widget_hide (pStatusBar);
 }
 
 int main( int argc, char* argv[] )
@@ -555,6 +564,7 @@ int main( int argc, char* argv[] )
     g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL);
     g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL);
 
+
     // Scrolled window for DocView
     pScrolledWindow = gtk_scrolled_window_new(0, 0);
     gtk_widget_set_hexpand (pScrolledWindow, TRUE);
@@ -563,6 +573,13 @@ int main( int argc, char* argv[] )
 
     gtk_container_add(GTK_CONTAINER(pScrolledWindow), pDocView);
 
+    GtkWidget* pProgressBar = gtk_progress_bar_new ();
+    g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar);
+
+    pStatusBar = gtk_statusbar_new ();
+    gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar);
+    gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar);
+
     gtk_widget_show_all( pWindow );
     // Hide the findbar by default.
     gtk_widget_hide(pFindbar);
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index b6b00afd..5517dc4 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -40,7 +40,7 @@ struct _LOKDocViewPrivate
 {
     gchar* m_aLOPath;
     gchar* m_aDocPath;
-    guint m_nLoadProgress;
+    gdouble m_nLoadProgress;
     gboolean m_bIsLoading;
     gboolean m_bCanZoomIn;
     gboolean m_bCanZoomOut;
@@ -108,6 +108,7 @@ struct _LOKDocViewPrivate
 
 enum
 {
+    LOAD_CHANGED,
     EDIT_CHANGED,
     COMMAND_CHANGED,
     SEARCH_NOT_FOUND,
@@ -341,17 +342,20 @@ globalCallback (gpointer pData)
     {
     case LOK_CALLBACK_STATUS_INDICATOR_START:
     {
-        priv->m_nLoadProgress = 0;
+        priv->m_nLoadProgress = 0.0;
+        g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 0.0);
     }
     break;
     case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
     {
-        priv->m_nLoadProgress = std::stoi(pCallback->m_aPayload);
+        priv->m_nLoadProgress = static_cast<gdouble>(std::stoi(pCallback->m_aPayload)/100.0);
+        g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, priv->m_nLoadProgress);
     }
     break;
     case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
     {
-        priv->m_nLoadProgress = 100;
+        priv->m_nLoadProgress = 1.0;
+        g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 1.0);
     }
     break;
     default:
@@ -1069,7 +1073,7 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va
         g_value_set_boolean (value, priv->m_bEdit);
         break;
     case PROP_LOAD_PROGRESS:
-        g_value_set_uint (value, priv->m_nLoadProgress);
+        g_value_set_double (value, priv->m_nLoadProgress);
         break;
     case PROP_ZOOM:
         g_value_set_float (value, priv->m_fZoom);
@@ -1210,11 +1214,11 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
      */
     g_object_class_install_property (pGObjectClass,
           PROP_LOAD_PROGRESS,
-          g_param_spec_int("load-progress",
-                           "Estimated Load Progress",
-                           "Whether the content is in edit mode or not",
-                           0, 100, 0,
-                           G_PARAM_READABLE));
+          g_param_spec_double("load-progress",
+                              "Estimated Load Progress",
+                              "Shows the progress of the document load operation",
+                              0.0, 1.0, 0.0,
+                              G_PARAM_READABLE));
 
     /**
      * LOKDocView:zoom-level:
@@ -1300,6 +1304,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
                                                        | G_PARAM_STATIC_STRINGS)));
 
     /**
+     * LOKDocView::load-changed:
+     * @pDocView: the #LOKDocView on which the signal is emitted
+     * @fLoadProgress: the new progress value
+     */
+    doc_view_signals[LOAD_CHANGED] =
+        g_signal_new("load-changed",
+                     G_TYPE_FROM_CLASS (pGObjectClass),
+                     G_SIGNAL_RUN_FIRST,
+                     0,
+                     NULL, NULL,
+                     g_cclosure_marshal_VOID__DOUBLE,
+                     G_TYPE_NONE, 1,
+                     G_TYPE_DOUBLE);
+
+    /**
      * LOKDocView::edit-changed:
      * @pDocView: the #LOKDocView on which the signal is emitted
      * @bEdit: the new edit value of the view
@@ -1403,16 +1422,16 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr
 {
     GTask* task = G_TASK(res);
 
-    g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL);
+    g_return_val_if_fail(g_task_is_valid(res, pDocView), false);
     //FIXME: make source_tag workx
     //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL);
-    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
+    g_return_val_if_fail(error == NULL || *error == NULL, false);
 
     return g_task_propagate_boolean(task, error);
 }
 
 static void
-lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer task_data, GCancellable* cancellable)
+lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer /*task_data*/, GCancellable* /*cancellable*/)
 {
     LOKDocView* pDocView = LOK_DOC_VIEW(source_object);
     LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
commit 6779212f0138fa5c8103e25375abf81cea816aee
Author: Pranav Kant <pranavk at gnome.org>
Date:   Mon Jul 6 22:01:30 2015 +0530

    lokdocview: Call open_document in another thread
    
    This is to keep the widget responsive during document load.
    
    Change-Id: I81acaffc75ca7deddd6cc2de6abae22d009d40cd

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index b98a856..3f56f08 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -45,8 +45,15 @@ GtkWidget*                     lok_doc_view_new                    (const gchar*
                                                                     GCancellable *cancellable,
                                                                     GError **error);
 
-gboolean                       lok_doc_view_open_document          (LOKDocView* pDocView,
-                                                                    const gchar* pPath);
+void                           lok_doc_view_open_document          (LOKDocView* pDocView,
+                                                                    const gchar* pPath,
+                                                                    GCancellable* cancellable,
+                                                                    GAsyncReadyCallback callback,
+                                                                    gpointer userdata);
+
+gboolean                       lok_doc_view_open_document_finish   (LOKDocView* pDocView,
+                                                                    GAsyncResult* res,
+                                                                    GError** error);
 
 /// Gets the document the viewer displays.
 LibreOfficeKitDocument*        lok_doc_view_get_document           (LOKDocView* pDocView);
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 6c0de39..a208051 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -41,6 +41,7 @@ std::map<std::string, GtkToolItem*> g_aCommandNameToolItems;
 bool g_bToolItemBroadcast = true;
 static GtkWidget* pVBox;
 static GtkComboBoxText* pPartSelector;
+static GtkWidget* pPartModeComboBox;
 /// Should the part selector avoid calling lok::Document::setPart()?
 static bool g_bPartSelectorBroadcast = true;
 GtkWidget* pFindbar;
@@ -291,6 +292,7 @@ static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpoint
     gtk_label_set_text(GTK_LABEL(pFindbarLabel), "Search key not found");
 }
 
+
 static void signalPart(LOKDocView* /*pLOKDocView*/, int nPart, gpointer /*pData*/)
 {
     g_bPartSelectorBroadcast = false;
@@ -381,6 +383,28 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ )
     }
 }
 
+static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpointer /*userdata*/)
+{
+    LOKDocView* pDocView1 = LOK_DOC_VIEW (source_object);
+    GError* error = NULL;
+    GList *focusChain = NULL;
+
+    if (!lok_doc_view_open_document_finish(pDocView1, res, &error))
+    {
+        g_warning ("Error occurred while opening the document : %s", error->message);
+        g_error_free (error);
+    }
+
+    populatePartSelector();
+    populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) );
+    // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode.
+    g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0);
+    g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0);
+
+    focusChain = g_list_append( focusChain, pDocView1 );
+    gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain );
+}
+
 int main( int argc, char* argv[] )
 {
     if( argc < 3 ||
@@ -436,7 +460,7 @@ int main( int argc, char* argv[] )
     gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator2, -1);
 
     GtkToolItem* pPartModeSelectorToolItem = gtk_tool_item_new();
-    GtkWidget* pPartModeComboBox = gtk_combo_box_text_new();
+    pPartModeComboBox = gtk_combo_box_text_new();
     gtk_container_add( GTK_CONTAINER(pPartModeSelectorToolItem), pPartModeComboBox );
     gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 );
 
@@ -543,21 +567,7 @@ int main( int argc, char* argv[] )
     // Hide the findbar by default.
     gtk_widget_hide(pFindbar);
 
-    int bOpened = lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2] );
-    if (!bOpened)
-        g_error("main: lok_doc_view_open_document() failed");
-    assert(lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)));
-
-    populatePartSelector();
-    populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) );
-    // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode.
-    g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0);
-    g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0);
-
-    // Make only LOKDocView widget as focussable
-    GList *focusChain = NULL;
-    focusChain = g_list_append( focusChain, pDocView );
-    gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain );
+    lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView );
 
     gtk_main();
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 3823e94..b6b00afd 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -108,8 +108,6 @@ struct _LOKDocViewPrivate
 
 enum
 {
-    LOAD_CHANGED,
-    LOAD_FAILED,
     EDIT_CHANGED,
     COMMAND_CHANGED,
     SEARCH_NOT_FOUND,
@@ -337,19 +335,23 @@ static gboolean
 globalCallback (gpointer pData)
 {
     CallbackData* pCallback = static_cast<CallbackData*>(pData);
+    LOKDocViewPrivate* priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pCallback->m_pDocView));
 
     switch (pCallback->m_nType)
     {
     case LOK_CALLBACK_STATUS_INDICATOR_START:
     {
+        priv->m_nLoadProgress = 0;
     }
     break;
     case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
     {
+        priv->m_nLoadProgress = std::stoi(pCallback->m_aPayload);
     }
     break;
     case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
     {
+        priv->m_nLoadProgress = 100;
     }
     break;
     default:
@@ -1389,15 +1391,30 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error)
 }
 
 /**
- * lok_doc_view_open_document:
+ * lok_doc_view_open_document_finish:
  * @pDocView: The #LOKDocView instance
- * @pPath: The path of the document that #LOKDocView widget should try to open
+ * @res:
+ * @error:
  *
  * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise
  */
 SAL_DLLPUBLIC_EXPORT gboolean
-lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath)
+lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GError** error)
+{
+    GTask* task = G_TASK(res);
+
+    g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL);
+    //FIXME: make source_tag workx
+    //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL);
+    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
+
+    return g_task_propagate_boolean(task, error);
+}
+
+static void
+lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer task_data, GCancellable* cancellable)
 {
+    LOKDocView* pDocView = LOK_DOC_VIEW(source_object);
     LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
 
     if ( priv->m_pDocument )
@@ -1407,13 +1424,13 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath)
     }
 
     priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView);
-    priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, pPath );
+    priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath );
     if ( !priv->m_pDocument )
     {
         // FIXME: should have a GError parameter and populate it.
         char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice );
         fprintf( stderr, "Error opening document '%s'\n", pError );
-        return FALSE;
+        g_task_return_new_error(task, 0, 0, pError);
     }
     else
     {
@@ -1438,8 +1455,34 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath)
                                     nDocumentHeightPixels);
         gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE);
         gtk_widget_grab_focus(GTK_WIDGET(pDocView));
+        g_task_return_boolean (task, true);
     }
-    return TRUE;
+}
+
+/**
+ * lok_doc_view_open_document:
+ * @pDocView: The #LOKDocView instance
+ * @pPath: The path of the document that #LOKDocView widget should try to open
+ *
+ * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise
+ */
+SAL_DLLPUBLIC_EXPORT void
+lok_doc_view_open_document (LOKDocView* pDocView,
+                            const gchar* pPath,
+                            GCancellable* cancellable,
+                            GAsyncReadyCallback callback,
+                            gpointer userdata)
+{
+    GTask *task;
+    LOKDocViewPrivate *priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
+    priv->m_aDocPath = g_strdup(pPath);
+
+    task = g_task_new(pDocView, cancellable, callback, userdata);
+    // FIXME: Use source_tag to check the task.
+    //g_task_set_source_tag(task, lok_doc_view_open_document);
+
+    g_task_run_in_thread(task, lok_doc_view_open_document_func);
+    g_object_unref(task);
 }
 
 /**
commit faa5b9602839b93fc4b82bb36fbef03e022a1924
Author: Jean-Pierre Ledure <jp at ledure.be>
Date:   Sun Jul 26 13:10:18 2015 +0200

    Access2Base - Return value of Execute method in CommandBarControl
    
    Method always returned False. Should return True when successful.
    
    Change-Id: I82c8a6e425409032ccf5217b940ec81b277a6313

diff --git a/wizards/source/access2base/CommandBarControl.xba b/wizards/source/access2base/CommandBarControl.xba
index a6bdcbc..286dc07 100644
--- a/wizards/source/access2base/CommandBarControl.xba
+++ b/wizards/source/access2base/CommandBarControl.xba
@@ -152,24 +152,25 @@ Const cstThisSub = "CommandBarControl.Execute"
 	Utils._SetCalledSub(cstThisSub)
 
 Dim sExecute As String
-	Execute = False
+
+	Execute = True
 	sExecute = _GetPropertyValue(_Element, "CommandURL", "")
 
 	Select Case True
-		Case sExecute = ""
+		Case sExecute = ""		:	Execute = False
 		Case _IsLeft(sExecute, ".uno:")
 			Execute = DoCmd.RunCommand(sExecute)
 		Case _IsLeft(sExecute, "vnd.sun.star.script:")
 			Execute = Utils._RunScript(sExecute, Array(Nothing))
 		Case Else
 	End Select
-
+	
 Exit_Function:
 	Utils._ResetCalledSub(cstThisSub)
 	Exit Function
 Error_Function:
 	TraceError(TRACEABORT, Err, cstThisSub, Erl)
-	Reset = False
+	Execute = False
 	GoTo Exit_Function
 End Function	'	Execute	V1.3.0
 
commit 33a21d37f376abaaabdaceaa09160cab962038fc
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Sun Jul 26 00:23:50 2015 -0500

    Revert "Resolves: tdf#88314 close temp file after each thread completes"
    
    This reverts commit 738cf411e9315d17c7eb8be47ded643a00dfe5c5.
    
    It brokes windows in https://gerrit.libreoffice.org/#/c/17289/
    as per http://ci.libreoffice.org/job/lo_gerrit_master/4465/Gerrit=Gerrit,Platform=Windows/
    
    was pushed despite that.. :-(

diff --git a/package/inc/ZipOutputEntry.hxx b/package/inc/ZipOutputEntry.hxx
index d8d0ee6..2a5aa04 100644
--- a/package/inc/ZipOutputEntry.hxx
+++ b/package/inc/ZipOutputEntry.hxx
@@ -37,8 +37,7 @@ class ZipOutputEntry
 {
     ::com::sun::star::uno::Sequence< sal_Int8 > m_aDeflateBuffer;
     ZipUtils::Deflater m_aDeflater;
-    css::uno::Reference< css::uno::XComponentContext > m_xContext;
-    OUString m_aTempURL;
+    css::uno::Reference< css::io::XTempFile > m_xTempFile;
     css::uno::Reference< css::io::XOutputStream > m_xOutStream;
 
     ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XCipherContext > m_xCipherContext;
@@ -59,18 +58,14 @@ public:
 
     ~ZipOutputEntry();
 
-    /* This block of methods is for threaded zipping, where we compress to a temp stream, whose
-       data is retrieved via getData */
-    void createBufferFile();
-    void setParallelDeflateException(const ::css::uno::Any &rAny) { m_aParallelDeflateException = rAny; }
-    css::uno::Reference< css::io::XInputStream > getData() const;
-    ::css::uno::Any getParallelDeflateException() const { return m_aParallelDeflateException; }
-    void closeBufferFile();
-
+    css::uno::Reference< css::io::XInputStream > getData();
     ZipEntry* getZipEntry() { return m_pCurrentEntry; }
     ZipPackageStream* getZipPackageStream() { return m_pCurrentStream; }
     bool isEncrypt() { return m_bEncryptCurrentEntry; }
 
+    void setParallelDeflateException(const ::css::uno::Any &rAny) { m_aParallelDeflateException = rAny; }
+    ::css::uno::Any getParallelDeflateException() const { return m_aParallelDeflateException; }
+
     void closeEntry();
     void write(const css::uno::Sequence< sal_Int8 >& rBuffer);
 
diff --git a/package/source/zipapi/ZipOutputEntry.cxx b/package/source/zipapi/ZipOutputEntry.cxx
index aa85b11..de44ae4 100644
--- a/package/source/zipapi/ZipOutputEntry.cxx
+++ b/package/source/zipapi/ZipOutputEntry.cxx
@@ -21,8 +21,6 @@
 
 #include <com/sun/star/io/TempFile.hpp>
 #include <com/sun/star/packages/zip/ZipConstants.hpp>
-#include <com/sun/star/ucb/SimpleFileAccess.hpp>
-#include <com/sun/star/ucb/XSimpleFileAccess3.hpp>
 #include <comphelper/storagehelper.hxx>
 
 #include <osl/time.h>
@@ -51,56 +49,38 @@ ZipOutputEntry::ZipOutputEntry(
         bool bEncrypt)
 : m_aDeflateBuffer(n_ConstBufferSize)
 , m_aDeflater(DEFAULT_COMPRESSION, true)
-, m_xContext(rxContext)
-, m_xOutStream(rxOutput)
 , m_pCurrentEntry(&rEntry)
 , m_nDigested(0)
 , m_bEncryptCurrentEntry(bEncrypt)
 , m_pCurrentStream(pStream)
 {
+    if (rxOutput.is())
+    {
+        m_xOutStream = rxOutput;
+    }
+    else
+    {
+        m_xTempFile = io::TempFile::create(rxContext);
+        m_xOutStream = m_xTempFile->getOutputStream();
+    }
     assert(m_pCurrentEntry->nMethod == DEFLATED && "Use ZipPackageStream::rawWrite() for STORED entries");
     if (m_bEncryptCurrentEntry)
     {
-        m_xCipherContext = ZipFile::StaticGetCipher( m_xContext, pStream->GetEncryptionData(), true );
-        m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( m_xContext, pStream->GetEncryptionData() );
+        m_xCipherContext = ZipFile::StaticGetCipher( rxContext, pStream->GetEncryptionData(), true );
+        m_xDigestContext = ZipFile::StaticGetDigestContextForChecksum( rxContext, pStream->GetEncryptionData() );
     }
 }
 
 ZipOutputEntry::~ZipOutputEntry()
 {
-    if (!m_aTempURL.isEmpty())
-    {
-        uno::Reference < ucb::XSimpleFileAccess3 > xAccess(ucb::SimpleFileAccess::create(m_xContext));
-        xAccess->kill(m_aTempURL);
-    }
 }
 
-void ZipOutputEntry::createBufferFile()
-{
-    assert(!m_xOutStream.is() && m_aTempURL.isEmpty() &&
-           "should only be called in the threaded mode where there is no existing stream yet");
-    uno::Reference < beans::XPropertySet > xTempFileProps(
-            io::TempFile::create(m_xContext),
-            uno::UNO_QUERY_THROW );
-    xTempFileProps->setPropertyValue("RemoveFile", uno::makeAny(sal_False));
-    uno::Any aUrl = xTempFileProps->getPropertyValue( "Uri" );
-    aUrl >>= m_aTempURL;
-    assert(!m_aTempURL.isEmpty());
-
-    uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext));
-    m_xOutStream = xTempAccess->openFileWrite(m_aTempURL);
-}
-
-void ZipOutputEntry::closeBufferFile()
+uno::Reference< io::XInputStream > ZipOutputEntry::getData()
 {
     m_xOutStream->closeOutput();
-    m_xOutStream.clear();
-}
-
-uno::Reference< io::XInputStream > ZipOutputEntry::getData() const
-{
-    uno::Reference < ucb::XSimpleFileAccess3 > xTempAccess(ucb::SimpleFileAccess::create(m_xContext));
-    return xTempAccess->openFileRead(m_aTempURL);
+    uno::Reference< io::XSeekable > xTempSeek(m_xOutStream, UNO_QUERY_THROW);
+    xTempSeek->seek(0);
+    return m_xTempFile->getInputStream();
 }
 
 void ZipOutputEntry::closeEntry()
diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx
index f28d891..f3c5361 100644
--- a/package/source/zippackage/ZipPackageStream.cxx
+++ b/package/source/zippackage/ZipPackageStream.cxx
@@ -472,7 +472,6 @@ public:
 private:
     virtual void doWork() SAL_OVERRIDE
     {
-        mpEntry->createBufferFile();
         try
         {
             deflateZipEntry(mpEntry, mxInStream);
@@ -482,7 +481,6 @@ private:
         {
             mpEntry->setParallelDeflateException(::cppu::getCaughtException());
         }
-        mpEntry->closeBufferFile();
     }
 };
 
commit 11f24bc2f032b31095663cb09ef948eee2c61f49
Author: Marek Doležel <marekdolezel at gmail.com>
Date:   Sat Jul 25 20:52:37 2015 +0200

    tdf#92130 fix DoEvents to be recognized as keyword
    
    Change-Id: I24868acec66a72abbb52b8026ed3a092dbd97632
    Reviewed-on: https://gerrit.libreoffice.org/17347
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/comphelper/source/misc/syntaxhighlight.cxx b/comphelper/source/misc/syntaxhighlight.cxx
index d1fffbc..710d8c0 100644
--- a/comphelper/source/misc/syntaxhighlight.cxx
+++ b/comphelper/source/misc/syntaxhighlight.cxx
@@ -78,6 +78,7 @@ static const char* strListBasicKeyWords[] = {
     "defvar",
     "dim",
     "do",
+    "doevents",
     "double",
     "each",
     "else",
commit c17ea618d8431306b130c023575ffed50fcbe3f8
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Jul 25 22:45:43 2015 +0200

    fix some small regressions in no-chart area panel
    
    Change-Id: I04239c0bcf78ee9029a2a17514d10d28c3b99d58

diff --git a/include/svx/sidebar/AreaPropertyPanelBase.hxx b/include/svx/sidebar/AreaPropertyPanelBase.hxx
index 3f7d574..9fdbba1 100644
--- a/include/svx/sidebar/AreaPropertyPanelBase.hxx
+++ b/include/svx/sidebar/AreaPropertyPanelBase.hxx
@@ -97,13 +97,13 @@ public:
     virtual void setFillStyleAndHatch(const XFillStyleItem* pStyleItem, const XFillHatchItem& aHatchItem) = 0;
     virtual void setFillStyleAndBitmap(const XFillStyleItem* pStyleItem, const XFillBitmapItem& aHatchItem) = 0;
 
-    void updateFillTransparence(bool bDisabled, bool bDefault, const SfxUInt16Item* pItem);
-    void updateFillFloatTransparence(bool bDisabled, bool bDefault, const XFillFloatTransparenceItem* pItem);
-    void updateFillStyle(bool bDisabled, bool bDefault, const XFillStyleItem* pItem);
-    void updateFillGradient(bool bDisabled, bool bDefault, const XFillGradientItem* pItem);
-    void updateFillHatch(bool bDisabled, bool bDefault, const XFillHatchItem* pItem);
-    void updateFillColor(bool bDefault, const XFillColorItem* pItem);
-    void updateFillBitmap(bool BDisabled, bool bDefault, const XFillBitmapItem* pItem);
+    void updateFillTransparence(bool bDisabled, bool bDefaultOrSet, const SfxUInt16Item* pItem);
+    void updateFillFloatTransparence(bool bDisabled, bool bDefaultOrSet, const XFillFloatTransparenceItem* pItem);
+    void updateFillStyle(bool bDisabled, bool bDefaultOrSet, const XFillStyleItem* pItem);
+    void updateFillGradient(bool bDisabled, bool bDefaultOrSet, const XFillGradientItem* pItem);
+    void updateFillHatch(bool bDisabled, bool bDefaultOrSet, const XFillHatchItem* pItem);
+    void updateFillColor(bool bDefaultOrSet, const XFillColorItem* pItem);
+    void updateFillBitmap(bool BDisabled, bool bDefaultOrSet, const XFillBitmapItem* pItem);
 
 protected:
     sal_uInt16                                          meLastXFS;
diff --git a/svx/source/sidebar/area/AreaPropertyPanelBase.cxx b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
index 9db2ad5..e21502b 100644
--- a/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
+++ b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
@@ -799,36 +799,37 @@ void AreaPropertyPanelBase::NotifyItemUpdate(
     const bool /*bIsEnabled*/)
 {
     const bool bDisabled(SfxItemState::DISABLED == eState);
+    const bool bDefaultOrSet(SfxItemState::DEFAULT <= eState);
     const bool bDefault(SfxItemState::DEFAULT == eState);
 
     switch(nSID)
     {
         case SID_ATTR_FILL_TRANSPARENCE:
-            updateFillTransparence(bDisabled, bDefault,
+            updateFillTransparence(bDisabled, bDefaultOrSet,
                     static_cast<const SfxUInt16Item*>(pState));
         break;
         case SID_ATTR_FILL_FLOATTRANSPARENCE:
-            updateFillFloatTransparence(bDisabled, bDefault,
+            updateFillFloatTransparence(bDisabled, bDefaultOrSet,
                     static_cast<const XFillFloatTransparenceItem*>(pState));
         break;
         case SID_ATTR_FILL_STYLE:
-            updateFillStyle(bDisabled, bDefault,
+            updateFillStyle(bDisabled, bDefaultOrSet,
                     static_cast<const XFillStyleItem*>(pState));
         break;
         case SID_ATTR_FILL_COLOR:
-            updateFillColor(bDefault,
+            updateFillColor(bDefaultOrSet,
                     static_cast<const XFillColorItem*>(pState));
         break;
         case SID_ATTR_FILL_GRADIENT:
-            updateFillGradient(bDisabled, bDefault,
+            updateFillGradient(bDisabled, bDefaultOrSet,
                     static_cast<const XFillGradientItem*>(pState));
         break;
         case SID_ATTR_FILL_HATCH:
-            updateFillHatch(bDisabled, bDefault,
+            updateFillHatch(bDisabled, bDefaultOrSet,
                     static_cast<const XFillHatchItem*>(pState));
         break;
         case SID_ATTR_FILL_BITMAP:
-            updateFillBitmap(bDisabled, bDefault,
+            updateFillBitmap(bDisabled, bDefaultOrSet,
                     static_cast<const XFillBitmapItem*>(pState));
         break;
         case SID_GRADIENT_LIST:
commit 9ba833f0148522e14a2c639017afd90749816380
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Jul 25 22:25:10 2015 +0200

    don't show the area sidebar for panels where it makes no sense
    
    Change-Id: I06655e0574b28a88db920424fa515b8350133f10

diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 267387f..f19f690 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -212,6 +212,8 @@ ChartAreaPanel::ChartAreaPanel(vcl::Window* pParent,
     mxSelectionListener(new ChartSidebarSelectionListener(this)),
     mbUpdate(true)
 {
+    std::vector<ObjectType> aAcceptedTypes { OBJECTTYPE_PAGE, OBJECTTYPE_DIAGRAM, OBJECTTYPE_DATA_SERIES, OBJECTTYPE_TITLE, OBJECTTYPE_LEGEND};
+    mxSelectionListener->setAcceptedTypes(aAcceptedTypes);
     Initialize();
 }
 
@@ -227,7 +229,7 @@ void ChartAreaPanel::dispose()
 
     css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
     if (xSelectionSupplier.is())
-        xSelectionSupplier->removeSelectionChangeListener(mxSelectionListener);
+        xSelectionSupplier->removeSelectionChangeListener(mxSelectionListener.get());
 
     AreaPropertyPanelBase::dispose();
 }
@@ -239,7 +241,7 @@ void ChartAreaPanel::Initialize()
 
     css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
     if (xSelectionSupplier.is())
-        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener.get());
 
     updateData();
 }
@@ -404,7 +406,7 @@ void ChartAreaPanel::updateModel(
 
     css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
     if (xSelectionSupplier.is())
-        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+        xSelectionSupplier->addSelectionChangeListener(mxSelectionListener.get());
 }
 
 
diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.hxx b/chart2/source/controller/sidebar/ChartAreaPanel.hxx
index 827f1c9..ccd9acc 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.hxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.hxx
@@ -86,7 +86,7 @@ private:
 
     css::uno::Reference<css::frame::XModel> mxModel;
     css::uno::Reference<css::util::XModifyListener> mxListener;
-    css::uno::Reference<css::view::XSelectionChangeListener> mxSelectionListener;
+    rtl::Reference<ChartSidebarSelectionListener> mxSelectionListener;
 
     void Initialize();
 
diff --git a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx
index 1f435e1..7f13479 100644
--- a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx
+++ b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.cxx
@@ -23,19 +23,16 @@ ChartSidebarSelectionListenerParent::~ChartSidebarSelectionListenerParent()
 
 ChartSidebarSelectionListener::ChartSidebarSelectionListener(
         ChartSidebarSelectionListenerParent* pParent):
-    mpParent(pParent),
-    mbAll(true),
-    meType()
+    mpParent(pParent)
 {
 }
 
 ChartSidebarSelectionListener::ChartSidebarSelectionListener(
         ChartSidebarSelectionListenerParent* pParent,
         ObjectType eType):
-    mpParent(pParent),
-    mbAll(false),
-    meType(eType)
+    mpParent(pParent)
 {
+    maTypes.push_back(eType);
 }
 
 ChartSidebarSelectionListener::~ChartSidebarSelectionListener()
@@ -45,13 +42,10 @@ ChartSidebarSelectionListener::~ChartSidebarSelectionListener()
 void ChartSidebarSelectionListener::selectionChanged(const css::lang::EventObject& rEvent)
         throw (::css::uno::RuntimeException, ::std::exception)
 {
-    (void)rEvent;
     bool bCorrectObjectSelected = false;
-    if (mbAll)
-        bCorrectObjectSelected = true;
 
     css::uno::Reference<css::frame::XController> xController(rEvent.Source, css::uno::UNO_QUERY);
-    if (!mbAll && xController.is())
+    if (xController.is())
     {
         css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(xController, css::uno::UNO_QUERY);
         if (xSelectionSupplier.is())
@@ -62,7 +56,8 @@ void ChartSidebarSelectionListener::selectionChanged(const css::lang::EventObjec
                 OUString aCID;
                 aAny >>= aCID;
                 ObjectType eType = ObjectIdentifier::getObjectType(aCID);
-                bCorrectObjectSelected = eType == meType;
+                bCorrectObjectSelected = std::any_of(maTypes.begin(), maTypes.end(),
+                        [=](const ObjectType& eTypeInVector) { return eType == eTypeInVector; });
             }
         }
     }
@@ -76,6 +71,11 @@ void ChartSidebarSelectionListener::disposing(const css::lang::EventObject& /*rE
     mpParent->SelectionInvalid();
 }
 
+void ChartSidebarSelectionListener::setAcceptedTypes(const std::vector<ObjectType>& aTypes)
+{
+    maTypes = aTypes;
+}
+
 } }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx
index cfe90e7..3c31644 100644
--- a/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx
+++ b/chart2/source/controller/sidebar/ChartSidebarSelectionListener.hxx
@@ -15,6 +15,8 @@
 
 #include "ObjectIdentifier.hxx"
 
+#include <vector>
+
 namespace chart {
 namespace sidebar {
 
@@ -44,11 +46,12 @@ public:
     virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent)
         throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE;
 
+    void setAcceptedTypes(const std::vector<ObjectType>& aTypes);
+
 private:
     ChartSidebarSelectionListenerParent* mpParent;
 
-    bool mbAll;
-    ObjectType meType;
+    std::vector<ObjectType> maTypes;
 };
 
 } }
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
index da8c01f..01e184b 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
@@ -1266,7 +1266,8 @@
         </prop>
         <prop oor:name="ContextList">
           <value oor:separator=";">
-            Chart, any, visible ;
+            Chart, Chart, visible ;
+            Chart, Series, visible ;
           </value>
         </prop>
         <prop oor:name="ImplementationURL" oor:type="xs:string">
commit 87f750f1c574142958331643e7b0a9fb0b182102
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Jul 25 17:46:43 2015 +0200

    also update for the first selected object
    
    Change-Id: I7df8772c7414df694eda5ea30b74eccd6e9b98db

diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 7f5077f..267387f 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -240,6 +240,8 @@ void ChartAreaPanel::Initialize()
     css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier(mxModel->getCurrentController(), css::uno::UNO_QUERY);
     if (xSelectionSupplier.is())
         xSelectionSupplier->addSelectionChangeListener(mxSelectionListener);
+
+    updateData();
 }
 
 void ChartAreaPanel::setFillTransparence(const XFillTransparenceItem& rItem)
commit 5845e73783fc99cd42188481fc5df29f0786394f
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Jul 25 01:55:36 2015 +0200

    handle chart wall correctly in area panel
    
    Change-Id: Iacd9498884a20357f217e1165a3422b6f1e2aa81

diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 9343499..7f5077f 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -42,7 +42,21 @@ css::uno::Reference<css::beans::XPropertySet> getPropSet(
         css::uno::Reference<css::frame::XModel> xModel)
 {
     OUString aCID = getCID(xModel);
-    return ObjectIdentifier::getObjectPropertySet(aCID, xModel);
+    css::uno::Reference<css::beans::XPropertySet> xPropSet =
+        ObjectIdentifier::getObjectPropertySet(aCID, xModel);
+
+    ObjectType eType = ObjectIdentifier::getObjectType(aCID);
+    if (eType == OBJECTTYPE_DIAGRAM)
+    {
+        css::uno::Reference<css::chart2::XDiagram> xDiagram(
+                xPropSet, css::uno::UNO_QUERY);
+        if (!xDiagram.is())
+            return xPropSet;
+
+        xPropSet.set(xDiagram->getWall());
+    }
+
+    return xPropSet;
 }
 
 ChartController* getController(css::uno::Reference<css::frame::XModel> xModel)
commit 6301e1e8b983f099d1f93140a3fb54c635206ac6
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Jul 25 01:31:50 2015 +0200

    provide a few more common property names
    
    Change-Id: I574af7999f8a76457dd61e66854db191b8876dfa

diff --git a/chart2/source/tools/FillProperties.cxx b/chart2/source/tools/FillProperties.cxx
index 123275f..37b4a8f 100644
--- a/chart2/source/tools/FillProperties.cxx
+++ b/chart2/source/tools/FillProperties.cxx
@@ -60,6 +60,13 @@ void lcl_AddPropertiesToVector_without_BitmapProperties( ::std::vector< ::com::s
                   | beans::PropertyAttribute::MAYBEDEFAULT ));
 
     rOutProperties.push_back(
+        Property( "Transparency",
+                  FillProperties::PROP_FILL_TRANSPARENCE,
+                  cppu::UnoType<sal_Int16>::get(),
+                  beans::PropertyAttribute::BOUND
+                  | beans::PropertyAttribute::MAYBEDEFAULT ));
+
+    rOutProperties.push_back(
         Property( "FillTransparence",
                   FillProperties::PROP_FILL_TRANSPARENCE,
                   cppu::UnoType<sal_Int16>::get(),
commit 7b9818c4cc0c955d9b5a0f0adba34a9c44b6065c
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jul 24 16:58:04 2015 +0200

    handle bitmap in chart area panel
    
    Change-Id: I3137fc1ac066b712594d0cf471ca4eb8a344c0bd

diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx
index 9749b36..e5d40d2 100644
--- a/chart2/source/controller/inc/ChartController.hxx
+++ b/chart2/source/controller/inc/ChartController.hxx
@@ -435,6 +435,7 @@ public:
     bool isShapeContext() const;
 
     ViewElementListProvider getViewElementListProvider();
+    DrawModelWrapper* GetDrawModelWrapper();
 
     DECL_LINK( NotifyUndoActionHdl, SdrUndoAction* );
 
@@ -442,7 +443,6 @@ public:
     //private
 
 private:
-    DrawModelWrapper* GetDrawModelWrapper();
     DrawViewWrapper* GetDrawViewWrapper();
 
 private:
diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 966a9fd..9343499 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -12,6 +12,8 @@
 #include "ChartController.hxx"
 #include "ViewElementListProvider.hxx"
 
+#include "chartview/DrawModelWrapper.hxx"
+
 #include <svx/xfltrit.hxx>
 #include <svx/xflftrit.hxx>
 
@@ -43,7 +45,7 @@ css::uno::Reference<css::beans::XPropertySet> getPropSet(
     return ObjectIdentifier::getObjectPropertySet(aCID, xModel);
 }
 
-ViewElementListProvider getViewElementListProvider( css::uno::Reference<css::frame::XModel> xModel)
+ChartController* getController(css::uno::Reference<css::frame::XModel> xModel)
 {
     css::uno::Reference<css::frame::XController>xController = xModel->getCurrentController();
     if (!xController.is())
@@ -53,10 +55,22 @@ ViewElementListProvider getViewElementListProvider( css::uno::Reference<css::fra
     if (!pController)
         throw std::exception();
 
+    return pController;
+}
+
+ViewElementListProvider getViewElementListProvider( css::uno::Reference<css::frame::XModel> xModel)
+{
+    ChartController* pController = getController(xModel);
     ViewElementListProvider aProvider = pController->getViewElementListProvider();
     return aProvider;
 }
 
+DrawModelWrapper* getDrawModelWrapper(css::uno::Reference<css::frame::XModel> xModel)
+{
+    ChartController* pController = getController(xModel);
+    return pController->GetDrawModelWrapper();
+}
+
 XGradient getXGradientForName(css::uno::Reference<css::frame::XModel> xModel,
         const OUString& rName)
 {
@@ -113,6 +127,34 @@ XHatch getXHatchFromName(css::uno::Reference<css::frame::XModel> xModel,
     return XHatch();
 }
 
+GraphicObject getXBitmapFromName(css::uno::Reference<css::frame::XModel> xModel,
+        const OUString& rName)
+{
+    try
+    {
+        ViewElementListProvider aProvider = getViewElementListProvider(xModel);
+        XBitmapListRef aRef = aProvider.GetBitmapList();
+        size_t n = aRef->Count();
+        for (size_t i = 0; i < n; ++i)
+        {
+            XBitmapEntry* pBitmap = aRef->GetBitmap(i);
+            if (!pBitmap)
+                continue;
+
+            if (pBitmap->GetName().equalsIgnoreAsciiCase(rName))
+            {
+                return GraphicObject(pBitmap->GetGraphicObject());
+            }
+        }
+    }
+    catch (...)
+    {
+        // ignore exception
+    }
+
+    return GraphicObject();
+}
+
 class PreventUpdate
 {
 public:
@@ -298,6 +340,25 @@ void ChartAreaPanel::updateData()
     XHatch xHatch = getXHatchFromName(mxModel, aHatchName);
     XFillHatchItem aHatchItem(aHatchName, xHatch);
     updateFillHatch(false, true, &aHatchItem);
+
+    OUString aBitmapName;
+    xPropSet->getPropertyValue("FillBitmapName") >>= aBitmapName;
+    GraphicObject xBitmap = getXBitmapFromName(mxModel, aBitmapName);
+    XFillBitmapItem aBitmapItem(aBitmapName, xBitmap);
+    XFillBitmapItem* pBitmapItem = NULL;
+    try
+    {
+        DrawModelWrapper* pModelWrapper = getDrawModelWrapper(mxModel);
+        if (pModelWrapper)
+        {
+            pBitmapItem = aBitmapItem.checkForUniqueItem(&pModelWrapper->getSdrModel());
+        }
+    }
+    catch (...)
+    {
+    }
+    updateFillBitmap(false, true, pBitmapItem ? pBitmapItem : &aBitmapItem);
+    delete pBitmapItem;
 }
 
 void ChartAreaPanel::modelInvalid()
commit 8ab10c27be8ab33e5cf355ab91f6783175184784
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jul 24 13:37:15 2015 +0200

    update hatch in chart sidebar
    
    There is a huge level of insanity in the hatch handling. Apparently
    different parts of the code use different case of the hatch id which
    makes it difficult to handle it.
    
    Change-Id: I5674e21a6c9a2d01d7b641473e00ab5e2bcaffd4

diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 9e1b5e8..966a9fd 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -43,33 +43,76 @@ css::uno::Reference<css::beans::XPropertySet> getPropSet(
     return ObjectIdentifier::getObjectPropertySet(aCID, xModel);
 }
 
-XGradient getXGradientForName(css::uno::Reference<css::frame::XModel> xModel,
-        const OUString& rName)
+ViewElementListProvider getViewElementListProvider( css::uno::Reference<css::frame::XModel> xModel)
 {
     css::uno::Reference<css::frame::XController>xController = xModel->getCurrentController();
     if (!xController.is())
-        return XGradient();
+        throw std::exception();
 
     ChartController* pController = dynamic_cast<ChartController*>(xController.get());
     if (!pController)
-        return XGradient();
+        throw std::exception();
 
     ViewElementListProvider aProvider = pController->getViewElementListProvider();
-    XGradientListRef aRef = aProvider.GetGradientList();
-    size_t n = aRef->Count();
-    for (size_t i = 0; i < n; ++i)
-    {
-        XGradientEntry* pGradient = aRef->GetGradient(i);
-        if (!pGradient)
-            continue;
+    return aProvider;
+}
 
-        if (pGradient->GetName() == rName)
-            return XGradient(pGradient->GetGradient());
+XGradient getXGradientForName(css::uno::Reference<css::frame::XModel> xModel,
+        const OUString& rName)
+{
+    try
+    {
+        ViewElementListProvider aProvider = getViewElementListProvider(xModel);
+        XGradientListRef aRef = aProvider.GetGradientList();
+        size_t n = aRef->Count();
+        for (size_t i = 0; i < n; ++i)
+        {
+            XGradientEntry* pGradient = aRef->GetGradient(i);
+            if (!pGradient)
+                continue;
+
+            if (pGradient->GetName() == rName)
+                return XGradient(pGradient->GetGradient());
+        }
+    }
+    catch (...)
+    {
+        // ignore exception
     }
 
     return XGradient();
 }
 
+XHatch getXHatchFromName(css::uno::Reference<css::frame::XModel> xModel,
+        OUString& rName)
+{
+    try
+    {
+        ViewElementListProvider aProvider = getViewElementListProvider(xModel);
+        XHatchListRef aRef = aProvider.GetHatchList();
+        size_t n = aRef->Count();
+        for (size_t i = 0; i < n; ++i)
+        {
+            XHatchEntry* pHatch = aRef->GetHatch(i);
+            if (!pHatch)
+                continue;
+
+            if (pHatch->GetName().equalsIgnoreAsciiCase(rName))
+            {
+                // we need to update the hatch name
+                rName = pHatch->GetName();
+                return XHatch(pHatch->GetHatch());
+            }
+        }
+    }
+    catch (...)
+    {
+        // ignore exception
+    }
+
+    return XHatch();
+}
+
 class PreventUpdate
 {
 public:
@@ -249,6 +292,12 @@ void ChartAreaPanel::updateData()
     XGradient xGradient = getXGradientForName(mxModel, aGradientName);
     XFillGradientItem aGradientItem(aGradientName, xGradient);
     updateFillGradient(false, true, &aGradientItem);
+
+    OUString aHatchName;
+    xPropSet->getPropertyValue("HatchName") >>= aHatchName;
+    XHatch xHatch = getXHatchFromName(mxModel, aHatchName);
+    XFillHatchItem aHatchItem(aHatchName, xHatch);
+    updateFillHatch(false, true, &aHatchItem);
 }
 
 void ChartAreaPanel::modelInvalid()
commit b5c0f852b51dd8b0e9b8bf65fbaa18bc61558107
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jul 24 01:47:31 2015 +0200

    update gradients in sidebar as well
    
    Change-Id: I0dc737c133e905d75fab23457fb86c8d2b724ce8

diff --git a/chart2/source/controller/inc/ChartController.hxx b/chart2/source/controller/inc/ChartController.hxx
index fb84c45..9749b36 100644
--- a/chart2/source/controller/inc/ChartController.hxx
+++ b/chart2/source/controller/inc/ChartController.hxx
@@ -127,6 +127,7 @@ class ChartWindow;
 class DrawModelWrapper;
 class DrawViewWrapper;
 class ReferenceSizeProvider;
+class ViewElementListProvider;
 
 class ChartController   : public ::cppu::WeakImplHelper12 <
          ::com::sun::star::frame::XController   //comprehends XComponent (required interface)
@@ -433,6 +434,8 @@ public:
 
     bool isShapeContext() const;
 
+    ViewElementListProvider getViewElementListProvider();
+
     DECL_LINK( NotifyUndoActionHdl, SdrUndoAction* );
 
 public:
diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx
index 138fc65..66a7b29 100644
--- a/chart2/source/controller/main/ChartController.cxx
+++ b/chart2/source/controller/main/ChartController.cxx
@@ -43,6 +43,7 @@
 #include "DrawCommandDispatch.hxx"
 #include "ShapeController.hxx"
 #include "UndoActions.hxx"
+#include "ViewElementListProvider.hxx"
 
 #include <comphelper/InlineContainer.hxx>
 #include <cppuhelper/supportsservice.hxx>
@@ -1623,6 +1624,11 @@ void ChartController::impl_initializeAccessible( const uno::Reference< lang::XIn
         ;
 }
 
+ViewElementListProvider ChartController::getViewElementListProvider()
+{
+    return ViewElementListProvider(m_pDrawModelWrapper.get());
+}
+
 } //namespace chart
 
 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 6dcadd1..9e1b5e8 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -10,6 +10,7 @@
 #include "ChartAreaPanel.hxx"
 
 #include "ChartController.hxx"
+#include "ViewElementListProvider.hxx"
 
 #include <svx/xfltrit.hxx>
 #include <svx/xflftrit.hxx>
@@ -42,6 +43,33 @@ css::uno::Reference<css::beans::XPropertySet> getPropSet(
     return ObjectIdentifier::getObjectPropertySet(aCID, xModel);
 }
 
+XGradient getXGradientForName(css::uno::Reference<css::frame::XModel> xModel,
+        const OUString& rName)
+{
+    css::uno::Reference<css::frame::XController>xController = xModel->getCurrentController();
+    if (!xController.is())
+        return XGradient();
+
+    ChartController* pController = dynamic_cast<ChartController*>(xController.get());
+    if (!pController)
+        return XGradient();
+
+    ViewElementListProvider aProvider = pController->getViewElementListProvider();
+    XGradientListRef aRef = aProvider.GetGradientList();
+    size_t n = aRef->Count();
+    for (size_t i = 0; i < n; ++i)
+    {
+        XGradientEntry* pGradient = aRef->GetGradient(i);
+        if (!pGradient)
+            continue;
+
+        if (pGradient->GetName() == rName)
+            return XGradient(pGradient->GetGradient());
+    }
+
+    return XGradient();
+}
+
 class PreventUpdate
 {
 public:
@@ -215,6 +243,12 @@ void ChartAreaPanel::updateData()
     xPropSet->getPropertyValue("Transparency") >>= nFillTransparence;
     SfxUInt16Item aTransparenceItem(0, nFillTransparence);
     updateFillTransparence(false, true, &aTransparenceItem);
+
+    OUString aGradientName;
+    xPropSet->getPropertyValue("GradientName") >>= aGradientName;
+    XGradient xGradient = getXGradientForName(mxModel, aGradientName);
+    XFillGradientItem aGradientItem(aGradientName, xGradient);
+    updateFillGradient(false, true, &aGradientItem);
 }
 
 void ChartAreaPanel::modelInvalid()
commit e4daf8be5e9c84c378ec6477163647d1c9b7ef55
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jul 24 00:52:42 2015 +0200

    this nasty update cycle was causing many issues
    
    Setting the property from the sidebar was causing the model to be
    changed and therefore updating the sidebar again.
    
    Change-Id: I9ca690ae05d4cb0f2ce16f905a29582cc9e86f64

diff --git a/chart2/source/controller/sidebar/ChartAreaPanel.cxx b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
index 72da2c9..6dcadd1 100644
--- a/chart2/source/controller/sidebar/ChartAreaPanel.cxx
+++ b/chart2/source/controller/sidebar/ChartAreaPanel.cxx
@@ -42,6 +42,24 @@ css::uno::Reference<css::beans::XPropertySet> getPropSet(
     return ObjectIdentifier::getObjectPropertySet(aCID, xModel);
 }
 
+class PreventUpdate
+{
+public:
+    PreventUpdate(bool& bUpdate):
+        mbUpdate(bUpdate)
+    {
+        mbUpdate = false;
+    }
+
+    ~PreventUpdate()
+    {
+        mbUpdate = true;
+    }
+
+private:
+    bool& mbUpdate;
+};
+
 }
 
 VclPtr<vcl::Window> ChartAreaPanel::Create(
@@ -64,7 +82,8 @@ ChartAreaPanel::ChartAreaPanel(vcl::Window* pParent,
     svx::sidebar::AreaPropertyPanelBase(pParent, rxFrame),
     mxModel(pController->getModel()),
     mxListener(new ChartSidebarModifyListener(this)),
-    mxSelectionListener(new ChartSidebarSelectionListener(this))
+    mxSelectionListener(new ChartSidebarSelectionListener(this)),
+    mbUpdate(true)
 {
     Initialize();
 }
@@ -98,6 +117,7 @@ void ChartAreaPanel::Initialize()
 
 void ChartAreaPanel::setFillTransparence(const XFillTransparenceItem& rItem)
 {
+    PreventUpdate aProtector(mbUpdate);
     css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
     if (!xPropSet.is())
         return;
@@ -108,6 +128,7 @@ void ChartAreaPanel::setFillTransparence(const XFillTransparenceItem& rItem)
 void ChartAreaPanel::setFillFloatTransparence(
         const XFillFloatTransparenceItem& rItem)
 {
+    PreventUpdate aProtector(mbUpdate);
     css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
     if (!xPropSet.is())
         return;
@@ -117,6 +138,7 @@ void ChartAreaPanel::setFillFloatTransparence(
 
 void ChartAreaPanel::setFillStyle(const XFillStyleItem& rItem)
 {
+    PreventUpdate aProtector(mbUpdate);
     css::uno::Reference<css::beans::XPropertySet> xPropSet = getPropSet(mxModel);
     if (!xPropSet.is())
         return;
@@ -139,6 +161,7 @@ void ChartAreaPanel::setFillStyleAndColor(const XFillStyleItem* pStyleItem,

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list