Blame SOURCES/0050-lokdocview-Restructure-this-GObject-class.patch

135360
From 90cd5fdf14031c259ddc4f9ecf9ada7c37fcf421 Mon Sep 17 00:00:00 2001
135360
From: Pranav Kant <pranavk@gnome.org>
135360
Date: Thu, 11 Jun 2015 22:00:11 +0530
135360
Subject: [PATCH 050/398] lokdocview: Restructure this GObject class
135360
135360
This is a big messy commit restructuring the whole class to follow most
135360
common practices followed by standard GObject classes, so that it can
135360
keep gobject-introspection happy; hence, allowing this widget to be used
135360
from other languages.
135360
135360
(cherry picked from commit 3061e486f9f9313c15cba6782edfaee96fe4f83d)
135360
135360
Change-Id: I10c34dad402d1ec586958b2db21ff44412c36cea
135360
---
135360
 include/LibreOfficeKit/LibreOfficeKitGtk.h         |   17 +-
135360
 .../qa/gtktiledviewer/gtktiledviewer.cxx           |    4 +-
135360
 libreofficekit/source/gtk/lokdocview.cxx           | 1856 +++++++++++---------
135360
 3 files changed, 1041 insertions(+), 836 deletions(-)
135360
135360
diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
index bdd2e9ab90e3..7048dbefc0a1 100644
135360
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
135360
@@ -25,23 +25,19 @@ G_BEGIN_DECLS
135360
 #define LOK_IS_DOC_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  LOK_TYPE_DOC_VIEW))
135360
 #define LOK_DOC_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  LOK_TYPE_DOC_VIEW, LOKDocViewClass))
135360
 
135360
-
135360
-typedef struct _LOKDocView       LOKDocView;
135360
-typedef struct _LOKDocViewClass  LOKDocViewClass;
135360
+typedef struct _LOKDocView        LOKDocView;
135360
+typedef struct _LOKDocViewClass   LOKDocViewClass;
135360
+typedef struct _LOKDocViewPrivate LOKDocViewPrivate;
135360
 
135360
 struct _LOKDocView
135360
 {
135360
     GtkDrawingArea aDrawingArea;
135360
-    struct LOKDocView_Impl* m_pImpl;
135360
+    LOKDocViewPrivate* priv;
135360
 };
135360
 
135360
 struct _LOKDocViewClass
135360
 {
135360
     GtkDrawingAreaClass parent_class;
135360
-    void (* edit_changed)  (LOKDocView* pView, gboolean was_edit);
135360
-    void (* command_changed) (LOKDocView* pView, char* new_state);
135360
-    void (* search_not_found) (LOKDocView* pView, char* new_state);
135360
-    void (* part_changed) (LOKDocView* pView, int new_part);
135360
 };
135360
 
135360
 GType                          lok_doc_view_get_type               (void) G_GNUC_CONST;
135360
@@ -78,9 +74,8 @@ void                           lok_doc_view_post_command           (LOKDocView*
135360
                                                                     const char* pArguments);
135360
 
135360
 /// Posts a keyboard event to LibreOfficeKit.
135360
-void                           lok_doc_view_post_key               (GtkWidget* pWidget,
135360
-                                                                    GdkEventKey* pEvent,
135360
-                                                                    gpointer pData);
135360
+void                           lok_doc_view_post_key               (LOKDocView* pDocView,
135360
+                                                                    GdkEvent* pEvent);
135360
 
135360
 float                          lok_doc_view_pixel_to_twip          (LOKDocView* pDocView,
135360
                                                                     float fInput);
135360
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
index 580d5f66f683..8b006797c226 100644
135360
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
135360
@@ -145,12 +145,12 @@ static void getVisibleAreaTwips(GdkRectangle* pArea)
135360
 
135360
 
135360
 /// Handles the key-press-event of the window.
135360
-static gboolean signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData)
135360
+static gboolean signalKey(GtkWidget* /*pWidget*/, GdkEvent* pEvent, gpointer/* pData*/)
135360
 {
135360
     LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView);
135360
     if (!gtk_widget_get_visible(pFindbar) && bool(lok_doc_view_get_edit(pLOKDocView)))
135360
         {
135360
-            lok_doc_view_post_key(pWidget, pEvent, pData);
135360
+            lok_doc_view_post_key(pLOKDocView, pEvent);
135360
             return TRUE;
135360
         }
135360
     return FALSE;
135360
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
135360
index b00556620288..7031be9b6536 100644
135360
--- a/libreofficekit/source/gtk/lokdocview.cxx
135360
+++ b/libreofficekit/source/gtk/lokdocview.cxx
135360
@@ -36,26 +36,30 @@
135360
 // Number of handles around a graphic selection.
135360
 #define GRAPHIC_HANDLE_COUNT 8
135360
 
135360
-/// Holds data used by LOKDocView only.
135360
-struct LOKDocView_Impl
135360
+struct _LOKDocViewPrivate
135360
 {
135360
-    LOKDocView* m_pDocView;
135360
-    TileBuffer m_aTileBuffer;
135360
-
135360
-    float m_fZoom;
135360
-
135360
+    gchar* m_aLOPath;
135360
+    gchar* m_aDocPath;
135360
+    guint m_nLoadProgress;
135360
+    gboolean m_bIsLoading;
135360
+    gboolean m_bCanZoomIn;
135360
+    gboolean m_bCanZoomOut;
135360
     LibreOfficeKit* m_pOffice;
135360
     LibreOfficeKitDocument* m_pDocument;
135360
-    long m_nDocumentWidthTwips;
135360
-    long m_nDocumentHeightTwips;
135360
+
135360
+    TileBuffer m_aTileBuffer;
135360
+
135360
+    gfloat m_fZoom;
135360
+    glong m_nDocumentWidthTwips;
135360
+    glong m_nDocumentHeightTwips;
135360
     /// View or edit mode.
135360
-    bool m_bEdit;
135360
+    gboolean m_bEdit;
135360
     /// Position and size of the visible cursor.
135360
     GdkRectangle m_aVisibleCursor;
135360
     /// Cursor overlay is visible or hidden (for blinking).
135360
-    bool m_bCursorOverlayVisible;
135360
+    gboolean m_bCursorOverlayVisible;
135360
     /// Cursor is visible or hidden (e.g. for graphic selection).
135360
-    bool m_bCursorVisible;
135360
+    gboolean m_bCursorVisible;
135360
     /// Time of the last button press.
135360
     guint32 m_nLastButtonPressTime;
135360
     /// Time of the last button release.
135360
@@ -67,7 +71,7 @@ struct LOKDocView_Impl
135360
     /// Position and size of the selection end.
135360
     GdkRectangle m_aTextSelectionEnd;
135360
     GdkRectangle m_aGraphicSelection;
135360
-    bool m_bInDragGraphicSelection;
135360
+    gboolean m_bInDragGraphicSelection;
135360
 
135360
     /// @name Start/middle/end handle.
135360
     ///@{
135360
@@ -76,19 +80,19 @@ struct LOKDocView_Impl
135360
     /// Rectangle of the text selection start handle, to know if the user clicked on it or not
135360
     GdkRectangle m_aHandleStartRect;
135360
     /// If we are in the middle of a drag of the text selection end handle.
135360
-    bool m_bInDragStartHandle;
135360
+    gboolean m_bInDragStartHandle;
135360
     /// Bitmap of the text selection middle handle.
135360
     cairo_surface_t* m_pHandleMiddle;
135360
     /// Rectangle of the text selection middle handle, to know if the user clicked on it or not
135360
     GdkRectangle m_aHandleMiddleRect;
135360
     /// If we are in the middle of a drag of the text selection middle handle.
135360
-    bool m_bInDragMiddleHandle;
135360
+    gboolean m_bInDragMiddleHandle;
135360
     /// Bitmap of the text selection end handle.
135360
     cairo_surface_t* m_pHandleEnd;
135360
     /// Rectangle of the text selection end handle, to know if the user clicked on it or not
135360
     GdkRectangle m_aHandleEndRect;
135360
     /// If we are in the middle of a drag of the text selection end handle.
135360
-    bool m_bInDragEndHandle;
135360
+    gboolean m_bInDragEndHandle;
135360
     ///@}
135360
 
135360
     /// @name Graphic handles.
135360
@@ -98,103 +102,38 @@ struct LOKDocView_Impl
135360
     /// Rectangle of a graphic selection handle, to know if the user clicked on it or not.
135360
     GdkRectangle m_aGraphicHandleRects[8];
135360
     /// If we are in the middle of a drag of a graphic selection handle.
135360
-    bool m_bInDragGraphicHandles[8];
135360
+    gboolean m_bInDragGraphicHandles[8];
135360
     ///@}
135360
-
135360
-    /// Callback data, allocated in lok_doc_view_callback_worker(), released in lok_doc_view_callback().
135360
-    struct CallbackData
135360
-    {
135360
-        int m_nType;
135360
-        std::string m_aPayload;
135360
-        LOKDocView* m_pDocView;
135360
-
135360
-        CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView);
135360
-    };
135360
-
135360
-
135360
-    LOKDocView_Impl(LOKDocView* pDocView);
135360
-    ~LOKDocView_Impl();
135360
-    /// Connected to the destroy signal of LOKDocView, deletes its LOKDocView_Impl.
135360
-    static void destroy(LOKDocView* pDocView, gpointer pData);
135360
-    /// Connected to the draw of the GtkDrawingArea
135360
-    static gboolean renderDocument(GtkWidget *widget, cairo_t *cr, gpointer user_data);
135360
-    /// Implementation of draw event handler, invoked by renderDocument().
135360
-    gboolean renderDocumentImpl(cairo_t* cr);
135360
-    /// Receives a key press or release event.
135360
-    void signalKey(GdkEventKey* pEvent);
135360
-    /*
135360
-     * The user drags the handle, which is below the cursor, but wants to move the
135360
-     * cursor accordingly.
135360
-     *
135360
-     * @param pHandle the rectangle of the handle
135360
-     * @param pEvent the motion event
135360
-     * @param pPoint the computed point (output parameter)
135360
-     */
135360
-    static void getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint);
135360
-    /// Receives a button press event.
135360
-    static gboolean signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView);
135360
-    /// Implementation of button press event handler, invoked by signalButton().
135360
-    gboolean signalButtonImpl(GdkEventButton* pEvent);
135360
-    /// Receives a motion event.
135360
-    static gboolean signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView);
135360
-    /// Implementation of motion event handler, invoked by signalMotion().
135360
-    gboolean signalMotionImpl(GdkEventButton* pEvent);
135360
-    /// Receives an expose event.
135360
-    static gboolean renderOverlay(GtkWidget* pWidget, cairo_t* cr, gpointer userdata);
135360
-    /// Implementation of expose event handler (renders cursor and selection overlay), invoked by renderOverlay().
135360
-    gboolean renderOverlayImpl(cairo_t *cr);
135360
-    /// Is rRectangle empty?
135360
-    static bool isEmptyRectangle(const GdkRectangle& rRectangle);
135360
-    /*
135360
-     * Renders pHandle below an rCursor rectangle on pCairo.
135360
-     * @param rRectangle output parameter, the rectangle that contains the rendered handle.
135360
-     */
135360
-    void renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle);
135360
-    /// Renders pHandle around an rSelection rectangle on pCairo.
135360
-    void renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& rSelection, cairo_surface_t* pHandle);
135360
-    /// Takes care of the blinking cursor.
135360
-    static gboolean handleTimeout(gpointer pData);
135360
-    /// Implementation of the timeout handler, invoked by handleTimeout().
135360
-    gboolean handleTimeoutImpl();
135360
-    /// Returns the GdkRectangle of a x,y,width,height string.
135360
-    GdkRectangle payloadToRectangle(const char* pPayload);
135360
-    /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string.
135360
-    std::vector<GdkRectangle> payloadToRectangles(const char* pPayload);
135360
-    /// Returns the string representation of a LibreOfficeKitCallbackType enumeration element.
135360
-    static const char* callbackTypeToString(int nType);
135360
-    /// Invoked on the main thread if callbackWorker() requests so.
135360
-    static gboolean callback(gpointer pData);
135360
-    /// Invoked on the main thread if globalCallbackWorker() requests so.
135360
-    static gboolean globalCallback(gpointer pData);
135360
-    /// Implementation of the callback handler, invoked by callback();
135360
-    gboolean callbackImpl(CallbackData* pCallbackData);
135360
-    /// Our LOK callback, runs on the LO thread.
135360
-    static void callbackWorker(int nType, const char* pPayload, void* pData);
135360
-    /// Implementation of the callback worder handler, invoked by callbackWorker().
135360
-    void callbackWorkerImpl(int nType, const char* pPayload);
135360
-    /// Our global LOK callback, runs on the LO thread.
135360
-    static void globalCallbackWorker(int nType, const char* pPayload, void* pData);
135360
-    /// Implementation of the global callback worder handler, invoked by globalCallbackWorker().
135360
-    void globalCallbackWorkerImpl(int nType, const char* pPayload);
135360
-    /// Command state (various buttons like bold are toggled or not) is changed.
135360
-    void commandChanged(const std::string& rPayload);
135360
-    /// Search did not find any matches.
135360
-    void searchNotFound(const std::string& rPayload);
135360
-    /// LOK decided to change parts, need to update UI.
135360
-    void setPart(const std::string& rPayload);
135360
-    /// Sets the tiles enclosed by rRectangle as invalid in m_aTileBuffer
135360
-    void setTilesInvalid(const GdkRectangle& rRectangle);
135360
 };
135360
 
135360
 enum
135360
 {
135360
+    LOAD_CHANGED,
135360
+    LOAD_FAILED,
135360
     EDIT_CHANGED,
135360
     COMMAND_CHANGED,
135360
     SEARCH_NOT_FOUND,
135360
     PART_CHANGED,
135360
+    HYPERLINK_CLICKED,
135360
+
135360
     LAST_SIGNAL
135360
 };
135360
 
135360
+enum
135360
+{
135360
+    PROP_0,
135360
+
135360
+    PROP_LO_PATH,
135360
+    PROP_DOC_PATH,
135360
+    PROP_EDITABLE,
135360
+    PROP_LOAD_PROGRESS,
135360
+    PROP_ZOOM,
135360
+    PROP_IS_LOADING,
135360
+    PROP_DOC_WIDTH,
135360
+    PROP_DOC_HEIGHT,
135360
+    PROP_CAN_ZOOM_IN,
135360
+    PROP_CAN_ZOOM_OUT
135360
+};
135360
 
135360
 static guint doc_view_signals[LAST_SIGNAL] = { 0 };
135360
 
135360
@@ -203,15 +142,26 @@ SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type();
135360
 #pragma GCC diagnostic push
135360
 #pragma GCC diagnostic ignored "-Wunused-function"
135360
 #endif
135360
-G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA)
135360
+G_DEFINE_TYPE_WITH_PRIVATE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA)
135360
 #ifdef __GNUC__
135360
 #pragma GCC diagnostic pop
135360
 #endif
135360
 
135360
-namespace {
135360
 
135360
-/// Sets rWidth and rHeight from a "width, height" string.
135360
-void payloadToSize(const char* pPayload, long& rWidth, long& rHeight)
135360
+struct CallbackData
135360
+{
135360
+    int m_nType;
135360
+    std::string m_aPayload;
135360
+    LOKDocView* m_pDocView;
135360
+
135360
+    CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView)
135360
+        : m_nType(nType),
135360
+          m_aPayload(rPayload),
135360
+          m_pDocView(pDocView) {}
135360
+};
135360
+
135360
+static void
135360
+payloadToSize(const char* pPayload, long& rWidth, long& rHeight)
135360
 {
135360
     rWidth = rHeight = 0;
135360
     gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2);
135360
@@ -226,177 +176,70 @@ void payloadToSize(const char* pPayload, long& rWidth, long& rHeight)
135360
     g_strfreev(ppCoordinates);
135360
 }
135360
 
135360
-}
135360
-
135360
-
135360
-
135360
-namespace {
135360
-
135360
-/// Implementation of the global callback handler, invoked by globalCallback();
135360
-gboolean globalCallbackImpl(LOKDocView_Impl::CallbackData* pCallback)
135360
+/// Returns the string representation of a LibreOfficeKitCallbackType enumeration element.
135360
+static const char*
135360
+callbackTypeToString (int nType)
135360
 {
135360
-    switch (pCallback->m_nType)
135360
+    switch (nType)
135360
     {
135360
+    case LOK_CALLBACK_INVALIDATE_TILES:
135360
+        return "LOK_CALLBACK_INVALIDATE_TILES";
135360
+    case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
135360
+        return "LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR";
135360
+    case LOK_CALLBACK_TEXT_SELECTION:
135360
+        return "LOK_CALLBACK_TEXT_SELECTION";
135360
+    case LOK_CALLBACK_TEXT_SELECTION_START:
135360
+        return "LOK_CALLBACK_TEXT_SELECTION_START";
135360
+    case LOK_CALLBACK_TEXT_SELECTION_END:
135360
+        return "LOK_CALLBACK_TEXT_SELECTION_END";
135360
+    case LOK_CALLBACK_CURSOR_VISIBLE:
135360
+        return "LOK_CALLBACK_CURSOR_VISIBLE";
135360
+    case LOK_CALLBACK_GRAPHIC_SELECTION:
135360
+        return "LOK_CALLBACK_GRAPHIC_SELECTION";
135360
+    case LOK_CALLBACK_HYPERLINK_CLICKED:
135360
+        return "LOK_CALLBACK_HYPERLINK_CLICKED";
135360
+    case LOK_CALLBACK_STATE_CHANGED:
135360
+        return "LOK_CALLBACK_STATE_CHANGED";
135360
     case LOK_CALLBACK_STATUS_INDICATOR_START:
135360
-    {
135360
-    }
135360
-    break;
135360
+        return "LOK_CALLBACK_STATUS_INDICATOR_START";
135360
     case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
135360
-    {
135360
-    }
135360
-    break;
135360
+        return "LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE";
135360
     case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
135360
-    {
135360
-    }
135360
-    break;
135360
-    default:
135360
-        g_assert(false);
135360
-        break;
135360
+        return "LOK_CALLBACK_STATUS_INDICATOR_FINISH";
135360
+    case LOK_CALLBACK_SEARCH_NOT_FOUND:
135360
+        return "LOK_CALLBACK_SEARCH_NOT_FOUND";
135360
+    case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
135360
+        return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED";
135360
+    case LOK_CALLBACK_SET_PART:
135360
+        return "LOK_CALLBACK_SET_PART";
135360
     }
135360
-    delete pCallback;
135360
-
135360
-    return G_SOURCE_REMOVE;
135360
-}
135360
-
135360
-}
135360
-
135360
-LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView)
135360
-    : m_nType(nType),
135360
-    m_aPayload(rPayload),
135360
-    m_pDocView(pDocView)
135360
-{
135360
-}
135360
-
135360
-LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView)
135360
-    : m_pDocView(pDocView),
135360
-      m_aTileBuffer(TileBuffer(0,0)),
135360
-      m_fZoom(1),
135360
-      m_pOffice(0),
135360
-      m_pDocument(0),
135360
-      m_nDocumentWidthTwips(0),
135360
-      m_nDocumentHeightTwips(0),
135360
-      m_bEdit(false),
135360
-      m_aVisibleCursor({0, 0, 0, 0}),
135360
-      m_bCursorOverlayVisible(false),
135360
-      m_bCursorVisible(true),
135360
-      m_nLastButtonPressTime(0),
135360
-      m_nLastButtonReleaseTime(0),
135360
-      m_aTextSelectionStart({0, 0, 0, 0}),
135360
-      m_aTextSelectionEnd({0, 0, 0, 0}),
135360
-      m_aGraphicSelection({0, 0, 0, 0}),
135360
-      m_bInDragGraphicSelection(false),
135360
-
135360
-      // Start/middle/end handle.
135360
-      m_pHandleStart(0),
135360
-      m_aHandleStartRect({0, 0, 0, 0}),
135360
-      m_bInDragStartHandle(false),
135360
-      m_pHandleMiddle(0),
135360
-      m_aHandleMiddleRect({0, 0, 0, 0}),
135360
-      m_bInDragMiddleHandle(false),
135360
-      m_pHandleEnd(0),
135360
-      m_aHandleEndRect({0, 0, 0, 0}),
135360
-      m_bInDragEndHandle(false),
135360
-
135360
-      m_pGraphicHandle(0)
135360
-{
135360
-    memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects));
135360
-    memset(&m_bInDragGraphicHandles, 0, sizeof(m_bInDragGraphicHandles));
135360
-}
135360
-
135360
-LOKDocView_Impl::~LOKDocView_Impl()
135360
-{
135360
-    if (m_pDocument)
135360
-        m_pDocument->pClass->destroy(m_pDocument);
135360
-    if (m_pOffice)
135360
-        m_pOffice->pClass->destroy(m_pOffice);
135360
-    m_pDocument = 0;
135360
-    m_pOffice = 0;
135360
-}
135360
-
135360
-void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/)
135360
-{
135360
-    // We specifically need to destroy the document when closing in order to ensure
135360
-    // that lock files etc. are cleaned up.
135360
-    delete pDocView->m_pImpl;
135360
-}
135360
-
135360
-gboolean LOKDocView_Impl::renderDocument(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata)
135360
-{
135360
-    LOKDocView *pDocView = LOK_DOC_VIEW (userdata);
135360
-    return pDocView->m_pImpl->renderDocumentImpl(cr);
135360
+    return 0;
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::renderDocumentImpl(cairo_t *pCairo)
135360
+static bool
135360
+isEmptyRectangle(const GdkRectangle& rRectangle)
135360
 {
135360
-    long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom);
135360
-    long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom);
135360
-    // Total number of rows / columns in this document.
135360
-    guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels);
135360
-    guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
135360
-    GdkRectangle aVisibleArea;
135360
-
135360
-    gdk_cairo_get_clip_rectangle (pCairo, &aVisibleArea);
135360
-
135360
-    aVisibleArea.x = pixelToTwip (aVisibleArea.x, m_fZoom);
135360
-    aVisibleArea.y = pixelToTwip (aVisibleArea.y, m_fZoom);
135360
-    aVisibleArea.width = pixelToTwip (aVisibleArea.width, m_fZoom);
135360
-    aVisibleArea.height = pixelToTwip (aVisibleArea.height, m_fZoom);
135360
-
135360
-    // Render the tiles.
135360
-    for (guint nRow = 0; nRow < nRows; ++nRow)
135360
-    {
135360
-        for (guint nColumn = 0; nColumn < nColumns; ++nColumn)
135360
-        {
135360
-            GdkRectangle aTileRectangleTwips, aTileRectanglePixels;
135360
-            bool bPaint = true;
135360
-
135360
-            // Determine size of the tile: the rightmost/bottommost tiles may
135360
-            // be smaller, and we need the size to decide if we need to repaint.
135360
-            if (nColumn == nColumns - 1)
135360
-                aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels;
135360
-            else
135360
-                aTileRectanglePixels.width = nTileSizePixels;
135360
-            if (nRow == nRows - 1)
135360
-                aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels;
135360
-            else
135360
-                aTileRectanglePixels.height = nTileSizePixels;
135360
-
135360
-            // Determine size and position of the tile in document coordinates,
135360
-            // so we can decide if we can skip painting for partial rendering.
135360
-            aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn;
135360
-            aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow;
135360
-            aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom);
135360
-            aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, m_fZoom);
135360
-
135360
-            if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0))
135360
-                bPaint = false;
135360
-
135360
-            if (bPaint)
135360
-            {
135360
-                Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom);
135360
-                GdkPixbuf* pPixBuf = currentTile.getBuffer();
135360
-                gdk_cairo_set_source_pixbuf (pCairo, pPixBuf,
135360
-                                             twipToPixel(aTileRectangleTwips.x, m_fZoom),
135360
-                                             twipToPixel(aTileRectangleTwips.y, m_fZoom));
135360
-                cairo_paint(pCairo);
135360
-            }
135360
-        }
135360
-    }
135360
-    return FALSE;
135360
+    return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0;
135360
 }
135360
 
135360
-void LOKDocView_Impl::signalKey(GdkEventKey* pEvent)
135360
+static void
135360
+signalKey (LOKDocView* pDocView, const GdkEvent* pEvent)
135360
 {
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
     int nCharCode = 0;
135360
     int nKeyCode = 0;
135360
+    guint keyval;
135360
+    GdkModifierType state;
135360
+    gdk_event_get_keyval (pEvent, &keyval);
135360
+    gdk_event_get_state (pEvent, &state);
135360
 
135360
-    if (!m_bEdit)
135360
+    if (!priv->m_bEdit)
135360
     {
135360
         g_info("signalKey: not in edit mode, ignore");
135360
         return;
135360
     }
135360
 
135360
-    switch (pEvent->keyval)
135360
+    switch (keyval)
135360
     {
135360
     case GDK_KEY_BackSpace:
135360
         nKeyCode = com::sun::star::awt::Key::BACKSPACE;
135360
@@ -423,325 +266,300 @@ void LOKDocView_Impl::signalKey(GdkEventKey* pEvent)
135360
         nKeyCode = com::sun::star::awt::Key::RIGHT;
135360
         break;
135360
     default:
135360
-        if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26)
135360
-            nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1);
135360
+        if (keyval >= GDK_KEY_F1 && keyval <= GDK_KEY_F26)
135360
+            nKeyCode = com::sun::star::awt::Key::F1 + (keyval - GDK_KEY_F1);
135360
         else
135360
-            nCharCode = gdk_keyval_to_unicode(pEvent->keyval);
135360
+            nCharCode = gdk_keyval_to_unicode(keyval);
135360
     }
135360
 
135360
     // rsc is not public API, but should be good enough for debugging purposes.
135360
     // If this is needed for real, then probably a new param of type
135360
     // css::awt::KeyModifier is needed in postKeyEvent().
135360
-    if (pEvent->state & GDK_SHIFT_MASK)
135360
+    if (state & GDK_SHIFT_MASK)
135360
         nKeyCode |= KEY_SHIFT;
135360
 
135360
     if (pEvent->type == GDK_KEY_RELEASE)
135360
-        m_pDocument->pClass->postKeyEvent(m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode);
135360
+        priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode);
135360
     else
135360
-        m_pDocument->pClass->postKeyEvent(m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode);
135360
-}
135360
-
135360
-gboolean LOKDocView_Impl::signalButton(GtkWidget* /*pEventBox*/, GdkEventButton* pEvent, LOKDocView* pDocView)
135360
-{
135360
-    return pDocView->m_pImpl->signalButtonImpl(pEvent);
135360
+        priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode);
135360
 }
135360
 
135360
-/// Receives a button press event.
135360
-gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent)
135360
+static gboolean
135360
+handleTimeout (gpointer pData)
135360
 {
135360
-    g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x, m_fZoom), (int)pixelToTwip(pEvent->y, m_fZoom));
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pData);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
 
135360
-    if (pEvent->type == GDK_BUTTON_RELEASE)
135360
+    if (priv->m_bEdit)
135360
     {
135360
-        if (m_bInDragStartHandle)
135360
-        {
135360
-            g_info("LOKDocView_Impl::signalButton: end of drag start handle");
135360
-            m_bInDragStartHandle = false;
135360
-            return FALSE;
135360
-        }
135360
-        else if (m_bInDragMiddleHandle)
135360
-        {
135360
-            g_info("LOKDocView_Impl::signalButton: end of drag middle handle");
135360
-            m_bInDragMiddleHandle = false;
135360
-            return FALSE;
135360
-        }
135360
-        else if (m_bInDragEndHandle)
135360
-        {
135360
-            g_info("LOKDocView_Impl::signalButton: end of drag end handle");
135360
-            m_bInDragEndHandle = false;
135360
-            return FALSE;
135360
-        }
135360
+        if (priv->m_bCursorOverlayVisible)
135360
+            priv->m_bCursorOverlayVisible = false;
135360
+        else
135360
+            priv->m_bCursorOverlayVisible = true;
135360
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
135360
+    }
135360
 
135360
-        for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
-        {
135360
-            if (m_bInDragGraphicHandles[i])
135360
-            {
135360
-                g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i);
135360
-                m_bInDragGraphicHandles[i] = false;
135360
-                m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom));
135360
-                return FALSE;
135360
-            }
135360
-        }
135360
+    return G_SOURCE_CONTINUE;
135360
+}
135360
 
135360
-        if (m_bInDragGraphicSelection)
135360
-        {
135360
-            g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
135360
-            m_bInDragGraphicSelection = false;
135360
-            m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom));
135360
-            return FALSE;
135360
-        }
135360
-    }
135360
+static void
135360
+commandChanged(LOKDocView* pDocView, const std::string& rString)
135360
+{
135360
+    g_signal_emit(pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str());
135360
+}
135360
 
135360
-    if (m_bEdit)
135360
-    {
135360
-        GdkRectangle aClick;
135360
-        aClick.x = pEvent->x;
135360
-        aClick.y = pEvent->y;
135360
-        aClick.width = 1;
135360
-        aClick.height = 1;
135360
-        if (pEvent->type == GDK_BUTTON_PRESS)
135360
-        {
135360
-            if (gdk_rectangle_intersect(&aClick, &m_aHandleStartRect, NULL))
135360
-            {
135360
-                g_info("LOKDocView_Impl::signalButton: start of drag start handle");
135360
-                m_bInDragStartHandle = true;
135360
-                return FALSE;
135360
-            }
135360
-            else if (gdk_rectangle_intersect(&aClick, &m_aHandleMiddleRect, NULL))
135360
-            {
135360
-                g_info("LOKDocView_Impl::signalButton: start of drag middle handle");
135360
-                m_bInDragMiddleHandle = true;
135360
-                return FALSE;
135360
-            }
135360
-            else if (gdk_rectangle_intersect(&aClick, &m_aHandleEndRect, NULL))
135360
-            {
135360
-                g_info("LOKDocView_Impl::signalButton: start of drag end handle");
135360
-                m_bInDragEndHandle = true;
135360
-                return FALSE;
135360
-            }
135360
+static void
135360
+searchNotFound(LOKDocView* pDocView, const std::string& rString)
135360
+{
135360
+    g_signal_emit(pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str());
135360
+}
135360
 
135360
-            for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
-            {
135360
-                if (gdk_rectangle_intersect(&aClick, &m_aGraphicHandleRects[i], NULL))
135360
-                {
135360
-                    g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i);
135360
-                    m_bInDragGraphicHandles[i] = true;
135360
-                    m_pDocument->pClass->setGraphicSelection(m_pDocument,
135360
-                                                             LOK_SETGRAPHICSELECTION_START,
135360
-                                                             pixelToTwip(m_aGraphicHandleRects[i].x + m_aGraphicHandleRects[i].width / 2, m_fZoom),
135360
-                                                             pixelToTwip(m_aGraphicHandleRects[i].y + m_aGraphicHandleRects[i].height / 2, m_fZoom));
135360
-                    return FALSE;
135360
-                }
135360
-            }
135360
-        }
135360
-    }
135360
+static void
135360
+setPart(LOKDocView* pDocView, const std::string& rString)
135360
+{
135360
+    g_signal_emit(pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString));
135360
+}
135360
 
135360
-    if (!m_bEdit)
135360
-        lok_doc_view_set_edit(m_pDocView, TRUE);
135360
+/// Implementation of the global callback handler, invoked by globalCallback();
135360
+static gboolean
135360
+globalCallback (gpointer pData)
135360
+{
135360
+    CallbackData* pCallback = static_cast<CallbackData*>(pData);
135360
 
135360
-    switch (pEvent->type)
135360
+    switch (pCallback->m_nType)
135360
     {
135360
-    case GDK_BUTTON_PRESS:
135360
+    case LOK_CALLBACK_STATUS_INDICATOR_START:
135360
     {
135360
-        int nCount = 1;
135360
-        if ((pEvent->time - m_nLastButtonPressTime) < 250)
135360
-            nCount++;
135360
-        m_nLastButtonPressTime = pEvent->time;
135360
-        m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount);
135360
-        break;
135360
     }
135360
-    case GDK_BUTTON_RELEASE:
135360
+    break;
135360
+    case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
135360
     {
135360
-        int nCount = 1;
135360
-        if ((pEvent->time - m_nLastButtonReleaseTime) < 250)
135360
-            nCount++;
135360
-        m_nLastButtonReleaseTime = pEvent->time;
135360
-        m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount);
135360
-        break;
135360
     }
135360
+    break;
135360
+    case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
135360
+    {
135360
+    }
135360
+    break;
135360
     default:
135360
+        g_assert(false);
135360
         break;
135360
     }
135360
-    return FALSE;
135360
+    delete pCallback;
135360
+
135360
+    return G_SOURCE_REMOVE;
135360
 }
135360
 
135360
-void LOKDocView_Impl::getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint)
135360
+static void
135360
+globalCallbackWorker(int nType, const char* pPayload, void* pData)
135360
 {
135360
-    GdkPoint aCursor, aHandle;
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pData);
135360
 
135360
-    // Center of the cursor rectangle: we know that it's above the handle.
135360
-    aCursor.x = pHandle->x + pHandle->width / 2;
135360
-    aCursor.y = pHandle->y - pHandle->height / 2;
135360
-    // Center of the handle rectangle.
135360
-    aHandle.x = pHandle->x + pHandle->width / 2;
135360
-    aHandle.y = pHandle->y + pHandle->height / 2;
135360
-    // Our target is the original cursor position + the dragged offset.
135360
-    pPoint->x = aCursor.x + (pEvent->x - aHandle.x);
135360
-    pPoint->y = aCursor.y + (pEvent->y - aHandle.y);
135360
+    CallbackData* pCallback = new CallbackData(nType, pPayload ? pPayload : "(nil)", pDocView);
135360
+    g_info("LOKDocView_Impl::globalCallbackWorkerImpl: %s, '%s'", callbackTypeToString(nType), pPayload);
135360
+    gdk_threads_add_idle(globalCallback, pCallback);
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::signalMotion(GtkWidget* /*pEventBox*/, GdkEventButton* pEvent, LOKDocView* pDocView)
135360
+static GdkRectangle
135360
+payloadToRectangle (LOKDocView* pDocView, const char* pPayload)
135360
 {
135360
-    return pDocView->m_pImpl->signalMotionImpl(pEvent);
135360
-}
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+    GdkRectangle aRet;
135360
+    gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4);
135360
+    gchar** ppCoordinate = ppCoordinates;
135360
 
135360
-gboolean LOKDocView_Impl::signalMotionImpl(GdkEventButton* pEvent)
135360
-{
135360
-    GdkPoint aPoint;
135360
+    aRet.width = aRet.height = aRet.x = aRet.y = 0;
135360
 
135360
-    if (m_bInDragMiddleHandle)
135360
-    {
135360
-        g_info("lcl_signalMotion: dragging the middle handle");
135360
-        LOKDocView_Impl::getDragPoint(&m_aHandleMiddleRect, pEvent, &aPoint);
135360
-        m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom));
135360
-        return FALSE;
135360
-    }
135360
-    if (m_bInDragStartHandle)
135360
-    {
135360
-        g_info("lcl_signalMotion: dragging the start handle");
135360
-        LOKDocView_Impl::getDragPoint(&m_aHandleStartRect, pEvent, &aPoint);
135360
-        m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom));
135360
-        return FALSE;
135360
-    }
135360
-    if (m_bInDragEndHandle)
135360
-    {
135360
-        g_info("lcl_signalMotion: dragging the end handle");
135360
-        LOKDocView_Impl::getDragPoint(&m_aHandleEndRect, pEvent, &aPoint);
135360
-        m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom));
135360
-        return FALSE;
135360
-    }
135360
-    for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
-    {
135360
-        if (m_bInDragGraphicHandles[i])
135360
-        {
135360
-            g_info("lcl_signalMotion: dragging the graphic handle #%d", i);
135360
-            return FALSE;
135360
-        }
135360
-    }
135360
-    if (m_bInDragGraphicSelection)
135360
-    {
135360
-        g_info("lcl_signalMotion: dragging the graphic selection");
135360
-        return FALSE;
135360
-    }
135360
+    if (!*ppCoordinate)
135360
+        return aRet;
135360
+    aRet.x = atoi(*ppCoordinate);
135360
+    if (aRet.x < 0)
135360
+        aRet.x = 0;
135360
+    ++ppCoordinate;
135360
+    if (!*ppCoordinate)
135360
+        return aRet;
135360
+    aRet.y = atoi(*ppCoordinate);
135360
+    if (aRet.y < 0)
135360
+        aRet.y = 0;
135360
+    ++ppCoordinate;
135360
+    if (!*ppCoordinate)
135360
+        return aRet;
135360
+    aRet.width = atoi(*ppCoordinate);
135360
+    if (aRet.x + aRet.width > priv->m_nDocumentWidthTwips)
135360
+        aRet.width = priv->m_nDocumentWidthTwips - aRet.x;
135360
+    ++ppCoordinate;
135360
+    if (!*ppCoordinate)
135360
+        return aRet;
135360
+    aRet.height = atoi(*ppCoordinate);
135360
+    if (aRet.y + aRet.height > priv->m_nDocumentHeightTwips)
135360
+        aRet.height = priv->m_nDocumentHeightTwips - aRet.y;
135360
+    g_strfreev(ppCoordinates);
135360
 
135360
-    GdkRectangle aMotionInTwipsInTwips;
135360
-    aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x, m_fZoom);
135360
-    aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, m_fZoom);
135360
-    aMotionInTwipsInTwips.width = 1;
135360
-    aMotionInTwipsInTwips.height = 1;
135360
-    if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &m_aGraphicSelection, 0))
135360
-    {
135360
-        g_info("lcl_signalMotion: start of drag graphic selection");
135360
-        m_bInDragGraphicSelection = true;
135360
-        m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom));
135360
-        return FALSE;
135360
-    }
135360
+    return aRet;
135360
+}
135360
 
135360
-    // Otherwise a mouse move, as on the desktop.
135360
-    m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), 1);
135360
+static const std::vector<GdkRectangle>
135360
+payloadToRectangles(LOKDocView* pDocView, const char* pPayload)
135360
+{
135360
+    std::vector<GdkRectangle> aRet;
135360
 
135360
-    return FALSE;
135360
+    gchar** ppRectangles = g_strsplit(pPayload, "; ", 0);
135360
+    for (gchar** ppRectangle = ppRectangles; *ppRectangle; ++ppRectangle)
135360
+        aRet.push_back(payloadToRectangle(pDocView, *ppRectangle));
135360
+    g_strfreev(ppRectangles);
135360
+
135360
+    return aRet;
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::renderOverlay(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata)
135360
+
135360
+static void
135360
+setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle)
135360
 {
135360
-    LOKDocView *pDocView = LOK_DOC_VIEW (userdata);
135360
-    return pDocView->m_pImpl->renderOverlayImpl(cr);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+    GdkRectangle aRectanglePixels;
135360
+    GdkPoint aStart, aEnd;
135360
+
135360
+    aRectanglePixels.x = twipToPixel(rRectangle.x, priv->m_fZoom);
135360
+    aRectanglePixels.y = twipToPixel(rRectangle.y, priv->m_fZoom);
135360
+    aRectanglePixels.width = twipToPixel(rRectangle.width, priv->m_fZoom);
135360
+    aRectanglePixels.height = twipToPixel(rRectangle.height, priv->m_fZoom);
135360
+
135360
+    aStart.x = aRectanglePixels.y / nTileSizePixels;
135360
+    aStart.y = aRectanglePixels.x / nTileSizePixels;
135360
+    aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
135360
+    aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
135360
+
135360
+    for (int i = aStart.x; i < aEnd.x; i++)
135360
+        for (int j = aStart.y; j < aEnd.y; j++)
135360
+            priv->m_aTileBuffer.setInvalid(i, j);
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::renderOverlayImpl(cairo_t *pCairo)
135360
+static gboolean
135360
+callback (gpointer pData)
135360
 {
135360
-    if (m_bEdit && m_bCursorVisible && m_bCursorOverlayVisible && !isEmptyRectangle(m_aVisibleCursor))
135360
-    {
135360
-        if (m_aVisibleCursor.width < 30)
135360
-            // Set a minimal width if it would be 0.
135360
-            m_aVisibleCursor.width = 30;
135360
+    CallbackData* pCallback = static_cast<CallbackData*>(pData);
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pCallback->m_pDocView);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
 
135360
-        cairo_set_source_rgb(pCairo, 0, 0, 0);
135360
-        cairo_rectangle(pCairo,
135360
-                        twipToPixel(m_aVisibleCursor.x, m_fZoom),
135360
-                        twipToPixel(m_aVisibleCursor.y, m_fZoom),
135360
-                        twipToPixel(m_aVisibleCursor.width, m_fZoom),
135360
-                        twipToPixel(m_aVisibleCursor.height, m_fZoom));
135360
-        cairo_fill(pCairo);
135360
-    }
135360
-
135360
-    if (m_bEdit && m_bCursorVisible && !isEmptyRectangle(m_aVisibleCursor) && m_aTextSelectionRectangles.empty())
135360
+    switch (pCallback->m_nType)
135360
     {
135360
-        // Have a cursor, but no selection: we need the middle handle.
135360
-        if (!m_pHandleMiddle)
135360
-            m_pHandleMiddle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_middle.png");
135360
-        renderHandle(pCairo, m_aVisibleCursor, m_pHandleMiddle, m_aHandleMiddleRect);
135360
-    }
135360
-
135360
-    if (!m_aTextSelectionRectangles.empty())
135360
+    case LOK_CALLBACK_INVALIDATE_TILES:
135360
     {
135360
-        for (GdkRectangle& rRectangle : m_aTextSelectionRectangles)
135360
+        if (pCallback->m_aPayload != "EMPTY")
135360
         {
135360
-            // Blue with 75% transparency.
135360
-            cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25);
135360
-            cairo_rectangle(pCairo,
135360
-                            twipToPixel(rRectangle.x, m_fZoom),
135360
-                            twipToPixel(rRectangle.y, m_fZoom),
135360
-                            twipToPixel(rRectangle.width, m_fZoom),
135360
-                            twipToPixel(rRectangle.height, m_fZoom));
135360
-            cairo_fill(pCairo);
135360
+            GdkRectangle aRectangle = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str());
135360
+            setTilesInvalid(pDocView, aRectangle);
135360
         }
135360
+        else
135360
+            priv->m_aTileBuffer.resetAllTiles();
135360
 
135360
-        // Handles
135360
-        if (!isEmptyRectangle(m_aTextSelectionStart))
135360
-        {
135360
-            // Have a start position: we need a start handle.
135360
-            if (!m_pHandleStart)
135360
-                m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
135360
-            renderHandle(pCairo, m_aTextSelectionStart, m_pHandleStart, m_aHandleStartRect);
135360
-        }
135360
-        if (!isEmptyRectangle(m_aTextSelectionEnd))
135360
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
135360
+    {
135360
+        priv->m_aVisibleCursor = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str());
135360
+        priv->m_bCursorOverlayVisible = true;
135360
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_TEXT_SELECTION:
135360
+    {
135360
+        priv->m_aTextSelectionRectangles = payloadToRectangles(pDocView, pCallback->m_aPayload.c_str());
135360
+        // In case the selection is empty, then we get no LOK_CALLBACK_TEXT_SELECTION_START/END events.
135360
+        if (priv->m_aTextSelectionRectangles.empty())
135360
         {
135360
-            // Have a start position: we need an end handle.
135360
-            if (!m_pHandleEnd)
135360
-                m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
135360
-            renderHandle(pCairo, m_aTextSelectionEnd, m_pHandleEnd, m_aHandleEndRect);
135360
+            memset(&priv->m_aTextSelectionStart, 0, sizeof(priv->m_aTextSelectionStart));
135360
+            memset(&priv->m_aHandleStartRect, 0, sizeof(priv->m_aHandleStartRect));
135360
+            memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd));
135360
+            memset(&priv->m_aHandleEndRect, 0, sizeof(priv->m_aHandleEndRect));
135360
         }
135360
+        else
135360
+            memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect));
135360
     }
135360
-
135360
-    if (!isEmptyRectangle(m_aGraphicSelection))
135360
+    break;
135360
+    case LOK_CALLBACK_TEXT_SELECTION_START:
135360
     {
135360
-        if (!m_pGraphicHandle)
135360
-            m_pGraphicHandle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_graphic.png");
135360
-        renderGraphicHandle(pCairo, m_aGraphicSelection, m_pGraphicHandle);
135360
+        priv->m_aTextSelectionStart = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str());
135360
     }
135360
+    break;
135360
+    case LOK_CALLBACK_TEXT_SELECTION_END:
135360
+    {
135360
+        priv->m_aTextSelectionEnd = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str());
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_CURSOR_VISIBLE:
135360
+    {
135360
+        priv->m_bCursorVisible = pCallback->m_aPayload == "true";
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_GRAPHIC_SELECTION:
135360
+    {
135360
+        if (pCallback->m_aPayload != "EMPTY")
135360
+            priv->m_aGraphicSelection = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str());
135360
+        else
135360
+            memset(&priv->m_aGraphicSelection, 0, sizeof(priv->m_aGraphicSelection));
135360
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_HYPERLINK_CLICKED:
135360
+    {
135360
+        GError* pError = NULL;
135360
+        gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError);
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_STATE_CHANGED:
135360
+    {
135360
+        commandChanged(pDocView, pCallback->m_aPayload);
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_SEARCH_NOT_FOUND:
135360
+    {
135360
+        searchNotFound(pDocView, pCallback->m_aPayload);
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
135360
+    {
135360
+        g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips);
135360
+        g_info ("startin");
135360
+        payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips);
135360
+        g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips);
135360
+        gtk_widget_set_size_request(GTK_WIDGET(pDocView),
135360
+                                    twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom),
135360
+                                    twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom));
135360
+    }
135360
+    break;
135360
+    case LOK_CALLBACK_SET_PART:
135360
+    {
135360
+        setPart(pDocView, pCallback->m_aPayload);
135360
+    }
135360
+    break;
135360
+    default:
135360
+        g_assert(false);
135360
+        break;
135360
+    }
135360
+    delete pCallback;
135360
 
135360
-    return FALSE;
135360
-}
135360
-
135360
-bool LOKDocView_Impl::isEmptyRectangle(const GdkRectangle& rRectangle)
135360
-{
135360
-    return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0;
135360
+    return G_SOURCE_REMOVE;
135360
 }
135360
 
135360
-void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle)
135360
+static void
135360
+callbackWorker (int nType, const char* pPayload, void* pData)
135360
 {
135360
-    GdkRectangle aRectanglePixels;
135360
-    GdkPoint aStart, aEnd;
135360
-
135360
-    aRectanglePixels.x = twipToPixel(rRectangle.x, m_fZoom);
135360
-    aRectanglePixels.y = twipToPixel(rRectangle.y, m_fZoom);
135360
-    aRectanglePixels.width = twipToPixel(rRectangle.width, m_fZoom);
135360
-    aRectanglePixels.height = twipToPixel(rRectangle.height, m_fZoom);
135360
-
135360
-    aStart.x = aRectanglePixels.y / nTileSizePixels;
135360
-    aStart.y = aRectanglePixels.x / nTileSizePixels;
135360
-    aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
135360
-    aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pData);
135360
 
135360
-    for (int i = aStart.x; i < aEnd.x; i++)
135360
-        for (int j = aStart.y; j < aEnd.y; j++)
135360
-            m_aTileBuffer.setInvalid(i, j);
135360
+    CallbackData* pCallback = new CallbackData(nType, pPayload ? pPayload : "(nil)", pDocView);
135360
+    g_info("lok_doc_view_callbackWorker: %s, '%s'", callbackTypeToString(nType), pPayload);
135360
+    gdk_threads_add_idle(callback, pCallback);
135360
 }
135360
 
135360
-void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle)
135360
+static void
135360
+renderHandle(LOKDocView* pDocView,
135360
+             cairo_t* pCairo,
135360
+             const GdkRectangle& rCursor,
135360
+             cairo_surface_t* pHandle,
135360
+             GdkRectangle& rRectangle)
135360
 {
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
     GdkPoint aCursorBottom;
135360
     int nHandleWidth, nHandleHeight;
135360
     double fHandleScale;
135360
@@ -749,16 +567,17 @@ void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor,
135360
     nHandleWidth = cairo_image_surface_get_width(pHandle);
135360
     nHandleHeight = cairo_image_surface_get_height(pHandle);
135360
     // We want to scale down the handle, so that its height is the same as the cursor caret.
135360
-    fHandleScale = twipToPixel(rCursor.height, m_fZoom) / nHandleHeight;
135360
+    fHandleScale = twipToPixel(rCursor.height, priv->m_fZoom) / nHandleHeight;
135360
     // We want the top center of the handle bitmap to be at the bottom center of the cursor rectangle.
135360
-    aCursorBottom.x = twipToPixel(rCursor.x, m_fZoom) + twipToPixel(rCursor.width, m_fZoom) / 2 - (nHandleWidth * fHandleScale) / 2;
135360
-    aCursorBottom.y = twipToPixel(rCursor.y, m_fZoom) + twipToPixel(rCursor.height, m_fZoom);
135360
-    cairo_save(pCairo);
135360
+    aCursorBottom.x = twipToPixel(rCursor.x, priv->m_fZoom) + twipToPixel(rCursor.width, priv->m_fZoom) / 2 - (nHandleWidth * fHandleScale) / 2;
135360
+    aCursorBottom.y = twipToPixel(rCursor.y, priv->m_fZoom) + twipToPixel(rCursor.height, priv->m_fZoom);
135360
+
135360
+    cairo_save (pCairo);
135360
     cairo_translate(pCairo, aCursorBottom.x, aCursorBottom.y);
135360
     cairo_scale(pCairo, fHandleScale, fHandleScale);
135360
     cairo_set_source_surface(pCairo, pHandle, 0, 0);
135360
     cairo_paint(pCairo);
135360
-    cairo_restore(pCairo);
135360
+    cairo_restore (pCairo);
135360
 
135360
     rRectangle.x = aCursorBottom.x;
135360
     rRectangle.y = aCursorBottom.y;
135360
@@ -767,23 +586,27 @@ void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor,
135360
 }
135360
 
135360
 /// Renders pHandle around an rSelection rectangle on pCairo.
135360
-void LOKDocView_Impl::renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& rSelection, cairo_surface_t* pHandle)
135360
+static void
135360
+renderGraphicHandle(LOKDocView* pDocView,
135360
+                    cairo_t* pCairo,
135360
+                    const GdkRectangle& rSelection,
135360
+                    cairo_surface_t* pHandle)
135360
 {
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
     int nHandleWidth, nHandleHeight;
135360
     GdkRectangle aSelection;
135360
 
135360
     nHandleWidth = cairo_image_surface_get_width(pHandle);
135360
     nHandleHeight = cairo_image_surface_get_height(pHandle);
135360
 
135360
-    aSelection.x = twipToPixel(rSelection.x, m_fZoom);
135360
-    aSelection.y = twipToPixel(rSelection.y, m_fZoom);
135360
-    aSelection.width = twipToPixel(rSelection.width, m_fZoom);
135360
-    aSelection.height = twipToPixel(rSelection.height, m_fZoom);
135360
+    aSelection.x = twipToPixel(rSelection.x, priv->m_fZoom);
135360
+    aSelection.y = twipToPixel(rSelection.y, priv->m_fZoom);
135360
+    aSelection.width = twipToPixel(rSelection.width, priv->m_fZoom);
135360
+    aSelection.height = twipToPixel(rSelection.height, priv->m_fZoom);
135360
 
135360
     for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
     {
135360
         int x = aSelection.x, y = aSelection.y;
135360
-        cairo_save(pCairo);
135360
 
135360
         switch (i)
135360
         {
135360
@@ -819,364 +642,722 @@ void LOKDocView_Impl::renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& r
135360
         x -= nHandleWidth / 2;
135360
         y -= nHandleHeight / 2;
135360
 
135360
-        m_aGraphicHandleRects[i].x = x;
135360
-        m_aGraphicHandleRects[i].y = y;
135360
-        m_aGraphicHandleRects[i].width = nHandleWidth;
135360
-        m_aGraphicHandleRects[i].height = nHandleHeight;
135360
+        priv->m_aGraphicHandleRects[i].x = x;
135360
+        priv->m_aGraphicHandleRects[i].y = y;
135360
+        priv->m_aGraphicHandleRects[i].width = nHandleWidth;
135360
+        priv->m_aGraphicHandleRects[i].height = nHandleHeight;
135360
 
135360
+        cairo_save (pCairo);
135360
         cairo_translate(pCairo, x, y);
135360
         cairo_set_source_surface(pCairo, pHandle, 0, 0);
135360
         cairo_paint(pCairo);
135360
-        cairo_restore(pCairo);
135360
+        cairo_restore (pCairo);
135360
     }
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::handleTimeout(gpointer pData)
135360
-{
135360
-    LOKDocView* pDocView = static_cast<LOKDocView*>(pData);
135360
-    return pDocView->m_pImpl->handleTimeoutImpl();
135360
-}
135360
 
135360
-gboolean LOKDocView_Impl::handleTimeoutImpl()
135360
+static gboolean
135360
+renderDocument(LOKDocView* pDocView, cairo_t* pCairo)
135360
 {
135360
-    if (m_bEdit)
135360
+    LOKDocViewPrivate *priv = pDocView->priv;
135360
+    GdkRectangle aVisibleArea;
135360
+    long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom);
135360
+    long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom);
135360
+    // Total number of rows / columns in this document.
135360
+    guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels);
135360
+    guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
135360
+
135360
+    gdk_cairo_get_clip_rectangle (pCairo, &aVisibleArea);
135360
+    aVisibleArea.x = pixelToTwip (aVisibleArea.x, priv->m_fZoom);
135360
+    aVisibleArea.y = pixelToTwip (aVisibleArea.y, priv->m_fZoom);
135360
+    aVisibleArea.width = pixelToTwip (aVisibleArea.width, priv->m_fZoom);
135360
+    aVisibleArea.height = pixelToTwip (aVisibleArea.height, priv->m_fZoom);
135360
+
135360
+    // Render the tiles.
135360
+    for (guint nRow = 0; nRow < nRows; ++nRow)
135360
     {
135360
-        if (m_bCursorOverlayVisible)
135360
-            m_bCursorOverlayVisible = false;
135360
-        else
135360
-            m_bCursorOverlayVisible = true;
135360
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDocView));
135360
-    }
135360
+        for (guint nColumn = 0; nColumn < nColumns; ++nColumn)
135360
+        {
135360
+            GdkRectangle aTileRectangleTwips, aTileRectanglePixels;
135360
+            bool bPaint = true;
135360
 
135360
-    return G_SOURCE_CONTINUE;
135360
-}
135360
+            // Determine size of the tile: the rightmost/bottommost tiles may
135360
+            // be smaller, and we need the size to decide if we need to repaint.
135360
+            if (nColumn == nColumns - 1)
135360
+                aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels;
135360
+            else
135360
+                aTileRectanglePixels.width = nTileSizePixels;
135360
+            if (nRow == nRows - 1)
135360
+                aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels;
135360
+            else
135360
+                aTileRectanglePixels.height = nTileSizePixels;
135360
 
135360
-GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload)
135360
-{
135360
-    GdkRectangle aRet;
135360
+            // Determine size and position of the tile in document coordinates,
135360
+            // so we can decide if we can skip painting for partial rendering.
135360
+            aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, priv->m_fZoom) * nColumn;
135360
+            aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, priv->m_fZoom) * nRow;
135360
+            aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, priv->m_fZoom);
135360
+            aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, priv->m_fZoom);
135360
 
135360
-    aRet.width = aRet.height = aRet.x = aRet.y = 0;
135360
-    gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4);
135360
-    gchar** ppCoordinate = ppCoordinates;
135360
-    if (!*ppCoordinate)
135360
-        return aRet;
135360
-    aRet.x = atoi(*ppCoordinate);
135360
-    if (aRet.x < 0)
135360
-        aRet.x = 0;
135360
-    ++ppCoordinate;
135360
-    if (!*ppCoordinate)
135360
-        return aRet;
135360
-    aRet.y = atoi(*ppCoordinate);
135360
-    if (aRet.y < 0)
135360
-        aRet.y = 0;
135360
-    ++ppCoordinate;
135360
-    if (!*ppCoordinate)
135360
-        return aRet;
135360
-    aRet.width = atoi(*ppCoordinate);
135360
-    if (aRet.x + aRet.width > m_nDocumentWidthTwips)
135360
-        aRet.width = m_nDocumentWidthTwips - aRet.x;
135360
-    ++ppCoordinate;
135360
-    if (!*ppCoordinate)
135360
-        return aRet;
135360
-    aRet.height = atoi(*ppCoordinate);
135360
-    if (aRet.y + aRet.height > m_nDocumentHeightTwips)
135360
-        aRet.height = m_nDocumentHeightTwips - aRet.y;
135360
-    g_strfreev(ppCoordinates);
135360
-    return aRet;
135360
+            if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0))
135360
+                bPaint = false;
135360
+
135360
+            if (bPaint)
135360
+            {
135360
+                Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom);
135360
+                GdkPixbuf* pPixBuf = currentTile.getBuffer();
135360
+                gdk_cairo_set_source_pixbuf (pCairo, pPixBuf,
135360
+                                             twipToPixel(aTileRectangleTwips.x, priv->m_fZoom),
135360
+                                             twipToPixel(aTileRectangleTwips.y, priv->m_fZoom));
135360
+                cairo_paint(pCairo);
135360
+            }
135360
+        }
135360
+    }
135360
+
135360
+    return FALSE;
135360
 }
135360
 
135360
-std::vector<GdkRectangle> LOKDocView_Impl::payloadToRectangles(const char* pPayload)
135360
+static gboolean
135360
+renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
135360
 {
135360
-    std::vector<GdkRectangle> aRet;
135360
+    LOKDocViewPrivate *priv = pDocView->priv;
135360
 
135360
-    gchar** ppRectangles = g_strsplit(pPayload, "; ", 0);
135360
-    for (gchar** ppRectangle = ppRectangles; *ppRectangle; ++ppRectangle)
135360
-        aRet.push_back(payloadToRectangle(*ppRectangle));
135360
-    g_strfreev(ppRectangles);
135360
+    if (priv->m_bEdit && priv->m_bCursorVisible && priv->m_bCursorOverlayVisible && !isEmptyRectangle(priv->m_aVisibleCursor))
135360
+    {
135360
+        if (priv->m_aVisibleCursor.width < 30)
135360
+            // Set a minimal width if it would be 0.
135360
+            priv->m_aVisibleCursor.width = 30;
135360
 
135360
-    return aRet;
135360
-}
135360
+        cairo_set_source_rgb(pCairo, 0, 0, 0);
135360
+        cairo_rectangle(pCairo,
135360
+                        twipToPixel(priv->m_aVisibleCursor.x, priv->m_fZoom),
135360
+                        twipToPixel(priv->m_aVisibleCursor.y, priv->m_fZoom),
135360
+                        twipToPixel(priv->m_aVisibleCursor.width, priv->m_fZoom),
135360
+                        twipToPixel(priv->m_aVisibleCursor.height, priv->m_fZoom));
135360
+        cairo_fill(pCairo);
135360
+    }
135360
 
135360
-/// Returns the string representation of a LibreOfficeKitCallbackType enumeration element.
135360
-const char* LOKDocView_Impl::callbackTypeToString(int nType)
135360
-{
135360
-    switch (nType)
135360
+    if (priv->m_bEdit && priv->m_bCursorVisible && !isEmptyRectangle(priv->m_aVisibleCursor) && priv->m_aTextSelectionRectangles.empty())
135360
     {
135360
-    case LOK_CALLBACK_INVALIDATE_TILES:
135360
-        return "LOK_CALLBACK_INVALIDATE_TILES";
135360
-    case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
135360
-        return "LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR";
135360
-    case LOK_CALLBACK_TEXT_SELECTION:
135360
-        return "LOK_CALLBACK_TEXT_SELECTION";
135360
-    case LOK_CALLBACK_TEXT_SELECTION_START:
135360
-        return "LOK_CALLBACK_TEXT_SELECTION_START";
135360
-    case LOK_CALLBACK_TEXT_SELECTION_END:
135360
-        return "LOK_CALLBACK_TEXT_SELECTION_END";
135360
-    case LOK_CALLBACK_CURSOR_VISIBLE:
135360
-        return "LOK_CALLBACK_CURSOR_VISIBLE";
135360
-    case LOK_CALLBACK_GRAPHIC_SELECTION:
135360
-        return "LOK_CALLBACK_GRAPHIC_SELECTION";
135360
-    case LOK_CALLBACK_HYPERLINK_CLICKED:
135360
-        return "LOK_CALLBACK_HYPERLINK_CLICKED";
135360
-    case LOK_CALLBACK_STATE_CHANGED:
135360
-        return "LOK_CALLBACK_STATE_CHANGED";
135360
-    case LOK_CALLBACK_STATUS_INDICATOR_START:
135360
-        return "LOK_CALLBACK_STATUS_INDICATOR_START";
135360
-    case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
135360
-        return "LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE";
135360
-    case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
135360
-        return "LOK_CALLBACK_STATUS_INDICATOR_FINISH";
135360
-    case LOK_CALLBACK_SEARCH_NOT_FOUND:
135360
-        return "LOK_CALLBACK_SEARCH_NOT_FOUND";
135360
-    case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
135360
-        return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED";
135360
-    case LOK_CALLBACK_SET_PART:
135360
-        return "LOK_CALLBACK_SET_PART";
135360
+        // Have a cursor, but no selection: we need the middle handle.
135360
+        gchar* handleMiddlePath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_middle.png", NULL);
135360
+        if (!priv->m_pHandleMiddle)
135360
+            priv->m_pHandleMiddle = cairo_image_surface_create_from_png(handleMiddlePath);
135360
+        g_free (handleMiddlePath);
135360
+        renderHandle(pDocView, pCairo, priv->m_aVisibleCursor, priv->m_pHandleMiddle, priv->m_aHandleMiddleRect);
135360
+    }
135360
+
135360
+    if (!priv->m_aTextSelectionRectangles.empty())
135360
+    {
135360
+        for (GdkRectangle& rRectangle : priv->m_aTextSelectionRectangles)
135360
+        {
135360
+            // Blue with 75% transparency.
135360
+            cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25);
135360
+            cairo_rectangle(pCairo,
135360
+                            twipToPixel(rRectangle.x, priv->m_fZoom),
135360
+                            twipToPixel(rRectangle.y, priv->m_fZoom),
135360
+                            twipToPixel(rRectangle.width, priv->m_fZoom),
135360
+                            twipToPixel(rRectangle.height, priv->m_fZoom));
135360
+            cairo_fill(pCairo);
135360
+        }
135360
+
135360
+        // Handles
135360
+        if (!isEmptyRectangle(priv->m_aTextSelectionStart))
135360
+        {
135360
+            // Have a start position: we need a start handle.
135360
+            gchar* handleStartPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_start.png", NULL);
135360
+            if (!priv->m_pHandleStart)
135360
+                priv->m_pHandleStart = cairo_image_surface_create_from_png(handleStartPath);
135360
+            renderHandle(pDocView, pCairo, priv->m_aTextSelectionStart, priv->m_pHandleStart, priv->m_aHandleStartRect);
135360
+            g_free (handleStartPath);
135360
+        }
135360
+        if (!isEmptyRectangle(priv->m_aTextSelectionEnd))
135360
+        {
135360
+            // Have a start position: we need an end handle.
135360
+            gchar* handleEndPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_end.png", NULL);
135360
+            if (!priv->m_pHandleEnd)
135360
+                priv->m_pHandleEnd = cairo_image_surface_create_from_png(handleEndPath);
135360
+            renderHandle(pDocView, pCairo, priv->m_aTextSelectionEnd, priv->m_pHandleEnd, priv->m_aHandleEndRect);
135360
+            g_free (handleEndPath);
135360
+        }
135360
     }
135360
-    return 0;
135360
-}
135360
 
135360
-gboolean LOKDocView_Impl::callback(gpointer pData)
135360
-{
135360
-    LOKDocView_Impl::CallbackData* pCallback = static_cast<LOKDocView_Impl::CallbackData*>(pData);
135360
-    return pCallback->m_pDocView->m_pImpl->callbackImpl(pCallback);
135360
-}
135360
+    if (!isEmptyRectangle(priv->m_aGraphicSelection))
135360
+    {
135360
+        gchar* handleGraphicPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_graphic.png", NULL);
135360
+        if (!priv->m_pGraphicHandle)
135360
+            priv->m_pGraphicHandle = cairo_image_surface_create_from_png(handleGraphicPath);
135360
+        renderGraphicHandle(pDocView, pCairo, priv->m_aGraphicSelection, priv->m_pGraphicHandle);
135360
+        g_free (handleGraphicPath);
135360
+    }
135360
 
135360
-gboolean LOKDocView_Impl::globalCallback(gpointer pData)
135360
-{
135360
-    LOKDocView_Impl::CallbackData* pCallback = static_cast<LOKDocView_Impl::CallbackData*>(pData);
135360
-    return globalCallbackImpl(pCallback);
135360
+    return FALSE;
135360
 }
135360
 
135360
-gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback)
135360
+static gboolean
135360
+lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent)
135360
 {
135360
-    switch (pCallback->m_nType)
135360
-    {
135360
-    case LOK_CALLBACK_INVALIDATE_TILES:
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pWidget);
135360
+    LOKDocViewPrivate *priv = pDocView->priv;
135360
+
135360
+    g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)",
135360
+           (int)pEvent->x, (int)pEvent->y,
135360
+           (int)pixelToTwip(pEvent->x, priv->m_fZoom),
135360
+           (int)pixelToTwip(pEvent->y, priv->m_fZoom));
135360
+
135360
+    if (pEvent->type == GDK_BUTTON_RELEASE)
135360
     {
135360
-        if (pCallback->m_aPayload != "EMPTY")
135360
+        if (priv->m_bInDragStartHandle)
135360
         {
135360
-            GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
135360
-            setTilesInvalid(aRectangle);
135360
+            g_info("LOKDocView_Impl::signalButton: end of drag start handle");
135360
+            priv->m_bInDragStartHandle = false;
135360
+            return FALSE;
135360
+        }
135360
+        else if (priv->m_bInDragMiddleHandle)
135360
+        {
135360
+            g_info("LOKDocView_Impl::signalButton: end of drag middle handle");
135360
+            priv->m_bInDragMiddleHandle = false;
135360
+            return FALSE;
135360
+        }
135360
+        else if (priv->m_bInDragEndHandle)
135360
+        {
135360
+            g_info("LOKDocView_Impl::signalButton: end of drag end handle");
135360
+            priv->m_bInDragEndHandle = false;
135360
+            return FALSE;
135360
         }
135360
-        else
135360
-            m_aTileBuffer.resetAllTiles();
135360
 
135360
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDocView));
135360
-    }
135360
-    break;
135360
-    case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
135360
-    {
135360
-        m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
135360
-        m_bCursorOverlayVisible = true;
135360
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDocView));
135360
-    }
135360
-    break;
135360
-    case LOK_CALLBACK_TEXT_SELECTION:
135360
-    {
135360
-        m_aTextSelectionRectangles = LOKDocView_Impl::payloadToRectangles(pCallback->m_aPayload.c_str());
135360
+        for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
+        {
135360
+            if (priv->m_bInDragGraphicHandles[i])
135360
+            {
135360
+                g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i);
135360
+                priv->m_bInDragGraphicHandles[i] = false;
135360
+                priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
135360
+                return FALSE;
135360
+            }
135360
+        }
135360
 
135360
-        // In case the selection is empty, then we get no LOK_CALLBACK_TEXT_SELECTION_START/END events.
135360
-        if (m_aTextSelectionRectangles.empty())
135360
+        if (priv->m_bInDragGraphicSelection)
135360
         {
135360
-            memset(&m_aTextSelectionStart, 0, sizeof(m_aTextSelectionStart));
135360
-            memset(&m_aHandleStartRect, 0, sizeof(m_aHandleStartRect));
135360
-            memset(&m_aTextSelectionEnd, 0, sizeof(m_aTextSelectionEnd));
135360
-            memset(&m_aHandleEndRect, 0, sizeof(m_aHandleEndRect));
135360
+            g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
135360
+            priv->m_bInDragGraphicSelection = false;
135360
+            priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
135360
+            return FALSE;
135360
         }
135360
-        else
135360
-            memset(&m_aHandleMiddleRect, 0, sizeof(m_aHandleMiddleRect));
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_TEXT_SELECTION_START:
135360
+
135360
+    if (priv->m_bEdit)
135360
     {
135360
-        m_aTextSelectionStart = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
135360
+        GdkRectangle aClick;
135360
+        aClick.x = pEvent->x;
135360
+        aClick.y = pEvent->y;
135360
+        aClick.width = 1;
135360
+        aClick.height = 1;
135360
+        if (pEvent->type == GDK_BUTTON_PRESS)
135360
+        {
135360
+            if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, NULL))
135360
+            {
135360
+                g_info("LOKDocView_Impl::signalButton: start of drag start handle");
135360
+                priv->m_bInDragStartHandle = true;
135360
+                return FALSE;
135360
+            }
135360
+            else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, NULL))
135360
+            {
135360
+                g_info("LOKDocView_Impl::signalButton: start of drag middle handle");
135360
+                priv->m_bInDragMiddleHandle = true;
135360
+                return FALSE;
135360
+            }
135360
+            else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, NULL))
135360
+            {
135360
+                g_info("LOKDocView_Impl::signalButton: start of drag end handle");
135360
+                priv->m_bInDragEndHandle = true;
135360
+                return FALSE;
135360
+            }
135360
+
135360
+            for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
+            {
135360
+                if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], NULL))
135360
+                {
135360
+                    g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i);
135360
+                    priv->m_bInDragGraphicHandles[i] = true;
135360
+                    priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument,
135360
+                                                             LOK_SETGRAPHICSELECTION_START,
135360
+                                                             pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom),
135360
+                                                             pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom));
135360
+                    return FALSE;
135360
+                }
135360
+            }
135360
+        }
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_TEXT_SELECTION_END:
135360
+
135360
+    if (!priv->m_bEdit)
135360
+        lok_doc_view_set_edit(pDocView, TRUE);
135360
+
135360
+    switch (pEvent->type)
135360
     {
135360
-        m_aTextSelectionEnd = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
135360
-    }
135360
-    break;
135360
-    case LOK_CALLBACK_CURSOR_VISIBLE:
135360
+    case GDK_BUTTON_PRESS:
135360
     {
135360
-        m_bCursorVisible = pCallback->m_aPayload == "true";
135360
+        int nCount = 1;
135360
+        if ((pEvent->time - priv->m_nLastButtonPressTime) < 250)
135360
+            nCount++;
135360
+        priv->m_nLastButtonPressTime = pEvent->time;
135360
+        priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount);
135360
+        break;
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_GRAPHIC_SELECTION:
135360
+    case GDK_BUTTON_RELEASE:
135360
     {
135360
-        if (pCallback->m_aPayload != "EMPTY")
135360
-            m_aGraphicSelection = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
135360
-        else
135360
-            memset(&m_aGraphicSelection, 0, sizeof(m_aGraphicSelection));
135360
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDocView));
135360
+        int nCount = 1;
135360
+        if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250)
135360
+            nCount++;
135360
+        priv->m_nLastButtonReleaseTime = pEvent->time;
135360
+        priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount);
135360
+        break;
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_HYPERLINK_CLICKED:
135360
+    default:
135360
+        break;
135360
+    }
135360
+    return FALSE;
135360
+}
135360
+
135360
+static void
135360
+getDragPoint(GdkRectangle* pHandle,
135360
+             GdkEventMotion* pEvent,
135360
+             GdkPoint* pPoint)
135360
+{
135360
+    GdkPoint aCursor, aHandle;
135360
+
135360
+    // Center of the cursor rectangle: we know that it's above the handle.
135360
+    aCursor.x = pHandle->x + pHandle->width / 2;
135360
+    aCursor.y = pHandle->y - pHandle->height / 2;
135360
+    // Center of the handle rectangle.
135360
+    aHandle.x = pHandle->x + pHandle->width / 2;
135360
+    aHandle.y = pHandle->y + pHandle->height / 2;
135360
+    // Our target is the original cursor position + the dragged offset.
135360
+    pPoint->x = aCursor.x + (pEvent->x - aHandle.x);
135360
+    pPoint->y = aCursor.y + (pEvent->y - aHandle.y);
135360
+}
135360
+
135360
+static gboolean
135360
+lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
135360
+{
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (pWidget);
135360
+    LOKDocViewPrivate *priv = pDocView->priv;
135360
+    GdkPoint aPoint;
135360
+
135360
+    if (priv->m_bInDragMiddleHandle)
135360
     {
135360
-        GError* pError = NULL;
135360
-        gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError);
135360
+        g_info("lcl_signalMotion: dragging the middle handle");
135360
+        getDragPoint(&priv->m_aHandleMiddleRect, pEvent, &aPoint);
135360
+        priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom));
135360
+        return FALSE;
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_STATE_CHANGED:
135360
+    if (priv->m_bInDragStartHandle)
135360
     {
135360
-        commandChanged(pCallback->m_aPayload);
135360
+        g_info("lcl_signalMotion: dragging the start handle");
135360
+        getDragPoint(&priv->m_aHandleStartRect, pEvent, &aPoint);
135360
+        priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom));
135360
+        return FALSE;
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_SEARCH_NOT_FOUND:
135360
+    if (priv->m_bInDragEndHandle)
135360
     {
135360
-        searchNotFound(pCallback->m_aPayload);
135360
+        g_info("lcl_signalMotion: dragging the end handle");
135360
+        getDragPoint(&priv->m_aHandleEndRect, pEvent, &aPoint);
135360
+        priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom));
135360
+        return FALSE;
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
135360
+    for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i)
135360
     {
135360
-        payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips);
135360
-        gtk_widget_set_size_request(GTK_WIDGET(m_pDocView),
135360
-                                    twipToPixel(m_nDocumentWidthTwips, m_fZoom),
135360
-                                    twipToPixel(m_nDocumentHeightTwips, m_fZoom));
135360
+        if (priv->m_bInDragGraphicHandles[i])
135360
+        {
135360
+            g_info("lcl_signalMotion: dragging the graphic handle #%d", i);
135360
+            return FALSE;
135360
+        }
135360
     }
135360
-    break;
135360
-    case LOK_CALLBACK_SET_PART:
135360
+    if (priv->m_bInDragGraphicSelection)
135360
     {
135360
-        setPart(pCallback->m_aPayload);
135360
+        g_info("lcl_signalMotion: dragging the graphic selection");
135360
+        return FALSE;
135360
     }
135360
-    break;
135360
-    default:
135360
-        g_assert(false);
135360
-        break;
135360
+
135360
+    GdkRectangle aMotionInTwipsInTwips;
135360
+    aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x, priv->m_fZoom);
135360
+    aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, priv->m_fZoom);
135360
+    aMotionInTwipsInTwips.width = 1;
135360
+    aMotionInTwipsInTwips.height = 1;
135360
+    if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &priv->m_aGraphicSelection, 0))
135360
+    {
135360
+        g_info("lcl_signalMotion: start of drag graphic selection");
135360
+        priv->m_bInDragGraphicSelection = true;
135360
+        priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom));
135360
+        return FALSE;
135360
     }
135360
-    delete pCallback;
135360
 
135360
-    return G_SOURCE_REMOVE;
135360
-}
135360
+    // Otherwise a mouse move, as on the desktop.
135360
+    priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), 1);
135360
 
135360
-void LOKDocView_Impl::callbackWorker(int nType, const char* pPayload, void* pData)
135360
-{
135360
-    LOKDocView* pDocView = static_cast<LOKDocView*>(pData);
135360
-    pDocView->m_pImpl->callbackWorkerImpl(nType, pPayload);
135360
+    return FALSE;
135360
 }
135360
 
135360
-void LOKDocView_Impl::globalCallbackWorker(int nType, const char* pPayload, void* pData)
135360
+static void lok_doc_view_init (LOKDocView* pDocView)
135360
 {
135360
-    LOKDocView* pDocView = static_cast<LOKDocView*>(pData);
135360
-    pDocView->m_pImpl->globalCallbackWorkerImpl(nType, pPayload);
135360
+    pDocView->priv = static_cast<LOKDocViewPrivate*>(lok_doc_view_get_instance_private (pDocView));
135360
+    pDocView->priv->m_bCursorVisible = true;
135360
+
135360
+    gtk_widget_add_events(GTK_WIDGET(pDocView),
135360
+                          GDK_BUTTON_PRESS_MASK
135360
+                          |GDK_BUTTON_RELEASE_MASK
135360
+                          |GDK_BUTTON_MOTION_MASK
135360
+                          |GDK_KEY_PRESS_MASK
135360
+                          |GDK_KEY_RELEASE_MASK);
135360
 }
135360
 
135360
-void LOKDocView_Impl::callbackWorkerImpl(int nType, const char* pPayload)
135360
+static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec)
135360
 {
135360
-    LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView);
135360
-    g_info("lok_doc_view_callback_worker: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload);
135360
-    gdk_threads_add_idle(LOKDocView_Impl::callback, pCallback);
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (object);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+
135360
+    switch (propId)
135360
+    {
135360
+    case PROP_LO_PATH:
135360
+        priv->m_aLOPath = g_value_dup_string (value);
135360
+        break;
135360
+    case PROP_DOC_PATH:
135360
+        priv->m_aDocPath = g_value_dup_string (value);
135360
+        break;
135360
+    case PROP_EDITABLE:
135360
+        lok_doc_view_set_edit (pDocView, g_value_get_boolean (value));
135360
+        break;
135360
+    case PROP_ZOOM:
135360
+        lok_doc_view_set_zoom (pDocView, g_value_get_float (value));
135360
+        break;
135360
+    case PROP_DOC_WIDTH:
135360
+        priv->m_nDocumentWidthTwips = g_value_get_long (value);
135360
+        break;
135360
+    case PROP_DOC_HEIGHT:
135360
+        priv->m_nDocumentHeightTwips = g_value_get_long (value);
135360
+        break;
135360
+    default:
135360
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec);
135360
+    }
135360
 }
135360
 
135360
-void LOKDocView_Impl::globalCallbackWorkerImpl(int nType, const char* pPayload)
135360
+static void lok_doc_view_get_property (GObject* object, guint propId, GValue *value, GParamSpec *pspec)
135360
 {
135360
-    LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView);
135360
-    g_info("LOKDocView_Impl::globalCallbackWorkerImpl: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload);
135360
-    gdk_threads_add_idle(LOKDocView_Impl::globalCallback, pCallback);
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (object);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+
135360
+    switch (propId)
135360
+    {
135360
+    case PROP_LO_PATH:
135360
+        g_value_set_string (value, priv->m_aLOPath);
135360
+        break;
135360
+    case PROP_DOC_PATH:
135360
+        g_value_set_string (value, priv->m_aDocPath);
135360
+        break;
135360
+    case PROP_EDITABLE:
135360
+        g_value_set_boolean (value, priv->m_bEdit);
135360
+        break;
135360
+    case PROP_LOAD_PROGRESS:
135360
+        g_value_set_uint (value, priv->m_nLoadProgress);
135360
+        break;
135360
+    case PROP_ZOOM:
135360
+        g_value_set_float (value, priv->m_fZoom);
135360
+        break;
135360
+    case PROP_IS_LOADING:
135360
+        g_value_set_boolean (value, priv->m_bIsLoading);
135360
+        break;
135360
+    case PROP_DOC_WIDTH:
135360
+        g_value_set_long (value, priv->m_nDocumentWidthTwips);
135360
+        break;
135360
+    case PROP_DOC_HEIGHT:
135360
+        g_value_set_long (value, priv->m_nDocumentHeightTwips);
135360
+        break;
135360
+    case PROP_CAN_ZOOM_IN:
135360
+        g_value_set_boolean (value, priv->m_bCanZoomIn);
135360
+        break;
135360
+    case PROP_CAN_ZOOM_OUT:
135360
+        g_value_set_boolean (value, priv->m_bCanZoomOut);
135360
+        break;
135360
+    default:
135360
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec);
135360
+    }
135360
 }
135360
 
135360
-void LOKDocView_Impl::commandChanged(const std::string& rString)
135360
+static gboolean lok_doc_view_draw (GtkWidget* pWidget, cairo_t* pCairo)
135360
 {
135360
-    g_signal_emit(m_pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str());
135360
+    LOKDocView *pDocView = LOK_DOC_VIEW (pWidget);
135360
+
135360
+    renderDocument (pDocView, pCairo);
135360
+    renderOverlay (pDocView, pCairo);
135360
+
135360
+    return FALSE;
135360
 }
135360
 
135360
-void LOKDocView_Impl::searchNotFound(const std::string& rString)
135360
+static void lok_doc_view_finalize (GObject* object)
135360
 {
135360
-    g_signal_emit(m_pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str());
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (object);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+
135360
+    if (priv->m_pDocument)
135360
+        priv->m_pDocument->pClass->destroy (priv->m_pDocument);
135360
+    if (priv->m_pOffice)
135360
+        priv->m_pOffice->pClass->destroy (priv->m_pOffice);
135360
+
135360
+    G_OBJECT_CLASS (lok_doc_view_parent_class)->finalize (object);
135360
 }
135360
 
135360
-void LOKDocView_Impl::setPart(const std::string& rString)
135360
+static void lok_doc_view_constructed (GObject* object)
135360
 {
135360
-    g_signal_emit(m_pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString));
135360
+    LOKDocView* pDocView = LOK_DOC_VIEW (object);
135360
+    LOKDocViewPrivate* priv = pDocView->priv;
135360
+
135360
+    G_OBJECT_CLASS (lok_doc_view_parent_class)->constructed (object);
135360
+
135360
+    pDocView->priv->m_pOffice = lok_init (priv->m_aLOPath);
135360
 }
135360
 
135360
 static void lok_doc_view_class_init (LOKDocViewClass* pClass)
135360
 {
135360
-    GObjectClass *gobject_class = G_OBJECT_CLASS(pClass);
135360
-    pClass->edit_changed = NULL;
135360
+    GObjectClass *pGObjectClass = G_OBJECT_CLASS(pClass);
135360
+    GtkWidgetClass *pWidgetClass = GTK_WIDGET_CLASS(pClass);
135360
+
135360
+    pGObjectClass->get_property = lok_doc_view_get_property;
135360
+    pGObjectClass->set_property = lok_doc_view_set_property;
135360
+    pGObjectClass->finalize = lok_doc_view_finalize;
135360
+    pGObjectClass->constructed = lok_doc_view_constructed;
135360
+
135360
+    pWidgetClass->draw = lok_doc_view_draw;
135360
+    pWidgetClass->button_press_event = lok_doc_view_signal_button;
135360
+    pWidgetClass->button_release_event = lok_doc_view_signal_button;
135360
+    pWidgetClass->motion_notify_event = lok_doc_view_signal_motion;
135360
+
135360
+    /**
135360
+     * LOKDocView:lopath:
135360
+     *
135360
+     * The absolute path of the LibreOffice install.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_LO_PATH,
135360
+          g_param_spec_string("lopath",
135360
+                              "LO Path",
135360
+                              "LibreOffice Install Path",
135360
+                              0,
135360
+                              static_cast<GParamFlags>(G_PARAM_READWRITE
135360
+                                                       | G_PARAM_CONSTRUCT_ONLY)));
135360
+
135360
+    /**
135360
+     * LOKDocView:docpath:
135360
+     *
135360
+     * The path of the document that is currently being viewed.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_DOC_PATH,
135360
+          g_param_spec_string("docpath",
135360
+                              "Document Path",
135360
+                              "The URI of the document to open",
135360
+                              0,
135360
+                              G_PARAM_READWRITE));
135360
+
135360
+    /**
135360
+     * LOKDocView:editable:
135360
+     *
135360
+     * Whether the document loaded inside of #LOKDocView is editable or not.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_EDITABLE,
135360
+          g_param_spec_boolean("editable",
135360
+                               "Editable",
135360
+                               "Whether the content is in edit mode or not",
135360
+                               FALSE,
135360
+                               G_PARAM_READWRITE));
135360
+
135360
+    /**
135360
+     * LOKDocView:load-progress:
135360
+     *
135360
+     * The percent completion of the current loading operation of the
135360
+     * document. This can be used for progress bars. Note that this is not a
135360
+     * very accurate progress indicator, and its value might reset it couple of
135360
+     * times to 0 and start again. You should not rely on its numbers.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_LOAD_PROGRESS,
135360
+          g_param_spec_int("load-progress",
135360
+                           "Estimated Load Progress",
135360
+                           "Whether the content is in edit mode or not",
135360
+                           0, 100, 0,
135360
+                           G_PARAM_READABLE));
135360
+
135360
+    /**
135360
+     * LOKDocView:zoom-level:
135360
+     *
135360
+     * The current zoom level of the document loaded inside #LOKDocView. The
135360
+     * default value is 1.0.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_ZOOM,
135360
+          g_param_spec_float("zoom-level",
135360
+                             "Zoom Level",
135360
+                             "The current zoom level of the content",
135360
+                             0, 5.0, 1.0,
135360
+                             static_cast<GParamFlags>(G_PARAM_READWRITE |
135360
+                                                      G_PARAM_CONSTRUCT)));
135360
+
135360
+    /**
135360
+     * LOKDocView:is-loading:
135360
+     *
135360
+     * Whether the requested document is being loaded or not. %TRUE if it is
135360
+     * being loaded, otherwise %FALSE.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_IS_LOADING,
135360
+          g_param_spec_boolean("is-loading",
135360
+                               "Is Loading",
135360
+                               "Whether the view is loading a document",
135360
+                               FALSE,
135360
+                               G_PARAM_READABLE));
135360
+
135360
+    /**
135360
+     * LOKDocView:doc-width:
135360
+     *
135360
+     * The width of the currently loaded document in #LOKDocView in twips.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_DOC_WIDTH,
135360
+          g_param_spec_long("doc-width",
135360
+                            "Document Width",
135360
+                            "Width of the document in twips",
135360
+                            0, G_MAXLONG, 0,
135360
+                            G_PARAM_READWRITE));
135360
+
135360
+    /**
135360
+     * LOKDocView:doc-height:
135360
+     *
135360
+     * The height of the currently loaded document in #LOKDocView in twips.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_DOC_HEIGHT,
135360
+          g_param_spec_long("doc-height",
135360
+                            "Document Height",
135360
+                            "Height of the document in twips",
135360
+                            0, G_MAXLONG, 0,
135360
+                            G_PARAM_READWRITE));
135360
+
135360
+    /**
135360
+     * LOKDocView:can-zoom-in:
135360
+     *
135360
+     * It tells whether the view can further be zoomed in or not.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_CAN_ZOOM_IN,
135360
+          g_param_spec_boolean("can-zoom-in",
135360
+                               "Can Zoom In",
135360
+                               "Whether the view can be zoomed in further",
135360
+                               TRUE,
135360
+                               static_cast<GParamFlags>(G_PARAM_READABLE
135360
+                                                       | G_PARAM_STATIC_STRINGS)));
135360
+
135360
+    /**
135360
+     * LOKDocView:can-zoom-out:
135360
+     *
135360
+     * It tells whether the view can further be zoomed out or not.
135360
+     */
135360
+    g_object_class_install_property (pGObjectClass,
135360
+          PROP_CAN_ZOOM_OUT,
135360
+          g_param_spec_boolean("can-zoom-out",
135360
+                               "Can Zoom Out",
135360
+                               "Whether the view can be zoomed out further",
135360
+                               TRUE,
135360
+                               static_cast<GParamFlags>(G_PARAM_READABLE
135360
+                                                       | G_PARAM_STATIC_STRINGS)));
135360
+
135360
+    /**
135360
+     * LOKDocView::edit-changed:
135360
+     * @pDocView: the #LOKDocView on which the signal is emitted
135360
+     * @bEdit: the new edit value of the view
135360
+     */
135360
     doc_view_signals[EDIT_CHANGED] =
135360
         g_signal_new("edit-changed",
135360
-                     G_TYPE_FROM_CLASS (gobject_class),
135360
+                     G_TYPE_FROM_CLASS (pGObjectClass),
135360
                      G_SIGNAL_RUN_FIRST,
135360
-                     G_STRUCT_OFFSET (LOKDocViewClass, edit_changed),
135360
+                     0,
135360
                      NULL, NULL,
135360
                      g_cclosure_marshal_VOID__BOOLEAN,
135360
                      G_TYPE_NONE, 1,
135360
                      G_TYPE_BOOLEAN);
135360
-    pClass->command_changed = NULL;
135360
+
135360
+    /**
135360
+     * LOKDocView::command-changed:
135360
+     * @pDocView: the #LOKDocView on which the signal is emitted
135360
+     * @aCommand: the command that was changed
135360
+     */
135360
     doc_view_signals[COMMAND_CHANGED] =
135360
         g_signal_new("command-changed",
135360
-                     G_TYPE_FROM_CLASS(gobject_class),
135360
+                     G_TYPE_FROM_CLASS(pGObjectClass),
135360
                      G_SIGNAL_RUN_FIRST,
135360
-                     G_STRUCT_OFFSET(LOKDocViewClass, command_changed),
135360
+                     0,
135360
                      NULL, NULL,
135360
                      g_cclosure_marshal_VOID__STRING,
135360
                      G_TYPE_NONE, 1,
135360
                      G_TYPE_STRING);
135360
-    pClass->search_not_found = 0;
135360
+
135360
+    /**
135360
+     * LOKDocView::search-not-found:
135360
+     * @pDocView: the #LOKDocView on which the signal is emitted
135360
+     * @aCommand: the string for which the search was not found.
135360
+     */
135360
     doc_view_signals[SEARCH_NOT_FOUND] =
135360
         g_signal_new("search-not-found",
135360
-                     G_TYPE_FROM_CLASS(gobject_class),
135360
+                     G_TYPE_FROM_CLASS(pGObjectClass),
135360
                      G_SIGNAL_RUN_FIRST,
135360
-                     G_STRUCT_OFFSET(LOKDocViewClass, search_not_found),
135360
+                     0,
135360
                      NULL, NULL,
135360
                      g_cclosure_marshal_VOID__STRING,
135360
                      G_TYPE_NONE, 1,
135360
                      G_TYPE_STRING);
135360
-    pClass->part_changed = 0;
135360
+
135360
+    /**
135360
+     * LOKDocView::part-changed:
135360
+     * @pDocView: the #LOKDocView on which the signal is emitted
135360
+     * @aCommand: the part number which the view changed to
135360
+     */
135360
     doc_view_signals[PART_CHANGED] =
135360
         g_signal_new("part-changed",
135360
-                     G_TYPE_FROM_CLASS(gobject_class),
135360
+                     G_TYPE_FROM_CLASS(pGObjectClass),
135360
                      G_SIGNAL_RUN_FIRST,
135360
-                     G_STRUCT_OFFSET(LOKDocViewClass, part_changed),
135360
+                     0,
135360
                      NULL, NULL,
135360
                      g_cclosure_marshal_VOID__INT,
135360
                      G_TYPE_NONE, 1,
135360
                      G_TYPE_INT);
135360
-}
135360
 
135360
-static void lok_doc_view_init (LOKDocView* pDocView)
135360
-{
135360
-    pDocView->m_pImpl = new LOKDocView_Impl(pDocView);
135360
-
135360
-    g_signal_connect(G_OBJECT(pDocView),
135360
-                     "draw",
135360
-                     G_CALLBACK(LOKDocView_Impl::renderDocument), pDocView);
135360
-    g_signal_connect(G_OBJECT(pDocView),
135360
-                     "draw",
135360
-                     G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView);
135360
-    gtk_widget_add_events(GTK_WIDGET(pDocView),
135360
-                           GDK_BUTTON_PRESS_MASK
135360
-                          |GDK_BUTTON_RELEASE_MASK
135360
-                          |GDK_BUTTON_MOTION_MASK);
135360
-
135360
-    g_signal_connect(G_OBJECT(pDocView),
135360
-                     "button-press-event",
135360
-                     G_CALLBACK(LOKDocView_Impl::signalButton), pDocView);
135360
-    g_signal_connect(G_OBJECT(pDocView),
135360
-                     "button-release-event",
135360
-                     G_CALLBACK(LOKDocView_Impl::signalButton), pDocView);
135360
-    g_signal_connect(G_OBJECT(pDocView),
135360
-                     "motion-notify-event",
135360
-                     G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView);
135360
-
135360
-    g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0);
135360
+    /**
135360
+     * LOKDocView::hyperlinked-clicked:
135360
+     * @pDocView: the #LOKDocView on which the signal is emitted
135360
+     * @aHyperlink: the URI which the application should handle
135360
+     */
135360
+    doc_view_signals[PART_CHANGED] =
135360
+        g_signal_new("hyperlinked-clicked",
135360
+                     G_TYPE_FROM_CLASS(pGObjectClass),
135360
+                     G_SIGNAL_RUN_FIRST,
135360
+                     0,
135360
+                     NULL, NULL,
135360
+                     g_cclosure_marshal_VOID__STRING,
135360
+                     G_TYPE_NONE, 1,
135360
+                     G_TYPE_STRING);
135360
 }
135360
 
135360
+
135360
+
135360
 /**
135360
  * lok_doc_view_new:
135360
  * @pPath: LibreOffice install path.
135360
  *
135360
  * Returns: The #LOKDocView widget instance.
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new(const char* pPath)
135360
+SAL_DLLPUBLIC_EXPORT GtkWidget*
135360
+lok_doc_view_new (const char* pPath)
135360
 {
135360
-    LOKDocView* pDocView = LOK_DOC_VIEW(g_object_new(LOK_TYPE_DOC_VIEW, NULL));
135360
-    pDocView->m_pImpl->m_pOffice = lok_init (pPath);
135360
-    if (pDocView->m_pImpl->m_pOffice == NULL)
135360
-        return NULL;
135360
-    return GTK_WIDGET( pDocView );
135360
+    return GTK_WIDGET (g_object_new(LOK_TYPE_DOC_VIEW, "lopath", pPath, NULL));
135360
 }
135360
 
135360
 /**
135360
@@ -1186,47 +1367,47 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new(const char* pPath)
135360
  *
135360
  * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, char* pPath )
135360
+SAL_DLLPUBLIC_EXPORT gboolean
135360
+lok_doc_view_open_document (LOKDocView* pDocView, char* pPath)
135360
 {
135360
-    if ( pDocView->m_pImpl->m_pDocument )
135360
+    if ( pDocView->priv->m_pDocument )
135360
     {
135360
-        pDocView->m_pImpl->m_pDocument->pClass->destroy( pDocView->m_pImpl->m_pDocument );
135360
-        pDocView->m_pImpl->m_pDocument = 0;
135360
+        pDocView->priv->m_pDocument->pClass->destroy( pDocView->priv->m_pDocument );
135360
+        pDocView->priv->m_pDocument = 0;
135360
     }
135360
 
135360
-    pDocView->m_pImpl->m_pOffice->pClass->registerCallback(pDocView->m_pImpl->m_pOffice, &LOKDocView_Impl::globalCallbackWorker, pDocView);
135360
-    pDocView->m_pImpl->m_pDocument = pDocView->m_pImpl->m_pOffice->pClass->documentLoad( pDocView->m_pImpl->m_pOffice,
135360
+    pDocView->priv->m_pOffice->pClass->registerCallback(pDocView->priv->m_pOffice, globalCallbackWorker, pDocView);
135360
+    pDocView->priv->m_pDocument = pDocView->priv->m_pOffice->pClass->documentLoad( pDocView->priv->m_pOffice,
135360
                                                                    pPath );
135360
-    if ( !pDocView->m_pImpl->m_pDocument )
135360
+    if ( !pDocView->priv->m_pDocument )
135360
     {
135360
         // FIXME: should have a GError parameter and populate it.
135360
-        char *pError = pDocView->m_pImpl->m_pOffice->pClass->getError( pDocView->m_pImpl->m_pOffice );
135360
+        char *pError = pDocView->priv->m_pOffice->pClass->getError( pDocView->priv->m_pOffice );
135360
         fprintf( stderr, "Error opening document '%s'\n", pError );
135360
         return FALSE;
135360
     }
135360
     else
135360
     {
135360
-        pDocView->m_pImpl->m_pDocument->pClass->initializeForRendering(pDocView->m_pImpl->m_pDocument);
135360
-        pDocView->m_pImpl->m_pDocument->pClass->registerCallback(pDocView->m_pImpl->m_pDocument, &LOKDocView_Impl::callbackWorker, pDocView);
135360
-        pDocView->m_pImpl->m_pDocument->pClass->getDocumentSize(pDocView->m_pImpl->m_pDocument, &pDocView->m_pImpl->m_nDocumentWidthTwips, &pDocView->m_pImpl->m_nDocumentHeightTwips);
135360
-        g_timeout_add(600, &LOKDocView_Impl::handleTimeout, pDocView);
135360
-
135360
-        float zoom = pDocView->m_pImpl->m_fZoom;
135360
-        long nDocumentWidthTwips = pDocView->m_pImpl->m_nDocumentWidthTwips;
135360
-        long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips;
135360
+        pDocView->priv->m_pDocument->pClass->initializeForRendering(pDocView->priv->m_pDocument);
135360
+        pDocView->priv->m_pDocument->pClass->registerCallback(pDocView->priv->m_pDocument, callbackWorker, pDocView);
135360
+        pDocView->priv->m_pDocument->pClass->getDocumentSize(pDocView->priv->m_pDocument, &pDocView->priv->m_nDocumentWidthTwips, &pDocView->priv->m_nDocumentHeightTwips);
135360
+        g_timeout_add(600, handleTimeout, pDocView);
135360
+
135360
+        float zoom = pDocView->priv->m_fZoom;
135360
+        long nDocumentWidthTwips = pDocView->priv->m_nDocumentWidthTwips;
135360
+        long nDocumentHeightTwips = pDocView->priv->m_nDocumentHeightTwips;
135360
         long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom);
135360
         long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom);
135360
         // Total number of columns in this document.
135360
         guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
135360
 
135360
 
135360
-        pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument,
135360
-                                                      nColumns);
135360
+        pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument,
135360
+                                                   nColumns);
135360
         gtk_widget_set_size_request(GTK_WIDGET(pDocView),
135360
                                     nDocumentWidthPixels,
135360
                                     nDocumentHeightPixels);
135360
     }
135360
-
135360
     return TRUE;
135360
 }
135360
 
135360
@@ -1236,9 +1417,10 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView,
135360
  *
135360
  * Returns: The #LibreOfficeKitDocument instance the widget is currently showing
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView)
135360
+SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument*
135360
+lok_doc_view_get_document (LOKDocView* pDocView)
135360
 {
135360
-    return pDocView->m_pImpl->m_pDocument;
135360
+    return pDocView->priv->m_pDocument;
135360
 }
135360
 
135360
 /**
135360
@@ -1248,16 +1430,17 @@ SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocVie
135360
  *
135360
  * Sets the new zoom level for the widget.
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZoom )
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom)
135360
 {
135360
-    pDocView->m_pImpl->m_fZoom = fZoom;
135360
-    long nDocumentWidthPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips, fZoom);
135360
-    long nDocumentHeightPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips, fZoom);
135360
+    pDocView->priv->m_fZoom = fZoom;
135360
+    long nDocumentWidthPixels = twipToPixel(pDocView->priv->m_nDocumentWidthTwips, fZoom);
135360
+    long nDocumentHeightPixels = twipToPixel(pDocView->priv->m_nDocumentHeightTwips, fZoom);
135360
     // Total number of columns in this document.
135360
     guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels);
135360
 
135360
-    pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument,
135360
-                                                  nColumns);
135360
+    pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument,
135360
+                                               nColumns);
135360
     gtk_widget_set_size_request(GTK_WIDGET(pDocView),
135360
                                 nDocumentWidthPixels,
135360
                                 nDocumentHeightPixels);
135360
@@ -1269,35 +1452,41 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ
135360
  *
135360
  * Returns: The current zoom factor value in float for pDocView
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT float lok_doc_view_get_zoom ( LOKDocView* pDocView )
135360
+SAL_DLLPUBLIC_EXPORT float
135360
+lok_doc_view_get_zoom (LOKDocView* pDocView)
135360
 {
135360
-    return pDocView->m_pImpl->m_fZoom;
135360
+    return pDocView->priv->m_fZoom;
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_parts( LOKDocView* pDocView )
135360
+SAL_DLLPUBLIC_EXPORT int
135360
+lok_doc_view_get_parts (LOKDocView* pDocView)
135360
 {
135360
-    return pDocView->m_pImpl->m_pDocument->pClass->getParts( pDocView->m_pImpl->m_pDocument );
135360
+    return pDocView->priv->m_pDocument->pClass->getParts( pDocView->priv->m_pDocument );
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_part( LOKDocView* pDocView )
135360
+SAL_DLLPUBLIC_EXPORT int
135360
+lok_doc_view_get_part (LOKDocView* pDocView)
135360
 {
135360
-    return pDocView->m_pImpl->m_pDocument->pClass->getPart( pDocView->m_pImpl->m_pDocument );
135360
+    return pDocView->priv->m_pDocument->pClass->getPart( pDocView->priv->m_pDocument );
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_part( LOKDocView* pDocView, int nPart)
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_set_part (LOKDocView* pDocView, int nPart)
135360
 {
135360
-    pDocView->m_pImpl->m_pDocument->pClass->setPart( pDocView->m_pImpl->m_pDocument, nPart );
135360
+    pDocView->priv->m_pDocument->pClass->setPart( pDocView->priv->m_pDocument, nPart );
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT char* lok_doc_view_get_part_name( LOKDocView* pDocView, int nPart )
135360
+SAL_DLLPUBLIC_EXPORT char*
135360
+lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart)
135360
 {
135360
-    return pDocView->m_pImpl->m_pDocument->pClass->getPartName( pDocView->m_pImpl->m_pDocument, nPart );
135360
+    return pDocView->priv->m_pDocument->pClass->getPartName( pDocView->priv->m_pDocument, nPart );
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView,
135360
-                                                    int nPartMode )
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_set_partmode(LOKDocView* pDocView,
135360
+                          int nPartMode)
135360
 {
135360
-    pDocView->m_pImpl->m_pDocument->pClass->setPartMode( pDocView->m_pImpl->m_pDocument, nPartMode );
135360
+    pDocView->priv->m_pDocument->pClass->setPartMode( pDocView->priv->m_pDocument, nPartMode );
135360
 }
135360
 
135360
 /**
135360
@@ -1307,19 +1496,20 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView,
135360
  *
135360
  * Sets the edit-mode for pDocView
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView,
135360
-                                                gboolean bEdit )
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_set_edit(LOKDocView* pDocView,
135360
+                      gboolean bEdit)
135360
 {
135360
-    gboolean bWasEdit = pDocView->m_pImpl->m_bEdit;
135360
+    gboolean bWasEdit = pDocView->priv->m_bEdit;
135360
 
135360
-    if (!pDocView->m_pImpl->m_bEdit && bEdit)
135360
+    if (!pDocView->priv->m_bEdit && bEdit)
135360
         g_info("lok_doc_view_set_edit: entering edit mode");
135360
-    else if (pDocView->m_pImpl->m_bEdit && !bEdit)
135360
+    else if (pDocView->priv->m_bEdit && !bEdit)
135360
     {
135360
         g_info("lok_doc_view_set_edit: leaving edit mode");
135360
-        pDocView->m_pImpl->m_pDocument->pClass->resetSelection(pDocView->m_pImpl->m_pDocument);
135360
+        pDocView->priv->m_pDocument->pClass->resetSelection(pDocView->priv->m_pDocument);
135360
     }
135360
-    pDocView->m_pImpl->m_bEdit = bEdit;
135360
+    pDocView->priv->m_bEdit = bEdit;
135360
     g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit);
135360
     gtk_widget_queue_draw(GTK_WIDGET(pDocView));
135360
 }
135360
@@ -1330,20 +1520,39 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView,
135360
  *
135360
  * Returns: %TRUE if the given pDocView is in edit mode.
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_get_edit(LOKDocView* pDocView)
135360
+SAL_DLLPUBLIC_EXPORT gboolean
135360
+lok_doc_view_get_edit (LOKDocView* pDocView)
135360
 {
135360
-    return pDocView->m_pImpl->m_bEdit;
135360
+    return pDocView->priv->m_bEdit;
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_command(LOKDocView* pDocView, const char* pCommand, const char* pArguments)
135360
+/**
135360
+ * lok_doc_view_post_command:
135360
+ * @pDocView: the #LOKDocView instance
135360
+ * @pCommand: the command to issue to LO core
135360
+ * @pArguments: the arguments to the given command
135360
+ *
135360
+ * This methods forwards your command to LO core.
135360
+*/
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_post_command (LOKDocView* pDocView,
135360
+                           const char* pCommand,
135360
+                           const char* pArguments)
135360
 {
135360
-    pDocView->m_pImpl->m_pDocument->pClass->postUnoCommand(pDocView->m_pImpl->m_pDocument, pCommand, pArguments);
135360
+    pDocView->priv->m_pDocument->pClass->postUnoCommand(pDocView->priv->m_pDocument, pCommand, pArguments);
135360
 }
135360
 
135360
-SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData)
135360
+/**
135360
+ * lok_doc_view_post_key:
135360
+ * @pDocView: the #LOKDocView instance
135360
+ * @pEvent: the #GdkEventKey containing information about the event
135360
+ *
135360
+ * This methods forwards your key events to the LO core.
135360
+*/
135360
+SAL_DLLPUBLIC_EXPORT void
135360
+lok_doc_view_post_key (LOKDocView* pDocView, GdkEvent* pEvent)
135360
 {
135360
-    LOKDocView* pDocView = static_cast<LOKDocView *>(pData);
135360
-    pDocView->m_pImpl->signalKey(pEvent);
135360
+    signalKey(pDocView, pEvent);
135360
 }
135360
 
135360
 /**
135360
@@ -1355,9 +1564,10 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEvent
135360
  *
135360
  * Returns: The corresponding value in twips
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, float fInput)
135360
+SAL_DLLPUBLIC_EXPORT float
135360
+lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput)
135360
 {
135360
-    return pixelToTwip(fInput, pDocView->m_pImpl->m_fZoom);
135360
+    return pixelToTwip(fInput, pDocView->priv->m_fZoom);
135360
 }
135360
 
135360
 /**
135360
@@ -1369,10 +1579,10 @@ SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, floa
135360
  *
135360
  * Returns: The corresponding value in pixels
135360
  */
135360
-SAL_DLLPUBLIC_EXPORT float lok_doc_view_twip_to_pixel(LOKDocView* pDocView, float fInput)
135360
+SAL_DLLPUBLIC_EXPORT float
135360
+lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput)
135360
 {
135360
-    return twipToPixel(fInput, pDocView->m_pImpl->m_fZoom);
135360
+    return twipToPixel(fInput, pDocView->priv->m_fZoom);
135360
 }
135360
 
135360
-
135360
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
135360
-- 
135360
2.12.0
135360