From 34a8ad7556a7a69f70a87d4d4e3dab328cff33de Mon Sep 17 00:00:00 2001 From: Pranav Kant 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::iterator it = m_mTiles.begin(); - for (; it != m_mTiles.end(); it++) - { - it->second.tile_release(); - } - m_mTiles.clear(); + std::map::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 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 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