desktop/source/lib/init.cxx | 18 ++ include/vcl/ITiledRenderable.hxx | 8 + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 128 +++++++++++++++++++- sc/inc/docuno.hxx | 3 sc/source/ui/inc/tabview.hxx | 2 sc/source/ui/unoobj/docuno.cxx | 13 ++ sc/source/ui/view/tabview.cxx | 29 ++++ 7 files changed, 199 insertions(+), 2 deletions(-)
New commits: commit ecef9cb66c5f6009c7b062b489f93de85b70beeb Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Oct 30 12:34:38 2015 +0100 gtktiledviewer: initial row headers for spreadsheet documents Change-Id: Iec9080d7017ddcf2b605243bc820f9664110c2e8 diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx index 8b81c73..8d6d172 100644 --- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx @@ -32,6 +32,37 @@ static int help() return 1; } +/// Represents the row header widget for spreadsheets. +class TiledRowBar +{ +public: + /// Stores size and content of a single row header. + struct Header + { + int m_nSize; + std::string m_aText; + Header(int nSize, const std::string& rText) + : m_nSize(nSize), + m_aText(rText) + { + } + }; + + static const int HEADER_WIDTH = 50; + + GtkWidget* m_pDrawingArea; + std::vector<Header> m_aHeaders; + int m_nHeightPixel = 0; + + TiledRowBar(GtkWidget* pDocView); + static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); + gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); + static gboolean docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); + gboolean docConfigureEventImpl(GtkWidget* pWidget, GdkEventConfigure* pEvent); + /// Draws rText at the center of rRectangle on pCairo. + void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); +}; + /// Represents all the state that is specific to one GtkWindow of this app. class TiledWindow { @@ -56,6 +87,7 @@ public: GtkWidget* m_pFindbarEntry; GtkWidget* m_pFindbarLabel; bool m_bFindAll; + std::shared_ptr<TiledRowBar> m_pRowBar; TiledWindow() : m_pDocView(0), @@ -92,6 +124,92 @@ static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) return g_aWindows[pToplevel]; } +TiledRowBar::TiledRowBar(GtkWidget* pDocView) + : m_pDrawingArea(gtk_drawing_area_new()), + m_nHeightPixel(0) +{ + gtk_widget_set_size_request(m_pDrawingArea, HEADER_WIDTH, -1); + g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledRowBar::draw), this); + g_signal_connect(pDocView, "configure-event", G_CALLBACK(TiledRowBar::docConfigureEvent), this); +} + +gboolean TiledRowBar::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) +{ + return static_cast<TiledRowBar*>(pData)->drawImpl(pWidget, pCairo); +} + +void TiledRowBar::drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText) +{ + cairo_text_extents_t extents; + cairo_text_extents(pCairo, rText.c_str(), &extents); + // Cairo reference point for text is the bottom left corner. + cairo_move_to(pCairo, rRectangle.x + rRectangle.width / 2 - extents.width / 2, rRectangle.y + rRectangle.height / 2 + extents.height / 2); + cairo_show_text(pCairo, rText.c_str()); +} + +gboolean TiledRowBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) +{ + cairo_set_source_rgb(pCairo, 0, 0, 0); + + int nTotal = 0; + for (const Header& rHeader : m_aHeaders) + { + GdkRectangle aRectangle; + aRectangle.x = 0; + aRectangle.y = nTotal - 1; + aRectangle.width = HEADER_WIDTH - 1; + aRectangle.height = rHeader.m_nSize; + // Bottom line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); + cairo_fill(pCairo); + // Left line. + cairo_rectangle(pCairo, aRectangle.width, aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); + drawText(pCairo, aRectangle, rHeader.m_aText); + nTotal += rHeader.m_nSize; + if (nTotal > m_nHeightPixel) + break; + } + + return FALSE; +} + +gboolean TiledRowBar::docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData) +{ + return static_cast<TiledRowBar*>(pData)->docConfigureEventImpl(pWidget, pEvent); +} + +gboolean TiledRowBar::docConfigureEventImpl(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/) +{ + if (g_aWindows.find(gtk_widget_get_toplevel(pDocView)) == g_aWindows.end()) + return TRUE; + + TiledWindow& rWindow = lcl_getTiledWindow(pDocView); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); + m_nHeightPixel = gtk_adjustment_get_page_size(pVAdjustment); + + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); + if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) + { + m_aHeaders.clear(); + char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); + std::stringstream aStream(pValues); + free(pValues); + assert(!aStream.str().empty()); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { + Header aHeader(std::atoi(rValue.second.get<std::string>("size").c_str()), rValue.second.get<std::string>("text")); + m_aHeaders.push_back(aHeader); + } + gtk_widget_show(m_pDrawingArea); + gtk_widget_queue_draw(m_pDrawingArea); + } + + return TRUE; +} + static void lcl_registerToolItem(TiledWindow& rWindow, GtkToolItem* pItem, const std::string& rName) { rWindow.m_aToolItemCommandNames[pItem] = rName; @@ -798,11 +916,17 @@ static GtkWidget* createWindow(TiledWindow& rWindow) gtk_box_pack_end(GTK_BOX(rWindow.m_pVBox), rWindow.m_pFindbar, FALSE, FALSE, 0); + // Horizontal box for the row bar + doc view. + GtkWidget* pHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), pHBox); + rWindow.m_pRowBar.reset(new TiledRowBar(rWindow.m_pDocView)); + gtk_box_pack_start(GTK_BOX(pHBox), rWindow.m_pRowBar->m_pDrawingArea, FALSE, FALSE, 0); + // Scrolled window for DocView rWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); gtk_widget_set_hexpand(rWindow.m_pScrolledWindow, TRUE); gtk_widget_set_vexpand(rWindow.m_pScrolledWindow, TRUE); - gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), rWindow.m_pScrolledWindow); + gtk_container_add(GTK_CONTAINER(pHBox), rWindow.m_pScrolledWindow); gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); @@ -819,6 +943,8 @@ static GtkWidget* createWindow(TiledWindow& rWindow) gtk_widget_show_all(pWindow); // Hide the findbar by default. gtk_widget_hide(rWindow.m_pFindbar); + // Same for the row bar. + gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); g_aWindows[pWindow] = rWindow; return pWindow; commit a7ce5f83343f8f6ba8a59b05820b3a2066c0ce9a Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Oct 30 11:18:19 2015 +0100 LOK: initial Document::getCommandValues() for RowColumnHeaders Only the row info and for the entire tiled rendering area as a start. Change-Id: Idbccd805b355e8d151ab7025ac1cf0c686cb237b diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 8e3b88e..32b0101 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1135,7 +1135,23 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo { return getStyles(pThis, pCommand); } - else { + else if (OString(pCommand) == ".uno:ViewRowColumnHeaders") + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) + { + gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; + return 0; + } + + OUString aHeaders = pDoc->getRowColumnHeaders(); + OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8); + char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1)); + strcpy(pMemory, aString.getStr()); + return pMemory; + } + else + { gImpl->maLastExceptionMsg = "Unknown command, no values returned"; return NULL; } diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index 8ae719e..48a13ff 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -148,6 +148,14 @@ public: return OUString(); } + /** + * Get position and content of row/column headers of Calc documents. + */ + virtual OUString getRowColumnHeaders() + { + return OUString(); + } + /// Sets the clipboard of the component. virtual void setClipboard(const css::uno::Reference<css::datatransfer::clipboard::XClipboard>& xClipboard) = 0; diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index ea924a8..e2a2dbc 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -404,6 +404,9 @@ public: /// @see vcl::ITiledRenderable::isMimeTypeSupported(). virtual bool isMimeTypeSupported() override; + + /// @see vcl::ITiledRenderable::getRowColumnHeaders(). + virtual OUString getRowColumnHeaders() override; }; class ScDrawPagesObj : public cppu::WeakImplHelper< diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index 24be8c0..51cb7c1 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -517,6 +517,8 @@ public: void EnableAutoSpell( bool bEnable ); void ResetAutoSpell(); void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges ); + /// @see ScModelObj::getRowColumnHeaders(). + OUString getRowColumnHeaders(); }; #endif diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index c6070f1..27fe638 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -869,6 +869,19 @@ bool ScModelObj::isMimeTypeSupported() return EditEngine::HasValidData(aDataHelper.GetTransferable()); } +OUString ScModelObj::getRowColumnHeaders() +{ + ScViewData* pViewData = ScDocShell::GetViewData(); + if (!pViewData) + return OUString(); + + ScTabView* pTabView = pViewData->GetView(); + if (!pTabView) + return OUString(); + + return pTabView->getRowColumnHeaders(); +} + void ScModelObj::initializeForTiledRendering() { SolarMutexGuard aGuard; diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 6e39053..aa50aaf 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -50,6 +50,7 @@ #include <string> #include <algorithm> +#include <boost/property_tree/json_parser.hpp> #include <basegfx/tools/zoomtools.hxx> @@ -2278,4 +2279,32 @@ void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<ed } } +OUString ScTabView::getRowColumnHeaders() +{ + ScDocument* pDoc = aViewData.GetDocument(); + if (!pDoc) + return OUString(); + + SCCOL nEndCol = 0; + SCROW nEndRow = 0; + pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); + + boost::property_tree::ptree aRows; + for (SCROW nRow = 0; nRow < nEndRow; ++nRow) + { + boost::property_tree::ptree aRow; + sal_uInt16 nSize = pRowBar[SC_SPLIT_BOTTOM]->GetEntrySize(nRow); + aRow.put("size", OString::number(nSize).getStr()); + OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); + aRow.put("text", aText.toUtf8().getStr()); + aRows.push_back(std::make_pair("", aRow)); + } + + boost::property_tree::ptree aTree; + aTree.add_child("rows", aRows); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + return OUString::fromUtf8(aStream.str().c_str()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits