summaryrefslogtreecommitdiff
path: root/libreofficekit
diff options
context:
space:
mode:
Diffstat (limited to 'libreofficekit')
-rw-r--r--libreofficekit/Executable_gtktiledviewer.mk7
-rw-r--r--libreofficekit/Executable_tilebench.mk2
-rw-r--r--libreofficekit/Library_libreofficekitgtk.mk7
-rw-r--r--libreofficekit/Module_libreofficekit.mk12
-rw-r--r--libreofficekit/README.md13
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx11
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx6
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx7
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx29
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx98
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx1
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx10
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.hxx2
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx94
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx5
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv.ui122
-rw-r--r--libreofficekit/qa/tilebench/tilebench.cxx66
-rw-r--r--libreofficekit/qa/unit/checkapi.cxx5
-rw-r--r--libreofficekit/qa/unit/test.h2
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx305
-rw-r--r--libreofficekit/source/gtk/tilebuffer.cxx7
-rw-r--r--libreofficekit/source/gtk/tilebuffer.hxx2
22 files changed, 586 insertions, 227 deletions
diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk
index 99ef51af8975..b2383ee0c964 100644
--- a/libreofficekit/Executable_gtktiledviewer.mk
+++ b/libreofficekit/Executable_gtktiledviewer.mk
@@ -29,12 +29,17 @@ $(eval $(call gb_Executable_add_cxxflags,gtktiledviewer,\
$(eval $(call gb_Executable_add_libs,gtktiledviewer,\
$(GTK3_LIBS) \
+))
+
+ifneq ($(OS), WNT)
+$(eval $(call gb_Executable_add_libs,gtktiledviewer,\
-lX11 \
-lXext \
-lXrender \
-lSM \
-lICE \
))
+endif
$(eval $(call gb_Executable_use_libraries,gtktiledviewer,\
libreofficekitgtk \
@@ -42,7 +47,7 @@ $(eval $(call gb_Executable_use_libraries,gtktiledviewer,\
ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
$(eval $(call gb_Executable_add_libs,gtktiledviewer,\
- -lm $(DLOPEN_LIBS) \
+ -lm $(UNIX_DLAPI_LIBS) \
))
endif
diff --git a/libreofficekit/Executable_tilebench.mk b/libreofficekit/Executable_tilebench.mk
index ae0a3b1f099b..e4a7908dc02b 100644
--- a/libreofficekit/Executable_tilebench.mk
+++ b/libreofficekit/Executable_tilebench.mk
@@ -23,7 +23,7 @@ $(eval $(call gb_Executable_use_libraries,tilebench,\
))
$(eval $(call gb_Executable_add_libs,tilebench,\
- -lm $(DLOPEN_LIBS) \
+ -lm $(UNIX_DLAPI_LIBS) \
))
$(eval $(call gb_Executable_add_exception_objects,tilebench,\
diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk
index 842bce6ac993..4430c039703b 100644
--- a/libreofficekit/Library_libreofficekitgtk.mk
+++ b/libreofficekit/Library_libreofficekitgtk.mk
@@ -31,12 +31,17 @@ $(eval $(call gb_Library_add_libs,libreofficekitgtk,\
$(eval $(call gb_Library_add_defs,libreofficekitgtk,\
-DLOK_PATH="\"$(LIBDIR)/libreoffice/$(LIBO_LIB_FOLDER)\"" \
+ -DLOK_DOC_VIEW_IMPLEMENTATION \
))
ifeq ($(OS),$(filter LINUX %BSD SOLARIS, $(OS)))
$(eval $(call gb_Library_add_libs,libreofficekitgtk,\
- $(DLOPEN_LIBS) -lm \
+ $(UNIX_DLAPI_LIBS) -lm \
))
endif
+$(eval $(call gb_Library_use_packages,libreofficekitgtk, \
+ libreofficekit_selectionhandles \
+))
+
# vim: set noet sw=4 ts=4:
diff --git a/libreofficekit/Module_libreofficekit.mk b/libreofficekit/Module_libreofficekit.mk
index 351f89a33e48..7452b2da3f8f 100644
--- a/libreofficekit/Module_libreofficekit.mk
+++ b/libreofficekit/Module_libreofficekit.mk
@@ -28,11 +28,21 @@ $(eval $(call gb_Module_add_targets,libreofficekit,\
endif # ($(ENABLE_GTK3),)
$(eval $(call gb_Module_add_targets,libreofficekit,\
- Executable_tilebench \
+ $(if $(DISABLE_DYNLOADING),,Executable_tilebench) \
Package_selectionhandles \
UIConfig_libreofficekit \
))
+else ifeq ($(OS),WNT)
+
+ifneq ($(ENABLE_GTKTILEDVIEWER),)
+$(eval $(call gb_Module_add_targets,libreofficekit,\
+ Library_libreofficekitgtk \
+ Executable_gtktiledviewer \
+ Package_selectionhandles \
+))
+endif
+
endif
# vim: set ts=4 sw=4 et:
diff --git a/libreofficekit/README.md b/libreofficekit/README.md
index 7eb7bb5fd355..95a33707a28a 100644
--- a/libreofficekit/README.md
+++ b/libreofficekit/README.md
@@ -97,6 +97,19 @@ To debug with `gdb`:
before `bin/run`, this will run gtktiledviewer in the debugger instead.
+### Building and running gtktiledviewer on Windows
+
+A pre-requisite is pre-built GTK3 libraries. See [official GTK documentation](https://www.gtk.org/docs/installations/windows/).
+Building of gtktiledviewer on Windows is enabled by passing
+
+ --with-gtk3-build=<path/to/GTK3/build/directory>
+
+to configure.
+
+Running the compiled executable requires GTK's bin in PATH:
+
+ PATH=${PATH}:/cygdrive/c/gtk-build/gtk/x64/release/bin bin/run gtktiledviewer --lo-path=$(cygpath -am $PWD/instdir/program) ../test.odt
+
## LibreOfficeKitGtk
Currently consists of only a very basic GTK document viewer widget.
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
index 4d2dbd41f251..ef2f26917b30 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
@@ -148,16 +148,21 @@ static void initWindow(GtvApplicationWindow* window)
{
GtvApplicationWindowPrivate* priv = getPrivate(window);
-#ifdef __GNUC__
+#if defined __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif defined _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4996)
#endif
GList *focusChain = nullptr;
focusChain = g_list_append( focusChain, window->lokdocview );
gtk_container_set_focus_chain ( GTK_CONTAINER (priv->container), focusChain );
-#ifdef __GNUC__
+#if defined __GNUC__
#pragma GCC diagnostic pop
+#elif defined _MSC_VER
+#pragma warning(pop)
#endif
// TODO: Implement progressbar in statusbar
@@ -331,6 +336,8 @@ static void setupDocView(GtvApplicationWindow* window)
g_signal_connect(window->lokdocview, "search-result-count", G_CALLBACK(LOKDocViewSigHandlers::searchResultCount), nullptr);
g_signal_connect(window->lokdocview, "part-changed", G_CALLBACK(LOKDocViewSigHandlers::partChanged), nullptr);
g_signal_connect(window->lokdocview, "hyperlink-clicked", G_CALLBACK(LOKDocViewSigHandlers::hyperlinkClicked), nullptr);
+ g_signal_connect(window->lokdocview, "content-control",
+ G_CALLBACK(LOKDocViewSigHandlers::contentControl), nullptr);
g_signal_connect(window->lokdocview, "cursor-changed", G_CALLBACK(LOKDocViewSigHandlers::cursorChanged), nullptr);
g_signal_connect(window->lokdocview, "address-changed", G_CALLBACK(LOKDocViewSigHandlers::addressChanged), nullptr);
g_signal_connect(window->lokdocview, "formula-changed", G_CALLBACK(LOKDocViewSigHandlers::formulaChanged), nullptr);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
index dc106e58dcb4..6019050236e8 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-calc-header-bar.cxx
@@ -11,11 +11,13 @@
#include <cmath>
#include <iostream>
+#include <vector>
#include "gtv-calc-header-bar.hxx"
#include <boost/property_tree/ptree.hpp>
#include <o3tl/unreachable.hxx>
+#include <utility>
namespace {
@@ -26,9 +28,9 @@ struct GtvCalcHeaderBarPrivateImpl
{
int m_nSize;
std::string m_aText;
- Header(int nSize, const std::string& rText)
+ Header(int nSize, std::string aText)
: m_nSize(nSize),
- m_aText(rText)
+ m_aText(std::move(aText))
{ }
};
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
index b557fe4ba99b..f2c1e9b9351a 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
@@ -9,8 +9,6 @@
#include <gtk/gtk.h>
-#include <pwd.h>
-
#include <cstring>
#include "gtv-helpers.hxx"
@@ -94,8 +92,9 @@ void GtvHelpers::clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelecti
std::string GtvHelpers::getNextAuthor()
{
static int nCounter = 0;
- struct passwd* pPasswd = getpwuid(getuid());
- return std::string(pPasswd->pw_gecos) + " #" + std::to_string(++nCounter);
+ const gchar* pname = g_get_real_name();
+ std::string name = pname ? std::string(pname) : std::string();
+ return name + " #" + std::to_string(++nCounter);
}
GtkWidget* GtvHelpers::createCommentBox(const boost::property_tree::ptree& aComment)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index a67d3427eae5..f23148eaf2f9 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -11,7 +11,6 @@
#include <gdk/gdkkeysyms.h>
#include <iostream>
-#include <sstream>
#include <LibreOfficeKit/LibreOfficeKitGtk.h>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -20,6 +19,8 @@
#include "gtv-lok-dialog.hxx"
#include <com/sun/star/awt/Key.hpp>
+
+#include <o3tl/unit_conversion.hxx>
#include <vcl/event.hxx>
namespace {
@@ -83,20 +84,6 @@ getPrivate(GtvLokDialog* dialog)
return static_cast<GtvLokDialogPrivate*>(gtv_lok_dialog_get_instance_private(dialog));
}
-static float
-pixelToTwip(float fInput)
-{
- return (fInput / 96 / 1.0 /* zoom */) * 1440.0f;
-}
-
-#if 0
-static float
-twipToPixel(float fInput)
-{
- return fInput / 1440.0f * 96 * 1.0 /* zoom */;
-}
-#endif
-
static void
gtv_lok_dialog_draw(GtkWidget* pDialogDrawingArea, cairo_t* pCairo, gpointer)
{
@@ -235,8 +222,8 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
static_cast<int>(pEvent->x), static_cast<int>(pEvent->y),
- static_cast<int>(pixelToTwip(pEvent->x)),
- static_cast<int>(pixelToTwip(pEvent->y)));
+ static_cast<int>(o3tl::toTwips(pEvent->x, o3tl::Length::px)),
+ static_cast<int>(o3tl::toTwips(pEvent->y, o3tl::Length::px)));
pDocument->pClass->postWindowMouseEvent(pDocument,
priv->dialogid,
@@ -531,8 +518,8 @@ gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/
g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
aEventType.c_str(),
static_cast<int>(pEvent->x), static_cast<int>(pEvent->y),
- static_cast<int>(pixelToTwip(pEvent->x)),
- static_cast<int>(pixelToTwip(pEvent->y)));
+ static_cast<int>(o3tl::toTwips(pEvent->x, o3tl::Length::px)),
+ static_cast<int>(o3tl::toTwips(pEvent->y, o3tl::Length::px)));
switch (pEvent->type)
{
@@ -614,8 +601,8 @@ gtv_lok_dialog_floating_win_signal_motion(GtkWidget* /*pDialogDrawingArea*/, Gdk
g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
static_cast<int>(pEvent->x), static_cast<int>(pEvent->y),
- static_cast<int>(pixelToTwip(pEvent->x)),
- static_cast<int>(pixelToTwip(pEvent->y)));
+ static_cast<int>(o3tl::toTwips(pEvent->x, o3tl::Length::px)),
+ static_cast<int>(o3tl::toTwips(pEvent->y, o3tl::Length::px)));
pDocument->pClass->postWindowMouseEvent(pDocument,
priv->m_nChildId,
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 90b96e57488a..520472f201e5 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -202,6 +202,39 @@ void LOKDocViewSigHandlers::formulaChanged(LOKDocView* pDocView, char* pPayload,
gtk_entry_set_text(pFormulabar, pPayload);
}
+void LOKDocViewSigHandlers::contentControl(LOKDocView* pDocView, gchar* pJson, gpointer)
+{
+ GtvApplicationWindow* window
+ = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
+ GtvMainToolbar* toolbar = gtv_application_window_get_main_toolbar(window);
+ gtv_application_window_set_part_broadcast(window, false);
+ gtk_list_store_clear(
+ GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(toolbar->m_pContentControlSelector))));
+ if (!window->lokdocview)
+ {
+ return;
+ }
+
+ std::stringstream aStream(pJson);
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aStream, aTree);
+ boost::optional<boost::property_tree::ptree&> oItems = aTree.get_child_optional("items");
+ if (oItems)
+ {
+ for (const auto& rItem : *oItems)
+ {
+ std::string aValue = rItem.second.get_value<std::string>();
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(toolbar->m_pContentControlSelector),
+ aValue.c_str());
+ }
+ }
+
+ boost::optional<boost::property_tree::ptree&> oDate = aTree.get_child_optional("date");
+ gtk_widget_set_sensitive(GTK_WIDGET(toolbar->m_pContentControlDateSelector), bool(oDate));
+
+ gtv_application_window_set_part_broadcast(window, true);
+}
+
void LOKDocViewSigHandlers::passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
@@ -334,6 +367,11 @@ void LOKDocViewSigHandlers::window(LOKDocView* pDocView, gchar* pPayload, gpoint
{
const unsigned nParentId = std::atoi(aRoot.get<std::string>("parentId").c_str());
GtkWindow* pDialog = gtv_application_window_get_child_window_by_id(window, nParentId);
+ if (!pDialog)
+ {
+ g_warning("no parent dialog (id: %d) for created child; is child a sidebar?", nParentId);
+ return;
+ }
const std::string aPos = aRoot.get<std::string>("position");
std::vector<int> aPosPoints = GtvHelpers::split<int>(aPos, ", ", 2);
gtv_lok_dialog_child_create(GTV_LOK_DIALOG(pDialog), nWinId, aPosPoints[0], aPosPoints[1], aSizePoints[0], aSizePoints[1]);
@@ -409,36 +447,36 @@ gboolean LOKDocViewSigHandlers::configureEvent(GtkWidget* pWidget, GdkEventConfi
}
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 = GTV_CALC_HEADER_BAR(window->rowbar)->m_nSizePixel = gtk_adjustment_get_page_size(pVAdjustment);
- int rowPosPixel = GTV_CALC_HEADER_BAR(window->rowbar)->m_nPositionPixel = gtk_adjustment_get_value(pVAdjustment);
- GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(window->scrolledwindow));
- int colSizePixel = GTV_CALC_HEADER_BAR(window->columnbar)->m_nSizePixel = gtk_adjustment_get_page_size(pHAdjustment);
- int colPosPixel = GTV_CALC_HEADER_BAR(window->columnbar)->m_nPositionPixel = 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"));
- gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->columnbar), &aTree.get_child("columns"));
- gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->cornerarea), nullptr);
- }
+ if (!pDocument || pDocument->pClass->getDocumentType(pDocument) != LOK_DOCTYPE_SPREADSHEET)
+ return true;
+
+ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(window->scrolledwindow));
+ int rowSizePixel = GTV_CALC_HEADER_BAR(window->rowbar)->m_nSizePixel = gtk_adjustment_get_page_size(pVAdjustment);
+ int rowPosPixel = GTV_CALC_HEADER_BAR(window->rowbar)->m_nPositionPixel = gtk_adjustment_get_value(pVAdjustment);
+ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(window->scrolledwindow));
+ int colSizePixel = GTV_CALC_HEADER_BAR(window->columnbar)->m_nSizePixel = gtk_adjustment_get_page_size(pHAdjustment);
+ int colPosPixel = GTV_CALC_HEADER_BAR(window->columnbar)->m_nPositionPixel = 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"));
+ gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->columnbar), &aTree.get_child("columns"));
+ gtv_calc_header_bar_configure(GTV_CALC_HEADER_BAR(window->cornerarea), nullptr);
return true;
}
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
index 41fc73ab1a07..0c5bb7113e26 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
@@ -27,6 +27,7 @@ namespace LOKDocViewSigHandlers {
void passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer);
void comment(LOKDocView* pDocView, gchar* pComment, gpointer);
void window(LOKDocView* pDocView, gchar* pPayload, gpointer);
+ void contentControl(LOKDocView* pDocView, gchar* pComment, gpointer);
gboolean configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData);
}
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx
index 73ff6042e911..7127581856fc 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx
@@ -16,6 +16,7 @@
#include <LibreOfficeKit/LibreOfficeKitGtk.h>
+#include <algorithm>
#include <fstream>
#include <map>
#include <memory>
@@ -116,6 +117,10 @@ gtv_main_toolbar_init(GtvMainToolbar* toolbar)
toolbar->m_pAddressbar = GTK_WIDGET(gtk_builder_get_object(builder.get(), "addressbar_entry"));
toolbar->m_pFormulabar = GTK_WIDGET(gtk_builder_get_object(builder.get(), "formulabar_entry"));
+ toolbar->m_pContentControlSelector
+ = GTK_WIDGET(gtk_builder_get_object(builder.get(), "combo_contentcontrolselector"));
+ toolbar->m_pContentControlDateSelector
+ = GTK_WIDGET(gtk_builder_get_object(builder.get(), "menu_contentcontroldateselector"));
// TODO: compile with -rdynamic and get rid of it
gtk_builder_add_callback_symbol(builder.get(), "btn_clicked", G_CALLBACK(btn_clicked));
@@ -125,9 +130,14 @@ gtv_main_toolbar_init(GtvMainToolbar* toolbar)
gtk_builder_add_callback_symbol(builder.get(), "getRulerState", G_CALLBACK(getRulerState));
gtk_builder_add_callback_symbol(builder.get(), "recentUnoChanged", G_CALLBACK(recentUnoChanged));
gtk_builder_add_callback_symbol(builder.get(), "unoCommandDebugger", G_CALLBACK(unoCommandDebugger));
+ gtk_builder_add_callback_symbol(builder.get(), "commandValuesDebugger", G_CALLBACK(commandValuesDebugger));
gtk_builder_add_callback_symbol(builder.get(), "toggleEditing", G_CALLBACK(toggleEditing));
gtk_builder_add_callback_symbol(builder.get(), "changePartMode", G_CALLBACK(changePartMode));
gtk_builder_add_callback_symbol(builder.get(), "changePart", G_CALLBACK(changePart));
+ gtk_builder_add_callback_symbol(builder.get(), "changeContentControl",
+ G_CALLBACK(changeContentControl));
+ gtk_builder_add_callback_symbol(builder.get(), "changeDateContentControl",
+ G_CALLBACK(changeDateContentControl));
gtk_builder_add_callback_symbol(builder.get(), "changeZoom", G_CALLBACK(changeZoom));
gtk_builder_add_callback_symbol(builder.get(), "toggleFindbar", G_CALLBACK(toggleFindbar));
gtk_builder_add_callback_symbol(builder.get(), "documentRedline", G_CALLBACK(documentRedline));
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.hxx b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.hxx
index 0930228fda59..91827ef92695 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.hxx
@@ -29,6 +29,8 @@ struct GtvMainToolbar
GtkWidget* m_pAddressbar;
GtkWidget* m_pFormulabar;
+ GtkWidget* m_pContentControlSelector;
+ GtkWidget* m_pContentControlDateSelector;
};
struct GtvMainToolbarClass
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
index be7cd4445536..1f2520162c10 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
@@ -16,6 +16,7 @@
#include <sal/macros.h>
+#include <cassert>
#include <map>
#include <vector>
@@ -186,8 +187,9 @@ static void iterateUnoParams(GtkWidget* pWidget, gpointer userdata)
GList* pIt = nullptr;
guint i = 0;
const gchar* unoParam[3];
- for (pIt = pChildren.get(), i = 0; pIt != nullptr && i < 3; pIt = pIt->next, i++)
+ for (pIt = pChildren.get(), i = 0; i < 3; pIt = pIt->next, i++)
{
+ assert(pIt != nullptr);
unoParam[i] = gtk_entry_get_text(GTK_ENTRY(pIt->data));
}
@@ -282,6 +284,41 @@ void unoCommandDebugger(GtkWidget* pButton, gpointer /* pItem */)
gtk_widget_destroy(pUnoCmdDialog);
}
+void commandValuesDebugger(GtkWidget* pButton, gpointer /* pItem */)
+{
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(pButton));
+ GtkWidget* pUnoCmdDialog = gtk_dialog_new_with_buttons ("Get command values",
+ GTK_WINDOW (window),
+ GTK_DIALOG_MODAL,
+ "Execute",
+ GTK_RESPONSE_OK,
+ nullptr);
+ g_object_set(G_OBJECT(pUnoCmdDialog), "resizable", FALSE, nullptr);
+ GtkWidget* pDialogMessageArea = gtk_dialog_get_content_area (GTK_DIALOG (pUnoCmdDialog));
+ GtkWidget* pUnoCmdAreaBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start(GTK_BOX(pDialogMessageArea), pUnoCmdAreaBox, true, true, 2);
+
+ GtkWidget* pUnoCmdLabel = gtk_label_new("Enter UNO command");
+ gtk_box_pack_start(GTK_BOX(pUnoCmdAreaBox), pUnoCmdLabel, true, true, 2);
+
+ GtkWidget* pUnoCmdEntry = gtk_entry_new ();
+ gtk_box_pack_start(GTK_BOX(pUnoCmdAreaBox), pUnoCmdEntry, true, true, 2);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(pUnoCmdEntry), "e.g. .uno:Undo");
+
+ gtk_widget_show_all(pUnoCmdDialog);
+
+ gint res = gtk_dialog_run (GTK_DIALOG(pUnoCmdDialog));
+ if (res == GTK_RESPONSE_OK)
+ {
+ const gchar* pUnoCmd = gtk_entry_get_text(GTK_ENTRY(pUnoCmdEntry));
+ gchar* pValues = lok_doc_view_get_command_values(LOK_DOC_VIEW(window->lokdocview), pUnoCmd);
+ g_info("lok::Document::getCommandValues(%s) : %s", pUnoCmd, pValues);
+ g_free(pValues);
+ }
+
+ gtk_widget_destroy(pUnoCmdDialog);
+}
+
void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(pButton));
@@ -316,6 +353,49 @@ void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ )
}
}
+void changeContentControl(GtkWidget* pSelector, gpointer /*pItem*/)
+{
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(pSelector));
+ if (gtv_application_window_get_part_broadcast(window) && window->lokdocview)
+ {
+ int nItem = gtk_combo_box_get_active(GTK_COMBO_BOX(pSelector));
+ boost::property_tree::ptree aValues;
+ aValues.put("type", "drop-down");
+ aValues.put("selected", std::to_string(nItem));
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aValues);
+ std::string aJson = aStream.str();
+ lok_doc_view_send_content_control_event(LOK_DOC_VIEW(window->lokdocview), aJson.c_str());
+ }
+}
+
+void changeDateContentControl(GtkWidget* pSelector, gpointer /*pItem*/)
+{
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(pSelector));
+ if (gtv_application_window_get_part_broadcast(window) && window->lokdocview)
+ {
+ GtkPopover* pPopover = GTK_POPOVER(gtk_widget_get_parent(gtk_widget_get_parent(pSelector)));
+ guint nYear, nMonth, nDay;
+ gtk_calendar_get_date(GTK_CALENDAR(pSelector), &nYear, &nMonth, &nDay);
+ gtk_popover_popdown(pPopover);
+
+ std::stringstream aDate;
+ aDate << std::setfill('0') << std::setw(4) << nYear;
+ aDate << "-";
+ aDate << std::setfill('0') << std::setw(2) << (nMonth + 1);
+ aDate << "-";
+ aDate << std::setfill('0') << std::setw(2) << nDay;
+ aDate << "T00:00:00Z";
+ boost::property_tree::ptree aValues;
+ aValues.put("type", "date");
+ aValues.put("selected", aDate.str());
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aValues);
+ std::string aJson = aStream.str();
+ lok_doc_view_send_content_control_event(LOK_DOC_VIEW(window->lokdocview), aJson.c_str());
+ }
+}
+
void changeZoom( GtkWidget* pButton, gpointer /* pItem */ )
{
static const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 };
@@ -332,11 +412,11 @@ void changeZoom( GtkWidget* pButton, gpointer /* pItem */ )
if ( strcmp(sName, "zoom-in-symbolic") == 0)
{
- for ( size_t i = 0; i < SAL_N_ELEMENTS( fZooms ); i++ )
+ for ( const auto& i : fZooms )
{
- if ( fCurrentZoom < fZooms[i] )
+ if ( fCurrentZoom < i )
{
- fZoom = fZooms[i];
+ fZoom = i;
break;
}
}
@@ -347,11 +427,11 @@ void changeZoom( GtkWidget* pButton, gpointer /* pItem */ )
}
else if ( strcmp(sName, "zoom-out-symbolic") == 0)
{
- for ( size_t i = 0; i < SAL_N_ELEMENTS( fZooms ); i++ )
+ for ( const auto& i : fZooms )
{
- if ( fCurrentZoom > fZooms[i] )
+ if ( fCurrentZoom > i )
{
- fZoom = fZooms[i];
+ fZoom = i;
}
}
}
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx
index a441d4e13bf5..447b7be8898f 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx
@@ -26,6 +26,8 @@ void recentUnoChanged(GtkWidget* pSelector, gpointer /* pItem */);
void unoCommandDebugger(GtkWidget* pButton, gpointer /* pItem */);
+void commandValuesDebugger(GtkWidget* pButton, gpointer /* pItem */);
+
void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/);
void changePartMode(GtkWidget* pSelector, gpointer /* pItem */);
@@ -67,6 +69,9 @@ gboolean signalAddressbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer /*pD
/// Handles the key-press-event of the formula entry widget.
gboolean signalFormulabar(GtkWidget* /*pWidget*/, GdkEventKey* /*pEvent*/, gpointer /*pData*/);
+void changeContentControl(GtkWidget* pSelector, gpointer /*pItem*/);
+
+void changeDateContentControl(GtkWidget* pSelector, gpointer /*pItem*/);
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/libreofficekit/qa/gtktiledviewer/gtv.ui b/libreofficekit/qa/gtktiledviewer/gtv.ui
index 01a9e268f34c..3b9ab76d0c5d 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv.ui
+++ b/libreofficekit/qa/gtktiledviewer/gtv.ui
@@ -106,12 +106,11 @@
</child>
<child>
<object class="GtkToolbar" id="findtoolbar">
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
<property name="toolbar_style">both-horiz</property>
<child>
<object class="GtkToolButton" id="findbar_close">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">__glade_unnamed_1</property>
<property name="use_underline">True</property>
<property name="icon_name">window-close-symbolic</property>
@@ -143,7 +142,6 @@
<child>
<object class="GtkToolButton" id="findbar_next">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">__glade_unnamed_3</property>
<property name="use_underline">True</property>
<property name="icon_name">go-down-symbolic</property>
@@ -157,7 +155,6 @@
<child>
<object class="GtkToolButton" id="findbar_prev">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">toolbutton</property>
<property name="use_underline">True</property>
<property name="icon_name">go-up-symbolic</property>
@@ -171,7 +168,6 @@
<child>
<object class="GtkToggleToolButton" id="findbar_findall">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Highlight all</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="toggleFindAll" swapped="no"/>
@@ -208,12 +204,11 @@
</object>
<object class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
<property name="toolbar_style">icons</property>
<child>
<object class="GtkToolButton" id="btn_save">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Save</property>
<property name="icon_name">document-save-symbolic</property>
<signal name="clicked" handler="btn_clicked" swapped="no"/>
@@ -236,7 +231,6 @@
<child>
<object class="GtkToolButton" id="btn_copy">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Copy</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-copy-symbolic</property>
@@ -250,7 +244,6 @@
<child>
<object class="GtkToolButton" id="btn_paste">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Paste</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-paste-symbolic</property>
@@ -274,7 +267,6 @@
<child>
<object class="GtkToolButton" id="btn_undo">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Undo</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-undo-symbolic</property>
@@ -288,7 +280,6 @@
<child>
<object class="GtkToolButton" id="btn_redo">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Redo</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-redo-symbolic</property>
@@ -302,7 +293,6 @@
<child>
<object class="GtkToolButton" id="btn_docrepair">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Document Repair</property>
<property name="use_underline">True</property>
<property name="icon_name">document-properties</property>
@@ -316,7 +306,6 @@
<child>
<object class="GtkToolButton" id="btn_docredlines">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Document redlines</property>
<property name="use_underline">True</property>
<property name="icon_name">system-run</property>
@@ -340,7 +329,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_find">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Find</property>
<property name="use_underline">True</property>
<property name="icon_name">edit-find-symbolic</property>
@@ -364,7 +352,6 @@
<child>
<object class="GtkToolButton" id="btn_zoomin">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Zoom In</property>
<property name="use_underline">True</property>
<property name="icon_name">zoom-in-symbolic</property>
@@ -378,7 +365,6 @@
<child>
<object class="GtkToolButton" id="btn_zoomoriginal">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Zoom Original</property>
<property name="use_underline">True</property>
<property name="icon_name">zoom-original-symbolic</property>
@@ -392,7 +378,6 @@
<child>
<object class="GtkToolButton" id="btn_zoomout">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Zoom out</property>
<property name="use_underline">True</property>
<property name="icon_name">zoom-out-symbolic</property>
@@ -443,10 +428,49 @@
</packing>
</child>
<child>
- <object class="GtkToggleToolButton" id="btn_editmode">
+ <object class="GtkToolItem" id="contentcontrolselectortoolitem">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Turn on/off edit mode</property>
+ <child>
+ <object class="GtkComboBoxText" id="combo_contentcontrolselector">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text">Content control list items</property>
+ <signal name="changed" handler="changeContentControl" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolItem" id="contentcontroldateselectortoolitem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkMenuButton" id="menu_contentcontroldateselector">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text">Content control date</property>
+ <property name="popover">calendar</property>
+ <property name="draw-indicator">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleToolButton" id="btn_editmode">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Turn on/off edit mode</property>
<property name="use_underline">True</property>
<property name="icon_name">insert-text-symbolic</property>
<signal name="clicked" handler="toggleEditing" swapped="no"/>
@@ -469,6 +493,7 @@
<child>
<object class="GtkToolItem" id="recentunoselectortoolitem">
<property name="visible">True</property>
+ <property name="tooltip_text">Recent UNO command selector</property>
<property name="can_focus">False</property>
<child>
<object class="GtkComboBoxText" id="combo_recentunoselector">
@@ -490,10 +515,9 @@
<child>
<object class="GtkToolButton" id="btn_unodebugger">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Uno Command Debugger</property>
+ <property name="tooltip_text">Uno Command Debugger</property>
<property name="use_underline">True</property>
- <property name="icon_name">dialog-question-symbolic</property>
+ <property name="icon_name">dialog-information-symbolic</property>
<signal name="clicked" handler="unoCommandDebugger" swapped="no"/>
</object>
<packing>
@@ -502,6 +526,19 @@
</packing>
</child>
<child>
+ <object class="GtkToolButton" id="btn_commandvaluesdebugger">
+ <property name="visible">True</property>
+ <property name="tooltip_text">Command values Debugger</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">dialog-question-symbolic</property>
+ <signal name="clicked" handler="commandValuesDebugger" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="homogeneous">True</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkSeparatorToolItem" id="separator6">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -514,7 +551,6 @@
<child>
<object class="GtkToolButton" id="btn_createview">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">Create new view</property>
<property name="use_underline">True</property>
<property name="icon_name">view-continuous-symbolic</property>
@@ -528,7 +564,6 @@
<child>
<object class="GtkToolButton" id="btn_rulerstate">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:UpdateRuler</property>
<property name="use_underline">True</property>
<property name="icon_name">text-x-generic</property>
@@ -542,12 +577,11 @@
</object>
<object class="GtkToolbar" id="toolbar2">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
<property name="toolbar_style">icons</property>
<child>
<object class="GtkToggleToolButton" id="btn_bold">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Bold</property>
<property name="use_underline">True</property>
<property name="icon_name">format-text-bold-symbolic</property>
@@ -561,7 +595,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_italic">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Italic</property>
<property name="use_underline">True</property>
<property name="icon_name">format-text-italic-symbolic</property>
@@ -575,7 +608,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_underline">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Underline</property>
<property name="use_underline">True</property>
<property name="icon_name">format-text-underline-symbolic</property>
@@ -589,7 +621,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_strikethrough">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:Strikeout</property>
<property name="use_underline">True</property>
<property name="icon_name">format-text-strikethrough-symbolic</property>
@@ -613,7 +644,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_superscript">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:SuperScript</property>
<property name="use_underline">True</property>
<property name="icon_name">go-up-symbolic</property>
@@ -627,7 +657,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_subscript">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:SubScript</property>
<property name="use_underline">True</property>
<property name="icon_name">go-down-symbolic</property>
@@ -651,7 +680,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_justifyleft">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:LeftPara</property>
<property name="use_underline">True</property>
<property name="icon_name">format-justify-left-symbolic</property>
@@ -665,7 +693,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_justifycenter">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:CenterPara</property>
<property name="use_underline">True</property>
<property name="icon_name">format-justify-center-symbolic</property>
@@ -679,7 +706,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_justifyright">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:RightPara</property>
<property name="use_underline">True</property>
<property name="icon_name">format-justify-right-symbolic</property>
@@ -693,7 +719,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_justifyfill">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:JustifyPara</property>
<property name="use_underline">True</property>
<property name="icon_name">format-justify-fill-symbolic</property>
@@ -717,7 +742,6 @@
<child>
<object class="GtkToolButton" id="btn_insertannotation">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:InsertAnnotation</property>
<property name="use_underline">True</property>
<property name="icon_name">changes-allow-symbolic</property>
@@ -731,7 +755,6 @@
<child>
<object class="GtkToolButton" id="btn_removeannotation">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:DeleteComment</property>
<property name="use_underline">True</property>
<property name="icon_name">changes-prevent-symbolic</property>
@@ -745,7 +768,6 @@
<child>
<object class="GtkToggleToolButton" id="btn_trackchanges">
<property name="visible">True</property>
- <property name="can_focus">False</property>
<property name="label" translatable="yes">.uno:TrackChanges</property>
<property name="use_underline">True</property>
<property name="icon_name">media-record-symbolic</property>
@@ -793,4 +815,28 @@
</packing>
</child>
</object>
+ <object class="GtkPopover" id="calendar">
+ <property name="can-focus">False</property>
+ <property name="position">bottom</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCalendar" id="date">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <signal name="day-selected-double-click" handler="changeDateContentControl" swapped="no"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
</interface>
diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx
index 6b6dcf4056a4..ffcdcefa009f 100644
--- a/libreofficekit/qa/tilebench/tilebench.cxx
+++ b/libreofficekit/qa/tilebench/tilebench.cxx
@@ -32,7 +32,7 @@ static int help( const char *error = nullptr )
{
if (error)
fprintf (stderr, "Error: %s\n\n", error);
- fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document] [--preinit] <options>\n");
+ fprintf( stderr, "Usage: tilebench <absolute-path-to-libreoffice-install> [path to document] [--preinit] [--save <path>] <options>\n");
fprintf( stderr, "\trenders a selection of small tiles from the document, checksums them and times the process based on options:\n" );
fprintf( stderr, "\t--tile\t[max parts|-1] [max tiles|-1]\n" );
fprintf( stderr, "\t--dialog\t<.uno:Command>\n" );
@@ -110,29 +110,36 @@ static void dumpTile(const char *pNameStem,
for (int x = 0; x < nWidth; ++x)
{
const char* pixel = row + x * 4;
- if (mode == LOK_TILEMODE_RGBA)
+
+ const int alpha = *(pixel + 3);
+ char buf[3];
+ if (alpha == 0)
{
- ofs.write(pixel, 3); // Skip alpha
+ buf[0] = 0;
+ buf[1] = 0;
+ buf[2] = 0;
}
- else if (mode == LOK_TILEMODE_BGRA)
+ else
{
- const int alpha = *(pixel + 3);
- char buf[3];
- if (alpha == 0)
- {
- buf[0] = 0;
- buf[1] = 0;
- buf[2] = 0;
- }
- else
+ switch (mode)
{
- buf[0] = (*(pixel + 2) * 255 + alpha / 2) / alpha;
- buf[1] = (*(pixel + 1) * 255 + alpha / 2) / alpha;
- buf[2] = (*(pixel + 0) * 255 + alpha / 2) / alpha;
+ case LOK_TILEMODE_RGBA:
+ buf[0] = (*(pixel + 0) * 255 + alpha / 2) / alpha;
+ buf[1] = (*(pixel + 1) * 255 + alpha / 2) / alpha;
+ buf[2] = (*(pixel + 2) * 255 + alpha / 2) / alpha;
+ break;
+ case LOK_TILEMODE_BGRA:
+ buf[0] = (*(pixel + 2) * 255 + alpha / 2) / alpha;
+ buf[1] = (*(pixel + 1) * 255 + alpha / 2) / alpha;
+ buf[2] = (*(pixel + 0) * 255 + alpha / 2) / alpha;
+ break;
+ default:
+ assert(false && "unhandled LibreOfficeKitTileMode");
+ break;
}
-
- ofs.write(buf, 3);
}
+
+ ofs.write(buf, 3);
if (dumpText)
{
int lowResI = (pixel[0] + pixel[1] + pixel[2])/(3*16);
@@ -579,6 +586,14 @@ int main( int argc, char* argv[] )
mode = argv[arg++];
}
+ const char *saveToPath = nullptr;
+ if (!strcmp (mode, "--save"))
+ {
+ pre_init = true;
+ saveToPath = argv[arg++];
+ mode = argv[arg++];
+ }
+
std::string user_url("file:///");
user_url.append(argv[1]);
user_url.append("../user");
@@ -598,6 +613,7 @@ int main( int argc, char* argv[] )
const char *user_profile = nullptr;
const char *doc_url = strdup([[[[[NSBundle mainBundle] bundleURL] absoluteString] stringByAppendingString:@"/test.odt"] UTF8String]);
const char *mode = "--tile";
+ const char *saveToPath = nullptr;
#endif
aTimes.emplace_back("initialization");
@@ -655,9 +671,19 @@ int main( int argc, char* argv[] )
}
}
testDialog (pDocument.get(), uno_cmd);
- } else
+ }
+ else
return help ("unknown parameter");
- }
+
+ if (saveToPath != nullptr)
+ {
+ aTimes.emplace_back("save");
+ pDocument->saveAs(saveToPath);
+ aTimes.emplace_back();
+ }
+ } else
+ fprintf(stderr, "Failed to load document '%s'\n",
+ (doc_url ? doc_url : "<null>"));
#ifdef IOS
Application::Quit();
diff --git a/libreofficekit/qa/unit/checkapi.cxx b/libreofficekit/qa/unit/checkapi.cxx
index acf00e0b9cb1..ec4a718366e9 100644
--- a/libreofficekit/qa/unit/checkapi.cxx
+++ b/libreofficekit/qa/unit/checkapi.cxx
@@ -11,10 +11,9 @@
#error Build system problem; LIBO_INTERNAL_ONLY should not be defined here
#endif
-#include <LibreOfficeKit/LibreOfficeKit.hxx>
-
#include <sal/config.h>
-#include <sal/saldllapi.h>
+#include <sal/types.h>
+
#include <cppunit/plugin/TestPlugIn.h>
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/libreofficekit/qa/unit/test.h b/libreofficekit/qa/unit/test.h
index ea44b9d391ec..f29db13bb85b 100644
--- a/libreofficekit/qa/unit/test.h
+++ b/libreofficekit/qa/unit/test.h
@@ -10,6 +10,8 @@
#ifndef INCLUDED_LIBREOFFICEKIT_QA_TEST_H
#define INCLUDED_LIBREOFFICEKIT_QA_TEST_H
+#include <LibreOfficeKit/LibreOfficeKit.h>
+
LibreOfficeKit* compile_test(void);
#endif // INCLUDED_LIBREOFFICEKIT_QA_TEST_H
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 156224b57351..60c3435ac28d 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -11,6 +11,7 @@
#include <math.h>
#include <string.h>
#include <memory>
+#include <utility>
#include <vector>
#include <string>
#include <sstream>
@@ -67,9 +68,9 @@ struct ViewRectangles
int m_nPart;
std::vector<GdkRectangle> m_aRectangles;
- ViewRectangles(int nPart = 0, const std::vector<GdkRectangle>& rRectangles = std::vector<GdkRectangle>())
+ ViewRectangles(int nPart = 0, std::vector<GdkRectangle>&& rRectangles = std::vector<GdkRectangle>())
: m_nPart(nPart),
- m_aRectangles(rRectangles)
+ m_aRectangles(std::move(rRectangles))
{
}
};
@@ -124,6 +125,10 @@ struct LOKDocViewPrivateImpl
guint32 m_nKeyModifier;
/// Rectangles of the current text selection.
std::vector<GdkRectangle> m_aTextSelectionRectangles;
+ /// Rectangles of the current content control.
+ std::vector<GdkRectangle> m_aContentControlRectangles;
+ /// Alias/title of the current content control.
+ std::string m_aContentControlAlias;
/// Rectangles of view selections. The current view can only see
/// them, can't modify them. Key is the view id.
std::map<int, ViewRectangles> m_aTextViewSelectionRectangles;
@@ -253,6 +258,15 @@ struct LOKDocViewPrivateImpl
}
};
+// Must be run with g_aLOKMutex locked
+void setDocumentView(LibreOfficeKitDocument* pDoc, int viewId)
+{
+ assert(pDoc);
+ std::stringstream ss;
+ ss << "lok::Document::setView(" << viewId << ")";
+ g_info("%s", ss.str().c_str());
+ pDoc->pClass->setView(pDoc, viewId);
+}
}
/// Wrapper around LOKDocViewPrivateImpl, managed by malloc/memset/free.
@@ -281,6 +295,7 @@ enum
ADDRESS_CHANGED,
FORMULA_CHANGED,
TEXT_SELECTION,
+ CONTENT_CONTROL,
PASSWORD_REQUIRED,
COMMENT,
RULER,
@@ -323,7 +338,6 @@ static void lok_doc_view_initable_iface_init (GInitableIface *iface);
static void callbackWorker (int nType, const char* pPayload, void* pData);
static void updateClientZoom (LOKDocView *pDocView);
-SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type();
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -355,9 +369,9 @@ struct CallbackData
std::string m_aPayload;
LOKDocView* m_pDocView;
- CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView)
+ CallbackData(int nType, std::string aPayload, LOKDocView* pDocView)
: m_nType(nType),
- m_aPayload(rPayload),
+ m_aPayload(std::move(aPayload)),
m_pDocView(pDocView) {}
};
@@ -555,30 +569,28 @@ handleGraphicSelectionOnButtonRelease(LOKDocView* pDocView, GdkEventButton* pEve
}
}
- if (priv->m_bInDragGraphicSelection)
- {
- g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
- priv->m_bInDragGraphicSelection = false;
+ if (!priv->m_bInDragGraphicSelection)
+ return false;
- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
- g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
+ g_info("LOKDocView_Impl::signalButton: end of drag graphic selection");
+ priv->m_bInDragGraphicSelection = false;
- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
- if (error != nullptr)
- {
- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
- g_clear_error(&error);
- }
- g_object_unref(task);
+ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
+ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION);
+ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END;
+ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom);
+ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom);
+ g_task_set_task_data(task, pLOEvent, LOEvent::destroy);
- return true;
+ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error);
+ if (error != nullptr)
+ {
+ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message);
+ g_clear_error(&error);
}
+ g_object_unref(task);
- return false;
+ return true;
}
static void
@@ -592,10 +604,8 @@ postKeyEventInThread(gpointer data)
gint nTileSizePixelsScaled = nTileSizePixels * nScaleFactor;
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
if (priv->m_nTileSizeTwips)
{
@@ -1394,6 +1404,61 @@ callback (gpointer pData)
break;
}
+ case LOK_CALLBACK_CONTENT_CONTROL:
+ {
+ std::stringstream aPayloadStream(pCallback->m_aPayload);
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aPayloadStream, aTree);
+ auto aAction = aTree.get<std::string>("action");
+ if (aAction == "show")
+ {
+ auto aRectangles = aTree.get<std::string>("rectangles");
+ priv->m_aContentControlRectangles = payloadToRectangles(pDocView, aRectangles.c_str());
+
+ auto it = aTree.find("alias");
+ if (it == aTree.not_found())
+ {
+ priv->m_aContentControlAlias.clear();
+ }
+ else
+ {
+ priv->m_aContentControlAlias = it->second.get_value<std::string>();
+ }
+ }
+ else if (aAction == "hide")
+ {
+ priv->m_aContentControlRectangles.clear();
+ priv->m_aContentControlAlias.clear();
+ }
+ else if (aAction == "change-picture")
+ {
+ GtkWidget* pDialog = gtk_file_chooser_dialog_new(
+ "Open File", GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView))),
+ GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel", GTK_RESPONSE_CANCEL, "Open",
+ GTK_RESPONSE_ACCEPT, nullptr);
+ gint nRet = gtk_dialog_run(GTK_DIALOG(pDialog));
+ if (nRet == GTK_RESPONSE_ACCEPT)
+ {
+ GtkFileChooser* pChooser = GTK_FILE_CHOOSER(pDialog);
+ char* pFilename = gtk_file_chooser_get_uri(pChooser);
+ boost::property_tree::ptree aValues;
+ aValues.put("type", "picture");
+ aValues.put("changed", pFilename);
+ std::stringstream aStream;
+ boost::property_tree::write_json(aStream, aValues);
+ std::string aJson = aStream.str();
+ lok_doc_view_send_content_control_event(pDocView, aJson.c_str());
+
+ g_free(pFilename);
+ }
+ gtk_widget_destroy(pDialog);
+ }
+ g_signal_emit(pCallback->m_pDocView, doc_view_signals[CONTENT_CONTROL], 0,
+ pCallback->m_aPayload.c_str());
+ gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+ }
+ break;
+
case LOK_CALLBACK_STATUS_INDICATOR_START:
case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
@@ -1414,6 +1479,26 @@ callback (gpointer pData)
case LOK_CALLBACK_TAB_STOP_LIST:
case LOK_CALLBACK_FORM_FIELD_BUTTON:
case LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY:
+ case LOK_CALLBACK_DOCUMENT_BACKGROUND_COLOR:
+ case LOK_COMMAND_BLOCKED:
+ case LOK_CALLBACK_SC_FOLLOW_JUMP:
+ case LOK_CALLBACK_PRINT_RANGES:
+ case LOK_CALLBACK_FONTS_MISSING:
+ case LOK_CALLBACK_MEDIA_SHAPE:
+ case LOK_CALLBACK_EXPORT_FILE:
+ case LOK_CALLBACK_VIEW_RENDER_STATE:
+ case LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR:
+ case LOK_CALLBACK_A11Y_FOCUS_CHANGED:
+ case LOK_CALLBACK_A11Y_CARET_CHANGED:
+ case LOK_CALLBACK_A11Y_TEXT_SELECTION_CHANGED:
+ case LOK_CALLBACK_A11Y_FOCUSED_CELL_CHANGED:
+ case LOK_CALLBACK_COLOR_PALETTES:
+ case LOK_CALLBACK_DOCUMENT_PASSWORD_RESET:
+ case LOK_CALLBACK_A11Y_EDITING_IN_SELECTION_STATE:
+ case LOK_CALLBACK_A11Y_SELECTION_CHANGED:
+ case LOK_CALLBACK_CORE_LOG:
+ case LOK_CALLBACK_TOOLTIP:
+ case LOK_CALLBACK_SHAPE_INNER_TEXT:
{
// TODO: Implement me
break;
@@ -1808,6 +1893,42 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
}
}
+ if (!priv->m_aContentControlRectangles.empty())
+ {
+ for (const GdkRectangle& rRectangle : priv->m_aContentControlRectangles)
+ {
+ // Black with 75% transparency.
+ cairo_set_source_rgba(pCairo, (double(0x7f))/255, (double(0x7f))/255, (double(0x7f))/255, 0.25);
+ cairo_rectangle(pCairo,
+ twipToPixel(rRectangle.x, priv->m_fZoom),
+ twipToPixel(rRectangle.y, priv->m_fZoom),
+ twipToPixel(rRectangle.width, priv->m_fZoom),
+ twipToPixel(rRectangle.height, priv->m_fZoom));
+ cairo_fill(pCairo);
+ }
+
+ if (!priv->m_aContentControlAlias.empty())
+ {
+ cairo_text_extents_t aExtents;
+ cairo_text_extents(pCairo, priv->m_aContentControlAlias.c_str(), &aExtents);
+ // Blue with 75% transparency.
+ cairo_set_source_rgba(pCairo, 0, 0, 1, 0.25);
+ cairo_rectangle(pCairo,
+ twipToPixel(priv->m_aContentControlRectangles[0].x, priv->m_fZoom) + aExtents.x_bearing,
+ twipToPixel(priv->m_aContentControlRectangles[0].y, priv->m_fZoom) + aExtents.y_bearing,
+ aExtents.width,
+ aExtents.height);
+ cairo_fill(pCairo);
+
+ cairo_move_to(pCairo,
+ twipToPixel(priv->m_aContentControlRectangles[0].x, priv->m_fZoom),
+ twipToPixel(priv->m_aContentControlRectangles[0].y, priv->m_fZoom));
+ cairo_set_source_rgb(pCairo, 0, 0, 0);
+ cairo_show_text(pCairo, priv->m_aContentControlAlias.c_str());
+ cairo_fill(pCairo);
+ }
+ }
+
// Selections of other views.
for (const auto& rPair : priv->m_aTextViewSelectionRectangles)
{
@@ -1926,8 +2047,8 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
twipToPixel(rRectangle.m_aRectangle.x + rRectangle.m_aRectangle.width, priv->m_fZoom) - 15,
twipToPixel(rRectangle.m_aRectangle.y + rRectangle.m_aRectangle.height, priv->m_fZoom) - 15,
5,
- 180.0 * (M_PI/180.0),
- 360.0 * (M_PI/180.0));
+ M_PI,
+ 2 * M_PI);
cairo_stroke(pCairo);
}
@@ -2072,10 +2193,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent)
GError* error = nullptr;
std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
if (priv->m_bInDragMiddleHandle)
{
g_info("lcl_signalMotion: dragging the middle handle");
@@ -2173,11 +2291,8 @@ setGraphicSelectionInThread(gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
- ss.str(std::string());
ss << "lok::Document::setGraphicSelection(" << pLOEvent->m_nSetGraphicSelectionType;
ss << ", " << pLOEvent->m_nSetGraphicSelectionX;
ss << ", " << pLOEvent->m_nSetGraphicSelectionY << ")";
@@ -2197,6 +2312,7 @@ setClientZoomInThread(gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->setClientZoom(priv->m_pDocument,
pLOEvent->m_nTilePixelWidth,
pLOEvent->m_nTilePixelHeight,
@@ -2213,11 +2329,8 @@ postMouseEventInThread(gpointer data)
LOEvent* pLOEvent = static_cast<LOEvent*>(g_task_get_task_data(task));
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
- ss.str(std::string());
ss << "lok::Document::postMouseEvent(" << pLOEvent->m_nPostMouseEventType;
ss << ", " << pLOEvent->m_nPostMouseEventX;
ss << ", " << pLOEvent->m_nPostMouseEventY;
@@ -2249,7 +2362,13 @@ openDocumentInThread (gpointer data)
}
priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView);
- priv->m_pDocument = priv->m_pOffice->pClass->documentLoadWithOptions( priv->m_pOffice, priv->m_aDocPath.c_str(), "en-US" );
+ std::string url = priv->m_aDocPath;
+ if (gchar* pURL = g_filename_to_uri(url.c_str(), nullptr, nullptr))
+ {
+ url = pURL;
+ g_free(pURL);
+ }
+ priv->m_pDocument = priv->m_pOffice->pClass->documentLoadWithOptions( priv->m_pOffice, url.c_str(), "en-US" );
if ( !priv->m_pDocument )
{
char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice );
@@ -2273,10 +2392,7 @@ setPartInThread(gpointer data)
int nPart = pLOEvent->m_nPart;
std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart );
aGuard.unlock();
@@ -2293,10 +2409,7 @@ setPartmodeInThread(gpointer data)
int nPartMode = pLOEvent->m_nPartMode;
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode );
}
@@ -2316,10 +2429,7 @@ setEditInThread(gpointer data)
{
g_info("lok_doc_view_set_edit: leaving edit mode");
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->resetSelection(priv->m_pDocument);
}
priv->m_bEdit = bEdit;
@@ -2336,11 +2446,8 @@ postCommandInThread (gpointer data)
LOKDocViewPrivate& priv = getPrivate(pDocView);
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
- ss.str(std::string());
ss << "lok::Document::postUnoCommand(" << pLOEvent->m_pCommand << ", " << pLOEvent->m_pArguments << ")";
g_info("%s", ss.str().c_str());
priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments, pLOEvent->m_bNotifyWhenFinished);
@@ -2387,11 +2494,8 @@ paintTileInThread (gpointer data)
aTileRectangle.y = pixelToTwip(nTileSizePixelsScaled, pLOEvent->m_fPaintTileZoom * nScaleFactor) * pLOEvent->m_nPaintTileX;
std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
- ss.str(std::string());
GTimer* aTimer = g_timer_new();
gulong nElapsedMs;
ss << "lok::Document::paintTile(" << static_cast<void*>(pBuffer) << ", "
@@ -2665,12 +2769,9 @@ static void lok_doc_view_destroy (GtkWidget* widget)
// Ignore notifications sent to this view on shutdown.
std::unique_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
if (priv->m_pDocument)
{
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, nullptr, nullptr);
}
@@ -2684,17 +2785,13 @@ static void lok_doc_view_destroy (GtkWidget* widget)
if (priv->m_pDocument)
{
- if (priv->m_pDocument->pClass->getViewsCount(priv->m_pDocument) > 1)
- {
- priv->m_pDocument->pClass->destroyView(priv->m_pDocument, priv->m_nViewId);
- }
- else
+ // This call may drop several views - e.g., embedded OLE in-place clients
+ priv->m_pDocument->pClass->destroyView(priv->m_pDocument, priv->m_nViewId);
+ if (priv->m_pDocument->pClass->getViewsCount(priv->m_pDocument) == 0)
{
- if (priv->m_pDocument)
- {
- priv->m_pDocument->pClass->destroy (priv->m_pDocument);
- priv->m_pDocument = nullptr;
- }
+ // Last view(s) gone
+ priv->m_pDocument->pClass->destroy (priv->m_pDocument);
+ priv->m_pDocument = nullptr;
if (priv->m_pOffice)
{
priv->m_pOffice->pClass->destroy (priv->m_pOffice);
@@ -2726,16 +2823,17 @@ static gboolean timeout_wakeup(void *)
// integrate our mainloop with LOK's
static int lok_poll_callback(void*, int timeoutUs)
{
- if (timeoutUs)
+ bool bWasEvent(false);
+ if (timeoutUs > 0)
{
guint timeout = g_timeout_add(timeoutUs / 1000, timeout_wakeup, nullptr);
- g_main_context_iteration(nullptr, true);
+ bWasEvent = g_main_context_iteration(nullptr, true);
g_source_remove(timeout);
}
else
- g_main_context_iteration(nullptr, FALSE);
+ bWasEvent = g_main_context_iteration(nullptr, timeoutUs < 0);
- return 0;
+ return bWasEvent ? 1 : 0;
}
// thread-safe wakeup of our mainloop
@@ -2756,6 +2854,8 @@ static gboolean spin_lok_loop(void *pData)
static void updateClientZoom(LOKDocView *pDocView)
{
LOKDocViewPrivate& priv = getPrivate(pDocView);
+ if (!priv->m_fZoom)
+ return; // Not initialized yet?
gint nScaleFactor = gtk_widget_get_scale_factor(GTK_WIDGET(pDocView));
gint nTileSizePixelsScaled = nTileSizePixels * nScaleFactor;
GError* error = nullptr;
@@ -3282,6 +3382,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
G_TYPE_BOOLEAN);
/**
+ * LOKDocView::content-control:
+ * @pDocView: the #LOKDocView on which the signal is emitted
+ * @pPayload: the JSON string containing the information about ruler properties
+ */
+ doc_view_signals[CONTENT_CONTROL] =
+ g_signal_new("content-control",
+ G_TYPE_FROM_CLASS(pGObjectClass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ nullptr, nullptr,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ /**
* LOKDocView::password-required:
* @pDocView: the #LOKDocView on which the signal is emitted
* @pUrl: URL of the document for which password is required
@@ -3618,10 +3733,7 @@ lok_doc_view_get_parts (LOKDocView* pDocView)
return -1;
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
return priv->m_pDocument->pClass->getParts( priv->m_pDocument );
}
@@ -3633,10 +3745,7 @@ lok_doc_view_get_part (LOKDocView* pDocView)
return -1;
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
return priv->m_pDocument->pClass->getPart( priv->m_pDocument );
}
@@ -3670,6 +3779,20 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart)
priv->m_nPartId = nPart;
}
+SAL_DLLPUBLIC_EXPORT void lok_doc_view_send_content_control_event(LOKDocView* pDocView,
+ const gchar* pArguments)
+{
+ LOKDocViewPrivate& priv = getPrivate(pDocView);
+ if (!priv->m_pDocument)
+ {
+ return;
+ }
+
+ std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
+ return priv->m_pDocument->pClass->sendContentControlEvent(priv->m_pDocument, pArguments);
+}
+
SAL_DLLPUBLIC_EXPORT gchar*
lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart)
{
@@ -3678,10 +3801,7 @@ lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart)
return nullptr;
std::scoped_lock<std::mutex> aGuard(g_aLOKMutex);
- std::stringstream ss;
- ss << "lok::Document::setView(" << priv->m_nViewId << ")";
- g_info("%s", ss.str().c_str());
- priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId);
+ setDocumentView(priv->m_pDocument, priv->m_nViewId);
return priv->m_pDocument->pClass->getPartName( priv->m_pDocument, nPart );
}
@@ -3725,6 +3845,7 @@ lok_doc_view_reset_view(LOKDocView* pDocView)
priv->m_nLastButtonPressTime = 0;
priv->m_nLastButtonReleaseTime = 0;
priv->m_aTextSelectionRectangles.clear();
+ priv->m_aContentControlRectangles.clear();
memset(&priv->m_aTextSelectionStart, 0, sizeof(priv->m_aTextSelectionStart));
memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd));
diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx
index 6836031661bc..3c73c9dddf83 100644
--- a/libreofficekit/source/gtk/tilebuffer.cxx
+++ b/libreofficekit/source/gtk/tilebuffer.cxx
@@ -9,19 +9,22 @@
#include "tilebuffer.hxx"
+#include <o3tl/unit_conversion.hxx>
+
/* ------------------
Utility functions
------------------
*/
+// We know that VirtualDevices use a DPI of 96.
float pixelToTwip(float fInput, float zoom)
{
- return (fInput / DPI / zoom) * 1440.0f;
+ return o3tl::toTwips(fInput / zoom, o3tl::Length::px);
}
float twipToPixel(float fInput, float zoom)
{
- return fInput / 1440.0f * DPI * zoom;
+ return o3tl::convert(fInput * zoom, o3tl::Length::twip, o3tl::Length::px);
}
/* ----------------------------
diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx
index 79fa48c555db..239482e34625 100644
--- a/libreofficekit/source/gtk/tilebuffer.hxx
+++ b/libreofficekit/source/gtk/tilebuffer.hxx
@@ -18,8 +18,6 @@
#define LOK_TILEBUFFER_ERROR (LOKTileBufferErrorQuark())
-// We know that VirtualDevices use a DPI of 96.
-const int DPI = 96;
// Lets use a square of side 256 pixels for each tile.
const int nTileSizePixels = 256;