tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / libreofficekit / qa / gtktiledviewer / gtv-main-toolbar.cxx
blob7127581856fce3a639c4e05964394ca59af66b28
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <gtk/gtk.h>
12 #include "gtv-application-window.hxx"
13 #include "gtv-main-toolbar.hxx"
14 #include "gtv-signal-handlers.hxx"
15 #include "gtv-helpers.hxx"
17 #include <LibreOfficeKit/LibreOfficeKitGtk.h>
19 #include <algorithm>
20 #include <fstream>
21 #include <map>
22 #include <memory>
24 namespace {
26 struct GtvMainToolbarPrivateImpl
28 GtkWidget* toolbar1;
29 GtkWidget* toolbar2;
31 GtkWidget* m_pEnableEditing;
32 GtkWidget* m_pLeftpara;
33 GtkWidget* m_pCenterpara;
34 GtkWidget* m_pRightpara;
35 GtkWidget* m_pJustifypara;
36 GtkWidget* m_pDeleteComment;
37 GtkWidget* m_pPartSelector;
38 GtkWidget* m_pPartModeSelector;
39 GtkWidget* m_pRecentUnoSelector;
40 std::map<std::string, std::string> m_pRecentUnoCommands;
42 /// Sensitivity (enabled or disabled) for each tool item, ignoring edit state
43 std::map<GtkToolItem*, bool> m_aToolItemSensitivities;
45 GtvMainToolbarPrivateImpl() :
46 toolbar1(nullptr),
47 toolbar2(nullptr),
48 m_pEnableEditing(nullptr),
49 m_pLeftpara(nullptr),
50 m_pCenterpara(nullptr),
51 m_pRightpara(nullptr),
52 m_pJustifypara(nullptr),
53 m_pDeleteComment(nullptr),
54 m_pPartSelector(nullptr),
55 m_pPartModeSelector(nullptr),
56 m_pRecentUnoSelector(nullptr)
57 { }
60 struct GtvMainToolbarPrivate
62 GtvMainToolbarPrivateImpl* m_pImpl;
64 GtvMainToolbarPrivateImpl* operator->()
66 return m_pImpl;
72 #if defined __clang__
73 #if __has_warning("-Wdeprecated-volatile")
74 #pragma clang diagnostic push
75 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
76 #endif
77 #endif
78 G_DEFINE_TYPE_WITH_PRIVATE(GtvMainToolbar, gtv_main_toolbar, GTK_TYPE_BOX);
79 #if defined __clang__
80 #if __has_warning("-Wdeprecated-volatile")
81 #pragma clang diagnostic pop
82 #endif
83 #endif
85 static GtvMainToolbarPrivate&
86 getPrivate(GtvMainToolbar* toolbar)
88 return *static_cast<GtvMainToolbarPrivate*>(gtv_main_toolbar_get_instance_private(toolbar));
91 static void
92 gtv_main_toolbar_init(GtvMainToolbar* toolbar)
94 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
95 priv.m_pImpl = new GtvMainToolbarPrivateImpl();
97 const std::string uiFilePath = GtvHelpers::getDirPath(__FILE__) + std::string(UI_FILE_NAME);
98 GtvGtkWrapper<GtkBuilder> builder(gtk_builder_new_from_file(uiFilePath.c_str()),
99 [](GtkBuilder* pBuilder) {
100 g_object_unref(pBuilder);
103 priv->toolbar1 = GTK_WIDGET(gtk_builder_get_object(builder.get(), "toolbar1"));
104 gtk_box_pack_start(GTK_BOX(toolbar), priv->toolbar1, false, false, false);
105 priv->toolbar2 = GTK_WIDGET(gtk_builder_get_object(builder.get(), "toolbar2"));
106 gtk_box_pack_start(GTK_BOX(toolbar), priv->toolbar2, false, false, false);
108 priv->m_pEnableEditing = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_editmode"));
109 priv->m_pLeftpara = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_justifyleft"));
110 priv->m_pCenterpara = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_justifycenter"));
111 priv->m_pRightpara = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_justifyright"));
112 priv->m_pJustifypara = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_justifyfill"));
113 priv->m_pDeleteComment = GTK_WIDGET(gtk_builder_get_object(builder.get(), "btn_removeannotation"));
114 priv->m_pPartSelector = GTK_WIDGET(gtk_builder_get_object(builder.get(), "combo_partselector"));
115 priv->m_pPartModeSelector = GTK_WIDGET(gtk_builder_get_object(builder.get(), "combo_partsmodeselector"));
116 priv->m_pRecentUnoSelector = GTK_WIDGET(gtk_builder_get_object(builder.get(), "combo_recentunoselector"));
118 toolbar->m_pAddressbar = GTK_WIDGET(gtk_builder_get_object(builder.get(), "addressbar_entry"));
119 toolbar->m_pFormulabar = GTK_WIDGET(gtk_builder_get_object(builder.get(), "formulabar_entry"));
120 toolbar->m_pContentControlSelector
121 = GTK_WIDGET(gtk_builder_get_object(builder.get(), "combo_contentcontrolselector"));
122 toolbar->m_pContentControlDateSelector
123 = GTK_WIDGET(gtk_builder_get_object(builder.get(), "menu_contentcontroldateselector"));
125 // TODO: compile with -rdynamic and get rid of it
126 gtk_builder_add_callback_symbol(builder.get(), "btn_clicked", G_CALLBACK(btn_clicked));
127 gtk_builder_add_callback_symbol(builder.get(), "doCopy", G_CALLBACK(doCopy));
128 gtk_builder_add_callback_symbol(builder.get(), "doPaste", G_CALLBACK(doPaste));
129 gtk_builder_add_callback_symbol(builder.get(), "createView", G_CALLBACK(createView));
130 gtk_builder_add_callback_symbol(builder.get(), "getRulerState", G_CALLBACK(getRulerState));
131 gtk_builder_add_callback_symbol(builder.get(), "recentUnoChanged", G_CALLBACK(recentUnoChanged));
132 gtk_builder_add_callback_symbol(builder.get(), "unoCommandDebugger", G_CALLBACK(unoCommandDebugger));
133 gtk_builder_add_callback_symbol(builder.get(), "commandValuesDebugger", G_CALLBACK(commandValuesDebugger));
134 gtk_builder_add_callback_symbol(builder.get(), "toggleEditing", G_CALLBACK(toggleEditing));
135 gtk_builder_add_callback_symbol(builder.get(), "changePartMode", G_CALLBACK(changePartMode));
136 gtk_builder_add_callback_symbol(builder.get(), "changePart", G_CALLBACK(changePart));
137 gtk_builder_add_callback_symbol(builder.get(), "changeContentControl",
138 G_CALLBACK(changeContentControl));
139 gtk_builder_add_callback_symbol(builder.get(), "changeDateContentControl",
140 G_CALLBACK(changeDateContentControl));
141 gtk_builder_add_callback_symbol(builder.get(), "changeZoom", G_CALLBACK(changeZoom));
142 gtk_builder_add_callback_symbol(builder.get(), "toggleFindbar", G_CALLBACK(toggleFindbar));
143 gtk_builder_add_callback_symbol(builder.get(), "documentRedline", G_CALLBACK(documentRedline));
144 gtk_builder_add_callback_symbol(builder.get(), "documentRepair", G_CALLBACK(documentRepair));
145 gtk_builder_add_callback_symbol(builder.get(), "signalAddressbar", G_CALLBACK(signalAddressbar));
146 gtk_builder_add_callback_symbol(builder.get(), "signalFormulabar", G_CALLBACK(signalFormulabar));
148 // find toolbar
149 // Note: These buttons are not the part of GtvMainToolbar
150 gtk_builder_add_callback_symbol(builder.get(), "signalSearchNext", G_CALLBACK(signalSearchNext));
151 gtk_builder_add_callback_symbol(builder.get(), "signalSearchPrev", G_CALLBACK(signalSearchPrev));
152 gtk_builder_add_callback_symbol(builder.get(), "signalFindbar", G_CALLBACK(signalFindbar));
153 gtk_builder_add_callback_symbol(builder.get(), "toggleFindAll", G_CALLBACK(toggleFindAll));
155 gtk_builder_connect_signals(builder.get(), nullptr);
157 gtk_widget_show_all(GTK_WIDGET(toolbar));
160 static void
161 gtv_main_toolbar_finalize(GObject* object)
163 GtvMainToolbarPrivate& priv = getPrivate(GTV_MAIN_TOOLBAR(object));
165 delete priv.m_pImpl;
166 priv.m_pImpl = nullptr;
168 G_OBJECT_CLASS (gtv_main_toolbar_parent_class)->finalize (object);
171 static void
172 gtv_main_toolbar_class_init(GtvMainToolbarClass* klass)
174 G_OBJECT_CLASS(klass)->finalize = gtv_main_toolbar_finalize;
177 static void populatePartSelector(GtvMainToolbar* toolbar)
179 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
180 GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(toolbar)));
181 gtv_application_window_set_part_broadcast(window, false);
182 gtk_list_store_clear( GTK_LIST_STORE(
183 gtk_combo_box_get_model(
184 GTK_COMBO_BOX(priv->m_pPartSelector) )) );
186 if (!window->lokdocview)
188 return;
191 const int nMaxLength = 50;
192 char sText[nMaxLength];
194 int nParts = lok_doc_view_get_parts(LOK_DOC_VIEW(window->lokdocview));
195 for ( int i = 0; i < nParts; i++ )
197 char* pName = lok_doc_view_get_part_name(LOK_DOC_VIEW(window->lokdocview), i);
198 assert( pName );
199 snprintf( sText, nMaxLength, "%i (%s)", i+1, pName );
200 free( pName );
202 gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT(priv->m_pPartSelector), sText );
204 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->m_pPartSelector), lok_doc_view_get_part(LOK_DOC_VIEW(window->lokdocview)));
206 gtv_application_window_set_part_broadcast(window, true);
209 static void populateRecentUnoSelector(GtvMainToolbar* toolbar)
211 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
212 GtkComboBoxText* pSelector = GTK_COMBO_BOX_TEXT(priv->m_pRecentUnoSelector);
214 unsigned counter = 0;
215 std::ifstream is("/tmp/gtv-recentunos.txt");
216 while (is.good() && counter < 10)
218 std::string unoCommandStr;
219 std::getline(is, unoCommandStr);
220 std::vector<std::string> aUnoCmd = GtvHelpers::split<std::string>(unoCommandStr, " | ", 2);
221 if (aUnoCmd.size() != 2)
222 continue;
223 auto it = priv->m_pRecentUnoCommands.emplace(aUnoCmd[0], aUnoCmd[1]);
224 if (it.second)
226 gtk_combo_box_text_append_text(pSelector, aUnoCmd[0].c_str());
227 ++counter;
232 void
233 gtv_main_toolbar_doc_loaded(GtvMainToolbar* toolbar, LibreOfficeKitDocumentType eDocType, bool bEditMode)
235 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
236 gtk_widget_set_visible(toolbar->m_pAddressbar, false);
237 gtk_widget_set_visible(toolbar->m_pFormulabar, false);
238 if (eDocType == LOK_DOCTYPE_SPREADSHEET)
240 gtk_tool_button_set_label(GTK_TOOL_BUTTON(priv->m_pLeftpara), ".uno:AlignLeft");
241 gtk_tool_button_set_label(GTK_TOOL_BUTTON(priv->m_pCenterpara), ".uno:AlignHorizontalCenter");
242 gtk_tool_button_set_label(GTK_TOOL_BUTTON(priv->m_pRightpara), ".uno:AlignRight");
243 gtk_widget_hide(priv->m_pJustifypara);
244 gtk_tool_button_set_label(GTK_TOOL_BUTTON(priv->m_pDeleteComment), ".uno:DeleteNote");
246 gtk_widget_set_visible(toolbar->m_pAddressbar, true);
247 gtk_widget_set_visible(toolbar->m_pFormulabar, true);
249 else if (eDocType == LOK_DOCTYPE_PRESENTATION)
251 gtk_tool_button_set_label(GTK_TOOL_BUTTON(priv->m_pDeleteComment), ".uno:DeleteAnnotation");
254 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(priv->m_pEnableEditing), bEditMode);
256 // populate combo boxes
257 populatePartSelector(toolbar);
259 // populate recent uno selector
260 populateRecentUnoSelector(toolbar);
263 void
264 gtv_main_toolbar_add_recent_uno(GtvMainToolbar* toolbar, const std::string& rUnoCmdStr)
266 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
267 GtkComboBoxText* pSelector = GTK_COMBO_BOX_TEXT(priv->m_pRecentUnoSelector);
269 const std::vector<std::string> aUnoCmd = GtvHelpers::split<std::string>(rUnoCmdStr, " | ", 2);
270 priv->m_pRecentUnoCommands[aUnoCmd[0]] = aUnoCmd[1];
271 // keep placeholder string at the top
272 gtk_combo_box_text_insert_text(pSelector, 1, aUnoCmd[0].c_str());
273 // TODO: Remove other text entries with same key
276 std::string
277 gtv_main_toolbar_get_recent_uno_args(GtvMainToolbar* toolbar, const std::string& rUnoCmd)
279 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
280 auto it = std::find_if(priv->m_pRecentUnoCommands.begin(), priv->m_pRecentUnoCommands.end(),
281 [&rUnoCmd](const std::pair<std::string, std::string>& pair) {
282 return rUnoCmd == pair.first;
284 std::string ret;
285 if (it != priv->m_pRecentUnoCommands.end())
286 ret = it->second;
287 return ret;
290 GtkContainer*
291 gtv_main_toolbar_get_first_toolbar(GtvMainToolbar* toolbar)
293 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
294 return GTK_CONTAINER(priv->toolbar1);
297 GtkContainer*
298 gtv_main_toolbar_get_second_toolbar(GtvMainToolbar* toolbar)
300 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
301 return GTK_CONTAINER(priv->toolbar2);
304 void
305 gtv_main_toolbar_set_sensitive_internal(GtvMainToolbar* toolbar, GtkToolItem* pItem, bool isSensitive)
307 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
308 priv->m_aToolItemSensitivities[pItem] = isSensitive;
311 static void setSensitiveIfEdit(GtvMainToolbar* toolbar, GtkToolItem* pItem, bool bEdit)
313 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
314 // some buttons remain enabled always
315 const gchar* pIconName = gtk_tool_button_get_icon_name(GTK_TOOL_BUTTON(pItem));
316 if (g_strcmp0(pIconName, "zoom-in-symbolic") != 0 &&
317 g_strcmp0(pIconName, "zoom-original-symbolic") != 0 &&
318 g_strcmp0(pIconName, "zoom-out-symbolic") != 0 &&
319 g_strcmp0(pIconName, "insert-text-symbolic") != 0 &&
320 g_strcmp0(pIconName, "view-continuous-symbolic") != 0 &&
321 g_strcmp0(pIconName, "document-properties") != 0 &&
322 g_strcmp0(pIconName, "system-run") != 0)
324 bool state = true;
325 if (priv->m_aToolItemSensitivities.find(pItem) != priv->m_aToolItemSensitivities.end())
326 state = priv->m_aToolItemSensitivities[pItem];
328 gtk_widget_set_sensitive(GTK_WIDGET(pItem), bEdit && state);
332 void
333 gtv_main_toolbar_set_edit(GtvMainToolbar* toolbar, gboolean bEdit)
335 GtvMainToolbarPrivate& priv = getPrivate(toolbar);
336 GtvGtkWrapper<GList> pList(gtk_container_get_children(GTK_CONTAINER(priv->toolbar1)),
337 [](GList* l)
339 g_list_free(l);
341 for (GList* l = pList.get(); l != nullptr; l = l->next)
343 if (GTK_IS_TOOL_BUTTON(l->data))
345 setSensitiveIfEdit(toolbar, GTK_TOOL_ITEM(l->data), bEdit);
349 pList.reset(gtk_container_get_children(GTK_CONTAINER(priv->toolbar2)));
350 for (GList* l = pList.get(); l != nullptr; l = l->next)
352 if (GTK_IS_TOOL_BUTTON(l->data))
354 setSensitiveIfEdit(toolbar, GTK_TOOL_ITEM(l->data), bEdit);
359 GtkWidget*
360 gtv_main_toolbar_new()
362 return GTK_WIDGET(g_object_new(GTV_TYPE_MAIN_TOOLBAR,
363 "orientation", GTK_ORIENTATION_VERTICAL,
364 nullptr));
367 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */