diff options
author | Pranav Kant <pranavk@collabora.co.uk> | 2017-07-05 13:59:11 +0530 |
---|---|---|
committer | Pranav Kant <pranavk@collabora.co.uk> | 2017-07-05 16:41:33 +0530 |
commit | e9bc71ef452650a0ea350ffab8a54fecc29d2a6c (patch) | |
tree | 4144ec61b467ac489f58d0d42fb2c52958a82810 | |
parent | a1709e10022995bb5305bfd6b7eab7618dcdf917 (diff) |
Separate signal handler file and impelment copy/paste
Change-Id: I08639feb0c1a2c47e5a7bd0ecfa3b72033c632e5
5 files changed, 276 insertions, 18 deletions
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx new file mode 100644 index 000000000000..ce6989c382f5 --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx @@ -0,0 +1,86 @@ +/* -*- 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 <cstring> + +#include <gtv-helpers.hxx> + +void +userPromptDialog(GtkWindow* pWindow, const std::string& aTitle, std::map<std::string, std::string>& aEntries) +{ + GtkWidget* pDialog = gtk_dialog_new_with_buttons (aTitle.c_str(), + pWindow, + GTK_DIALOG_MODAL, + "Ok", + GTK_RESPONSE_OK, + nullptr); + + GtkWidget* pDialogMessageArea = gtk_dialog_get_content_area (GTK_DIALOG (pDialog)); + GtkWidget* pEntryArea = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(pDialogMessageArea), pEntryArea); + for (const auto& entry : aEntries) + { + GtkWidget* pEntry = gtk_entry_new(); +#if GTK_CHECK_VERSION(3,2,0) + gtk_entry_set_placeholder_text(GTK_ENTRY(pEntry), entry.first.c_str()); +#endif + gtk_container_add(GTK_CONTAINER(pEntryArea), pEntry); + } + + gtk_widget_show_all(pDialog); + + gint res = gtk_dialog_run(GTK_DIALOG(pDialog)); + switch(res) + { + case GTK_RESPONSE_OK: + GList* pList = gtk_container_get_children(GTK_CONTAINER(pEntryArea)); + + for (GList* l = pList; l != nullptr; l = l->next) + { + const gchar* pKey = gtk_entry_get_placeholder_text(GTK_ENTRY(l->data)); + aEntries[std::string(pKey)] = std::string(gtk_entry_get_text(GTK_ENTRY(l->data))); + } + break; + } + + gtk_widget_destroy(pDialog); +} + +/// Our GtkClipboardGetFunc implementation for HTML. +static void htmlGetFunc(GtkClipboard* /*pClipboard*/, GtkSelectionData* pSelectionData, guint /*info*/, gpointer pUserData) +{ + GdkAtom aAtom(gdk_atom_intern("text/html", false)); + const gchar* pSelection = static_cast<const gchar*>(pUserData); + gtk_selection_data_set(pSelectionData, aAtom, 8, reinterpret_cast<const guchar *>(pSelection), strlen(pSelection)); +} + +/// Our GtkClipboardClearFunc implementation for HTML. +static void htmlClearFunc(GtkClipboard* /*pClipboard*/, gpointer pData) +{ + g_free(pData); +} + +void +clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelection) +{ + GtkTargetList* pList = gtk_target_list_new(nullptr, 0); + GdkAtom aAtom(gdk_atom_intern("text/html", false)); + gtk_target_list_add(pList, aAtom, 0, 0); + gint nTargets = 0; + GtkTargetEntry* pTargets = gtk_target_table_new_from_list(pList, &nTargets); + + gtk_clipboard_set_with_data(pClipboard, pTargets, nTargets, htmlGetFunc, htmlClearFunc, g_strdup(pSelection)); + + gtk_target_table_free(pTargets, nTargets); + gtk_target_list_unref(pList); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx new file mode 100644 index 000000000000..627eb2701644 --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx @@ -0,0 +1,24 @@ +/* -*- 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_HELPERS_H +#define GTV_HELPERS_H + +#include <gtk/gtk.h> + +#include <string> +#include <map> + +void userPromptDialog(GtkWindow* pWindow, const std::string& aTitle, std::map<std::string, std::string>& aEntries); + +void clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelection); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx index b00501b0e10a..ea91347cd09f 100644 --- a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx @@ -11,6 +11,12 @@ #include <gtv-application-window.hxx> #include <gtv-main-toolbar.hxx> +#include <gtv-signal-handlers.hxx> +#include <gtv-helpers.hxx> + +#include <map> +#include <boost/property_tree/json_parser.hpp> +#include <boost/optional.hpp> struct _GtvMainToolbar { @@ -35,21 +41,6 @@ getPrivate(GtvMainToolbar* toolbar) } static void -btn_clicked(GtkWidget* pWidget, gpointer) -{ - GApplication* app = g_application_get_default(); - GtkWindow* window = gtk_application_get_active_window(GTK_APPLICATION(app)); - - GtkToolButton* pItem = GTK_TOOL_BUTTON(pWidget); - const gchar* unoCmd = gtk_tool_button_get_label(pItem); - LOKDocView* lokdocview = gtv_application_window_get_lokdocview(GTV_APPLICATION_WINDOW(window)); - if (lokdocview) - { - lok_doc_view_post_command(lokdocview, unoCmd, nullptr, false); - } -} - -static void gtv_main_toolbar_init(GtvMainToolbar* toolbar) { GtkBuilder* builder = gtk_builder_new_from_file("gtv.ui"); @@ -60,10 +51,9 @@ gtv_main_toolbar_init(GtvMainToolbar* toolbar) priv->toolbar2 = GTK_WIDGET(gtk_builder_get_object(builder, "toolbar2")); gtk_box_pack_start(GTK_BOX(toolbar), priv->toolbar2, false, false, false); - priv->btn_save = GTK_WIDGET(gtk_builder_get_object(builder, "btn_save")); - priv->btn_bold = GTK_WIDGET(gtk_builder_get_object(builder, "btn_bold")); - gtk_builder_add_callback_symbol(builder, "btn_clicked", G_CALLBACK(btn_clicked)); + gtk_builder_add_callback_symbol(builder, "doCopy", G_CALLBACK(doCopy)); + gtk_builder_add_callback_symbol(builder, "doPaste", G_CALLBACK(doPaste)); gtk_builder_connect_signals(builder, nullptr); gtk_widget_show_all(GTK_WIDGET(toolbar)); diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx new file mode 100644 index 000000000000..c3ef94099196 --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx @@ -0,0 +1,135 @@ +/* -*- 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 <gtv-application-window.hxx> +#include <gtv-helpers.hxx> + +#include <map> +#include <vector> + +#include <boost/property_tree/json_parser.hpp> +#include <boost/optional.hpp> + +void btn_clicked(GtkWidget* pWidget, gpointer) +{ + GApplication* app = g_application_get_default(); + GtkWindow* window = gtk_application_get_active_window(GTK_APPLICATION(app)); + + GtkToolButton* pItem = GTK_TOOL_BUTTON(pWidget); + const gchar* label = gtk_tool_button_get_label(pItem); + if (g_str_has_prefix(label, ".uno:")) + { + std::string aArguments; + if (g_strcmp0(label, ".uno:InsertAnnotation") == 0) + { + std::map<std::string, std::string> aEntries; + aEntries["Text"] = ""; + userPromptDialog(window, "Insert Comment", aEntries); + + boost::property_tree::ptree aTree; + aTree.put(boost::property_tree::ptree::path_type(g_strconcat("Text", "/", "type", nullptr), '/'), "string"); + aTree.put(boost::property_tree::ptree::path_type(g_strconcat("Text", "/", "value", nullptr), '/'), aEntries["Text"]); + + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + aArguments = aStream.str(); + } + + bool bNotify = g_strcmp0(label, ".uno:Save") == 0; + LOKDocView* lokdocview = gtv_application_window_get_lokdocview(GTV_APPLICATION_WINDOW(window)); + if (lokdocview) + lok_doc_view_post_command(lokdocview, label, aArguments.c_str(), bNotify); + } +} + +void doCopy(GtkWidget* pButton, gpointer /*pItem*/) +{ + GApplication* app = g_application_get_default(); + GtkWindow* window = gtk_application_get_active_window(GTK_APPLICATION(app)); + LOKDocView* pLOKDocView = gtv_application_window_get_lokdocview(GTV_APPLICATION_WINDOW(window)); + char* pUsedFormat = nullptr; + // TODO: Should check `text-selection` signal before trying to copy + char* pSelection = lok_doc_view_copy_selection(pLOKDocView, "text/html", &pUsedFormat); + if (!pSelection) + return; + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(pButton), GDK_SELECTION_CLIPBOARD); + std::string aUsedFormat(pUsedFormat); + if (aUsedFormat == "text/plain;charset=utf-8") + gtk_clipboard_set_text(pClipboard, pSelection, -1); + else + clipboardSetHtml(pClipboard, pSelection); + + free(pSelection); + free(pUsedFormat); +} + +void doPaste(GtkWidget* pButton, gpointer /*pItem*/) +{ + GApplication* app = g_application_get_default(); + GtkWindow* window = gtk_application_get_active_window(GTK_APPLICATION(app)); + LOKDocView* pLOKDocView = gtv_application_window_get_lokdocview(GTV_APPLICATION_WINDOW(window)); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(pButton), GDK_SELECTION_CLIPBOARD); + GdkAtom* pTargets; + gint nTargets; + std::map<std::string, GdkAtom> aTargets; + if (gtk_clipboard_wait_for_targets(pClipboard, &pTargets, &nTargets)) + { + for (gint i = 0; i < nTargets; ++i) + { + gchar* pName = gdk_atom_name(pTargets[i]); + aTargets[pName] = pTargets[i]; + g_free(pName); + } + g_free(pTargets); + } + + boost::optional<GdkAtom> oTarget; + std::string aTargetName; + + std::vector<std::string> aPreferredNames = + { + std::string("image/png"), + std::string("text/html") + }; + for (const std::string& rName : aPreferredNames) + { + std::map<std::string, GdkAtom>::iterator it = aTargets.find(rName); + if (it != aTargets.end()) + { + aTargetName = it->first; + oTarget = it->second; + break; + } + } + + if (oTarget) + { + GtkSelectionData* pSelectionData = gtk_clipboard_wait_for_contents(pClipboard, *oTarget); + if (!pSelectionData) + { + return; + } + gint nLength; + const guchar* pData = gtk_selection_data_get_data_with_length(pSelectionData, &nLength); + bool bSuccess = lok_doc_view_paste(pLOKDocView, aTargetName.c_str(), reinterpret_cast<const char*>(pData), nLength); + gtk_selection_data_free(pSelectionData); + if (bSuccess) + return; + } + + gchar* pText = gtk_clipboard_wait_for_text(pClipboard); + if (pText) + lok_doc_view_paste(pLOKDocView, "text/plain;charset=utf-8", pText, strlen(pText)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx new file mode 100644 index 000000000000..bc6b6ab2c97b --- /dev/null +++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx @@ -0,0 +1,23 @@ +/* -*- 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_SIGNAL_HANDLERS_H +#define GTV_SIGNAL_HANDLERS_H + +#include <gtk/gtk.h> + +void btn_clicked(GtkWidget* pWidget, gpointer); + +void doCopy(GtkWidget* pButton, gpointer /*pItem*/); + +void doPaste(GtkWidget* pButton, gpointer /*pItem*/); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |