Blob Blame History Raw
From 34a8ad7556a7a69f70a87d4d4e3dab328cff33de Mon Sep 17 00:00:00 2001
From: Pranav Kant <pranavk@gnome.org>
Date: Thu, 4 Jun 2015 03:32:18 +0530
Subject: [PATCH 014/398] lokdocview: Add support for editing documents

Change-Id: I8637d99e6fa59129af207e667bcdf03dc212efeb
(cherry picked from commit 82a208a08fdfa8b6dab4f1577931f5e4f037276c)
---
 libreofficekit/source/gtk/lokdocview.cxx | 50 ++++++++++++++--
 libreofficekit/source/gtk/tilebuffer.cxx | 99 ++++++++++++++++++--------------
 libreofficekit/source/gtk/tilebuffer.hxx | 68 +++++++++++-----------
 3 files changed, 136 insertions(+), 81 deletions(-)

diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 413054cf873c..3b894f765faa 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -821,7 +821,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial)
 
             if (bPaint)
             {
-                g_info("gettile: (%d %d)", nRow, nColumn);
+                //                g_info("gettile: (%d %d)", nRow, nColumn);
 
                 Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn);
                 GdkPixbuf* pPixBuf = currentTile.tile_get_buffer();
@@ -934,17 +934,50 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback)
         if (pCallback->m_aPayload != "EMPTY")
         {
             GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
-            renderDocument(&aRectangle);
+            GdkRectangle aRectanglePixels;
+            aRectanglePixels.x = twipToPixel(aRectangle.x);
+            aRectanglePixels.y = twipToPixel(aRectangle.y);
+            aRectanglePixels.width = twipToPixel(aRectangle.width);
+            aRectanglePixels.height = twipToPixel(aRectangle.height);
+            int rowStart = aRectanglePixels.y / nTileSizePixels;
+            int colStart = aRectanglePixels.x / nTileSizePixels;
+            int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
+            int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
+            int i,j;
+            for (i = rowStart; i < rowEnd; i++) {
+                for (j = colStart; j < colEnd; j++) {
+                    m_pTileBuffer->tile_buffer_set_invalid(i, j);
+                }
+            }
+            renderDocument(0);
         }
         else
+        {
+            m_pTileBuffer->tile_buffer_reset_all_tiles();
             renderDocument(0);
+        }
     }
     break;
     case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
     {
         m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str());
         m_bCursorOverlayVisible = true;
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea));
+        GdkRectangle aRectanglePixels;
+        aRectanglePixels.x = twipToPixel(m_aVisibleCursor.x);
+        aRectanglePixels.y = twipToPixel(m_aVisibleCursor.y);
+        aRectanglePixels.width = twipToPixel(m_aVisibleCursor.width);
+        aRectanglePixels.height = twipToPixel(m_aVisibleCursor.height);
+        int rowStart = aRectanglePixels.y / nTileSizePixels;
+        int colStart = aRectanglePixels.x / nTileSizePixels;
+        int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels;
+        int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels;
+        int i,j;
+        for (i = rowStart; i < rowEnd; i++) {
+            for (j = colStart; j < colEnd; j++) {
+                m_pTileBuffer->tile_buffer_set_invalid(i, j);
+            }
+        }
+        renderDocument(0);
     }
     break;
     case LOK_CALLBACK_TEXT_SELECTION:
@@ -961,7 +994,6 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback)
         }
         else
             memset(&m_aHandleMiddleRect, 0, sizeof(m_aHandleMiddleRect));
-        gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea));
     }
     break;
     case LOK_CALLBACK_TEXT_SELECTION_START:
@@ -1144,6 +1176,16 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer )
     g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea),
                      "expose-event",
                      GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView);
+    g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea),
+                     "expose-event",
+                     GTK_SIGNAL_FUNC(LOKDocView_Impl::renderOverlay), pDocView);
+    gtk_widget_add_events(pDocView->m_pImpl->m_pDrawingArea,
+                          GDK_BUTTON_PRESS_MASK
+                          | GDK_BUTTON_RELEASE_MASK
+                          | GDK_BUTTON_MOTION_MASK);
+    g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-press-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView);
+    g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-release-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView);
+    g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "motion-notify-event", G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView);
 
     gtk_signal_connect(GTK_OBJECT(pDocView), "destroy", GTK_SIGNAL_FUNC(LOKDocView_Impl::destroy), 0);
 }
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
index e1b5b3294cc5..e13f5b034c1d 100644
--- a/libreofficekit/source/gtk/tilebuffer.cxx
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -23,69 +23,82 @@ static float twipToPixel(float fInput, float zoom)
 
 GdkPixbuf* Tile::tile_get_buffer()
 {
-  return m_pBuffer;
+    return m_pBuffer;
 }
 
 void Tile::tile_release()
 {
-  gdk_pixbuf_unref(m_pBuffer);
-  m_pBuffer = NULL;
+    g_object_unref (m_pBuffer);
+    m_pBuffer = NULL;
 }
 
 void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns)
 {
-  m_fZoomFactor = newZoomFactor;
+    m_fZoomFactor = newZoomFactor;
 
-  tile_buffer_reset_all_tiles();
+    tile_buffer_reset_all_tiles();
 
-  // set new buffer width and height
-  m_nWidth = columns;
-  m_nHeight = rows;
+    // set new buffer width and height
+    m_nWidth = columns;
+    m_nHeight = rows;
 }
 
 void TileBuffer::tile_buffer_reset_all_tiles()
 {
-  std::map<int, Tile>::iterator it = m_mTiles.begin();
-  for (; it != m_mTiles.end(); it++)
-    {
-       it->second.tile_release();
-    }
-  m_mTiles.clear();
+    std::map<int, Tile>::iterator it = m_mTiles.begin();
+    for (; it != m_mTiles.end(); it++)
+        {
+            it->second.tile_release();
+        }
+    m_mTiles.clear();
+}
+
+void TileBuffer::tile_buffer_set_invalid(int x, int y)
+{
+    int index = x * m_nWidth + y;
+    g_info("setting invalid : %d %d",x, y);
+    if (m_mTiles.find(index) != m_mTiles.end())
+        {
+            m_mTiles[index].valid = 0;
+            m_mTiles[index].tile_release();
+            m_mTiles.erase(index);
+        }
 }
 
 Tile& TileBuffer::tile_buffer_get_tile(int x, int y)
 {
-  int index = x * m_nWidth + y;
-  if(m_mTiles.find(index) == m_mTiles.end())
-    {
-      GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize);
-      if (!pPixBuf){
-        g_info ("error allocating memory to pixbuf");
-      }
-      unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
-      GdkRectangle aTileRectangle;
-      aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y;
-      aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x;
-
-      g_info ("rendering (%d %d)", x, y);
-      m_pLOKDocument->pClass->paintTile(m_pLOKDocument,
-                                        // Buffer and its size, depends on the position only.
-                                        pBuffer,
-                                        m_nTileSize, m_nTileSize,
-                                        // Position of the tile.
-                                        aTileRectangle.x, aTileRectangle.y,
-                                        // Size of the tile, depends on the zoom factor and the tile position only.
-                                        pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor));
-
-      //create a mapping for it
-      m_mTiles[index].tile_set_pixbuf(pPixBuf);
-      m_mTiles[index].valid = 1;
-    }
-
-  return m_mTiles[index];
+    int index = x * m_nWidth + y;
+    if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid)
+        {
+
+            GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize);
+            if (!pPixBuf){
+                g_info ("error allocating memory to pixbuf");
+            }
+            unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf);
+            GdkRectangle aTileRectangle;
+            aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y;
+            aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x;
+
+            g_info ("rendering (%d %d)", x, y);
+            m_pLOKDocument->pClass->paintTile(m_pLOKDocument,
+                                              // Buffer and its size, depends on the position only.
+                                              pBuffer,
+                                              m_nTileSize, m_nTileSize,
+                                              // Position of the tile.
+                                              aTileRectangle.x, aTileRectangle.y,
+                                              // Size of the tile, depends on the zoom factor and the tile position only.
+                                              pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor));
+
+            //create a mapping for it
+            m_mTiles[index].tile_set_pixbuf(pPixBuf);
+            m_mTiles[index].valid = 1;
+        }
+
+    return m_mTiles[index];
 }
 
 void Tile::tile_set_pixbuf(GdkPixbuf *buffer)
 {
-  m_pBuffer = buffer;
+    m_pBuffer = buffer;
 }
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 0bc2d38dd641..088df93ca6b6 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -25,18 +25,17 @@
 */
 class Tile
 {
-public:
-  Tile() : valid(0) {}
-  ~Tile() {
-    tile_release();
-  }
+ public:
+ Tile() : valid(0) {}
+    ~Tile() {
+    }
 
-  GdkPixbuf* tile_get_buffer();
-  void tile_release();
-  void tile_set_pixbuf(GdkPixbuf*);
-  bool valid;
-private:
-  GdkPixbuf *m_pBuffer;
+    GdkPixbuf* tile_get_buffer();
+    void tile_release();
+    void tile_set_pixbuf(GdkPixbuf*);
+    bool valid;
+ private:
+    GdkPixbuf *m_pBuffer;
 };
 
 /*
@@ -45,32 +44,33 @@ private:
 */
 class TileBuffer
 {
-public:
-  TileBuffer(LibreOfficeKitDocument *document,
-             int tileSize,
-             int rows,
-             int columns)
-    : m_pLOKDocument(document)
-    , m_nTileSize(tileSize)
-    , m_fZoomFactor(1)
-    , m_nWidth(columns)
-    , m_nHeight(rows)
+ public:
+ TileBuffer(LibreOfficeKitDocument *document,
+            int tileSize,
+            int rows,
+            int columns)
+     : m_pLOKDocument(document)
+        , m_nTileSize(tileSize)
+        , m_fZoomFactor(1)
+        , m_nWidth(columns)
+        , m_nHeight(rows)
     {  }
 
-  ~TileBuffer() {}
+    ~TileBuffer() {}
 
-  void tile_buffer_set_zoom(float zoomFactor, int rows, int columns);
-  Tile& tile_buffer_get_tile(int x, int y);
-  void tile_buffer_update();
-  void tile_buffer_reset_all_tiles();
-private:
-  LibreOfficeKitDocument *m_pLOKDocument;
-  int m_nTileSize;
-  float m_fZoomFactor;
-  std::map<int, Tile> m_mTiles;
-  //TODO: Also set width and height when document size changes
-  int m_nWidth;
-  int m_nHeight;
+    void tile_buffer_set_zoom(float zoomFactor, int rows, int columns);
+    Tile& tile_buffer_get_tile(int x, int y);
+    void tile_buffer_update();
+    void tile_buffer_reset_all_tiles();
+    void tile_buffer_set_invalid(int x, int y);
+ private:
+    LibreOfficeKitDocument *m_pLOKDocument;
+    int m_nTileSize;
+    float m_fZoomFactor;
+    std::map<int, Tile> m_mTiles;
+    //TODO: Also set width and height when document size changes
+    int m_nWidth;
+    int m_nHeight;
 };
 
 #endif // INCLUDED_TILEBUFFER_HXX
-- 
2.12.0