[Libreoffice-commits] core.git: 13 commits - include/LibreOfficeKit libreofficekit/qa libreofficekit/source

Pranav Kant pranavk at gnome.org
Tue Jul 28 06:04:52 PDT 2015


 include/LibreOfficeKit/LibreOfficeKitGtk.h          |   15 
 libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx |   66 +-
 libreofficekit/source/gtk/lokdocview.cxx            |  533 ++++++++++++++++----
 libreofficekit/source/gtk/tilebuffer.cxx            |   65 +-
 libreofficekit/source/gtk/tilebuffer.hxx            |   91 +++
 5 files changed, 626 insertions(+), 144 deletions(-)

New commits:
commit 2d2b392dcda5bdfab61a358dc1dd725d65fba07f
Author: Pranav Kant <pranavk at gnome.org>
Date:   Mon Jul 27 22:13:39 2015 +0530

    lokdocview: post_command arguments are not supposed to be const
    
    Change-Id: Ibc22d03d9eee9fd151ecf5773e36c2519141a5eb

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index a548261..7ce2764 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1947,7 +1947,7 @@ lok_doc_view_post_command (LOKDocView* pDocView,
     GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
     LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND);
     pLOEvent->m_pCommand = pCommand;
-    pLOEvent->m_pArguments  = pArguments;
+    pLOEvent->m_pArguments  = g_strdup(pArguments);
 
     g_task_set_task_data(task, pLOEvent, g_free);
     g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index d2451b6..dabf72f 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -158,7 +158,7 @@ struct LOEvent
     /// @name post_command parameters
     ///@{
     const gchar* m_pCommand;
-    const gchar* m_pArguments;
+    gchar* m_pArguments;
     ///@}
 
     /// @name open_document parameter
commit 7c45a57081a921b8f56812dd37c2fcd4b86d2a1a
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 26 22:39:43 2015 +0530

    lokdocview: setGraphicSelection in another thread
    
    Change-Id: Ib7a6bf63ee6f300c6c5d50d02a3465d0a075a5be

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 4745a82..a548261 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -889,7 +889,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
             {
                 g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i);
                 priv->m_bInDragGraphicHandles[i] = false;
-                priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
+
+                GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+                LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+                pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
+                pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+                pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+                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;
             }
         }
@@ -898,7 +908,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
         {
             g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
             priv->m_bInDragGraphicSelection = false;
-            priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
+
+            GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+            LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+            pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
+            pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+            pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+            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;
         }
     }
@@ -937,10 +957,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
                 {
                     g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i);
                     priv->m_bInDragGraphicHandles[i] = true;
-                    priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument,
-                                                             LOK_SETGRAPHICSELECTION_START,
-                                                             pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom),
-                                                             pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom));
+
+                    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+                    LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+                    pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START;
+                    pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom);
+                    pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom);
+                    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;
                 }
             }
@@ -1063,7 +1090,17 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
     {
         g_info("lcl_signalMotion: start of drag graphic selection");
         priv->m_bInDragGraphicSelection = true;
-        priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
+
+        GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+        LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+        pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START;
+        pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+        pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+        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;
     }
 
@@ -1084,6 +1121,20 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
 }
 
 static void
+setGraphicSelectionInThread(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->setGraphicSelection(priv->m_pDocument,
+                                                   pLOEvent->m_nSetGraphicSelectionType,
+                                                   pLOEvent->m_nSetGraphicSelectionX,
+                                                   pLOEvent->m_nSetGraphicSelectionY);
+}
+
+static void
 postMouseEventInThread(gpointer data)
 {
     GTask* task = G_TASK(data);
@@ -1282,6 +1333,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
     case LOK_POST_MOUSE_EVENT:
         postMouseEventInThread(task);
         break;
+    case LOK_SET_GRAPHIC_SELECTION:
+        setGraphicSelectionInThread(task);
+        break;
     }
 
     g_object_unref(task);
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index aa496aa..d2451b6 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -139,7 +139,8 @@ enum
     LOK_SET_PART,
     LOK_POST_KEY,
     LOK_PAINT_TILE,
-    LOK_POST_MOUSE_EVENT
+    LOK_POST_MOUSE_EVENT,
+    LOK_SET_GRAPHIC_SELECTION
 };
 
 /**
@@ -196,6 +197,13 @@ struct LOEvent
     int m_nPostMouseEventCount;
     ///@}
 
+    /// @name setGraphicSelection parameters
+    ///@{
+    int m_nSetGraphicSelectionType;
+    int m_nSetGraphicSelectionX;
+    int m_nSetGraphicSelectionY;
+    ///@}
+
     /// Constructor to instantiate an object of type `type`.
     LOEvent(int type)
         : m_nType(type) {}
commit de9224bf9686550e63876eb5ac1241b27c01bc25
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 26 22:23:46 2015 +0530

    lokdocview: Move postMouseEvent in separate LOK thread
    
    Change-Id: I9d1a08db2a91a596d3039a2388c22e6ea76dc2b1

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index b2d3dbf..4745a82 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -958,7 +958,16 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
         if ((pEvent->time - priv->m_nLastButtonPressTime) < 250)
             nCount++;
         priv->m_nLastButtonPressTime = pEvent->time;
-        priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount);
+        GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT);
+        pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONDOWN;
+        pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom);
+        pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom);
+        pLOEvent->m_nPostMouseEventCount = nCount;
+        g_task_set_task_data(task, pLOEvent, g_free);
+
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+        g_object_unref(task);
         break;
     }
     case GDK_BUTTON_RELEASE:
@@ -967,7 +976,16 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
         if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250)
             nCount++;
         priv->m_nLastButtonReleaseTime = pEvent->time;
-        priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount);
+        GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT);
+        pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONUP;
+        pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom);
+        pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom);
+        pLOEvent->m_nPostMouseEventCount = nCount;
+        g_task_set_task_data(task, pLOEvent, g_free);
+
+        g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
+        g_object_unref(task);
         break;
     }
     default:
@@ -1050,12 +1068,37 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
     }
 
     // Otherwise a mouse move, as on the desktop.
-    priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), 1);
+
+    GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
+    LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT);
+    pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEMOVE;
+    pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom);
+    pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom);
+    pLOEvent->m_nPostMouseEventCount = 1;
+    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;
 }
 
 static void
+postMouseEventInThread(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->postMouseEvent(priv->m_pDocument,
+                                              pLOEvent->m_nPostMouseEventType,
+                                              pLOEvent->m_nPostMouseEventX,
+                                              pLOEvent->m_nPostMouseEventY,
+                                              pLOEvent->m_nPostMouseEventCount);
+}
+
+static void
 openDocumentInThread (gpointer data)
 {
     GTask* task = G_TASK(data);
@@ -1236,6 +1279,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
     case LOK_PAINT_TILE:
         paintTileInThread(task);
         break;
+    case LOK_POST_MOUSE_EVENT:
+        postMouseEventInThread(task);
+        break;
     }
 
     g_object_unref(task);
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 6e57d2f..aa496aa 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -138,7 +138,8 @@ enum
     LOK_SET_PARTMODE,
     LOK_SET_PART,
     LOK_POST_KEY,
-    LOK_PAINT_TILE
+    LOK_PAINT_TILE,
+    LOK_POST_MOUSE_EVENT
 };
 
 /**
@@ -187,6 +188,14 @@ struct LOEvent
     float m_fPaintTileZoom;
     ///@}
 
+    /// @name postMouseEvent parameters
+    ///@{
+    int m_nPostMouseEventType;
+    int m_nPostMouseEventX;
+    int m_nPostMouseEventY;
+    int m_nPostMouseEventCount;
+    ///@}
+
     /// Constructor to instantiate an object of type `type`.
     LOEvent(int type)
         : m_nType(type) {}
commit 4fb3d2e6be39fb3a7323b11a02adf853ed37a3ca
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 26 18:24:02 2015 +0530

    lokdocview: Use only one ctor for instantiating LOEvent
    
    ... and set each member variable manually.
    
    Additionally, improves documentation of the struct LOEvent.
    
    Change-Id: I2e8e1dc70298dc85943769e2f01c6127eedb8207

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 289d954..b2d3dbf 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -39,8 +39,8 @@
 /// Private struct used by this GObject type
 struct _LOKDocViewPrivate
 {
-    gchar* m_aLOPath;
-    gchar* m_aDocPath;
+    const gchar* m_aLOPath;
+    const gchar* m_aDocPath;
     gdouble m_nLoadProgress;
     gboolean m_bIsLoading;
     gboolean m_bCanZoomIn;
@@ -302,7 +302,10 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
     if (pEvent->type == GDK_KEY_RELEASE)
     {
         GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
-        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY);
+        pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP;
+        pLOEvent->m_nCharCode = nCharCode;
+        pLOEvent->m_nKeyCode  = nKeyCode;
         g_task_set_task_data(task, pLOEvent, g_free);
         g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
         g_object_unref(task);
@@ -310,7 +313,10 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
     else
     {
         GTask* task = g_task_new(pDocView, NULL, NULL, NULL);
-        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode);
+        LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY);
+        pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYINPUT;
+        pLOEvent->m_nCharCode = nCharCode;
+        pLOEvent->m_nKeyCode  = nKeyCode;
         g_task_set_task_data(task, pLOEvent, g_free);
         g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
         g_object_unref(task);
@@ -1163,7 +1169,7 @@ paintTileInThread (gpointer data)
     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;
+    int index = pLOEvent->m_nPaintTileX * buffer.m_nWidth + pLOEvent->m_nPaintTileY;
     if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() &&
         buffer.m_mTiles[index].valid)
         return;
@@ -1177,21 +1183,21 @@ paintTileInThread (gpointer data)
 
     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;
+    aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileY;
+    aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileX;
 
     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));
+                                         pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom),
+                                         pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom));
 
     double elapsedTime = g_test_timer_elapsed();
     g_info ("Rendered (%d, %d) in %f seconds",
-            pLOEvent->m_nX,
-            pLOEvent->m_nY,
+            pLOEvent->m_nPaintTileX,
+            pLOEvent->m_nPaintTileY,
             elapsedTime);
 
     //create a mapping for it
@@ -1674,9 +1680,12 @@ lok_doc_view_open_document (LOKDocView* pDocView,
                             gpointer userdata)
 {
     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);
+
+    LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC);
+    pLOEvent->m_pPath = pPath;
+
+    priv->m_aDocPath = pPath;
     g_task_set_task_data(task, pLOEvent, g_free);
 
     g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
@@ -1836,9 +1845,11 @@ lok_doc_view_post_command (LOKDocView* pDocView,
 {
 
     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);
+    LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND);
+    pLOEvent->m_pCommand = pCommand;
+    pLOEvent->m_pArguments  = pArguments;
 
+    g_task_set_task_data(task, pLOEvent, g_free);
     g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
     g_object_unref(task);
 }
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
index a8594fc..21ea58b 100644
--- a/libreofficekit/source/gtk/tilebuffer.cxx
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -70,26 +70,35 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task)
     {
         m_mTiles[index].valid = false;
 
-        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, fZoom);
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE);
+        pLOEvent->m_nPaintTileX = x;
+        pLOEvent->m_nPaintTileY = y;
+        pLOEvent->m_fPaintTileZoom = fZoom;
         g_task_set_task_data(task, pLOEvent, g_free);
         g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL);
     }
 }
 
-Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task)
+Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task)
 {
     int index = x * m_nWidth + y;
 
     if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid)
     {
-        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom);
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE);
+        pLOEvent->m_nPaintTileX = x;
+        pLOEvent->m_nPaintTileY = y;
+        pLOEvent->m_fPaintTileZoom = fZoom;
         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())
     {
-        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom);
+        LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE);
+        pLOEvent->m_nPaintTileX = x;
+        pLOEvent->m_nPaintTileY = y;
+        pLOEvent->m_fPaintTileZoom = fZoom;
         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 f23b023..6e57d2f 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -152,46 +152,44 @@ struct LOEvent
 {
     /// To identify the type of LOK call
     int m_nType;
+
+    /// @name post_command parameters
+    ///@{
     const gchar* m_pCommand;
     const gchar* m_pArguments;
-    gchar* m_pPath;
+    ///@}
+
+    /// @name open_document parameter
+    ///@{
+    const gchar* m_pPath;
+    ///@}
+
+    /// set_edit parameter
     gboolean m_bEdit;
+
+    /// set_partmode parameter
     int m_nPartMode;
+
+    /// set_part parameter
     int m_nPart;
+
+    /// @name postKeyEvent parameters
+    ///@{
     int m_nKeyEvent;
     int m_nCharCode;
     int m_nKeyCode;
+    ///@}
 
-    int m_nX;
-    int m_nY;
-    float m_fZoom;
+    /// @name paintTile parameters
+    ///@{
+    int m_nPaintTileX;
+    int m_nPaintTileY;
+    float m_fPaintTileZoom;
+    ///@}
 
-    /// Constructor to easily instantiate an object for LOK call of `type' type.
+    /// Constructor to instantiate an object 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) {}
 };
 
 #endif // INCLUDED_TILEBUFFER_HXX
commit ee0f4f75d2d95aaed8995337947c4cc665722aaf
Author: Pranav Kant <pranavk at gnome.org>
Date:   Sun Jul 26 17:22:13 2015 +0530

    lokdocview: Follow the camelCase naming convention
    
    Change-Id: I05582d33ee3535d4b677fa8138c9d573585a4252

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 825eb10..289d954 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -1050,7 +1050,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
 }
 
 static void
-lok_doc_view_open_document_in_thread (gpointer data)
+openDocumentInThread (gpointer data)
 {
     GTask* task = G_TASK(data);
     LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
@@ -1099,7 +1099,7 @@ lok_doc_view_open_document_in_thread (gpointer data)
 }
 
 static void
-lok_doc_view_set_part_in_thread(gpointer data)
+setPartInThread(gpointer data)
 {
     GTask* task = G_TASK(data);
     LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
@@ -1111,7 +1111,7 @@ lok_doc_view_set_part_in_thread(gpointer data)
 }
 
 static void
-lok_doc_view_set_partmode_in_thread(gpointer data)
+setPartmodeInThread(gpointer data)
 {
     GTask* task = G_TASK(data);
     LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
@@ -1123,7 +1123,7 @@ lok_doc_view_set_partmode_in_thread(gpointer data)
 }
 
 static void
-lok_doc_view_set_edit_in_thread(gpointer data)
+setEditInThread(gpointer data)
 {
     GTask* task = G_TASK(data);
     LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
@@ -1145,7 +1145,7 @@ lok_doc_view_set_edit_in_thread(gpointer data)
 }
 
 static void
-lok_doc_view_post_command_in_thread (gpointer data)
+postCommandInThread (gpointer data)
 {
     GTask* task = G_TASK(data);
     LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task));
@@ -1210,19 +1210,19 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/)
     switch (pLOEvent->m_nType)
     {
     case LOK_LOAD_DOC:
-        lok_doc_view_open_document_in_thread (task);
+        openDocumentInThread(task);
         break;
     case LOK_POST_COMMAND:
-        lok_doc_view_post_command_in_thread (task);
+        postCommandInThread(task);
         break;
     case LOK_SET_EDIT:
-        lok_doc_view_set_edit_in_thread(task);
+        setEditInThread(task);
         break;
     case LOK_SET_PART:
-        lok_doc_view_set_part_in_thread(task);
+        setPartInThread(task);
         break;
     case LOK_SET_PARTMODE:
-        lok_doc_view_set_partmode_in_thread(task);
+        setPartmodeInThread(task);
         break;
     case LOK_POST_KEY:
         postKeyEventInThread(task);
commit 57ec1780d654e335e09a6c64c4d48234f0556635
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 a7f12df929226ba43356d3d092851b07c84ae1c4
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 e032b64451347f5079c2a5bfbfda8d843db91e2d
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 4edbf5a01fb8d93f3e6f2b9f7100a0c3d2eafa6e
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 a433ea9f46cc1cc0de7282f3d360d70ad215aaa8
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 cb94e003c066033db96da62596022385794f281c
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 da129b682f81a8fdbc6be95142456f204b2b7951
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 645f00543405450cd3a3862482dc4e1cda65d098
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);
 }
 
 /**


More information about the Libreoffice-commits mailing list