~ubuntu-branches/debian/experimental/geany/experimental

« back to all changes in this revision

Viewing changes to plugins/htmlchars.c

  • Committer: Bazaar Package Importer
  • Author(s): Damián Viano
  • Date: 2008-05-02 11:37:45 UTC
  • mfrom: (1.2.1 upstream) (3.1.6 hardy)
  • Revision ID: james.westby@ubuntu.com-20080502113745-xzp4g6dmovrpoj17
Tags: 0.14-1
New upstream release (Closes: #478126)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      htmlchars.c - this file is part of Geany, a fast and lightweight IDE
 
3
 *
 
4
 *      Copyright 2006-2008 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
 
5
 *      Copyright 2007-2008 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
 
6
 *
 
7
 *      This program is free software; you can redistribute it and/or modify
 
8
 *      it under the terms of the GNU General Public License as published by
 
9
 *      the Free Software Foundation; either version 2 of the License, or
 
10
 *      (at your option) any later version.
 
11
 *
 
12
 *      This program is distributed in the hope that it will be useful,
 
13
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *      GNU General Public License for more details.
 
16
 *
 
17
 *      You should have received a copy of the GNU General Public License
 
18
 *      along with this program; if not, write to the Free Software
 
19
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
20
 *      MA 02110-1301, USA.
 
21
 *
 
22
 * $Id: htmlchars.c 2411 2008-03-26 17:10:18Z ntrel $
 
23
 */
 
24
 
 
25
/* HTML Characters plugin (Inserts HTML character entities like '&amp;') */
 
26
 
 
27
#include "geany.h"
 
28
#include "support.h"
 
29
#include "plugindata.h"
 
30
#include "document.h"
 
31
#include "keybindings.h"
 
32
#include "pluginmacros.h"
 
33
 
 
34
 
 
35
PluginFields    *plugin_fields;
 
36
GeanyData               *geany_data;
 
37
 
 
38
 
 
39
PLUGIN_VERSION_CHECK(48)
 
40
 
 
41
PLUGIN_INFO(_("HTML Characters"), _("Inserts HTML character entities like '&amp;'."), VERSION,
 
42
        _("The Geany developer team"))
 
43
 
 
44
 
 
45
/* Keybinding(s) */
 
46
enum
 
47
{
 
48
        KB_INSERT_HTML_CHARS,
 
49
        KB_COUNT
 
50
};
 
51
 
 
52
PLUGIN_KEY_GROUP(html_chars, KB_COUNT)
 
53
 
 
54
 
 
55
enum
 
56
{
 
57
        COLUMN_CHARACTER,
 
58
        COLUMN_HTML_NAME,
 
59
        N_COLUMNS
 
60
};
 
61
 
 
62
 
 
63
static GtkWidget *sc_dialog = NULL;
 
64
static GtkTreeStore *sc_store = NULL;
 
65
static GtkTreeView *sc_tree = NULL;
 
66
 
 
67
static void sc_on_tools_show_dialog_insert_special_chars_response
 
68
                (GtkDialog *dialog, gint response, gpointer user_data);
 
69
static void sc_on_tree_row_activated
 
70
                (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data);
 
71
static void sc_fill_store(GtkTreeStore *store);
 
72
static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter);
 
73
 
 
74
 
 
75
static void tools_show_dialog_insert_special_chars(void)
 
76
{
 
77
        if (sc_dialog == NULL)
 
78
        {
 
79
                gint height;
 
80
                GtkCellRenderer *renderer;
 
81
                GtkTreeViewColumn *column;
 
82
                GtkWidget *swin, *vbox, *label;
 
83
 
 
84
                sc_dialog = gtk_dialog_new_with_buttons(
 
85
                                        _("Special Characters"), GTK_WINDOW(app->window),
 
86
                                        GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
87
                                        _("_Insert"), GTK_RESPONSE_OK, NULL);
 
88
                vbox = p_ui->dialog_vbox_new(GTK_DIALOG(sc_dialog));
 
89
                gtk_box_set_spacing(GTK_BOX(vbox), 6);
 
90
                gtk_widget_set_name(sc_dialog, "GeanyDialog");
 
91
 
 
92
                height = GEANY_WINDOW_MINIMAL_HEIGHT;
 
93
                gtk_window_set_default_size(GTK_WINDOW(sc_dialog), height * 8 / 10, height);
 
94
                gtk_dialog_set_default_response(GTK_DIALOG(sc_dialog), GTK_RESPONSE_CANCEL);
 
95
 
 
96
                label = gtk_label_new(_("Choose a special character from the list below and double click on it or use the button to insert it at the current cursor position."));
 
97
                gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 
98
                gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
99
                gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
100
 
 
101
                sc_tree = GTK_TREE_VIEW(gtk_tree_view_new());
 
102
 
 
103
                sc_store = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
 
104
                gtk_tree_view_set_model(GTK_TREE_VIEW(sc_tree),
 
105
                                                                GTK_TREE_MODEL(sc_store));
 
106
 
 
107
                renderer = gtk_cell_renderer_text_new();
 
108
                column = gtk_tree_view_column_new_with_attributes(
 
109
                                                                _("Character"), renderer, "text", COLUMN_CHARACTER, NULL);
 
110
                gtk_tree_view_column_set_resizable(column, TRUE);
 
111
                gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
 
112
 
 
113
                renderer = gtk_cell_renderer_text_new();
 
114
                column = gtk_tree_view_column_new_with_attributes(
 
115
                                                                _("HTML (name)"), renderer, "text", COLUMN_HTML_NAME, NULL);
 
116
                gtk_tree_view_column_set_resizable(column, TRUE);
 
117
                gtk_tree_view_append_column(GTK_TREE_VIEW(sc_tree), column);
 
118
 
 
119
                swin = gtk_scrolled_window_new(NULL, NULL);
 
120
                gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin), GTK_POLICY_AUTOMATIC,
 
121
                        GTK_POLICY_AUTOMATIC);
 
122
                gtk_scrolled_window_add_with_viewport(
 
123
                                        GTK_SCROLLED_WINDOW(swin), GTK_WIDGET(sc_tree));
 
124
 
 
125
                gtk_box_pack_start(GTK_BOX(vbox), swin, TRUE, TRUE, 0);
 
126
 
 
127
                g_signal_connect((gpointer) sc_tree, "row-activated",
 
128
                                        G_CALLBACK(sc_on_tree_row_activated), NULL);
 
129
 
 
130
                g_signal_connect((gpointer) sc_dialog, "response",
 
131
                                        G_CALLBACK(sc_on_tools_show_dialog_insert_special_chars_response), NULL);
 
132
 
 
133
                g_signal_connect((gpointer) sc_dialog, "delete_event",
 
134
                                        G_CALLBACK(gtk_widget_hide_on_delete), NULL);
 
135
 
 
136
                sc_fill_store(sc_store);
 
137
 
 
138
                /*gtk_tree_view_expand_all(special_characters_tree);*/
 
139
                gtk_tree_view_set_search_column(sc_tree, COLUMN_HTML_NAME);
 
140
        }
 
141
        gtk_widget_show_all(sc_dialog);
 
142
}
 
143
 
 
144
 
 
145
/* fill the tree model with data
 
146
 ** TODO move this in a file and make it extendable for more data types */
 
147
static void sc_fill_store(GtkTreeStore *store)
 
148
{
 
149
        GtkTreeIter iter;
 
150
        GtkTreeIter *parent_iter = NULL;
 
151
        guint i;
 
152
 
 
153
        gchar *chars[][2] =
 
154
                {
 
155
                        { _("HTML characters"), NULL },
 
156
                        { "\"", "&quot;" },
 
157
                        { "&", "&amp;" },
 
158
                        { "<", "&lt;" },
 
159
                        { ">", "&gt;" },
 
160
 
 
161
                        { _("ISO 8859-1 characters"), NULL },
 
162
                        { " ", "&nbsp;" },
 
163
                        { "¡", "&iexcl;" },
 
164
                        { "¢", "&cent;" },
 
165
                        { "£", "&pound;" },
 
166
                        { "¤", "&curren;" },
 
167
                        { "¥", "&yen;" },
 
168
                        { "¦", "&brvbar;" },
 
169
                        { "§", "&sect;" },
 
170
                        { "¨", "&uml;" },
 
171
                        { "©", "&copy;" },
 
172
                        { "®", "&reg;" },
 
173
                        { "«", "&laquo;" },
 
174
                        { "»", "&raquo;" },
 
175
                        { "¬", "&not;" },
 
176
                        { " ", "&shy;" },
 
177
                        { "¯", "&macr;" },
 
178
                        { "°", "&deg;" },
 
179
                        { "±", "&plusmn;" },
 
180
                        { "¹", "&sup1;" },
 
181
                        { "²", "&sup2;" },
 
182
                        { "³", "&sup3;" },
 
183
                        { "¼", "&frac14;" },
 
184
                        { "½", "&frac12;" },
 
185
                        { "¾", "&frac34;" },
 
186
                        { "×", "&times;" },
 
187
                        { "÷", "&divide;" },
 
188
                        { "´", "&acute;" },
 
189
                        { "µ", "&micro;" },
 
190
                        { "¶", "&para;" },
 
191
                        { "·", "&middot;" },
 
192
                        { "¸", "&cedil;" },
 
193
                        { "ª", "&ordf;" },
 
194
                        { "º", "&ordm;" },
 
195
                        { "¿", "&iquest;" },
 
196
                        { "À", "&Agrave;" },
 
197
                        { "Á", "&Aacute;" },
 
198
                        { "Â", "&Acirc;" },
 
199
                        { "Ã", "&Atilde;" },
 
200
                        { "Ä", "&Auml;" },
 
201
                        { "Å", "&Aring;" },
 
202
                        { "Æ", "&AElig;" },
 
203
                        { "Ç", "&Ccedil;" },
 
204
                        { "È", "&Egrave;" },
 
205
                        { "É", "&Eacute;" },
 
206
                        { "Ê", "&Ecirc;" },
 
207
                        { "Ë", "&Euml;" },
 
208
                        { "Ì", "&Igrave;" },
 
209
                        { "Í", "&Iacute;" },
 
210
                        { "Î", "&Icirc;" },
 
211
                        { "Ï", "&Iuml;" },
 
212
                        { "Ð", "&ETH;" },
 
213
                        { "Ñ", "&Ntilde;" },
 
214
                        { "Ò", "&Ograve;" },
 
215
                        { "Ó", "&Oacute;" },
 
216
                        { "Ô", "&Ocirc;" },
 
217
                        { "Õ", "&Otilde;" },
 
218
                        { "Ö", "&Ouml;" },
 
219
                        { "Ø", "&Oslash;" },
 
220
                        { "Ù", "&Ugrave;" },
 
221
                        { "Ú", "&Uacute;" },
 
222
                        { "Û", "&Ucirc;" },
 
223
                        { "Ü", "&Uuml;" },
 
224
                        { "Ý", "&Yacute;" },
 
225
                        { "Þ", "&THORN;" },
 
226
                        { "ß", "&szlig;" },
 
227
                        { "à", "&agrave;" },
 
228
                        { "á", "&aacute;" },
 
229
                        { "â", "&acirc;" },
 
230
                        { "ã", "&atilde;" },
 
231
                        { "ä", "&auml;" },
 
232
                        { "å", "&aring;" },
 
233
                        { "æ", "&aelig;" },
 
234
                        { "ç", "&ccedil;" },
 
235
                        { "è", "&egrave;" },
 
236
                        { "é", "&eacute;" },
 
237
                        { "ê", "&ecirc;" },
 
238
                        { "ë", "&euml;" },
 
239
                        { "ì", "&igrave;" },
 
240
                        { "í", "&iacute;" },
 
241
                        { "î", "&icirc;" },
 
242
                        { "ï", "&iuml;" },
 
243
                        { "ð", "&eth;" },
 
244
                        { "ñ", "&ntilde;" },
 
245
                        { "ò", "&ograve;" },
 
246
                        { "ó", "&oacute;" },
 
247
                        { "ô", "&ocirc;" },
 
248
                        { "õ", "&otilde;" },
 
249
                        { "ö", "&ouml;" },
 
250
                        { "ø", "&oslash;" },
 
251
                        { "ù", "&ugrave;" },
 
252
                        { "ú", "&uacute;" },
 
253
                        { "û", "&ucirc;" },
 
254
                        { "ü", "&uuml;" },
 
255
                        { "ý", "&yacute;" },
 
256
                        { "þ", "&thorn;" },
 
257
                        { "ÿ", "&yuml;" },
 
258
 
 
259
                        { _("Greek characters"), NULL },
 
260
                        { "Α", "&Alpha;" },
 
261
                        { "α", "&alpha;" },
 
262
                        { "Β", "&Beta;" },
 
263
                        { "β", "&beta;" },
 
264
                        { "Γ", "&Gamma;" },
 
265
                        { "γ", "&gamma;" },
 
266
                        { "Δ", "&Delta;" },
 
267
                        { "δ", "&Delta;" },
 
268
                        { "δ", "&delta;" },
 
269
                        { "Ε", "&Epsilon;" },
 
270
                        { "ε", "&epsilon;" },
 
271
                        { "Ζ", "&Zeta;" },
 
272
                        { "ζ", "&zeta;" },
 
273
                        { "Η", "&Eta;" },
 
274
                        { "η", "&eta;" },
 
275
                        { "Θ", "&Theta;" },
 
276
                        { "θ", "&theta;" },
 
277
                        { "Ι", "&Iota;" },
 
278
                        { "ι", "&iota;" },
 
279
                        { "Κ", "&Kappa;" },
 
280
                        { "κ", "&kappa;" },
 
281
                        { "Λ", "&Lambda;" },
 
282
                        { "λ", "&lambda;" },
 
283
                        { "Μ", "&Mu;" },
 
284
                        { "μ", "&mu;" },
 
285
                        { "Ν", "&Nu;" },
 
286
                        { "ν", "&nu;" },
 
287
                        { "Ξ", "&Xi;" },
 
288
                        { "ξ", "&xi;" },
 
289
                        { "Ο", "&Omicron;" },
 
290
                        { "ο", "&omicron;" },
 
291
                        { "Π", "&Pi;" },
 
292
                        { "π", "&pi;" },
 
293
                        { "Ρ", "&Rho;" },
 
294
                        { "ρ", "&rho;" },
 
295
                        { "Σ", "&Sigma;" },
 
296
                        { "ς", "&sigmaf;" },
 
297
                        { "σ", "&sigma;" },
 
298
                        { "Τ", "&Tau;" },
 
299
                        { "τ", "&tau;" },
 
300
                        { "Υ", "&Upsilon;" },
 
301
                        { "υ", "&upsilon;" },
 
302
                        { "Φ", "&Phi;" },
 
303
                        { "φ", "&phi;" },
 
304
                        { "Χ", "&Chi;" },
 
305
                        { "χ", "&chi;" },
 
306
                        { "Ψ", "&Psi;" },
 
307
                        { "ψ", "&psi;" },
 
308
                        { "Ω", "&Omega;" },
 
309
                        { "ω", "&omega;" },
 
310
                        { "ϑ", "&thetasym;" },
 
311
                        { "ϒ", "&upsih;" },
 
312
                        { "ϖ", "&piv;" },
 
313
 
 
314
                        { _("Mathematical characters"), NULL },
 
315
                        { "∀", "&forall;" },
 
316
                        { "∂", "&part;" },
 
317
                        { "∃", "&exist;" },
 
318
                        { "∅", "&empty;" },
 
319
                        { "∇", "&nabla;" },
 
320
                        { "∈", "&isin;" },
 
321
                        { "∉", "&notin;" },
 
322
                        { "∋", "&ni;" },
 
323
                        { "∏", "&prod;" },
 
324
                        { "∑", "&sum;" },
 
325
                        { "−", "&minus;" },
 
326
                        { "∗", "&lowast;" },
 
327
                        { "√", "&radic;" },
 
328
                        { "∝", "&prop;" },
 
329
                        { "∞", "&infin;" },
 
330
                        { "∠", "&ang;" },
 
331
                        { "∧", "&and;" },
 
332
                        { "∨", "&or;" },
 
333
                        { "∩", "&cap;" },
 
334
                        { "∪", "&cup;" },
 
335
                        { "∫", "&int;" },
 
336
                        { "∴", "&there4;" },
 
337
                        { "∼", "&sim;" },
 
338
                        { "≅", "&cong;" },
 
339
                        { "≈", "&asymp;" },
 
340
                        { "≠", "&ne;" },
 
341
                        { "≡", "&equiv;" },
 
342
                        { "≤", "&le;" },
 
343
                        { "≥", "&ge;" },
 
344
                        { "⊂", "&sub;" },
 
345
                        { "⊃", "&sup;" },
 
346
                        { "⊄", "&nsub;" },
 
347
                        { "⊆", "&sube;" },
 
348
                        { "⊇", "&supe;" },
 
349
                        { "⊕", "&oplus;" },
 
350
                        { "⊗", "&otimes;" },
 
351
                        { "⊥", "&perp;" },
 
352
                        { "⋅", "&sdot;" },
 
353
                        { "◊", "&loz;" },
 
354
 
 
355
                        { _("Technical characters"), NULL },
 
356
                        { "⌈", "&lceil;" },
 
357
                        { "⌉", "&rceil;" },
 
358
                        { "⌊", "&lfloor;" },
 
359
                        { "⌋", "&rfloor;" },
 
360
                        { "〈", "&lang;" },
 
361
                        { "〉", "&rang;" },
 
362
 
 
363
                        { _("Arrow characters"), NULL },
 
364
                        { "←", "&larr;" },
 
365
                        { "↑", "&uarr;" },
 
366
                        { "→", "&rarr;" },
 
367
                        { "↓", "&darr;" },
 
368
                        { "↔", "&harr;" },
 
369
                        { "↵", "&crarr;" },
 
370
                        { "⇐", "&lArr;" },
 
371
                        { "⇑", "&uArr;" },
 
372
                        { "⇒", "&rArr;" },
 
373
                        { "⇓", "&dArr;" },
 
374
                        { "⇔", "&hArr;" },
 
375
 
 
376
                        { _("Punctuation characters"), NULL },
 
377
                        { "–", "&ndash;" },
 
378
                        { "—", "&mdash;" },
 
379
                        { "‘", "&lsquo;" },
 
380
                        { "’", "&rsquo;" },
 
381
                        { "‚", "&sbquo;" },
 
382
                        { "“", "&ldquo;" },
 
383
                        { "”", "&rdquo;" },
 
384
                        { "„", "&bdquo;" },
 
385
                        { "†", "&dagger;" },
 
386
                        { "‡", "&Dagger;" },
 
387
                        { "…", "&hellip;" },
 
388
                        { "‰", "&permil;" },
 
389
                        { "‹", "&lsaquo;" },
 
390
                        { "›", "&rsaquo;" },
 
391
 
 
392
                        { _("Miscellaneous characters"), NULL },
 
393
                        { "•", "&bull;" },
 
394
                        { "′", "&prime;" },
 
395
                        { "″", "&Prime;" },
 
396
                        { "‾", "&oline;" },
 
397
                        { "⁄", "&frasl;" },
 
398
                        { "℘", "&weierp;" },
 
399
                        { "ℑ", "&image;" },
 
400
                        { "ℜ", "&real;" },
 
401
                        { "™", "&trade;" },
 
402
                        { "€", "&euro;" },
 
403
                        { "ℵ", "&alefsym;" },
 
404
                        { "♠", "&spades;" },
 
405
                        { "♣", "&clubs;" },
 
406
                        { "♥", "&hearts;" },
 
407
                        { "♦", "&diams;" },
 
408
                        { "Œ", "&OElig;" },
 
409
                        { "œ", "&oelig;" },
 
410
                        { "Š", "&Scaron;" },
 
411
                        { "š", "&scaron;" },
 
412
                        { "Ÿ", "&Yuml;" },
 
413
                        { "ƒ", "&fnof;" },
 
414
                };
 
415
 
 
416
        for (i = 0; i < G_N_ELEMENTS(chars); i++)
 
417
        {
 
418
                if (chars[i][1] == NULL)
 
419
                {       /* add a category */
 
420
                        gtk_tree_store_append(store, &iter, NULL);
 
421
                        gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0], -1);
 
422
                        if (parent_iter != NULL) gtk_tree_iter_free(parent_iter);
 
423
                        parent_iter = gtk_tree_iter_copy(&iter);
 
424
                }
 
425
                else
 
426
                {       /* add child to parent_iter */
 
427
                        gtk_tree_store_append(store, &iter, parent_iter);
 
428
                        gtk_tree_store_set(store, &iter, COLUMN_CHARACTER, chars[i][0],
 
429
                                                                                         COLUMN_HTML_NAME, chars[i][1], -1);
 
430
                }
 
431
        }
 
432
}
 
433
 
 
434
 
 
435
/* just inserts the HTML_NAME coloumn of the selected row at current position
 
436
 * returns only TRUE if a valid selection(i.e. no category) could be found */
 
437
static gboolean sc_insert(GtkTreeModel *model, GtkTreeIter *iter)
 
438
{
 
439
        gint idx = p_document->get_cur_idx();
 
440
        gboolean result = FALSE;
 
441
 
 
442
        if (DOC_IDX_VALID(idx))
 
443
        {
 
444
                gchar *str;
 
445
                gint pos = p_sci->get_current_position(doc_list[idx].sci);
 
446
 
 
447
                gtk_tree_model_get(model, iter, COLUMN_HTML_NAME, &str, -1);
 
448
                if (str && *str)
 
449
                {
 
450
                        p_sci->insert_text(doc_list[idx].sci, pos, str);
 
451
                        g_free(str);
 
452
                        result = TRUE;
 
453
                }
 
454
        }
 
455
        return result;
 
456
}
 
457
 
 
458
 
 
459
static void sc_on_tools_show_dialog_insert_special_chars_response(GtkDialog *dialog, gint response,
 
460
                                                                                                                gpointer user_data)
 
461
{
 
462
        if (response == GTK_RESPONSE_OK)
 
463
        {
 
464
                GtkTreeSelection *selection;
 
465
                GtkTreeModel *model;
 
466
                GtkTreeIter iter;
 
467
 
 
468
                selection = gtk_tree_view_get_selection(sc_tree);
 
469
 
 
470
                if (gtk_tree_selection_get_selected(selection, &model, &iter))
 
471
                {
 
472
                        /* only hide dialog if selection was not a category */
 
473
                        if (sc_insert(model, &iter))
 
474
                                gtk_widget_hide(GTK_WIDGET(dialog));
 
475
                }
 
476
        }
 
477
        else
 
478
                gtk_widget_hide(GTK_WIDGET(dialog));
 
479
}
 
480
 
 
481
 
 
482
static void sc_on_tree_row_activated(GtkTreeView *treeview, GtkTreePath *path,
 
483
                                                                                          GtkTreeViewColumn *col, gpointer user_data)
 
484
{
 
485
        GtkTreeIter iter;
 
486
        GtkTreeModel *model = GTK_TREE_MODEL(sc_store);
 
487
 
 
488
        if (gtk_tree_model_get_iter(model, &iter, path))
 
489
        {
 
490
                /* only hide dialog if selection was not a category */
 
491
                if (sc_insert(model, &iter))
 
492
                        gtk_widget_hide(sc_dialog);
 
493
                else
 
494
                {       /* double click on a category to toggle the expand or collapse it */
 
495
                        if (gtk_tree_view_row_expanded(sc_tree, path))
 
496
                                gtk_tree_view_collapse_row(sc_tree, path);
 
497
                        else
 
498
                                gtk_tree_view_expand_row(sc_tree, path, FALSE);
 
499
                }
 
500
        }
 
501
}
 
502
 
 
503
 
 
504
/* Callback when the menu item is clicked */
 
505
static void
 
506
item_activate(GtkMenuItem *menuitem, gpointer gdata)
 
507
{
 
508
        /* refuse opening the dialog if we don't have an active tab */
 
509
        gint idx = p_document->get_cur_idx();
 
510
 
 
511
        if (idx == -1 || ! doc_list[idx].is_valid) return;
 
512
 
 
513
        tools_show_dialog_insert_special_chars();
 
514
}
 
515
 
 
516
 
 
517
static void kb_activate(G_GNUC_UNUSED guint key_id)
 
518
{
 
519
        item_activate(NULL, NULL);
 
520
}
 
521
 
 
522
 
 
523
/* Called by Geany to initialize the plugin */
 
524
void init(GeanyData *data)
 
525
{
 
526
        GtkWidget *demo_item;
 
527
        const gchar *menu_text = _("_Insert Special HTML Characters");
 
528
        gchar *kb_label = _("Insert Special HTML Characters");
 
529
 
 
530
        /* Add an item to the Tools menu */
 
531
        demo_item = gtk_menu_item_new_with_mnemonic(menu_text);
 
532
        gtk_widget_show(demo_item);
 
533
        gtk_container_add(GTK_CONTAINER(geany_data->tools_menu), demo_item);
 
534
        g_signal_connect(G_OBJECT(demo_item), "activate", G_CALLBACK(item_activate), NULL);
 
535
 
 
536
        /* disable menu_item when there are no documents open */
 
537
        plugin_fields->menu_item = demo_item;
 
538
        plugin_fields->flags = PLUGIN_IS_DOCUMENT_SENSITIVE;
 
539
 
 
540
        /* setup keybindings */
 
541
        p_keybindings->set_item(plugin_key_group, KB_INSERT_HTML_CHARS, kb_activate,
 
542
                0, 0, "insert_html_chars", kb_label, demo_item);
 
543
}
 
544
 
 
545
 
 
546
/* Destroy widgets */
 
547
void cleanup(void)
 
548
{
 
549
        gtk_widget_destroy(plugin_fields->menu_item);
 
550
 
 
551
        if (sc_dialog != NULL)
 
552
                gtk_widget_destroy(sc_dialog);
 
553
}
 
554
 
 
555