diff options
author | Pranav Kant <pranavk@collabora.co.uk> | 2017-07-12 21:25:00 +0530 |
---|---|---|
committer | Pranav Kant <pranavk@collabora.co.uk> | 2017-07-12 22:05:16 +0530 |
commit | 96f4c2c2714dbb23cc7c3d579d7914f2a53907fb (patch) | |
tree | 5c0cd9f0bbcbe7858af9c92d06480e03fe8462b5 | |
parent | 7861d988874681a10be785bd074f3bd251b82727 (diff) |
row column bar compilable
Change-Id: I50efcb93a72cd375a7ecf712487debbf02acbd52
9 files changed, 329 insertions, 24 deletions
@@ -30,34 +30,13 @@ </packing> </child> <child> - <object class="GtkDrawingArea" id="cornerarea"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> + <placeholder/> </child> <child> - <object class="GtkDrawingArea" id="rowbararea"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> + <placeholder/> </child> <child> - <object class="GtkDrawingArea" id="columnbararea"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> + <placeholder/> </child> </object> <packing> diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk index 0f89aa4ff37a..cec96ba8fa2a 100644 --- a/libreofficekit/Executable_gtktiledviewer.mk +++ b/libreofficekit/Executable_gtktiledviewer.mk @@ -51,6 +51,7 @@ $(eval $(call gb_Executable_add_exception_objects,gtktiledviewer,\ libreofficekit/qa/gtktiledviewer/gtv-signal-handlers \ libreofficekit/qa/gtktiledviewer/gtv-helpers \ libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers \ + libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar \ )) # vim: set noet sw=4 ts=4: diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx index e4e0a79d554f..6456ecf2ab09 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx @@ -16,6 +16,7 @@ #include <gtv-main-toolbar.hxx> #include <gtv-helpers.hxx> #include <gtv-lokdocview-signal-handlers.hxx> +#include <gtv-calc-header-bar.hxx> #include <boost/property_tree/json_parser.hpp> #include <boost/optional.hpp> @@ -23,6 +24,7 @@ struct GtvApplicationWindowPrivate { GtkWidget* container; + GtkWidget* gridcontainer; GtkWidget* toolbarcontainer; gboolean toolbarBroadcast; @@ -55,9 +57,24 @@ gtv_application_window_init(GtvApplicationWindow* win) gtk_box_pack_start(GTK_BOX(priv->container), priv->toolbarcontainer, false, false, false); gtk_box_reorder_child(GTK_BOX(priv->container), priv->toolbarcontainer, 0); + + priv->gridcontainer = GTK_WIDGET(gtk_builder_get_object(builder, "maingrid")); // scrolled window containing the main drawing area win->scrolledwindow = GTK_WIDGET(gtk_builder_get_object(builder, "scrolledwindow")); + // calc header row bar + win->cornerarea = gtv_calc_header_bar_new(); + gtv_calc_header_bar_set_type(GTV_CALC_HEADER_BAR(win->cornerarea), CalcHeaderType::CORNER); + win->rowbar = gtv_calc_header_bar_new(); + gtv_calc_header_bar_set_type(GTV_CALC_HEADER_BAR(win->rowbar), CalcHeaderType::ROW); + win->columnbar = gtv_calc_header_bar_new(); + gtv_calc_header_bar_set_type(GTV_CALC_HEADER_BAR(win->columnbar), CalcHeaderType::COLUMN); + + // attach row/colum/corner to the container + gtk_grid_attach(GTK_GRID(priv->gridcontainer), win->cornerarea, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(priv->gridcontainer), win->rowbar, 0, 1, 1, 1); + gtk_grid_attach(GTK_GRID(priv->gridcontainer), win->columnbar, 1, 0, 1, 1); + // statusbar win->statusbar = GTK_WIDGET(gtk_builder_get_object(builder, "statusbar")); win->redlinelabel = GTK_WIDGET(gtk_builder_get_object(builder, "redlinelabel")); @@ -211,6 +228,7 @@ gtv_application_open_document_callback(GObject* source_object, GAsyncResult* res lok_doc_view_set_edit(pDocView, true); + initWindow(window); } @@ -321,6 +339,8 @@ static void setupDocView(LOKDocView* pDocView) g_signal_connect(pDocView, "formula-changed", G_CALLBACK(lokdocview_formulaChanged), nullptr); g_signal_connect(pDocView, "password-required", G_CALLBACK(lokdocview_passwordRequired), nullptr); // g_signal_connect(pDocView, "comment", G_CALLBACK(lokdocview_commentCallback), nullptr); + + g_signal_connect(pDocView, "configure-event", G_CALLBACK(lokdocview_configureEvent), nullptr); } void diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.hxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.hxx index 2d4ee78d0e6d..2a872170ccc0 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.hxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.hxx @@ -25,6 +25,11 @@ struct _GtvApplicationWindow GtkWidget* scrolledwindow; GtkWidget* lokdocview; + LibreOfficeKitDocumentType doctype; + + GtkWidget* rowbar; + GtkWidget* columnbar; + GtkWidget* cornerarea; GtkWidget* statusbar; GtkWidget* zoomlabel; diff --git a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx new file mode 100644 index 000000000000..14fc944b50d4 --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx @@ -0,0 +1,223 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <gtk/gtk.h> + +#include <cmath> +#include <iostream> + +#include <gtv-application-window.hxx> +#include <gtv-signal-handlers.hxx> +#include <gtv-helpers.hxx> +#include <gtv-calc-header-bar.hxx> + +#include <map> +#include <boost/property_tree/json_parser.hpp> +#include <boost/optional.hpp> + +struct _GtvCalcHeaderBar +{ + GtkDrawingArea parent; +}; + +struct GtvCalcHeaderBarPrivateImpl +{ + /// 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) + { } + }; + + std::vector<Header> m_aHeaders; + /// Height for row bar, width for column bar. + int m_nSizePixel; + /// Left/top position for the column/row bar -- initially 0, then may grow due to scrolling. + int m_nPositionPixel; + CalcHeaderType m_eType; +}; + +struct GtvCalcHeaderBarPrivate +{ + GtvCalcHeaderBarPrivateImpl* m_pImpl; + + GtvCalcHeaderBarPrivateImpl* operator->() + { + return m_pImpl; + } +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GtvCalcHeaderBar, gtv_calc_header_bar, GTK_TYPE_DRAWING_AREA); + +static const int ROW_HEADER_WIDTH = 50; +static const int COLUMN_HEADER_HEIGHT = 20; + +static GtvCalcHeaderBarPrivate& +getPrivate(GtvCalcHeaderBar* headerbar) +{ + return *static_cast<GtvCalcHeaderBarPrivate*>(gtv_calc_header_bar_get_instance_private(headerbar)); +} + +static void +gtv_calc_header_bar_init(GtvCalcHeaderBar* bar) +{ + GtvCalcHeaderBarPrivate& priv = getPrivate(bar); + priv.m_pImpl = new GtvCalcHeaderBarPrivateImpl(); +} + +static void +gtv_calc_header_bar_finalize(GObject* object) +{ + GtvCalcHeaderBarPrivate& priv = getPrivate(GTV_CALC_HEADER_BAR(object)); + + delete priv.m_pImpl; + priv.m_pImpl = nullptr; + + G_OBJECT_CLASS (gtv_calc_header_bar_parent_class)->finalize (object); +} + +void gtv_calc_header_bar_draw_text(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 gtv_calc_header_bar_draw_impl(GtkWidget* pWidget, cairo_t* pCairo) +{ + GtvCalcHeaderBarPrivate& priv = getPrivate(GTV_CALC_HEADER_BAR(pWidget)); + cairo_set_source_rgb(pCairo, 0, 0, 0); + + int nPrevious = 0; + for (const GtvCalcHeaderBarPrivateImpl::Header& rHeader : priv->m_aHeaders) + { + GdkRectangle aRectangle; + if (priv->m_eType == CalcHeaderType::ROW) + { + aRectangle.x = 0; + aRectangle.y = nPrevious - 1; + aRectangle.width = ROW_HEADER_WIDTH - 1; + aRectangle.height = rHeader.m_nSize - nPrevious; + // Left line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); + // Bottom line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); + cairo_fill(pCairo); + // Right line. + cairo_rectangle(pCairo, aRectangle.width, aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); + } + else + { + aRectangle.x = nPrevious - 1; + aRectangle.y = 0; + aRectangle.width = rHeader.m_nSize - nPrevious; + aRectangle.height = COLUMN_HEADER_HEIGHT - 1; + // Top line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, aRectangle.width, 1); + cairo_fill(pCairo); + // Right line. + cairo_rectangle(pCairo, aRectangle.x + aRectangle.width , aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); + // Bottom line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.height, aRectangle.width, 1); + cairo_fill(pCairo); + } + + gtv_calc_header_bar_draw_text(pCairo, aRectangle, rHeader.m_aText); + nPrevious = rHeader.m_nSize; + if (rHeader.m_nSize > priv->m_nSizePixel) + break; + } + + return FALSE; +} + +static gboolean +gtv_calc_header_bar_draw(GtkWidget* bar, cairo_t* pCairo) +{ + return gtv_calc_header_bar_draw_impl(bar, pCairo); +} + +static void +gtv_calc_header_bar_class_init(GtvCalcHeaderBarClass* klass) +{ + // TODO: Use templates to bind objects maybe ? + // But that requires compiling the .ui file into C source requiring + // glib-compile-resources (another dependency) as I can't find any gtk + // method to set the template from the .ui file directly; can only be set + // from gresource + GTK_WIDGET_CLASS(klass)->draw = gtv_calc_header_bar_draw; + G_OBJECT_CLASS(klass)->finalize = gtv_calc_header_bar_finalize; +} + +int gtv_calc_header_bar_get_pos_pixel(GtvCalcHeaderBar* bar) +{ + GtvCalcHeaderBarPrivate& priv = getPrivate(bar); + return priv->m_nPositionPixel; +} + +int gtv_calc_header_bar_get_size_pixel(GtvCalcHeaderBar* bar) +{ + GtvCalcHeaderBarPrivate& priv = getPrivate(bar); + return priv->m_nSizePixel; +} + +void gtv_calc_header_bar_configure(GtvCalcHeaderBar* bar, const boost::property_tree::ptree* values, int nPositionPixel) +{ + GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(bar))); + GtvCalcHeaderBarPrivate& priv = getPrivate(bar); + + //gtk_widget_show(rWindow.m_pCornerButton->m_pDrawingArea); + boost::property_tree::ptree val = *values; + priv->m_aHeaders.clear(); + try + { + for (boost::property_tree::ptree::value_type& rValue : val) + { + int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(window->lokdocview), std::atof(rValue.second.get<std::string>("size").c_str()))); + if (nSize >= nPositionPixel) + { + const int nScrolledSize = nSize - nPositionPixel; + GtvCalcHeaderBarPrivateImpl::Header aHeader(nScrolledSize, rValue.second.get<std::string>("text")); + priv->m_aHeaders.push_back(aHeader); + } + } + } + catch (boost::property_tree::ptree_bad_path& rException) + { + std::cerr << "gtv_calc_header_bar_configure: " << rException.what() << std::endl; + } + gtk_widget_show(GTK_WIDGET(bar)); + gtk_widget_queue_draw(GTK_WIDGET(bar)); +} + +void +gtv_calc_header_bar_set_type(GtvCalcHeaderBar* bar, CalcHeaderType eType) +{ + // TODO: Install type property for this class + GtvCalcHeaderBarPrivate& priv = getPrivate(bar); + priv->m_eType = eType; +} + +GtkWidget* +gtv_calc_header_bar_new() +{ + return GTK_WIDGET(g_object_new(GTV_CALC_HEADER_BAR_TYPE, + nullptr)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.hxx b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.hxx new file mode 100644 index 000000000000..957b0104e916 --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef GTV_CALC_HEADER_BAR_H +#define GTV_CALC_HEADER_BAR_H + +#include <gtk/gtk.h> + +#include <boost/property_tree/json_parser.hpp> + +G_BEGIN_DECLS + +#define GTV_CALC_HEADER_BAR_TYPE (gtv_calc_header_bar_get_type()) +G_DECLARE_FINAL_TYPE(GtvCalcHeaderBar, gtv_calc_header_bar, GTV, CALC_HEADER_BAR, GtkDrawingArea); + +enum CalcHeaderType { ROW, COLUMN, CORNER }; + +GtkWidget* gtv_calc_header_bar_new(); + +void gtv_calc_header_bar_configure(GtvCalcHeaderBar* bar, const boost::property_tree::ptree* values, int nPositionPixel); + +int gtv_calc_header_bar_get_pos_pixel(GtvCalcHeaderBar* bar); + +int gtv_calc_header_bar_get_size_pixel(GtvCalcHeaderBar* bar); + +void gtv_calc_header_bar_set_type(GtvCalcHeaderBar* bar, CalcHeaderType eType); + +G_END_DECLS + +#endif /* GTV_CALC_HEADER_BAR_H */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx index 87db4fdcadab..ea1c10769e65 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx @@ -12,6 +12,7 @@ #include <gtv-application-window.hxx> #include <gtv-helpers.hxx> #include <gtv-signal-handlers.hxx> +#include <gtv-calc-header-bar.hxx> #include <boost/property_tree/json_parser.hpp> #include <boost/optional.hpp> @@ -218,4 +219,40 @@ void lokdocview_passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bMod void lokdocview_commentCallback(LOKDocView* pDocView, gchar* pComment, gpointer); +gboolean lokdocview_configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData) +{ + GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pWidget))); + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview)); + if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) + { + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(window->scrolledwindow)); + int rowSizePixel = gtk_adjustment_get_page_size(pVAdjustment); + int rowPosPixel = gtk_adjustment_get_value(pVAdjustment); + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(window->scrolledwindow)); + int colSizePixel = gtk_adjustment_get_page_size(pHAdjustment); + int colPosPixel = gtk_adjustment_get_value(pHAdjustment); + + std::stringstream aCommand; + aCommand << ".uno:ViewRowColumnHeaders"; + aCommand << "?x=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(window->lokdocview), colPosPixel)); + aCommand << "&width=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(window->lokdocview), colSizePixel)); + aCommand << "&y=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(window->lokdocview), rowPosPixel)); + aCommand << "&height=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(window->lokdocview), rowSizePixel)); + std::stringstream ss; + ss << "lok::Document::getCommandValues(" << aCommand.str() << ")"; + g_info("%s", ss.str().c_str()); + char* pValues = pDocument->pClass->getCommandValues(pDocument, aCommand.str().c_str()); + g_info("lok::Document::getCommandValues() returned '%s'", pValues); + std::stringstream aStream(pValues); + free(pValues); + assert(!aStream.str().empty()); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + + gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->rowbar), &aTree.get_child("rows"), rowPosPixel); + gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->columnbar), &aTree.get_child("columns"), colPosPixel); +// for corner ? gtv_calc_header_bar_configure(window->rowbar); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx index 72013be9a741..7466684a0d1e 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx @@ -24,6 +24,7 @@ void lokdocview_addressChanged(LOKDocView* pDocView, char* pPayload, gpointer); void lokdocview_formulaChanged(LOKDocView* pDocView, char* pPayload, gpointer); void lokdocview_passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer); void lokdocview_commentCallback(LOKDocView* pDocView, gchar* pComment, gpointer); +gboolean lokdocview_configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); #endif diff --git a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx index 884a2c76ac71..4a143e9ea665 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx @@ -13,6 +13,7 @@ #include <gtv-main-toolbar.hxx> #include <gtv-signal-handlers.hxx> #include <gtv-helpers.hxx> +#include <gtv-calc-header-bar.hxx> #include <map> #include <boost/property_tree/json_parser.hpp> |