1 /* Bluefish HTML Editor
2 * htmlbar.c - plugin for html toolbar
3 *
4 * Copyright (C) 2002-2011 Olivier Sessink
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 /*#define DEBUG*/
20
21 #include <string.h>
22
23 #include "htmlbar.h"
24 #include <gmodule.h>
25 #include "../plugins.h"
26 #include "../rcfile.h"
27 #include "../bfwin_uimanager.h" /* bfwin_set_menu_toggle_item() */
28 #include "../document.h"
29 #include "../gtk_easy.h"
30 #include "../stringlist.h"
31 #include "../pixmap.h"
32 #include "htmlbar_uimanager.h"
33 #include "htmlbar_stock_icons.h"
34 #include "rpopup.h"
35 #include "prefs.h"
36
37 Thtmlbar htmlbar_v = {NULL, NULL, 0, 0, 1};
38
39 static void
htmlbar_doc_view_populate_popup(GtkTextView * textview,GtkMenu * menu,Tdocument * doc)40 htmlbar_doc_view_populate_popup(GtkTextView * textview, GtkMenu * menu, Tdocument * doc)
41 {
42 GtkWidget *menuitem;
43 DEBUG_MSG("htmlbar_doc_view_populate_popup, called\n");
44
45 menuitem = gtk_image_menu_item_new_with_label(_("Edit color"));
46 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), GTK_WIDGET(menuitem));
47 if (rpopup_doc_located_color(doc)) {
48 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(rpopup_edit_color_cb), doc);
49 } else {
50 gtk_widget_set_sensitive(menuitem, FALSE);
51 }
52
53 menuitem = gtk_image_menu_item_new_with_label(_("Edit tag"));
54 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem),
55 gtk_image_new_from_stock(BF_STOCK_EDIT_TAG, GTK_ICON_SIZE_MENU));
56 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), GTK_WIDGET(menuitem));
57 if (rpopup_doc_located_tag(doc)) {
58 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(rpopup_edit_tag_cb), doc);
59 } else {
60 gtk_widget_set_sensitive(menuitem, FALSE);
61 }
62 }
63
64 static void
htmlbar_doc_view_button_press(GtkWidget * widget,GdkEventButton * bevent,Tdocument * doc)65 htmlbar_doc_view_button_press(GtkWidget * widget, GdkEventButton * bevent, Tdocument * doc)
66 {
67 DEBUG_MSG("htmlbar_doc_view_button_press, called\n");
68 if (bevent->button == 3) {
69 rpopup_bevent_in_html_code(doc);
70 }
71 }
72
73 static void
htmlbar_sidepanel_initgui(Tbfwin * bfwin)74 htmlbar_sidepanel_initgui(Tbfwin *bfwin)
75 {
76 DEBUG_MSG("htmlbar_sidepanel_initgui, in_sidepanel=%d\n",htmlbar_v.in_sidepanel);
77 if (htmlbar_v.in_sidepanel && bfwin->leftpanel_notebook) {
78 Thtmlbarwin *hbw;
79 Thtmlbarsession *hbs;
80 GtkWidget *html_notebook;
81 GtkWidget *image;
82
83 hbs = g_hash_table_lookup(htmlbar_v.lookup, bfwin->session);
84 hbw = g_hash_table_lookup(htmlbar_v.lookup, bfwin);
85 if (!hbw || !hbs) {
86 g_warning("htmlbar, no hbw/hbs when creating sidebar, please report");
87 return;
88 }
89
90 image = gtk_image_new_from_stock(BF_STOCK_BROWSER_PREVIEW, GTK_ICON_SIZE_LARGE_TOOLBAR);
91 html_notebook = htmlbar_toolbar_create(hbw, hbs);
92 DEBUG_MSG("htmlbar_sidepanel_initgui, html_notebook=%p\n",html_notebook);
93 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(html_notebook), GTK_POS_LEFT);
94 gtk_widget_show_all(html_notebook);
95 DEBUG_MSG("htmlbar_sidepanel_initgui, append html_notebook=%p to leftpanel_notebook %p and image %p\n",html_notebook, bfwin->leftpanel_notebook, image);
96 gtk_notebook_append_page_menu(GTK_NOTEBOOK(bfwin->leftpanel_notebook),html_notebook,image,gtk_label_new(_("Htmlbar")));
97 DEBUG_MSG("handlebox=%p\n",hbw->handlebox);
98 if (hbw->handlebox) {
99 DEBUG_MSG("htmlbar_sidepanel_initgui, destroy hbw->handlebox %p\n",hbw->handlebox);
100 gtk_widget_destroy(hbw->handlebox);
101 hbw->handlebox = NULL;
102 }
103
104 }
105 }
106
107 /*static void
108 htmlbar_sidepanel_destroygui(Tbfwin *bfwin)
109 {
110
111 }
112 */
113 static void
htmlbar_init(void)114 htmlbar_init(void)
115 {
116 #ifdef ENABLE_NLS
117 DEBUG_MSG("htmlbar_init, gettext domain-name=%s\n", PACKAGE "_plugin_htmlbar");
118 bindtextdomain(PACKAGE "_plugin_htmlbar", LOCALEDIR);
119 bind_textdomain_codeset(PACKAGE "_plugin_htmlbar", "UTF-8");
120 #endif
121 htmlbar_v.quickbar_items = NULL;
122 htmlbar_v.in_sidepanel = 0;
123 htmlbar_v.lowercase_tags = 1;
124
125 htmlbar_v.lookup = g_hash_table_new_full(NULL /* == g_direct_hash() */ ,
126 NULL /* == g_direct_equal() */ ,
127 NULL, g_free);
128 DEBUG_MSG("htmlbar_init, will add doc_view_button_press %p\n", htmlbar_doc_view_button_press);
129 main_v->doc_view_populate_popup_cbs =
130 g_slist_prepend(main_v->doc_view_populate_popup_cbs, htmlbar_doc_view_populate_popup);
131 main_v->doc_view_button_press_cbs =
132 g_slist_prepend(main_v->doc_view_button_press_cbs, htmlbar_doc_view_button_press);
133 main_v->pref_initgui =
134 g_slist_prepend(main_v->pref_initgui, htmlbar_pref_initgui);
135 main_v->pref_apply =
136 g_slist_prepend(main_v->pref_apply, htmlbar_pref_apply);
137 main_v->sidepanel_initgui = g_slist_prepend(main_v->sidepanel_initgui,htmlbar_sidepanel_initgui);
138 /* main_v->sidepanel_destroygui = g_slist_prepend(main_v->sidepanel_destroygui,htmlbar_sidepanel_destroygui);*/
139 DEBUG_MSG("htmlbar_init, finished\n");
140 }
141
142 static void
htmlbar_initgui(Tbfwin * bfwin)143 htmlbar_initgui(Tbfwin * bfwin)
144 {
145 Thtmlbarwin *hbw;
146 Thtmlbarsession *hbs;
147 GtkAction *action;
148
149 hbw = g_new0(Thtmlbarwin, 1);
150 hbw->bfwin = bfwin;
151 if (g_hash_table_size(htmlbar_v.lookup)==1) { /* the first entry is the global session, so we make sure now we run this code only once! */
152 htmlbar_register_stock_icons();
153 }
154
155 g_hash_table_insert(htmlbar_v.lookup, bfwin, hbw);
156 DEBUG_MSG("htmlbar_initgui, adding hbw %p to hashtable %p with key %p\n", hbw, htmlbar_v.lookup, bfwin);
157 hbs = g_hash_table_lookup(htmlbar_v.lookup, bfwin->session);
158 if (!hbs) {
159 hbs = g_new0(Thtmlbarsession, 1);
160 hbs->view_htmlbar = TRUE;
161 DEBUG_MSG("htmlbar_initgui, adding hbs %p to hashtable %p with key %p\n", hbs, htmlbar_v.lookup,
162 bfwin->session);
163 g_hash_table_insert(htmlbar_v.lookup, bfwin->session, hbs);
164 }
165 DEBUG_MSG("htmlbar_initgui, created hbw=%p and hbs=%p, will call htmlbar_load_ui\n",hbw,hbs);
166 htmlbar_load_ui(hbw);
167 htmlbar_menu_create(hbw);
168 action = gtk_ui_manager_get_action(bfwin->uimanager, "/MainMenu/ViewMenu/ViewHTMLToolbar");
169 if (!htmlbar_v.in_sidepanel) {
170 htmlbar_toolbar_show(hbw, hbs, hbs->view_htmlbar);
171 gtk_action_set_visible(action, TRUE);
172 } else {
173 gtk_action_set_visible(action, FALSE);
174 }
175 DEBUG_MSG("htmlbar_initgui, finished\n");
176 }
177
178 static void
htmlbar_enforce_session(Tbfwin * bfwin)179 htmlbar_enforce_session(Tbfwin * bfwin)
180 {
181 Thtmlbarsession *hbs;
182 Thtmlbarwin *hbw;
183 DEBUG_MSG("htmlbar_enforce_session, started for session %p\n", bfwin->session);
184 hbs = g_hash_table_lookup(htmlbar_v.lookup, bfwin->session);
185 hbw = g_hash_table_lookup(htmlbar_v.lookup, bfwin);
186 if (!hbs || !hbw) {
187 return;
188 }
189 if (!htmlbar_v.in_sidepanel) {
190 htmlbar_toolbar_show(hbw, hbs, hbs->view_htmlbar);
191 bfwin_set_menu_toggle_item(hbw->actiongroup, "ViewHTMLToolbar", hbs->view_htmlbar);
192 }
193 }
194
195 static void
htmlbar_cleanup(void)196 htmlbar_cleanup(void)
197 {
198 GList *tmplist = g_list_first(gtk_window_list_toplevels());
199 while (tmplist) {
200 if (GTK_IS_WIDGET(tmplist->data)) {
201 const gchar *role = gtk_window_get_role((GtkWindow *) tmplist->data);
202 if (role && strcmp(role, "html_dialog") == 0) {
203 gtk_widget_hide(GTK_WIDGET(tmplist->data));
204 window_destroy(GTK_WIDGET(tmplist->data));
205 }
206 }
207 tmplist = g_list_next(tmplist);
208 }
209
210 free_stringlist(htmlbar_v.quickbar_items);
211 g_hash_table_unref(htmlbar_v.lookup);
212 main_v->doc_view_populate_popup_cbs =
213 g_slist_remove(main_v->doc_view_populate_popup_cbs, htmlbar_doc_view_populate_popup);
214 main_v->doc_view_button_press_cbs =
215 g_slist_remove(main_v->doc_view_button_press_cbs, htmlbar_doc_view_button_press);
216
217 }
218
219 static void
htmlbar_cleanup_gui(Tbfwin * bfwin)220 htmlbar_cleanup_gui(Tbfwin * bfwin)
221 {
222 /* BUG: clean the keys and structures in the hashtable */
223 DEBUG_MSG("htmlbar_cleanup_gui, cleanup bfwin %p\n",bfwin);
224 g_hash_table_remove(htmlbar_v.lookup, bfwin);
225 }
226
227 static GHashTable *
htmlbar_register_globses_config(GHashTable * configlist)228 htmlbar_register_globses_config(GHashTable * configlist)
229 {
230 DEBUG_MSG("htmlbar_register_globses_config, started\n");
231 configlist = make_config_list_item(configlist, &htmlbar_v.in_sidepanel, 'i', "htmlbar_in_sidepanel:", 0);
232 configlist = make_config_list_item(configlist, &htmlbar_v.quickbar_items, 'l', "htmlbar_quickbar:", 0);
233 configlist = make_config_list_item(configlist, &htmlbar_v.lowercase_tags, 'i', "lowercase_tags:", 0);
234 configlist = make_config_list_item(configlist, &htmlbar_v.transient_htdialogs, 'i', "htmlbar_transient:", 0);
235 return configlist;
236 }
237
238 static GHashTable *
htmlbar_register_session_config(GHashTable * configlist,Tsessionvars * session)239 htmlbar_register_session_config(GHashTable * configlist, Tsessionvars * session)
240 {
241 Thtmlbarsession *hbs;
242 DEBUG_MSG("htmlbar_register_session_config, started for %p\n", session);
243 hbs = g_hash_table_lookup(htmlbar_v.lookup, session);
244 if (!hbs) {
245 hbs = g_new0(Thtmlbarsession, 1);
246 hbs->view_htmlbar = TRUE;
247 hbs->thumbnailwidth = 300;
248 g_hash_table_insert(htmlbar_v.lookup, session, hbs);
249 DEBUG_MSG("htmlbar_register_session_config, adding hbs %p to hashtable %p with key %p\n", hbs,
250 htmlbar_v.lookup, session);
251 }
252 configlist = make_config_list_item(configlist, &hbs->view_htmlbar, 'i', "htmlbar_view:", 0);
253 configlist = make_config_list_item(configlist, &hbs->notebooktab, 'i', "htmlbar_notebooktab:", 0);
254 configlist = make_config_list_item(configlist, &hbs->thumbnailwidth, 'i', "htmlbar_thumbnailwidth:", 0);
255 return configlist;
256 }
257
258 static void
htmlbar_session_cleanup(Tsessionvars * session)259 htmlbar_session_cleanup(Tsessionvars * session)
260 {
261 DEBUG_MSG("htmlbar_session_cleanup, cleanup session %p\n", session);
262 g_hash_table_remove(htmlbar_v.lookup, session);
263 }
264
265
266 static TBluefishPlugin bfplugin = {
267 N_("HTML Features"),
268 BFPLUGIN_VERSION,
269 GTK_MAJOR_VERSION,
270 sizeof(Tdocument),
271 sizeof(Tsessionvars),
272 sizeof(Tglobalsession),
273 sizeof(Tbfwin),
274 sizeof(Tproject),
275 sizeof(Tmain),
276 sizeof(Tproperties),
277 BFPLUGIN_PRIORITY_DEFAULT,
278 1,
279 NULL, /* private */
280 htmlbar_init, /* init */
281 htmlbar_initgui,
282 htmlbar_enforce_session,
283 htmlbar_cleanup,
284 htmlbar_cleanup_gui,
285 htmlbar_register_globses_config,
286 htmlbar_register_session_config,
287 htmlbar_session_cleanup,
288 NULL, /* binary compatibility */
289 NULL,
290 NULL
291 };
292
293 G_MODULE_EXPORT TBluefishPlugin *
getplugin(void)294 getplugin(void)
295 {
296 return &bfplugin;
297 }
298