1 /*
2 * latex.c - Plugin to let Geany better work together with LaTeX
3 *
4 * Copyright 2007-2015 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
5 * Copyright 2005-2009 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
6 * Copyright 2006-2009 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
7 *
8 * For long list of friendly supporters please have a look at THANKS.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 /* LaTeX plugin */
26 /* This plugin improves the work with LaTeX and Geany.*/
27
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h" /* for the gettext domain */
31 #endif
32
33 #include <glib/gstdio.h>
34 #include "latex.h"
35 #include "ctype.h"
36
37 PLUGIN_VERSION_CHECK(224)
38
39 PLUGIN_SET_TRANSLATABLE_INFO(
40 LOCALEDIR,
41 GETTEXT_PACKAGE,
42 _("LaTeX"),
43 _("Extends LaTeX support"),
44 "0.7",
45 "Frank Lanitz <frank@frank.uvena.de>")
46
47 GeanyPlugin *geany_plugin;
48 GeanyData *geany_data;
49
50 /* Widgets for plugin */
51 static GtkWidget *menu_latex = NULL;
52 static GtkWidget *menu_bibtex = NULL;
53 static GtkWidget *menu_bibtex_menu = NULL;
54 static GtkWidget *menu_latex_menu = NULL;
55 static GtkWidget *menu_latex_wizard = NULL;
56 static GtkWidget *menu_latex_menu_special_char = NULL;
57 static GtkWidget *menu_latex_menu_special_char_submenu = NULL;
58 static GtkWidget *menu_latex_ref = NULL;
59 static GtkWidget *menu_latex_label = NULL;
60 static GtkWidget *menu_latex_bibtex = NULL;
61 static GtkWidget *menu_latex_bibtex_submenu = NULL;
62 static GtkWidget *menu_latex_insert_bibtex_cite = NULL;
63 static GtkWidget *menu_latex_format_insert = NULL;
64 static GtkWidget *menu_latex_format_insert_submenu = NULL;
65 static GtkWidget *menu_latex_fontsize = NULL;
66 static GtkWidget *menu_latex_fontsize_submenu = NULL;
67 static GtkWidget *menu_latex_insert_environment = NULL;
68 static GtkWidget *menu_latex_insert_usepackage = NULL;
69 static GtkWidget *menu_latex_insert_command = NULL;
70 static GtkWidget *menu_latex_replacement = NULL;
71 static GtkWidget *menu_latex_replacement_submenu = NULL;
72 static GtkWidget *menu_latex_replace_selection = NULL;
73 static GtkWidget *menu_latex_replace_toggle = NULL;
74 static GtkWidget *menu_latex_toolbar_wizard = NULL;
75
76 /* Options for plugin */
77 static gboolean glatex_set_koma_active = FALSE;
78 static gboolean glatex_deactivate_toolbaritems_with_non_latex = TRUE;
79 static gboolean glatex_deactivate_menubarentry_with_non_latex = TRUE;
80 static gboolean glatex_add_menu_on_startup;
81 static gchar *glatex_ref_chapter_string = NULL;
82 static gchar *glatex_ref_page_string = NULL;
83 static gchar *glatex_ref_all_string = NULL;
84 static gboolean glatex_set_toolbar_active = FALSE;
85 static gboolean glatex_capitalize_sentence_starts = FALSE;
86 static gboolean glatex_wizard_to_generic_toolbar = FALSE;
87
88 /* We want to keep this deactivated by default as the
89 * user needs to know what he is doing here.... */
90 static gboolean glatex_autocompletion_active = FALSE;
91 /* Value how many line should be search for autocompletion of \end{}
92 * and \endgroup{}. */
93 static gint glatex_autocompletion_context_size;
94 static gboolean glatex_autocompletion_only_for_latex;
95 gboolean glatex_autobraces_active = TRUE;
96 gboolean glatex_lowercase_on_smallcaps = FALSE;
97
98
99 /* Function will be deactivated, when only loaded */
100 static gboolean toggle_active = FALSE;
101
102 static GtkUIManager *uim;
103 static GtkActionGroup *group;
104 static GtkWidget *glatex_toolbar = NULL;
105 static GtkWidget *box = NULL;
106
107 static GtkToolItem *glatex_wizard_generic_toolbar_item = NULL;
108
109 /* Configuration file */
110 static gchar *config_file = NULL;
111
112 LaTeXWizard glatex_wizard;
113
114 const GtkActionEntry format_icons[] =
115 {
116 { "Wizard", GTK_STOCK_NEW, NULL, NULL, N_("Runs LaTeX wizard"), G_CALLBACK(glatex_kbwizard) },
117 { "Italic", GTK_STOCK_ITALIC, NULL, NULL, N_("Marks selected text as italic"), G_CALLBACK(glatex_kb_format_italic) },
118 { "Bold", GTK_STOCK_BOLD, NULL, NULL, N_("Marks selected text as bold"), G_CALLBACK(glatex_kb_format_bold) },
119 { "Underline", GTK_STOCK_UNDERLINE, NULL, NULL, N_("Underlines selected text"), G_CALLBACK(glatex_kb_format_typewriter) },
120 { "Centered", GTK_STOCK_JUSTIFY_CENTER, NULL, NULL, N_("Centered"), G_CALLBACK(glatex_kb_format_centering) },
121 { "Left", GTK_STOCK_JUSTIFY_LEFT, NULL, NULL, N_("Left side oriented"), G_CALLBACK(glatex_kb_format_left) },
122 { "Right", GTK_STOCK_JUSTIFY_RIGHT, NULL, NULL, N_("Right side oriented"), G_CALLBACK(glatex_kb_format_right) },
123 };
124
125 const guint ui_entries_n = G_N_ELEMENTS(format_icons);
126
127
128 /* fallback UI definition */
129 static const gchar *toolbar_markup =
130 "<ui>"
131 "<toolbar name='glatex_format_toolbar'>"
132 "<toolitem action='Wizard'/>"
133 "<separator/>"
134 "<toolitem action='Italic'/>"
135 "<toolitem action='Bold'/>"
136 "<toolitem action='Underline'/>"
137 "<separator/>"
138 "<toolitem action='Centered' />"
139 "<toolitem action='Left' />"
140 "<toolitem action='Right'/>"
141 "</toolbar>"
142 "</ui>";
143
144 static struct
145 {
146 GtkWidget *koma_active;
147 GtkWidget *toolbar_active;
148 GtkWidget *glatex_autocompletion_active;
149 GtkWidget *glatex_capitalize_sentence;
150 GtkWidget *wizard_to_generic_toolbar;
151 GtkWidget *lower_selection_on_smallcaps;
152 }
153 config_widgets;
154
155 /* Some functions*/
156 static void toggle_toolbar_items_by_file_type(gint id);
157 static void add_menu_to_menubar(void);
158 static void remove_menu_from_menubar(void);
159 static void add_wizard_to_generic_toolbar(void);
160 static void remove_wizard_from_generic_toolbar(void);
161
162
init_toolbar(void)163 static GtkWidget *init_toolbar(void)
164 {
165 GtkWidget *toolbar = NULL;
166
167 box = ui_lookup_widget(geany->main_widgets->window, "vbox1");
168 uim = gtk_ui_manager_new();
169 group = gtk_action_group_new("glatex_format_toolbar");
170 gtk_action_group_set_translation_domain(group, GETTEXT_PACKAGE);
171 gtk_action_group_add_actions(group, format_icons, ui_entries_n, NULL);
172 gtk_ui_manager_insert_action_group(uim, group, 0);
173 if (gtk_ui_manager_add_ui_from_string(uim, toolbar_markup, -1, NULL) > 0)
174 {
175 toolbar = gtk_ui_manager_get_widget(uim, "/ui/glatex_format_toolbar");
176 gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(toolbar), FALSE, TRUE, 0);
177 gtk_box_reorder_child(GTK_BOX(box), toolbar, 2);
178 }
179 /* TODO maybe more error handling */
180
181 return toolbar;
182 }
183
184
185 /* Move "geanyLaTex/general.conf" to "LaTex/general.conf"
186 if it still exists. */
187 static void
move_old_config_file(void)188 move_old_config_file(void)
189 {
190 gchar *filename_old, *filename_new, *dir_new;
191 GFile *file_old, *file_new;
192
193 filename_old = g_strconcat(geany->app->configdir,
194 G_DIR_SEPARATOR_S, "plugins", G_DIR_SEPARATOR_S,
195 "geanyLaTeX", G_DIR_SEPARATOR_S, "general.conf", NULL);
196
197 if (g_file_test(filename_old, G_FILE_TEST_EXISTS))
198 {
199 filename_new = g_strconcat(geany->app->configdir,
200 G_DIR_SEPARATOR_S, "plugins", G_DIR_SEPARATOR_S,
201 "LaTeX", G_DIR_SEPARATOR_S, "general.conf", NULL);
202
203 dir_new = g_path_get_dirname(filename_new);
204 if (!g_file_test(dir_new, G_FILE_TEST_IS_DIR)
205 && utils_mkdir(dir_new, TRUE) != 0)
206 {
207 dialogs_show_msgbox(GTK_MESSAGE_ERROR,
208 _("Plugin configuration directory could not be created."));
209 }
210
211 file_old = g_file_new_for_path(filename_old);
212 file_new = g_file_new_for_path(filename_new);
213
214 g_file_move(file_old, file_new, 0, NULL, NULL, NULL, NULL);
215
216 g_object_unref(file_old);
217 g_object_unref(file_new);
218
219 if (!g_file_test(filename_old, G_FILE_TEST_EXISTS))
220 {
221 gchar *dir_old;
222
223 /* File move successful, remove old dir. */
224 dir_old = g_path_get_dirname(filename_old);
225 g_rmdir(dir_old);
226 g_free(dir_old);
227 }
228
229 g_free(filename_new);
230 g_free(dir_new);
231 }
232
233 g_free(filename_old);
234 }
235
236
237 static void
on_configure_response(G_GNUC_UNUSED GtkDialog * dialog,gint response,G_GNUC_UNUSED gpointer user_data)238 on_configure_response(G_GNUC_UNUSED GtkDialog *dialog, gint response,
239 G_GNUC_UNUSED gpointer user_data)
240 {
241 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
242 {
243 GKeyFile *config = g_key_file_new();
244 gchar *data;
245 gchar *config_dir = g_path_get_dirname(config_file);
246 gint glatex_autocompletion_active_response;
247
248 config_file = g_strconcat(geany->app->configdir,
249 G_DIR_SEPARATOR_S, "plugins", G_DIR_SEPARATOR_S,
250 "LaTeX", G_DIR_SEPARATOR_S, "general.conf", NULL);
251 glatex_set_koma_active =
252 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_widgets.koma_active));
253 glatex_set_toolbar_active =
254 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_widgets.toolbar_active));
255 glatex_capitalize_sentence_starts =
256 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_widgets.glatex_capitalize_sentence));
257 glatex_wizard_to_generic_toolbar =
258 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_widgets.wizard_to_generic_toolbar));
259 glatex_lowercase_on_smallcaps =
260 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_widgets.lower_selection_on_smallcaps));
261
262 /* Check the response code for LaTeX's autocompletion functions.
263 * Due compatibility with oder Geany versions cass 0 will be treated
264 * as FALSE, which means autocompletion is deactivated. */
265 glatex_autocompletion_active_response = gtk_combo_box_get_active(
266 GTK_COMBO_BOX(config_widgets.glatex_autocompletion_active));
267 if (glatex_autocompletion_active_response == 0)
268 glatex_autocompletion_active = FALSE;
269 else
270 glatex_autocompletion_active = TRUE;
271
272 /* write stuff to file */
273 g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
274
275 g_key_file_set_boolean(config, "general", "glatex_set_koma_active",
276 glatex_set_koma_active);
277 g_key_file_set_boolean(config, "general", "glatex_set_toolbar_active",
278 glatex_set_toolbar_active);
279 g_key_file_set_boolean(config, "general", "glatex_set_autocompletion",
280 glatex_autocompletion_active);
281 g_key_file_set_boolean(config, "general", "glatex_lowercase_on_smallcaps",
282 glatex_lowercase_on_smallcaps);
283 g_key_file_set_boolean(config, "autocompletion",
284 "glatex_capitalize_sentence_starts", glatex_capitalize_sentence_starts);
285 g_key_file_set_boolean(config, "toolbar", "glatex_wizard_to_generic_toolbar",
286 glatex_wizard_to_generic_toolbar);
287
288
289 if (!g_file_test(config_dir, G_FILE_TEST_IS_DIR)
290 && utils_mkdir(config_dir, TRUE) != 0)
291 {
292 dialogs_show_msgbox(GTK_MESSAGE_ERROR,
293 _("Plugin configuration directory could not be created."));
294 }
295 else
296 {
297 /* write config to file */
298 data = g_key_file_to_data(config, NULL, NULL);
299 utils_write_file(config_file, data);
300 g_free(data);
301 }
302
303 g_free(config_dir);
304 g_key_file_free(config);
305
306 /* Apply changes to Geany */
307 /* Add toolbar if requested */
308 if (glatex_set_toolbar_active == TRUE)
309 {
310 if (glatex_toolbar == NULL)
311 {
312 glatex_toolbar = init_toolbar();
313 }
314 else
315 {
316 gtk_widget_show(glatex_toolbar);
317 }
318 }
319 /* Hide toolbar */
320 else if (glatex_set_toolbar_active == FALSE && glatex_toolbar != NULL)
321 {
322 gtk_widget_hide(glatex_toolbar);
323 }
324
325 /* Add wizard to generic toolbar if requested */
326 if (glatex_wizard_to_generic_toolbar == TRUE &&
327 glatex_wizard_generic_toolbar_item == NULL)
328 {
329 add_wizard_to_generic_toolbar();
330 }
331 else if (glatex_wizard_to_generic_toolbar == FALSE &&
332 glatex_wizard_generic_toolbar_item != NULL)
333 {
334 remove_wizard_from_generic_toolbar();
335 }
336 }
337 }
338
339 GtkWidget *
plugin_configure(GtkDialog * dialog)340 plugin_configure(GtkDialog * dialog)
341 {
342 GtkWidget *vbox;
343 GtkWidget *hbox_autocompletion;
344 GtkWidget *label_autocompletion = NULL;
345 gint tmp;
346
347 vbox = gtk_vbox_new(FALSE, 6);
348
349 config_widgets.koma_active = gtk_check_button_new_with_label(
350 _("Use KOMA script by default"));
351 config_widgets.toolbar_active = gtk_check_button_new_with_label(
352 _("Show extra plugin toolbar"));
353 config_widgets.glatex_capitalize_sentence = gtk_check_button_new_with_label(
354 _("Capitalize sentence on typing"));
355 config_widgets.wizard_to_generic_toolbar = gtk_check_button_new_with_label(
356 _("Add a wizard icon to Geany's main toolbar"));
357 config_widgets.lower_selection_on_smallcaps = gtk_check_button_new_with_label(
358 _("Lower selection when formatting smallcaps (\\textsc{})"));
359
360 config_widgets.glatex_autocompletion_active = gtk_combo_box_text_new();
361 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(config_widgets.glatex_autocompletion_active), 0,
362 _("Don't care about this inside plugin"));
363 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(config_widgets.glatex_autocompletion_active), 1,
364 _("Always perform autocompletion on LaTeX"));
365
366 /* Configuration for auto completion feature */
367 hbox_autocompletion = gtk_hbox_new(FALSE, 3);
368
369 /* Dirty workarround for transferring boolean into a valid interger value */
370 if (glatex_autocompletion_active == TRUE)
371 tmp = 1;
372 else
373 tmp = 0;
374
375 gtk_combo_box_set_active(GTK_COMBO_BOX(config_widgets.glatex_autocompletion_active), tmp);
376
377 label_autocompletion = gtk_label_new(_("Modus of autocompletion"));
378
379 gtk_box_pack_start(GTK_BOX(hbox_autocompletion), label_autocompletion, FALSE, FALSE, 3);
380 gtk_box_pack_start(GTK_BOX(hbox_autocompletion), config_widgets.glatex_autocompletion_active, TRUE, TRUE, 3);
381
382 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(config_widgets.koma_active),
383 glatex_set_koma_active);
384 gtk_box_pack_start(GTK_BOX(vbox), config_widgets.koma_active, FALSE, FALSE, 2);
385 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(config_widgets.toolbar_active),
386 glatex_set_toolbar_active);
387 gtk_box_pack_start(GTK_BOX(vbox), config_widgets.toolbar_active, FALSE, FALSE, 2);
388 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(config_widgets.glatex_capitalize_sentence),
389 glatex_capitalize_sentence_starts);
390 gtk_box_pack_start(GTK_BOX(vbox), config_widgets.glatex_capitalize_sentence, FALSE, FALSE, 2);
391 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(config_widgets.wizard_to_generic_toolbar),
392 glatex_wizard_to_generic_toolbar);
393 gtk_box_pack_start(GTK_BOX(vbox), config_widgets.lower_selection_on_smallcaps, FALSE, FALSE, 2);
394 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(config_widgets.lower_selection_on_smallcaps),
395 glatex_lowercase_on_smallcaps);
396 gtk_box_pack_start(GTK_BOX(vbox), config_widgets.wizard_to_generic_toolbar, FALSE, FALSE, 2);
397 gtk_box_pack_start(GTK_BOX(vbox), hbox_autocompletion, FALSE, FALSE, 2);
398
399 gtk_widget_show_all(vbox);
400 g_signal_connect(dialog, "response", G_CALLBACK(on_configure_response), NULL);
401 return vbox;
402 }
403
404 /* Functions to toggle the status of plugin */
glatex_set_latextoggle_status(gboolean new_status)405 static void glatex_set_latextoggle_status(gboolean new_status)
406 {
407 /* No more function at the moment.*/
408 if (toggle_active != new_status)
409 toggle_active = new_status;
410 }
411
glatex_toggle_status(G_GNUC_UNUSED GtkMenuItem * menuitem)412 static void glatex_toggle_status(G_GNUC_UNUSED GtkMenuItem * menuitem)
413 {
414 if (toggle_active == TRUE)
415 glatex_set_latextoggle_status(FALSE);
416 else
417 glatex_set_latextoggle_status(TRUE);
418 }
419
toggle_toolbar_item(const gchar * path,gboolean new_status)420 static void toggle_toolbar_item(const gchar *path, gboolean new_status)
421 {
422 if (gtk_action_get_sensitive(gtk_ui_manager_get_action(uim, path)) != new_status)
423 {
424 gtk_action_set_sensitive(gtk_ui_manager_get_action(uim, path), new_status);
425 }
426 }
427
428 static void
check_for_menu(gint ft_id)429 check_for_menu(gint ft_id)
430 {
431 /* We don't check whether the menu has been added here, as this
432 * will is checked by add_menu_to_menubar() anyway */
433 if (ft_id == GEANY_FILETYPES_LATEX)
434 {
435 add_menu_to_menubar();
436 }
437 if (ft_id != GEANY_FILETYPES_LATEX)
438 {
439 if (glatex_deactivate_menubarentry_with_non_latex == TRUE)
440 {
441 remove_menu_from_menubar();
442 }
443 }
444 }
445
446
activate_toolbar_items(void)447 static void activate_toolbar_items(void)
448 {
449 if (uim == NULL)
450 {
451 return;
452 }
453
454 toggle_toolbar_item("/ui/glatex_format_toolbar/Bold", TRUE);
455 toggle_toolbar_item("/ui/glatex_format_toolbar/Underline", TRUE);
456 toggle_toolbar_item("/ui/glatex_format_toolbar/Centered", TRUE);
457 toggle_toolbar_item("/ui/glatex_format_toolbar/Italic", TRUE);
458 toggle_toolbar_item("/ui/glatex_format_toolbar/Left", TRUE);
459 toggle_toolbar_item("/ui/glatex_format_toolbar/Right", TRUE);
460 gtk_ui_manager_ensure_update(uim);
461 }
462
deactivate_toolbar_items(void)463 static void deactivate_toolbar_items(void)
464 {
465 if (uim == NULL)
466 {
467 return;
468 }
469
470 toggle_toolbar_item("/ui/glatex_format_toolbar/Bold", FALSE);
471 toggle_toolbar_item("/ui/glatex_format_toolbar/Underline", FALSE);
472 toggle_toolbar_item("/ui/glatex_format_toolbar/Centered", FALSE);
473 toggle_toolbar_item("/ui/glatex_format_toolbar/Italic", FALSE);
474 toggle_toolbar_item("/ui/glatex_format_toolbar/Left", FALSE);
475 toggle_toolbar_item("/ui/glatex_format_toolbar/Right", FALSE);
476 gtk_ui_manager_ensure_update(uim);
477 }
478
479
toggle_toolbar_items_by_file_type(gint id)480 static void toggle_toolbar_items_by_file_type(gint id)
481 {
482 if (glatex_set_toolbar_active == TRUE)
483 {
484 if (id == GEANY_FILETYPES_LATEX ||
485 glatex_deactivate_toolbaritems_with_non_latex == FALSE)
486 {
487 activate_toolbar_items();
488 }
489 else
490 {
491 deactivate_toolbar_items();
492 }
493 }
494 }
495
496
on_document_activate(G_GNUC_UNUSED GObject * object,GeanyDocument * doc,G_GNUC_UNUSED gpointer data)497 static void on_document_activate(G_GNUC_UNUSED GObject *object,
498 GeanyDocument *doc, G_GNUC_UNUSED gpointer data)
499 {
500 g_return_if_fail(doc != NULL);
501
502 if (main_is_realized() == TRUE)
503 {
504 toggle_toolbar_items_by_file_type(doc->file_type->id);
505 check_for_menu(doc->file_type->id);
506 }
507 }
508
509
on_document_new(G_GNUC_UNUSED GObject * object,GeanyDocument * doc,G_GNUC_UNUSED gpointer data)510 static void on_document_new(G_GNUC_UNUSED GObject *object, GeanyDocument *doc,
511 G_GNUC_UNUSED gpointer data)
512 {
513 g_return_if_fail(doc != NULL);
514
515 if (main_is_realized() == TRUE)
516 {
517 toggle_toolbar_items_by_file_type(doc->file_type->id);
518 }
519 }
520
521
522 static void
on_geany_startup_complete(G_GNUC_UNUSED GObject * obj,G_GNUC_UNUSED gpointer user_data)523 on_geany_startup_complete(G_GNUC_UNUSED GObject *obj,
524 G_GNUC_UNUSED gpointer user_data)
525 {
526 GeanyDocument *doc = NULL;
527
528 doc = document_get_current();
529 if (doc != NULL)
530 {
531 toggle_toolbar_items_by_file_type(doc->file_type->id);
532 if (glatex_add_menu_on_startup == TRUE||
533 doc->file_type->id == GEANY_FILETYPES_LATEX)
534 {
535 add_menu_to_menubar();
536 }
537 }
538
539 }
540
541
on_document_filetype_set(G_GNUC_UNUSED GObject * obj,GeanyDocument * doc,G_GNUC_UNUSED GeanyFiletype * filetype_old,G_GNUC_UNUSED gpointer user_data)542 static void on_document_filetype_set(G_GNUC_UNUSED GObject *obj, GeanyDocument *doc,
543 G_GNUC_UNUSED GeanyFiletype *filetype_old,
544 G_GNUC_UNUSED gpointer user_data)
545 {
546 g_return_if_fail(doc != NULL);
547
548 if (main_is_realized() == TRUE)
549 {
550 toggle_toolbar_items_by_file_type(doc->file_type->id);
551 check_for_menu(doc->file_type->id);
552 }
553 }
554
555
get_position_relative(ScintillaObject * sci,gint pos,gint n)556 static gint get_position_relative(ScintillaObject *sci, gint pos, gint n)
557 {
558 return (gint) scintilla_send_message(sci, SCI_POSITIONRELATIVE, (uptr_t) pos, n);
559 }
560
561
get_char_relative(ScintillaObject * sci,gint pos,gint n)562 static gint get_char_relative(ScintillaObject *sci, gint pos, gint n)
563 {
564 return sci_get_char_at(sci, get_position_relative(sci, pos, n));
565 }
566
567
on_editor_notify(G_GNUC_UNUSED GObject * object,GeanyEditor * editor,SCNotification * nt,G_GNUC_UNUSED gpointer data)568 static gboolean on_editor_notify(G_GNUC_UNUSED GObject *object, GeanyEditor *editor,
569 SCNotification *nt, G_GNUC_UNUSED gpointer data)
570 {
571 ScintillaObject* sci;
572 gint pos;
573
574 g_return_val_if_fail(editor != NULL, FALSE);
575 sci = editor->sci;
576 /* Autocompletion for LaTeX specific stuff:
577 * Introducing \end{} or \endgroup{} after a \begin{}
578
579 * Function is based on function which was inside
580 * Geany's core under terms of GPLv2+
581 * EXtended for LaTeX with some more autocompletion features
582 * for e.g. _{} and ^{}.*/
583
584 if (glatex_autocompletion_active == TRUE &&
585 !(glatex_autocompletion_only_for_latex == TRUE &&
586 editor->document->file_type->id != GEANY_FILETYPES_LATEX))
587 {
588 pos = sci_get_current_position(sci);
589
590 if (nt->nmhdr.code == SCN_CHARADDED)
591 {
592 switch (nt->ch)
593 {
594 case '\n':
595 case '\r':
596 {
597 if (sci_get_char_at(sci, pos - (editor_get_eol_char_len (editor) + 1)) == '}'||
598 sci_get_char_at(sci, pos - (editor_get_eol_char_len (editor) + 1)) == ']')
599 {
600 gchar *buf, *construct;
601 /* TODO: Make possible to have longer than a 50 chars environment */
602 gchar env[50];
603 gint line = sci_get_line_from_position(sci, pos - (editor_get_eol_char_len (editor) + 1));
604 gint line_len = sci_get_line_length(sci, line);
605 gint i, start;
606 gint indent;
607 GeanyIndentPrefs* indent_prefs = editor_get_indent_prefs(editor);
608
609 /* get the line */
610 buf = sci_get_line(sci, line);
611
612 /* get to the first non-blank char (some kind of ltrim()) */
613 start = 0;
614 while (isspace(buf[start]) && buf[start] != '\0')
615 start++;
616
617 /* check for begin for autocompletion of \end{} and \endgr*/
618 if (strncmp(buf + start, "\\begin", 6) == 0)
619 {
620 gchar full_cmd[15];
621 guint j = 0;
622
623 /* take also "\begingroup" (or whatever there can be) and
624 * append "\endgroup" and so on. */
625 i = start + 6;
626 while (i < line_len && buf[i] != '{' && j < (sizeof(full_cmd) - 1))
627 {
628 /* copy all between "\begin" and "{" to full_cmd */
629 full_cmd[j] = buf[i];
630 i++;
631 j++;
632 }
633 full_cmd[j] = '\0';
634
635 /* go through the line and get the environment */
636 for (i = start + j; i < line_len; i++)
637 {
638 if (buf[i] == '{')
639 {
640 j = 0;
641 i++;
642 while (buf[i] != '}' && j < (sizeof(env) - 1))
643 { /* this could be done in a shorter way,
644 * but so it remains readable ;-) */
645 env[j] = buf[i];
646 j++;
647 i++;
648 }
649 env[j] = '\0';
650 break;
651 }
652 }
653 /* Search whether the environment is closed within the next
654 * lines. We assume, no \end is needed in such cases */
655 /* TODO using sci_find_text() should be way faster than getting
656 * the line buffer and performing string comparisons */
657 for (i = 1; i < glatex_autocompletion_context_size; i++)
658 {
659 gchar *tmp;
660 gchar *end_construct;
661 tmp = sci_get_line(sci, line + i);
662
663 end_construct = g_strdup_printf("\\end%s{%s}", full_cmd, env);
664 if (strstr(tmp, end_construct) != NULL)
665 {
666 /* Clean up everything and quit as nothing
667 * needs to be done */
668 g_free(tmp);
669 g_free(buf);
670 g_free(end_construct);
671 return FALSE;
672 }
673 g_free(tmp);
674 g_free(end_construct);
675 }
676
677 /* After we have this, we need to ensure basic
678 * indent is getting applied on closing command */
679 indent = sci_get_line_indentation(sci, line);
680
681 /* Now we build up closing string and insert
682 * it into document */
683 construct = g_strdup_printf("\t\n\\end%s{%s}", full_cmd, env);
684 editor_insert_text_block(editor, construct, pos,
685 1, -1, TRUE);
686 /* ... and setting the indention */
687 /* If user pressed carriage return, we end up in a new line. This line
688 * should be indented one level further than the previous indentation */
689 sci_set_line_indentation(sci, sci_get_current_line(sci),
690 indent + indent_prefs->width);
691 /* Set the cursor position to the end of the new line we're in which
692 * has just been indented */
693 sci_set_current_position(sci, sci_get_line_end_position(sci, sci_get_current_line(sci)), 1);
694 /* Indentation of the \end{} command, which is now in the next line,
695 * should be the same as the previous indentation */
696 sci_set_line_indentation(sci, sci_get_current_line(sci) + 1,
697 indent);
698 g_free(construct);
699 }
700 g_free(buf);
701 }
702
703 /* Now we are handling the case, a new line has been inserted
704 * but no closing braces */
705 else if (glatex_autobraces_active == TRUE)
706 {
707 gint line;
708
709 gint line_len;
710 gint i;
711 gchar *buf;
712
713 line = sci_get_line_from_position(sci, pos -
714 (editor_get_eol_char_len (editor) + 1));
715 line_len = sci_get_line_length(sci, line) -
716 editor_get_eol_char_len (editor);
717
718
719 /* Catching current line which has been 'finished'*/
720 buf = sci_get_line(sci, line);
721
722 /* Searching for either \ or " ", {, } from end of
723 * line back to start */
724 for (i = line_len; i >= 0 ; i--)
725 {
726 if (buf[i] == '\\')
727 {
728 if ((i > 0 && buf[i-1] != '\\') ||
729 (i == 0))
730 {
731 sci_insert_text(sci,
732 pos - (editor_get_eol_char_len (editor)), "{}");
733 }
734 /* We will stop here in any case */
735 break;
736 }
737 /* Else we want to stop once we found a space,
738 * some closing braces somewhere before as we
739 * are assuming, manipulating something here
740 * would cause a bigger mess. */
741 else if (buf[i] == ' ' ||
742 buf[i] == '}' ||
743 buf[i] == '{' ||
744 buf[i] == '"')
745 {
746 break;
747 }
748 }
749 g_free(buf);
750 }
751 break;
752 } /* Closing case \r or \n */
753 case '_':
754 case '^':
755 {
756 if (glatex_autobraces_active == TRUE)
757 {
758 sci_insert_text(sci, -1, "{}");
759 sci_set_current_position(sci, pos + 1, TRUE);
760 }
761 break;
762 }
763 default:
764 {
765 if (glatex_capitalize_sentence_starts == TRUE &&
766 g_ascii_isspace(get_char_relative(sci, pos, -2)))
767 {
768 gint prevNonWhite = 0;
769 gint i;
770
771 /* find the previous non-white character */
772 i = get_position_relative(sci, pos, -3);
773 while (g_ascii_isspace((prevNonWhite = sci_get_char_at(sci, i))))
774 {
775 /* no need to bother about multi-byte characters here since
776 * we only check for ASCII space characters anyway */
777 --i;
778 }
779
780 if (prevNonWhite == '.' ||
781 prevNonWhite == '!' ||
782 prevNonWhite == '?')
783 {
784 gchar *upperLtr = NULL;
785 gchar *selection = NULL;
786
787 sci_set_selection_start(sci, get_position_relative(sci, pos, -1));
788 sci_set_selection_end(sci, pos);
789
790 selection = sci_get_selection_contents(sci);
791 upperLtr = g_utf8_strup(selection, -1);
792 sci_replace_sel(sci, upperLtr);
793
794 g_free(upperLtr);
795 g_free(selection);
796 }
797 }
798 break;
799 }
800 } /* Closing switch */
801 /* later there could be some else ifs for other keywords */
802 }
803 } /* End of latex autocpletion */
804
805 /* Toggle special characters on input */
806 if (editor->document->file_type->id == GEANY_FILETYPES_LATEX &&
807 toggle_active == TRUE)
808 {
809 if (nt->nmhdr.code == SCN_CHARADDED)
810 {
811 gchar buf[7];
812 gint len;
813 sci = editor->sci;
814
815 len = g_unichar_to_utf8(nt->ch, buf);
816 if (len > 0)
817 {
818 const gchar *entity;
819
820 buf[len] = '\0';
821 entity = glatex_get_entity(buf);
822
823 if (entity != NULL)
824 {
825 pos = sci_get_current_position(sci);
826
827 sci_set_selection_start(editor->sci, pos - len);
828 sci_set_selection_end(editor->sci, pos);
829
830 sci_replace_sel(editor->sci, entity);
831 }
832 }
833 }
834 }
835 return FALSE;
836 }
837
838
on_document_close(G_GNUC_UNUSED GObject * obj,GeanyDocument * doc,G_GNUC_UNUSED gpointer user_data)839 static void on_document_close(G_GNUC_UNUSED GObject *obj, GeanyDocument *doc,
840 G_GNUC_UNUSED gpointer user_data)
841 {
842 g_return_if_fail(doc != NULL);
843
844 if (doc->index < 2)
845 deactivate_toolbar_items();
846 if (doc->index < 1 &&
847 glatex_deactivate_menubarentry_with_non_latex == TRUE)
848 remove_menu_from_menubar();
849 }
850
851
852 /* Called when keys were pressed */
glatex_kblatex_toggle(G_GNUC_UNUSED guint key_id)853 static void glatex_kblatex_toggle(G_GNUC_UNUSED guint key_id)
854 {
855 if (toggle_active == TRUE)
856 glatex_set_latextoggle_status(FALSE);
857 else
858 glatex_set_latextoggle_status(TRUE);
859 }
860
861
862 PluginCallback plugin_callbacks[] =
863 {
864 { "editor-notify", (GCallback) &on_editor_notify, FALSE, NULL },
865 { "document-activate", (GCallback) &on_document_activate, FALSE, NULL },
866 { "document-filetype-set", (GCallback) &on_document_filetype_set, FALSE, NULL },
867 { "document-new", (GCallback) &on_document_new, FALSE, NULL},
868 { "geany-startup-complete", (GCallback) &on_geany_startup_complete, FALSE, NULL },
869 { "document-close", (GCallback) &on_document_close, FALSE, NULL},
870 { NULL, NULL, FALSE, NULL }
871 };
872
873
874 static inline const gchar*
get_latex_command(gint tab_index)875 get_latex_command(gint tab_index)
876 {
877 return glatex_char_array[tab_index].latex;
878 }
879
880
881 static void
char_insert_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)882 char_insert_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,
883 G_GNUC_UNUSED gpointer gdata)
884 {
885 glatex_insert_string(get_latex_command(GPOINTER_TO_INT(gdata)), TRUE);
886 }
887
888
889 void
glatex_insert_label_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)890 glatex_insert_label_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,
891 G_GNUC_UNUSED gpointer gdata)
892 {
893 gchar *input = NULL;
894
895 input = dialogs_show_input(_("Insert Label"),
896 GTK_WINDOW(geany->main_widgets->window),
897 _("Label name:"),
898 NULL);
899
900 if (input)
901 {
902 gchar *label_str = NULL;
903
904 label_str = g_strconcat("\\label{",input , "}", NULL);
905 glatex_insert_string(label_str, TRUE);
906 g_free(input);
907 g_free(label_str);
908 }
909 }
910
911
912 void
glatex_insert_command_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)913 glatex_insert_command_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,
914 G_GNUC_UNUSED gpointer gdata)
915 {
916
917 gchar *input = NULL;
918
919 input = dialogs_show_input(_("Insert Command"),
920 GTK_WINDOW(geany->main_widgets->window),
921 _("Command name:"),
922 NULL);
923
924 if (input)
925 {
926 gchar *cmd_str = NULL;
927
928 GeanyDocument *doc = document_get_current();
929
930 sci_start_undo_action(doc->editor->sci);
931
932 cmd_str = g_strdup_printf("\\%s{", input);
933 glatex_insert_string(cmd_str, TRUE);
934 /* This shall put the cursor inside the braces */
935 glatex_insert_string("}", FALSE);
936
937 sci_end_undo_action(doc->editor->sci);
938 g_free(input);
939 g_free(cmd_str);
940 }
941 }
942
943
944 void
glatex_insert_ref_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)945 glatex_insert_ref_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,
946 G_GNUC_UNUSED gpointer gdata)
947 {
948 GtkWidget *dialog;
949 GtkWidget *vbox = NULL;
950 GtkWidget *label_ref = NULL;
951 GtkWidget *textbox_ref = NULL;
952 GtkWidget *table = NULL;
953 GtkWidget *radio1 = NULL;
954 GtkWidget *radio2 = NULL;
955 GtkWidget *radio3 = NULL;
956 GtkWidget *tmp_entry = NULL;
957 GtkTreeModel *model = NULL;
958 GeanyDocument *doc = NULL;
959 GSList *file_list = NULL;
960 gchar *dir;
961
962 doc = document_get_current();
963
964 dialog = gtk_dialog_new_with_buttons(_("Insert Reference"),
965 GTK_WINDOW(geany->main_widgets->window),
966 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL,
967 GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
968 NULL);
969 vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
970 gtk_widget_set_name(dialog, "GeanyDialog");
971 gtk_box_set_spacing(GTK_BOX(vbox), 10);
972
973 table = gtk_table_new(1, 2, FALSE);
974 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
975 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
976
977 label_ref = gtk_label_new(_("Reference name:"));
978 textbox_ref = gtk_combo_box_text_new_with_entry();
979
980 if (doc->real_path != NULL)
981 {
982 dir = g_path_get_dirname(doc->real_path);
983 file_list = utils_get_file_list_full(dir, TRUE, TRUE, NULL);
984 glatex_add_Labels(textbox_ref, file_list);
985 model = gtk_combo_box_get_model(GTK_COMBO_BOX(textbox_ref));
986 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
987 0, GTK_SORT_ASCENDING);
988 g_slist_foreach(file_list, (GFunc) g_free, NULL);
989 g_slist_free(file_list);
990 if (dir != NULL)
991 g_free(dir);
992 }
993
994
995 gtk_misc_set_alignment(GTK_MISC(label_ref), 0, 0.5);
996
997 gtk_table_attach_defaults(GTK_TABLE(table), label_ref, 0, 1, 0, 1);
998 gtk_table_attach_defaults(GTK_TABLE(table), textbox_ref, 1, 2, 0, 1);
999 gtk_container_add(GTK_CONTAINER(vbox), table);
1000
1001 radio1 = gtk_radio_button_new_with_mnemonic(NULL,
1002 _("_Standard Reference"));
1003 gtk_button_set_focus_on_click(GTK_BUTTON(radio1), FALSE);
1004 gtk_container_add(GTK_CONTAINER(vbox), radio1);
1005
1006 radio2 = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio1),
1007 _("_Page Reference"));
1008 gtk_button_set_focus_on_click(GTK_BUTTON(radio2), FALSE);
1009 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio2), FALSE);
1010 gtk_container_add(GTK_CONTAINER(vbox), radio2);
1011
1012 radio3 = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio1), _("_Add both"));
1013 gtk_button_set_focus_on_click(GTK_BUTTON(radio3), FALSE);
1014 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio3), FALSE);
1015 gtk_container_add(GTK_CONTAINER(vbox), radio3);
1016
1017 tmp_entry = gtk_bin_get_child(GTK_BIN(textbox_ref));
1018 g_signal_connect(G_OBJECT(tmp_entry), "activate",
1019 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1020
1021
1022 gtk_widget_show_all(vbox);
1023
1024
1025 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1026 {
1027 gchar *ref_string = NULL;
1028 GString *template_string = NULL;
1029
1030 ref_string = g_strdup(gtk_combo_box_text_get_active_text(
1031 GTK_COMBO_BOX_TEXT(textbox_ref)));
1032
1033 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio1)) == TRUE)
1034 {
1035 template_string = g_string_new(glatex_ref_chapter_string);
1036 }
1037 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio2))== TRUE)
1038 {
1039 template_string = g_string_new(glatex_ref_page_string);
1040 }
1041 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio3))== TRUE)
1042 {
1043 template_string = g_string_new(glatex_ref_all_string);
1044 }
1045
1046 if (ref_string != NULL && template_string != NULL)
1047 {
1048 gchar *tmp;
1049 utils_string_replace_all(template_string, "{{reference}}", ref_string);
1050 tmp = g_string_free(template_string, FALSE);
1051 glatex_insert_string(tmp, TRUE);
1052 g_free(ref_string);
1053 g_free(tmp);
1054 }
1055 else
1056 {
1057 if (ref_string != NULL)
1058 g_free(ref_string);
1059 if (template_string != NULL)
1060 g_string_free(template_string, TRUE);
1061 }
1062 }
1063
1064 gtk_widget_destroy(dialog);
1065 }
1066
1067
glatex_character_create_menu_item(GtkWidget * menu,const gchar * label,gint letter,MenuCallback callback)1068 static void glatex_character_create_menu_item(GtkWidget *menu, const gchar *label,
1069 gint letter, MenuCallback callback)
1070 {
1071 GtkWidget *tmp;
1072
1073 tmp = gtk_menu_item_new_with_label(label);
1074 gtk_widget_show(tmp);
1075 gtk_container_add(GTK_CONTAINER(menu), tmp);
1076 g_signal_connect(tmp, "activate",
1077 G_CALLBACK(callback), GINT_TO_POINTER(letter));
1078 }
1079
1080
1081 /* returns -1, if there are more than gint can work with or any other error
1082 * returns 0, if categorie is empty
1083 * if gint categorie is -1, function will count every element.
1084 * Useful, if there is no need for a categorie check.*/
1085 gint
glatex_count_menu_entries(SubMenuTemplate * tmp,gint categorie)1086 glatex_count_menu_entries(SubMenuTemplate *tmp, gint categorie)
1087 {
1088 /* TODO: Reset max value to stop before it's too late */
1089 gint i;
1090 gint count = 0;
1091
1092 if (categorie == -1)
1093 {
1094 for (i =1; tmp[i].label != NULL; i++)
1095 {
1096 count = count + 1;
1097 }
1098 }
1099 else
1100 {
1101 for (i = 1; tmp[i].label != NULL; i++)
1102 {
1103 if (tmp[i].cat == categorie)
1104 {
1105 count = count + 1;
1106 }
1107 if (i >= 256)
1108 {
1109 count = -1;
1110 break;
1111 }
1112 }
1113 }
1114 return count + 1;
1115 }
1116
1117 static gint
count_menu_cat_entries(CategoryName * tmp)1118 count_menu_cat_entries(CategoryName *tmp)
1119 {
1120 gint i;
1121
1122 for (i = 0; tmp[i].label != NULL; i++);
1123 return i;
1124 }
1125
1126
glatex_sub_menu_init(GtkWidget * base_menu,SubMenuTemplate * menu_template,CategoryName * category_name,MenuCallback callback_function)1127 static void glatex_sub_menu_init(GtkWidget *base_menu, SubMenuTemplate *menu_template,
1128 CategoryName *category_name,
1129 MenuCallback callback_function)
1130 {
1131 gint i;
1132 gint j;
1133 gint categories = count_menu_cat_entries(category_name);
1134 GtkWidget *sub_menu = NULL;
1135 GtkWidget *sub_menu_cat[categories][2];
1136 GtkWidget *active_submenu = NULL;
1137
1138 /* Creates sub menus based on information from letter.h */
1139 for (i = 0; i < categories; i++)
1140 {
1141 if (glatex_count_menu_entries(menu_template, i) > 0)
1142 {
1143 create_sub_menu(base_menu, sub_menu_cat[i][0],
1144 sub_menu_cat[i][1], category_name[i].label);
1145 }
1146 }
1147
1148 /* Searching for all categories */
1149 for (i = 0; i < categories; i++)
1150 {
1151 gboolean split = FALSE;
1152 gboolean last_sub_menu = FALSE;
1153 gboolean sorted = category_name[i].sorted;
1154 /* To check whether we need to build up a new sub sub menu. */
1155 gint local_count = 0;
1156 gint item_count = glatex_count_menu_entries(menu_template, i);
1157
1158 if (item_count < 1)
1159 continue;
1160
1161 /* Default is, not to split anything to make menu not */
1162 /* deeper than realy needed. */
1163 if (item_count > MAX_MENU_ENTRIES)
1164 {
1165 split = TRUE;
1166 }
1167
1168 /* Setting active sub menu to sub menu of category */
1169 sub_menu = sub_menu_cat[i][0];
1170 active_submenu = sub_menu;
1171 /* Finding entries for each category */
1172
1173 for (j = 0; menu_template[j].latex != NULL; j++)
1174 {
1175 if (menu_template[j].cat == i)
1176 {
1177 /* Creates a new sub sub menu if needed */
1178 if (split == TRUE && (local_count % MAX_MENU_ENTRIES) == 0)
1179 {
1180 gint next_split_point = 0;
1181 GtkWidget *tmp = NULL;
1182 GtkWidget *tmp_item = NULL;
1183
1184 sub_menu = active_submenu;
1185
1186 for (next_split_point = 0;
1187 next_split_point < MAX_MENU_ENTRIES ; next_split_point ++)
1188 {
1189 if (menu_template[j+next_split_point].cat != i)
1190 {
1191 last_sub_menu = TRUE;
1192 break;
1193 }
1194
1195 }
1196
1197 if (sorted == TRUE)
1198 {
1199 create_sub_menu(sub_menu_cat[i][0], tmp, tmp_item,
1200 g_strconcat(menu_template[j].label, " ... ",
1201 menu_template[j + next_split_point-1].label, NULL));
1202
1203 sub_menu = tmp;
1204 }
1205 else if (sorted == FALSE)
1206 {
1207 if (last_sub_menu == FALSE)
1208 {
1209 create_sub_menu(sub_menu, tmp, tmp_item, _("More"));
1210 sub_menu = active_submenu;
1211 active_submenu = tmp;
1212 }
1213 }
1214 }
1215
1216 /* Sets the counter to keep in track if a new ,,
1217 * submenu needs to be build up */
1218 local_count = local_count + 1;
1219 glatex_character_create_menu_item(sub_menu, g_strconcat(
1220 menu_template[j].label, "\t", menu_template[j].latex,
1221 NULL), j, callback_function);
1222 }
1223 }
1224 }
1225 }
1226
1227 static int
find_latex_enc(gint l_geany_enc)1228 find_latex_enc(gint l_geany_enc)
1229 {
1230 guint i;
1231 for (i = 0; i < LATEX_ENCODINGS_MAX; i++)
1232 {
1233 if (latex_encodings[i].geany_enc == l_geany_enc)
1234 return i;
1235 }
1236 return LATEX_ENCODING_NONE;
1237 }
1238
1239
1240 static void
show_output(const gchar * output,const gchar * name,const gint local_enc)1241 show_output(const gchar * output, const gchar * name, const gint local_enc)
1242 {
1243 GeanyDocument *doc = NULL;
1244 GeanyFiletype *ft = filetypes_lookup_by_name("LaTeX");
1245
1246 if (output)
1247 {
1248 doc = document_new_file(name, ft, output);
1249 document_set_encoding(doc, encodings_get_charset_from_index
1250 (latex_encodings[local_enc].geany_enc));
1251 }
1252 }
1253
glatex_insert_usepackage_dialog(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)1254 void glatex_insert_usepackage_dialog(G_GNUC_UNUSED GtkMenuItem * menuitem,
1255 G_GNUC_UNUSED gpointer gdata)
1256 {
1257 GtkWidget *dialog = NULL;
1258 GtkWidget *vbox = NULL;
1259 GtkWidget *label = NULL;
1260 GtkWidget *textbox = NULL;
1261 GtkWidget *table = NULL;
1262 GtkWidget *label_options = NULL;
1263 GtkWidget *textbox_options = NULL;
1264
1265 dialog = gtk_dialog_new_with_buttons(_("Add additional package"),
1266 GTK_WINDOW(geany->main_widgets->window),
1267 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL,
1268 GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
1269 NULL);
1270 vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
1271 gtk_widget_set_name(dialog, "GeanyDialog");
1272 gtk_box_set_spacing(GTK_BOX(vbox), 10);
1273
1274 table = gtk_table_new(1, 2, FALSE);
1275 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
1276 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
1277
1278 label = gtk_label_new(_("Package name:"));
1279 textbox = gtk_entry_new();
1280
1281 label_options = gtk_label_new(_("Package options:"));
1282 textbox_options = gtk_entry_new();
1283
1284 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1285 gtk_misc_set_alignment(GTK_MISC(label_options), 0, 0.5);
1286
1287 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
1288 gtk_table_attach_defaults(GTK_TABLE(table), textbox, 1, 2, 0, 1);
1289 gtk_table_attach_defaults(GTK_TABLE(table), label_options, 0, 1, 1, 2);
1290 gtk_table_attach_defaults(GTK_TABLE(table), textbox_options, 1, 2, 1, 2);
1291
1292 gtk_container_add(GTK_CONTAINER(vbox), table);
1293
1294 g_signal_connect(G_OBJECT(textbox), "activate",
1295 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1296 g_signal_connect(G_OBJECT(textbox_options), "activate",
1297 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1298
1299 gtk_widget_show_all(vbox);
1300
1301 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1302 {
1303 const gchar *pkg = NULL;
1304 const gchar *option = NULL;
1305 pkg = gtk_entry_get_text(GTK_ENTRY(textbox));
1306 option = gtk_entry_get_text(GTK_ENTRY(textbox_options));
1307 glatex_usepackage(pkg, option);
1308 }
1309
1310 gtk_widget_destroy(dialog);
1311
1312 }
1313
1314 void
on_insert_bibtex_dialog_activate(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)1315 on_insert_bibtex_dialog_activate(G_GNUC_UNUSED GtkMenuItem *menuitem,
1316 G_GNUC_UNUSED gpointer gdata)
1317 {
1318 GtkWidget *dialog;
1319 GtkWidget *vbox = NULL;
1320 GtkWidget *label= NULL;
1321 GtkWidget *textbox = NULL;
1322 GtkWidget *table = NULL;
1323 GtkWidget *tmp_entry = NULL;
1324 GtkTreeModel *model = NULL;
1325 GeanyDocument *doc = NULL;
1326
1327 doc = document_get_current();
1328
1329 dialog = gtk_dialog_new_with_buttons(_("Insert BibTeX Reference"),
1330 GTK_WINDOW(geany->main_widgets->window),
1331 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL,
1332 GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
1333 NULL);
1334 vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
1335 gtk_widget_set_name(dialog, "GeanyDialog");
1336 gtk_box_set_spacing(GTK_BOX(vbox), 10);
1337
1338 table = gtk_table_new(1, 2, FALSE);
1339 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
1340 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
1341
1342 label = gtk_label_new(_("BibTeX reference name:"));
1343 textbox = gtk_combo_box_text_new_with_entry();
1344
1345 if (doc->real_path != NULL)
1346 {
1347 GDir *dir;
1348 gchar *tmp_dir;
1349 const gchar *filename = NULL;
1350
1351 tmp_dir = g_path_get_dirname(doc->real_path);
1352 dir = g_dir_open(tmp_dir, 0, NULL);
1353
1354 if(dir == NULL)
1355 g_free(tmp_dir);
1356 g_return_if_fail(dir != NULL);
1357
1358 foreach_dir(filename, dir)
1359 {
1360 gchar *fullpath = NULL;
1361 fullpath = g_build_path(G_DIR_SEPARATOR_S, tmp_dir, filename, NULL);
1362
1363 glatex_parse_bib_file(fullpath, textbox);
1364 g_free(fullpath);
1365 }
1366 g_free(tmp_dir);
1367 g_dir_close(dir);
1368 model = gtk_combo_box_get_model(GTK_COMBO_BOX(textbox));
1369 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
1370 0, GTK_SORT_ASCENDING);
1371 }
1372
1373
1374 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1375
1376 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
1377 gtk_table_attach_defaults(GTK_TABLE(table), textbox, 1, 2, 0, 1);
1378 gtk_container_add(GTK_CONTAINER(vbox), table);
1379
1380 tmp_entry = gtk_bin_get_child(GTK_BIN(textbox));
1381 g_signal_connect(G_OBJECT(tmp_entry), "activate",
1382 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1383
1384 gtk_widget_show_all(vbox);
1385
1386 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1387 {
1388 gchar *ref_string = NULL;
1389 GString *template_string = NULL;
1390
1391 ref_string = g_strdup(gtk_combo_box_text_get_active_text(
1392 GTK_COMBO_BOX_TEXT(textbox)));
1393
1394 if (ref_string != NULL)
1395 {
1396 glatex_bibtex_insert_cite(ref_string, NULL);
1397 g_free(ref_string);
1398 }
1399 else
1400 {
1401 g_free(ref_string);
1402 g_free(template_string);
1403 }
1404 }
1405
1406 gtk_widget_destroy(dialog);
1407 }
1408
1409
1410 static void
on_wizard_response(G_GNUC_UNUSED GtkDialog * dialog,gint response,G_GNUC_UNUSED gpointer user_data)1411 on_wizard_response(G_GNUC_UNUSED GtkDialog *dialog, gint response,
1412 G_GNUC_UNUSED gpointer user_data)
1413 {
1414 GString *code = NULL;
1415 gchar *author = NULL;
1416 gchar *date = NULL;
1417 gchar *output = NULL;
1418 gchar *classoptions = NULL;
1419 gchar *title = NULL;
1420 gchar *enc_latex_char = NULL;
1421 gchar *documentclass_str = NULL;
1422 gchar *papersize = NULL;
1423 gchar *draft = NULL;
1424 gchar *fontsize = NULL;
1425 gchar *orientation_string = NULL;
1426 gboolean KOMA_active = FALSE;
1427 gboolean draft_active = FALSE;
1428 guint template_int;
1429 gint documentclass_int;
1430 gint encoding_int;
1431 gint papersize_int;
1432 gint paperorientation_int;
1433
1434 if (response == GTK_RESPONSE_OK ||
1435 response == GTK_RESPONSE_APPLY ||
1436 response == GTK_RESPONSE_ACCEPT)
1437 {
1438 KOMA_active = gtk_toggle_button_get_active(
1439 GTK_TOGGLE_BUTTON(glatex_wizard.checkbox_KOMA));
1440 draft_active = gtk_toggle_button_get_active(
1441 GTK_TOGGLE_BUTTON(glatex_wizard.checkbox_draft));
1442 documentclass_int = gtk_combo_box_get_active(
1443 GTK_COMBO_BOX(glatex_wizard.documentclass_combobox));
1444 template_int = gtk_combo_box_get_active(
1445 GTK_COMBO_BOX(glatex_wizard.template_combobox));
1446 encoding_int = gtk_combo_box_get_active(
1447 GTK_COMBO_BOX(glatex_wizard.encoding_combobox));
1448 /* We don't want to set an encoding, if there is none choosen */
1449 if (encoding_int != LATEX_ENCODINGS_MAX)
1450 {
1451 enc_latex_char = g_strconcat("\\usepackage[",
1452 latex_encodings[encoding_int].latex,"]{inputenc}\n", NULL);
1453 }
1454 fontsize = gtk_combo_box_text_get_active_text(
1455 GTK_COMBO_BOX_TEXT(glatex_wizard.fontsize_combobox));
1456 author = g_strdup(gtk_entry_get_text(GTK_ENTRY(glatex_wizard.author_textbox)));
1457 date = g_strdup(gtk_entry_get_text(GTK_ENTRY(glatex_wizard.date_textbox)));
1458 title = g_strdup(gtk_entry_get_text(GTK_ENTRY(glatex_wizard.title_textbox)));
1459 papersize_int = gtk_combo_box_get_active(
1460 GTK_COMBO_BOX(glatex_wizard.papersize_combobox));
1461 paperorientation_int = gtk_combo_box_get_active(
1462 GTK_COMBO_BOX(glatex_wizard.orientation_combobox));
1463
1464 if (KOMA_active == TRUE)
1465 {
1466 switch (papersize_int)
1467 {
1468 case 0:
1469 {
1470 papersize = g_utf8_casefold("paper=a4", -1);
1471 break;
1472 }
1473 case 1:
1474 {
1475 papersize = g_utf8_casefold("paper=a5", -1);
1476 break;
1477 }
1478 case 2:
1479 {
1480 papersize = g_utf8_casefold("paper=a6", -1);
1481 break;
1482 }
1483 }
1484
1485 }
1486 else
1487 {
1488 switch (papersize_int)
1489 {
1490 case 0:
1491 {
1492 papersize = g_utf8_casefold("a4paper", -1);
1493 break;
1494 }
1495 case 1:
1496 {
1497 papersize = g_utf8_casefold("a5paper", -1);
1498 break;
1499 }
1500 case 2:
1501 {
1502 papersize = g_utf8_casefold("a6paper", -1);
1503 break;
1504 }
1505 }
1506 }
1507
1508 if (papersize != NULL)
1509 {
1510 classoptions = g_strdup(papersize);
1511 g_free(papersize);
1512 }
1513
1514 switch (paperorientation_int)
1515 {
1516 case 2:
1517 {
1518 if (KOMA_active == TRUE)
1519 {
1520 orientation_string = g_utf8_casefold("paper=landscape", -1);
1521 }
1522 else
1523 {
1524 orientation_string = g_utf8_casefold("landscape", -1);
1525 }
1526 break;
1527 }
1528 /* 1 and default currently not handled differently, but
1529 * already inside for future use. Dear future me, sorry */
1530 case 1:
1531 default:
1532 {
1533 orientation_string = g_utf8_casefold("", -1);
1534 break;
1535 }
1536 }
1537 if (classoptions != NULL && !EMPTY(orientation_string))
1538 {
1539 classoptions = g_strconcat(classoptions, ",", orientation_string, NULL);
1540 g_free(orientation_string);
1541 }
1542
1543 if (classoptions != NULL && draft_active == TRUE)
1544 {
1545 draft = g_utf8_casefold("draft", -1);
1546 classoptions = g_strconcat(classoptions,",", draft, NULL);
1547 g_free(draft);
1548 }
1549 else if (classoptions == NULL && draft_active == TRUE)
1550 {
1551 draft = g_utf8_casefold("draft", -1);
1552 classoptions = g_strconcat(draft, NULL);
1553 g_free(draft);
1554 }
1555 if (classoptions != NULL && !EMPTY(fontsize))
1556 {
1557 classoptions = g_strconcat(classoptions, ",", fontsize, NULL);
1558 }
1559 else if (classoptions == NULL && !EMPTY(fontsize))
1560 {
1561 classoptions = g_strdup(fontsize);
1562 }
1563 g_free(fontsize);
1564
1565
1566 switch (documentclass_int)
1567 {
1568 case 0:
1569 {
1570 documentclass_str = g_utf8_casefold("book", -1);
1571 break;
1572 }
1573 case 1:
1574 {
1575 documentclass_str = g_utf8_casefold("article", -1);
1576 break;
1577 }
1578 case 2:
1579 {
1580 documentclass_str = g_utf8_casefold("report", -1);
1581 break;
1582 }
1583 case 3:
1584 {
1585 documentclass_str = g_utf8_casefold("letter", -1);
1586 break;
1587 }
1588 case 4:
1589 {
1590 documentclass_str = g_utf8_casefold("beamer", -1);
1591 }
1592 }
1593
1594 if (KOMA_active)
1595 {
1596 switch (documentclass_int)
1597 {
1598 case 0:
1599 {
1600 documentclass_str = g_utf8_casefold("scrbook", -1);
1601 break;
1602 }
1603 case 1:
1604 {
1605 documentclass_str = g_utf8_casefold("scrartcl", -1);
1606 break;
1607 }
1608 case 2:
1609 {
1610 documentclass_str = g_utf8_casefold("scrreprt", -1);
1611 break;
1612 }
1613 }
1614
1615 }
1616
1617 /* Get the correct template */
1618 /* First check whether its a build in one or a custom one than
1619 * assign the wished template */
1620 if (template_int < LATEX_WIZARD_TEMPLATE_END ||
1621 glatex_wizard.template_list == NULL)
1622 {
1623 if (template_int == LATEX_WIZARD_TEMPLATE_DEFAULT)
1624 code = g_string_new(TEMPLATE_LATEX);
1625 else if (documentclass_int == 3)
1626 code = g_string_new(TEMPLATE_LATEX_LETTER);
1627 else if (documentclass_int == 4)
1628 code = g_string_new(TEMPLATE_LATEX_BEAMER);
1629 else
1630 code = g_string_new(TEMPLATE_LATEX);
1631 }
1632 else
1633 {
1634 TemplateEntry *tmp = NULL;
1635
1636 /* Return if the value choose is for some uknown reason to high */
1637 if (template_int > (glatex_wizard.template_list->len + LATEX_WIZARD_TEMPLATE_END))
1638 return;
1639
1640 tmp = g_ptr_array_index(glatex_wizard.template_list, template_int - LATEX_WIZARD_TEMPLATE_END);
1641 code = glatex_get_template_from_file(tmp->filepath);
1642
1643 /* Cleaning up template array as there is no usage for anymore */
1644 g_ptr_array_foreach (glatex_wizard.template_list, (GFunc)glatex_free_template_entry, NULL);
1645 g_ptr_array_free(glatex_wizard.template_list, TRUE);
1646 }
1647
1648 if (code != NULL)
1649 {
1650 if (classoptions != NULL)
1651 {
1652 utils_string_replace_all(code, "{CLASSOPTION}", classoptions);
1653 g_free(classoptions);
1654 }
1655 if (documentclass_str != NULL)
1656 {
1657 utils_string_replace_all(code, "{DOCUMENTCLASS}", documentclass_str);
1658 g_free(documentclass_str);
1659 }
1660 if (enc_latex_char != NULL)
1661 {
1662 utils_string_replace_all(code, "{ENCODING}", enc_latex_char);
1663 g_free(enc_latex_char);
1664 }
1665 else
1666 /* If there is no encoding proberly set but {ENCODING} is set inside
1667 * the template, replace it with nothing */
1668 {
1669 utils_string_replace_all(code, "{ENCODING}", "");
1670 }
1671 switch (paperorientation_int){
1672 case 2:
1673 {
1674 utils_string_replace_all(code, "{GEOMETRY}",
1675 "\\usepackage[landscape]{geometry}\n");
1676 break;
1677 }
1678 default:
1679 {
1680 utils_string_replace_all(code, "{GEOMETRY}", "");
1681 break;
1682 }
1683 }
1684 if (!EMPTY(author))
1685 {
1686 gchar* author_string = NULL;
1687 if (documentclass_int == 3)
1688 {
1689 author_string = g_strconcat("\\signature{", author, "}\n", NULL);
1690 }
1691 else
1692 {
1693 author_string = g_strconcat("\\author{", author, "}\n", NULL);
1694 }
1695 utils_string_replace_all(code, "{AUTHOR}", author_string);
1696 g_free(author);
1697 g_free(author_string);
1698 }
1699 else
1700 {
1701 gchar* author_string = NULL;
1702 if (documentclass_int == 3)
1703 {
1704 utils_string_replace_all(code, "{AUTHOR}", "% \\signature{}\n");
1705 }
1706 else
1707 {
1708 utils_string_replace_all(code, "{AUTHOR}", "% \\author{}\n");
1709 }
1710 utils_string_replace_all(code, "{AUTHOR}", author_string);
1711 if (author != NULL)
1712 {
1713 g_free(author);
1714 }
1715 g_free(author_string);
1716 }
1717
1718 if (!EMPTY(date))
1719 {
1720 gchar *date_string = NULL;
1721 date_string = g_strconcat("\\date{", date, "}\n", NULL);
1722 utils_string_replace_all(code, "{DATE}", date_string);
1723 g_free(date);
1724 g_free(date_string);
1725 }
1726 else
1727 {
1728 utils_string_replace_all(code, "{DATE}", "% \\date{}\n");
1729 if (date != NULL)
1730 {
1731 g_free(date);
1732 }
1733 }
1734
1735 if (title != NULL)
1736 {
1737 gchar *title_string = NULL;
1738 if (documentclass_int == 3)
1739 {
1740 title_string = g_strconcat("\\subject{", title, "}\n", NULL);
1741 }
1742 else
1743 {
1744 title_string = g_strconcat("\\title{", title, "}\n", NULL);
1745 }
1746
1747 utils_string_replace_all(code, "{TITLE}", title_string);
1748 g_free(title);
1749 g_free(title_string);
1750 }
1751 else
1752 {
1753 if (documentclass_int == 3)
1754 {
1755 utils_string_replace_all(code, "{TITLE}", "% \\subject{} \n");
1756 }
1757 else
1758 {
1759 utils_string_replace_all(code, "{TITLE}", "% \\title{} \n");
1760 }
1761 if (title != NULL)
1762 {
1763 g_free(title);
1764 }
1765 }
1766 utils_string_replace_all(code, "{OPENING}", _("Dear Sir or Madame"));
1767 utils_string_replace_all(code, "{CLOSING}", _("With kind regards"));
1768
1769 output = g_string_free(code, FALSE);
1770 show_output(output, NULL, encoding_int);
1771 g_free(output);
1772 }
1773 else
1774 {
1775 g_warning(_("No template assigned. Aborting"));
1776 }
1777 }
1778 gtk_widget_destroy(GTK_WIDGET(dialog));
1779 }
1780
1781 void
glatex_wizard_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,G_GNUC_UNUSED gpointer gdata)1782 glatex_wizard_activated(G_GNUC_UNUSED GtkMenuItem * menuitem,
1783 G_GNUC_UNUSED gpointer gdata)
1784 {
1785 gint i;
1786 gchar *author;
1787 GtkWidget *dialog = NULL;
1788 GtkWidget *vbox = NULL;
1789 GtkWidget *label_documentclass = NULL;
1790 GtkWidget *label_encoding = NULL;
1791 GtkWidget *label_fontsize = NULL;
1792 GtkWidget *table = NULL;
1793 GtkWidget *label_author = NULL;
1794 GtkWidget *label_date = NULL;
1795 GtkWidget *label_title = NULL;
1796 GtkWidget *label_papersize = NULL;
1797 GtkWidget *label_template = NULL;
1798 GtkWidget *label_orientation = NULL;
1799 GtkWidget *fontsize_entry = NULL;
1800
1801 /* Building the wizard-dialog and showing it */
1802 dialog = gtk_dialog_new_with_buttons(_("LaTeX-Wizard"),
1803 GTK_WINDOW(geany->main_widgets->window),
1804 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL,
1805 GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
1806 NULL);
1807 gtk_widget_set_name(dialog, "GeanyDialog");
1808
1809 /* Creating and formatting table */
1810 table = gtk_table_new(2, 6, FALSE);
1811 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
1812 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
1813
1814 /* Templates
1815 * Adds custom templates if there are any. If there are none just
1816 * adds default one */
1817 label_template = gtk_label_new(_("Template:"));
1818
1819 glatex_wizard.template_combobox = gtk_combo_box_text_new();
1820 gtk_widget_set_tooltip_text(glatex_wizard.template_combobox,
1821 _("Set the template which should be used for creating the new document"));
1822 gtk_misc_set_alignment(GTK_MISC(label_template), 0, 0.5);
1823
1824 gtk_table_attach_defaults(GTK_TABLE(table), label_template, 0, 1, 0, 1);
1825 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.template_combobox, 1, 2, 0, 1);
1826
1827 /* Adding default/build in templates to pull down and set the generic
1828 * one as default */
1829 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.template_combobox),
1830 LATEX_WIZARD_TEMPLATE_DEFAULT, _("Default"));
1831 gtk_combo_box_set_active(GTK_COMBO_BOX(glatex_wizard.template_combobox),
1832 LATEX_WIZARD_TEMPLATE_DEFAULT);
1833
1834 /* Checking whether some custom template are available and adding
1835 * if so.
1836 * Also init array with templates available. */
1837 glatex_wizard.template_list = glatex_init_custom_templates();
1838 glatex_add_templates_to_combobox(glatex_wizard.template_list, glatex_wizard.template_combobox);
1839
1840 /* Documentclass */
1841 label_documentclass = gtk_label_new(_("Documentclass:"));
1842 glatex_wizard.documentclass_combobox = gtk_combo_box_text_new();
1843 gtk_widget_set_tooltip_text(glatex_wizard.documentclass_combobox,
1844 _("Choose the kind of document you want to write"));
1845 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.documentclass_combobox), 0,
1846 _("Book"));
1847 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.documentclass_combobox), 1,
1848 _("Article"));
1849 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.documentclass_combobox), 2,
1850 _("Report"));
1851 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.documentclass_combobox), 3,
1852 _("Letter"));
1853 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.documentclass_combobox), 4,
1854 _("Presentation"));
1855
1856 gtk_combo_box_set_active(GTK_COMBO_BOX(glatex_wizard.documentclass_combobox), 0);
1857
1858 gtk_misc_set_alignment(GTK_MISC(label_documentclass), 0, 0.5);
1859
1860 gtk_table_attach_defaults(GTK_TABLE(table), label_documentclass, 0, 1, 1, 2);
1861 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.documentclass_combobox, 1, 2, 1, 2);
1862
1863 /* Encoding */
1864 label_encoding = gtk_label_new(_("Encoding:"));
1865
1866 glatex_wizard.encoding_combobox = gtk_combo_box_text_new();
1867 gtk_widget_set_tooltip_text(glatex_wizard.encoding_combobox,
1868 _("Set the encoding for your new document"));
1869 for (i = 0; i < LATEX_ENCODINGS_MAX; i++)
1870 {
1871 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.encoding_combobox), i,
1872 latex_encodings[i].name);
1873 }
1874
1875 gtk_combo_box_set_active(GTK_COMBO_BOX(glatex_wizard.encoding_combobox),
1876 find_latex_enc(geany_data->file_prefs->default_new_encoding));
1877
1878 gtk_misc_set_alignment(GTK_MISC(label_encoding), 0, 0.5);
1879
1880 gtk_table_attach_defaults(GTK_TABLE(table), label_encoding, 0, 1, 2, 3);
1881 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.encoding_combobox, 1, 2, 2, 3);
1882
1883 /* fontsize */
1884 label_fontsize = gtk_label_new(_("Font size"));
1885 glatex_wizard.fontsize_combobox = gtk_combo_box_text_new_with_entry();
1886 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glatex_wizard.fontsize_combobox),"10pt");
1887 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glatex_wizard.fontsize_combobox),"11pt");
1888 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glatex_wizard.fontsize_combobox),"12pt");
1889 gtk_widget_set_tooltip_text(glatex_wizard.fontsize_combobox,
1890 _("Set the default font size of your new document"));
1891
1892 gtk_misc_set_alignment(GTK_MISC(label_fontsize), 0, 0.5);
1893
1894 gtk_table_attach_defaults(GTK_TABLE(table), label_fontsize, 0, 1, 3, 4);
1895 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.fontsize_combobox, 1, 2, 3, 4);
1896
1897 fontsize_entry = gtk_bin_get_child(GTK_BIN(glatex_wizard.fontsize_combobox));
1898 g_signal_connect(G_OBJECT(fontsize_entry), "activate",
1899 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1900
1901 /* Author */
1902 label_author = gtk_label_new(_("Author:"));
1903 glatex_wizard.author_textbox = gtk_entry_new();
1904 gtk_widget_set_tooltip_text(glatex_wizard.author_textbox,
1905 _("Sets the value of the \\author command. In most cases this should be your name"));
1906 if (geany_data->template_prefs->developer != NULL)
1907 {
1908 author = geany_data->template_prefs->developer;
1909 gtk_entry_set_text(GTK_ENTRY(glatex_wizard.author_textbox), author);
1910 }
1911 gtk_misc_set_alignment(GTK_MISC(label_author), 0, 0.5);
1912 gtk_table_attach_defaults(GTK_TABLE(table), label_author, 0, 1, 4, 5);
1913 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.author_textbox, 1, 2, 4, 5);
1914
1915 g_signal_connect(G_OBJECT(glatex_wizard.author_textbox), "activate",
1916 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1917
1918 /* Date */
1919 label_date = gtk_label_new(_("Date:"));
1920 glatex_wizard.date_textbox = gtk_entry_new();
1921 gtk_widget_set_tooltip_text(glatex_wizard.date_textbox,
1922 _("Sets the value of the \\date command inside header of your "
1923 "new created LaTeX-document. Keeping it at \\today is a good "
1924 "decision if you don't need any fixed date."));
1925 gtk_entry_set_text(GTK_ENTRY(glatex_wizard.date_textbox), "\\today");
1926 gtk_misc_set_alignment(GTK_MISC(label_date), 0, 0.5);
1927 gtk_table_attach_defaults(GTK_TABLE(table), label_date, 0, 1, 5, 6);
1928 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.date_textbox, 1, 2, 5, 6);
1929
1930 g_signal_connect(G_OBJECT(glatex_wizard.date_textbox), "activate",
1931 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1932
1933 /* Title of the new document */
1934 label_title = gtk_label_new(_("Title:"));
1935 glatex_wizard.title_textbox = gtk_entry_new();
1936 gtk_widget_set_tooltip_text(glatex_wizard.title_textbox,
1937 _("Sets the title of your new document."));
1938 gtk_misc_set_alignment(GTK_MISC(label_title), 0, 0.5);
1939 gtk_table_attach_defaults(GTK_TABLE(table), label_title, 0, 1, 6, 7);
1940 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.title_textbox, 1, 2, 6, 7);
1941
1942 g_signal_connect(G_OBJECT(glatex_wizard.title_textbox), "activate",
1943 G_CALLBACK(glatex_enter_key_pressed_in_entry), dialog);
1944
1945 /* Papersize */
1946 label_papersize = gtk_label_new(_("Paper size:"));
1947 glatex_wizard.papersize_combobox = gtk_combo_box_text_new();
1948 gtk_widget_set_tooltip_text(glatex_wizard.papersize_combobox,
1949 _("Choose the paper format for the newly created document"));
1950 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.papersize_combobox), 0, "A4");
1951 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.papersize_combobox), 1, "A5");
1952 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.papersize_combobox), 2, "A6");
1953
1954 gtk_combo_box_set_active(GTK_COMBO_BOX(glatex_wizard.papersize_combobox), 0);
1955
1956 gtk_misc_set_alignment(GTK_MISC(label_papersize), 0, 0.5);
1957
1958 gtk_table_attach_defaults(GTK_TABLE(table), label_papersize, 0, 1, 7, 8);
1959 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.papersize_combobox, 1, 2, 7, 8);
1960
1961 /* Paper direction */
1962 label_orientation = gtk_label_new(_("Paper Orientation:"));
1963 glatex_wizard.orientation_combobox = gtk_combo_box_text_new();
1964 gtk_widget_set_tooltip_text(glatex_wizard.orientation_combobox,
1965 _("Choose the paper orientation for the newly created document"));
1966 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.orientation_combobox), 0, "Default");
1967 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.orientation_combobox), 1, "Portrait");
1968 gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(glatex_wizard.orientation_combobox), 2, "Landscape");
1969
1970 gtk_combo_box_set_active(GTK_COMBO_BOX(glatex_wizard.orientation_combobox), 0);
1971
1972 gtk_misc_set_alignment(GTK_MISC(label_orientation), 0, 0.5);
1973
1974 gtk_table_attach_defaults(GTK_TABLE(table), label_orientation, 0, 1, 8, 9);
1975 gtk_table_attach_defaults(GTK_TABLE(table), glatex_wizard.orientation_combobox, 1, 2, 8, 9);
1976
1977
1978 /* Doing the rest .... */
1979 gtk_widget_show_all(table);
1980
1981 vbox = ui_dialog_vbox_new(GTK_DIALOG(dialog));
1982 gtk_box_set_spacing(GTK_BOX(vbox), 10);
1983 gtk_container_add(GTK_CONTAINER(vbox), table);
1984
1985 glatex_wizard.checkbox_KOMA = gtk_check_button_new_with_label(
1986 _("Use KOMA-script classes if possible"));
1987 gtk_widget_set_tooltip_text(glatex_wizard.checkbox_KOMA,
1988 _("Uses the KOMA-script classes by Markus Kohm.\n"
1989 "Keep in mind: To compile your document these classes "
1990 "have to be installed before."));
1991 gtk_button_set_focus_on_click(GTK_BUTTON(glatex_wizard.checkbox_KOMA), FALSE);
1992 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glatex_wizard.checkbox_KOMA), glatex_set_koma_active);
1993 gtk_box_pack_start(GTK_BOX(vbox), glatex_wizard.checkbox_KOMA, FALSE, FALSE, 5);
1994
1995 glatex_wizard.checkbox_draft = gtk_check_button_new_with_label(_("Use draft mode"));
1996 gtk_widget_set_tooltip_text(glatex_wizard.checkbox_draft,
1997 _("Set the draft flag inside new created documents to get "
1998 "documents with a number of debugging helpers"));
1999 gtk_button_set_focus_on_click(GTK_BUTTON(glatex_wizard.checkbox_draft), FALSE);
2000 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(glatex_wizard.checkbox_draft), FALSE);
2001 gtk_box_pack_start(GTK_BOX(vbox), glatex_wizard.checkbox_draft, FALSE, FALSE, 5);
2002 g_signal_connect(dialog, "response", G_CALLBACK(on_wizard_response), NULL);
2003
2004 gtk_widget_show_all(dialog);
2005 }
2006
init_keybindings(void)2007 static void init_keybindings(void)
2008 {
2009 GeanyKeyGroup *key_group;
2010
2011 /* init keybindings */
2012 key_group = plugin_set_key_group(geany_plugin, "latex", COUNT_KB, NULL);
2013 keybindings_set_item(key_group, KB_LATEX_WIZARD, glatex_kbwizard,
2014 0, 0, "run_latex_wizard", _("Run LaTeX-Wizard"), menu_latex_wizard);
2015 keybindings_set_item(key_group, KB_LATEX_INSERT_LABEL, glatex_kblabel_insert,
2016 0, 0, "insert_latex_label", _("Insert \\label"), menu_latex_label);
2017 keybindings_set_item(key_group, KB_LATEX_INSERT_REF, glatex_kbref_insert,
2018 0, 0, "insert_latex_ref", _("Insert \\ref"), menu_latex_ref);
2019 keybindings_set_item(key_group, KB_LATEX_INSERT_NEWLINE, glatex_kb_insert_newline,
2020 0, 0, "insert_new_line", _("Insert linebreak \\\\ "), NULL);
2021 keybindings_set_item(key_group, KB_LATEX_INSERT_COMMAND,
2022 glatex_kb_insert_command_dialog, 0, 0, "latex_insert_command",
2023 _("Insert command"), menu_latex_insert_command);
2024 keybindings_set_item(key_group, KB_LATEX_TOGGLE_ACTIVE, glatex_kblatex_toggle,
2025 0, 0, "latex_toggle_status", _("Turn input replacement on/off"),
2026 menu_latex_replace_toggle);
2027 keybindings_set_item(key_group, KB_LATEX_REPLACE_SPECIAL_CHARS,
2028 glatex_kb_replace_special_chars, 0, 0, "latex_replace_chars",
2029 _("Replace special characters"), NULL);
2030 keybindings_set_item(key_group, KB_LATEX_ENVIRONMENT_INSERT,
2031 glatex_kbref_insert_environment, 0, 0, "latex_insert_environment",
2032 _("Run insert environment dialog"), menu_latex_insert_environment);
2033 keybindings_set_item(key_group, KB_LATEX_INSERT_NEWITEM,
2034 glatex_kb_insert_newitem, 0, 0, "latex_insert_item", _("Insert \\item"), NULL);
2035 keybindings_set_item(key_group, KB_LATEX_FORMAT_BOLD, glatex_kb_format_bold,
2036 0, 0, "format_bold", _("Format selection in bold font face"), NULL);
2037 keybindings_set_item(key_group, KB_LATEX_FORMAT_ITALIC, glatex_kb_format_italic,
2038 0, 0, "format_italic", _("Format selection in italic font face"), NULL);
2039 keybindings_set_item(key_group, KB_LATEX_FORMAT_TYPEWRITER, glatex_kb_format_typewriter,
2040 0, 0, "format_typewriter", _("Format selection in typewriter font face"), NULL);
2041 keybindings_set_item(key_group, KB_LATEX_FORMAT_CENTER, glatex_kb_format_centering,
2042 0, 0, "format_center", _("Format selection centered"), NULL);
2043 keybindings_set_item(key_group, KB_LATEX_FORMAT_LEFT, glatex_kb_format_left,
2044 0, 0, "format_left", _("Format selection left-aligned"), NULL);
2045 keybindings_set_item(key_group, KB_LATEX_FORMAT_RIGHT, glatex_kb_format_right,
2046 0, 0, "format_right", _("Format selection right-aligned"), NULL);
2047 keybindings_set_item(key_group, KB_LATEX_ENVIRONMENT_INSERT_DESCRIPTION,
2048 glatex_kb_insert_description_list, 0, 0, "insert_description_list",
2049 _("Insert description list"), NULL);
2050 keybindings_set_item(key_group, KB_LATEX_ENVIRONMENT_INSERT_ITEMIZE,
2051 glatex_kb_insert_itemize_list, 0, 0, "insert_itemize_list",
2052 _("Insert itemize list"), NULL);
2053 keybindings_set_item(key_group, KB_LATEX_ENVIRONMENT_INSERT_ENUMERATE,
2054 glatex_kb_insert_enumerate_list, 0, 0, "insert_enumerate_list",
2055 _("Insert enumerate list"), NULL);
2056 keybindings_set_item(key_group, KB_LATEX_STRUCTURE_LVLUP,
2057 glatex_kb_structure_lvlup, 0, 0, "structure_lvl_up",
2058 _("Set selection one level up"), NULL);
2059 keybindings_set_item(key_group, KB_LATEX_STRUCTURE_LVLDOWN,
2060 glatex_kb_structure_lvldown, 0, 0, "structure_lvl_down",
2061 _("Set selection one level down"), NULL);
2062 keybindings_set_item(key_group, KB_LATEX_USEPACKAGE_DIALOG,
2063 glatex_kb_usepackage_dialog, 0, 0, "usepackage_dialog",
2064 _("Insert \\usepackage{}"), menu_latex_insert_usepackage);
2065 keybindings_set_item(key_group, KB_LATEX_INSERT_CITE,
2066 glatex_kb_insert_bibtex_cite, 0, 0, "insert_cite_dialog",
2067 _("Insert BibTeX reference dialog"), menu_latex_insert_bibtex_cite);
2068 }
2069
2070
plugin_help(void)2071 void plugin_help(void)
2072 {
2073 dialogs_show_msgbox(GTK_MESSAGE_INFO,
2074 _("LaTeX is a plugin to improve support for LaTeX in Geany."
2075 "\n\nPlease report all bugs or feature requests to one of the "
2076 "authors."));
2077 }
2078
2079
glatex_init_configuration(void)2080 static void glatex_init_configuration(void)
2081 {
2082 GKeyFile *config = g_key_file_new();
2083
2084 /* loading configurations from file ...*/
2085 config_file = g_strconcat(geany->app->configdir, G_DIR_SEPARATOR_S,
2086 "plugins", G_DIR_SEPARATOR_S,
2087 "LaTeX", G_DIR_SEPARATOR_S, "general.conf", NULL);
2088
2089 /* ... and Initialising options from config file */
2090 g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
2091
2092 glatex_set_koma_active = utils_get_setting_boolean(config, "general",
2093 "glatex_set_koma_active", FALSE);
2094 glatex_set_toolbar_active = utils_get_setting_boolean(config, "general",
2095 "glatex_set_toolbar_active", FALSE);
2096 glatex_autocompletion_active = utils_get_setting_boolean(config, "general",
2097 "glatex_set_autocompletion", TRUE);
2098 glatex_autobraces_active = utils_get_setting_boolean(config, "autocompletion",
2099 "glatex_set_autobraces", TRUE);
2100 glatex_lowercase_on_smallcaps = utils_get_setting_boolean(config, "general",
2101 "glatex_lowercase_on_smallcaps", FALSE);
2102
2103 /* Hidden preferences. Can be set directly via configuration file*/
2104 glatex_autocompletion_context_size = utils_get_setting_integer(config, "autocompletion",
2105 "glatex_set_autocompletion_contextsize", 5);
2106
2107 /* Doing some input validation */
2108 if (glatex_autocompletion_active == TRUE &&
2109 glatex_autocompletion_context_size <= 0)
2110 {
2111 glatex_autocompletion_context_size = 5;
2112 g_warning(_("glatex_set_autocompletion_contextsize has been "
2113 "initialized with an invalid value. Default value taken. "
2114 "Please check your configuration file"));
2115 }
2116 /* Increase value by an offset as we add a new line so 2 really means 2 */
2117 glatex_autocompletion_context_size = glatex_autocompletion_context_size + 2;
2118
2119 glatex_autocompletion_only_for_latex = utils_get_setting_boolean(config, "autocompletion",
2120 "glatex_autocompletion_only_for_latex", TRUE);
2121 glatex_capitalize_sentence_starts = utils_get_setting_boolean(config, "autocompletion",
2122 "glatex_capitalize_sentence_starts", FALSE);
2123
2124 glatex_deactivate_toolbaritems_with_non_latex = utils_get_setting_boolean(config, "toolbar",
2125 "glatex_deactivate_toolbaritems_with_non_latex", TRUE);
2126 glatex_wizard_to_generic_toolbar = utils_get_setting_boolean(config, "toolbar",
2127 "glatex_wizard_to_generic_toolbar", TRUE);
2128 glatex_deactivate_menubarentry_with_non_latex = utils_get_setting_boolean(config, "menu",
2129 "glatex_deactivate_menubarentry_with_non_latex", TRUE);
2130 glatex_add_menu_on_startup = utils_get_setting_boolean(config, "menu",
2131 "glatex_add_menu_on_startup", FALSE);
2132
2133 glatex_ref_page_string = utils_get_setting_string(config, "reference",
2134 "glatex_reference_page", _("page \\pageref{{{reference}}}"));
2135 glatex_ref_chapter_string = utils_get_setting_string(config, "reference",
2136 "glatex_reference_chapter", "\\ref{{{reference}}}");
2137 glatex_ref_all_string = utils_get_setting_string(config, "reference",
2138 "glatex_reference_all", _("\\ref{{{reference}}}, page \\pageref{{{reference}}}"));
2139
2140 glatex_ref_page_string = utils_get_setting_string(config, "reference",
2141 "glatex_reference_page", _("page \\pageref{{{reference}}}"));
2142 glatex_ref_chapter_string = utils_get_setting_string(config, "reference",
2143 "glatex_reference_chapter", "\\ref{{{reference}}}");
2144 glatex_ref_all_string = utils_get_setting_string(config, "reference",
2145 "glatex_reference_all", _("\\ref{{{reference}}}, page \\pageref{{{reference}}}"));
2146
2147 g_key_file_free(config);
2148 }
2149
2150
2151 static void
add_wizard_to_generic_toolbar(void)2152 add_wizard_to_generic_toolbar(void)
2153 {
2154 if (glatex_wizard_generic_toolbar_item == NULL)
2155 {
2156 /* TODO: Find a better icon as this one is used way too often */
2157 glatex_wizard_generic_toolbar_item =
2158 gtk_tool_button_new_from_stock(GTK_STOCK_NEW);
2159 plugin_add_toolbar_item(geany_plugin, glatex_wizard_generic_toolbar_item);
2160 gtk_widget_show_all(GTK_WIDGET(glatex_wizard_generic_toolbar_item));
2161 g_signal_connect(glatex_wizard_generic_toolbar_item, "clicked",
2162 G_CALLBACK(glatex_wizard_activated), NULL);
2163 }
2164 }
2165
2166
2167 static void
remove_wizard_from_generic_toolbar(void)2168 remove_wizard_from_generic_toolbar(void)
2169 {
2170 if (glatex_wizard_generic_toolbar_item != NULL)
2171 {
2172 gtk_widget_destroy(GTK_WIDGET(glatex_wizard_generic_toolbar_item));
2173 glatex_wizard_generic_toolbar_item = NULL;
2174 }
2175 }
2176
2177
2178 static void
add_menu_to_menubar(void)2179 add_menu_to_menubar(void)
2180 {
2181 GtkWidget *tmp = NULL;
2182 gint i;
2183 GtkMenuShell *menubar;
2184 GList *menubar_children;
2185
2186 /* First we check for the menubar where to add the LaTeX menu */
2187 menubar = GTK_MENU_SHELL(
2188 ui_lookup_widget(geany->main_widgets->window, "menubar1"));
2189
2190 /* First we check whether the LaTeX menu entry already exists */
2191 if (menu_latex == NULL)
2192 {
2193 /* Build up menu for menubar */
2194 menu_latex = gtk_menu_item_new_with_mnemonic(_("_LaTeX"));
2195 menubar_children = gtk_container_get_children(GTK_CONTAINER(menubar));
2196 gtk_menu_shell_insert(
2197 menubar, menu_latex, g_list_length(menubar_children)-1);
2198
2199 menu_latex_menu = gtk_menu_new();
2200 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex), menu_latex_menu);
2201
2202 /* Filling up menubar menus */
2203 /* LaTeX menu */
2204 menu_latex_wizard = ui_image_menu_item_new(GTK_STOCK_NEW, _("LaTeX-_Wizard"));
2205 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_wizard);
2206 gtk_widget_set_tooltip_text(menu_latex_wizard,
2207 _("Starts a Wizard to easily create LaTeX-documents"));
2208
2209 g_signal_connect(menu_latex_wizard, "activate",
2210 G_CALLBACK(glatex_wizard_activated), NULL);
2211
2212 menu_latex_menu_special_char = gtk_menu_item_new_with_mnemonic(_("I_nsert Special Character"));
2213 gtk_widget_set_tooltip_text(menu_latex_menu_special_char,
2214 _("Helps to use some not very common letters and signs"));
2215 gtk_container_add(GTK_CONTAINER(menu_latex_menu),
2216 menu_latex_menu_special_char);
2217
2218 menu_latex_menu_special_char_submenu = gtk_menu_new();
2219 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex_menu_special_char),
2220 menu_latex_menu_special_char_submenu);
2221 glatex_sub_menu_init(menu_latex_menu_special_char_submenu,
2222 glatex_char_array, glatex_cat_names, char_insert_activated);
2223
2224 menu_latex_ref = gtk_menu_item_new_with_mnemonic(_("Insert _Reference"));
2225 gtk_widget_set_tooltip_text(menu_latex_ref,
2226 _("Inserting references to the document"));
2227 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_ref);
2228 g_signal_connect(menu_latex_ref, "activate",
2229 G_CALLBACK(glatex_insert_ref_activated), NULL);
2230
2231 menu_latex_label = gtk_menu_item_new_with_mnemonic(_("Insert _Label"));
2232 gtk_widget_set_tooltip_text(menu_latex_label,
2233 _("Helps at inserting labels to a document"));
2234 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_label);
2235 g_signal_connect(menu_latex_label, "activate",
2236 G_CALLBACK(glatex_insert_label_activated), NULL);
2237
2238 menu_latex_insert_environment = gtk_menu_item_new_with_mnemonic(
2239 _("Insert _Environment"));
2240 gtk_widget_set_tooltip_text(menu_latex_insert_environment,
2241 _("Helps at inserting an environment a document"));
2242 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_insert_environment);
2243 g_signal_connect(menu_latex_insert_environment, "activate",
2244 G_CALLBACK(glatex_insert_environment_dialog), NULL);
2245
2246 menu_latex_insert_usepackage = gtk_menu_item_new_with_mnemonic(
2247 _("Insert P_ackage"));
2248 gtk_widget_set_tooltip_text(menu_latex_insert_usepackage,
2249 _("A small dialog to insert \\usepackage{} into header of current file"));
2250 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_insert_usepackage);
2251 g_signal_connect(menu_latex_insert_usepackage, "activate",
2252 G_CALLBACK(glatex_insert_usepackage_dialog), NULL);
2253
2254 menu_latex_format_insert = gtk_menu_item_new_with_mnemonic(_("_Format"));
2255 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_format_insert);
2256
2257 menu_latex_format_insert_submenu = gtk_menu_new();
2258 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex_format_insert),
2259 menu_latex_format_insert_submenu);
2260
2261 for (i = 0; i < LATEX_STYLES_END; i++)
2262 {
2263 tmp = NULL;
2264 tmp = gtk_menu_item_new_with_mnemonic(_(glatex_format_labels[i]));
2265 gtk_container_add(GTK_CONTAINER(menu_latex_format_insert_submenu), tmp);
2266 g_signal_connect(tmp, "activate",
2267 G_CALLBACK(glatex_insert_latex_format), GINT_TO_POINTER(i));
2268 }
2269
2270 /* Add font size menu */
2271 menu_latex_fontsize = gtk_menu_item_new_with_mnemonic(_("F_ont size"));
2272 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_fontsize);
2273
2274 menu_latex_fontsize_submenu = gtk_menu_new();
2275 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex_fontsize),
2276 menu_latex_fontsize_submenu);
2277
2278 for (i = 0; i < LATEX_FONTSIZE_END; i++)
2279 {
2280 tmp = NULL;
2281 tmp = gtk_menu_item_new_with_mnemonic(_(glatex_fontsize_labels[i]));
2282 gtk_container_add(GTK_CONTAINER(menu_latex_fontsize_submenu), tmp);
2283 g_signal_connect(tmp, "activate",
2284 G_CALLBACK(glatex_insert_latex_fontsize), GINT_TO_POINTER(i));
2285 }
2286
2287 /* Add menuitem for LaTeX replacement functions*/
2288 menu_latex_replacement = gtk_menu_item_new_with_mnemonic(
2289 _("_Special Character Replacement"));
2290 menu_latex_replacement_submenu = gtk_menu_new();
2291 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex_replacement),
2292 menu_latex_replacement_submenu);
2293 gtk_container_add(GTK_CONTAINER(menu_latex_menu), menu_latex_replacement);
2294
2295 /* Add menuitem for bulk replacment */
2296 menu_latex_replace_selection = gtk_menu_item_new_with_mnemonic(
2297 _("Bulk _Replace Special Characters"));
2298 gtk_widget_set_tooltip_text(menu_latex_replace_selection,
2299 _("_Replace selected special characters with TeX substitutes"));
2300 gtk_container_add(GTK_CONTAINER(menu_latex_replacement_submenu),
2301 menu_latex_replace_selection);
2302 g_signal_connect(menu_latex_replace_selection, "activate",
2303 G_CALLBACK(glatex_replace_special_character), NULL);
2304
2305 /* Add menu entry for toggling input replacment */
2306 menu_latex_replace_toggle = gtk_check_menu_item_new_with_mnemonic(
2307 _("Toggle _Special Character Replacement"));
2308 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_latex_replace_toggle),
2309 toggle_active);
2310 gtk_container_add(GTK_CONTAINER(menu_latex_replacement_submenu),
2311 menu_latex_replace_toggle);
2312
2313 g_signal_connect(menu_latex_replace_toggle, "activate",
2314 G_CALLBACK(glatex_toggle_status), NULL);
2315
2316 /* Add menu entry for inserting a command */
2317 menu_latex_insert_command = gtk_menu_item_new_with_mnemonic(
2318 _("Insert _Command"));
2319 gtk_widget_set_tooltip_text(menu_latex_ref,
2320 _("Inserting customized command to document"));
2321 gtk_container_add(GTK_CONTAINER(menu_latex_menu),
2322 menu_latex_insert_command);
2323 g_signal_connect(menu_latex_insert_command, "activate",
2324 G_CALLBACK(glatex_insert_command_activated), NULL);
2325
2326 /* Switch document sitiveness for menu entries */
2327 ui_add_document_sensitive(menu_latex_menu_special_char);
2328 ui_add_document_sensitive(menu_latex_ref);
2329 ui_add_document_sensitive(menu_latex_label);
2330 ui_add_document_sensitive(menu_latex_format_insert);
2331 ui_add_document_sensitive(menu_latex_insert_environment);
2332 ui_add_document_sensitive(menu_latex_insert_usepackage);
2333 ui_add_document_sensitive(menu_latex_insert_command);
2334 ui_add_document_sensitive(menu_latex_fontsize);
2335 ui_add_document_sensitive(menu_latex_replacement);
2336
2337
2338 gtk_widget_show_all(menu_latex);
2339 } /* only execute if menuitem "LaTeX" has not already been inserted
2340 into menubar before */
2341
2342 /* BibTeX menu */
2343 if (menu_bibtex == NULL)
2344 {
2345 menu_bibtex = gtk_menu_item_new_with_mnemonic(_("_BibTeX"));
2346 menubar_children = gtk_container_get_children(GTK_CONTAINER(menubar));
2347 gtk_menu_shell_insert(
2348 menubar, menu_bibtex, g_list_length(menubar_children)-1);
2349
2350 menu_bibtex_menu = gtk_menu_new();
2351 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_bibtex), menu_bibtex_menu);
2352
2353 menu_latex_insert_bibtex_cite =
2354 gtk_menu_item_new_with_mnemonic(_("Insert B_ibTeX reference"));
2355 gtk_widget_set_tooltip_text(menu_latex_insert_bibtex_cite,
2356 _("Helps to insert a reference out of BibTeX files"));
2357 gtk_container_add(GTK_CONTAINER(menu_bibtex_menu), menu_latex_insert_bibtex_cite);
2358 g_signal_connect(menu_latex_insert_bibtex_cite, "activate",
2359 G_CALLBACK(on_insert_bibtex_dialog_activate), NULL);
2360
2361 menu_latex_bibtex = gtk_menu_item_new_with_mnemonic(_("_BibTeX entries"));
2362 gtk_container_add(GTK_CONTAINER(menu_bibtex_menu), menu_latex_bibtex);
2363
2364 menu_latex_bibtex_submenu = gtk_menu_new();
2365 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_latex_bibtex),
2366 menu_latex_bibtex_submenu);
2367
2368 for (i = 0; i < GLATEX_BIBTEX_N_TYPES; i++)
2369 {
2370 tmp = NULL;
2371 tmp = gtk_menu_item_new_with_mnemonic(_(glatex_bibtex_types[i].label));
2372 gtk_container_add(GTK_CONTAINER(menu_latex_bibtex_submenu), tmp);
2373 g_signal_connect(tmp, "activate",
2374 G_CALLBACK(glatex_insert_bibtex_entry), GINT_TO_POINTER(i));
2375 }
2376
2377 /* Switch document sensitivness */
2378 ui_add_document_sensitive(menu_latex_bibtex);
2379
2380 gtk_widget_show_all(menu_bibtex);
2381 } /* Only insert BibTeX menu if not already done. */
2382 }
2383
2384 /* Removes the menubar menus from menubar if requested and available */
remove_menu_from_menubar(void)2385 static void remove_menu_from_menubar(void)
2386 {
2387 if (menu_latex != NULL)
2388 {
2389 gtk_widget_destroy(menu_latex);
2390 menu_latex = NULL;
2391 }
2392 if (menu_bibtex != NULL)
2393 {
2394 gtk_widget_destroy(menu_bibtex);
2395 menu_bibtex = NULL;
2396 }
2397 }
2398
2399
2400 static void
remove_menu_from_tools_menu(void)2401 remove_menu_from_tools_menu(void)
2402 {
2403 if (menu_latex_toolbar_wizard != NULL)
2404 {
2405 gtk_widget_destroy(menu_latex_toolbar_wizard);
2406 menu_latex_toolbar_wizard = NULL;
2407 }
2408 }
2409
2410
2411 static void
add_wizard_to_tools_menu(void)2412 add_wizard_to_tools_menu(void)
2413 {
2414 if (menu_latex_toolbar_wizard == NULL)
2415 {
2416 menu_latex_toolbar_wizard = ui_image_menu_item_new(GTK_STOCK_NEW,
2417 _("LaTeX-_Wizard"));
2418 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu), menu_latex_toolbar_wizard);
2419 gtk_widget_set_tooltip_text(menu_latex_toolbar_wizard,
2420 _("Starts a Wizard to easily create LaTeX-documents"));
2421 gtk_widget_show_all(menu_latex_toolbar_wizard);
2422 g_signal_connect(menu_latex_toolbar_wizard, "activate",
2423 G_CALLBACK(glatex_wizard_activated), NULL);
2424 }
2425 }
2426
2427
2428 void
plugin_init(G_GNUC_UNUSED GeanyData * data)2429 plugin_init(G_GNUC_UNUSED GeanyData * data)
2430 {
2431 GeanyDocument *doc = NULL;
2432
2433 doc = document_get_current();
2434
2435 glatex_init_configuration();
2436 glatex_init_encodings_latex();
2437
2438 add_wizard_to_tools_menu();
2439
2440 init_keybindings();
2441
2442 /* Check whether the toolbar should be shown or not and do so*/
2443 if (glatex_set_toolbar_active == TRUE)
2444 {
2445 glatex_toolbar = init_toolbar();
2446 }
2447 else
2448 {
2449 glatex_toolbar = NULL;
2450 }
2451
2452 if (glatex_wizard_to_generic_toolbar == TRUE)
2453 {
2454 add_wizard_to_generic_toolbar();
2455 }
2456 else
2457 {
2458 glatex_wizard_generic_toolbar_item = NULL;
2459 }
2460
2461 if (doc != NULL)
2462 {
2463 if (glatex_add_menu_on_startup == TRUE||
2464 doc->file_type->id == GEANY_FILETYPES_LATEX)
2465 {
2466 add_menu_to_menubar();
2467 }
2468 }
2469
2470 move_old_config_file();
2471 }
2472
2473 void
plugin_cleanup(void)2474 plugin_cleanup(void)
2475 {
2476 if (glatex_toolbar != NULL)
2477 gtk_widget_destroy(glatex_toolbar);
2478 remove_menu_from_menubar();
2479 remove_menu_from_tools_menu();
2480 remove_wizard_from_generic_toolbar();
2481 g_free(config_file);
2482 g_free(glatex_ref_chapter_string);
2483 g_free(glatex_ref_page_string);
2484 g_free(glatex_ref_all_string);
2485 }
2486