~ubuntu-branches/ubuntu/raring/geany/raring-proposed

« back to all changes in this revision

Viewing changes to src/ui_utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Damián Viano
  • Date: 2008-05-02 11:37:45 UTC
  • mto: (3.1.1 lenny) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20080502113745-7q62rqhl2ku02ptu
Import upstream version 0.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *      ui_utils.c - this file is part of Geany, a fast and lightweight IDE
3
3
 *
4
 
 *      Copyright 2006 Enrico Troeger <enrico.troeger@uvena.de>
5
 
 *      Copyright 2006 Nick Treleaven <nick.treleaven@btinternet.com>
 
4
 *      Copyright 2006-2008 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
 
5
 *      Copyright 2006-2008 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
6
6
 *
7
7
 *      This program is free software; you can redistribute it and/or modify
8
8
 *      it under the terms of the GNU General Public License as published by
18
18
 *      along with this program; if not, write to the Free Software
19
19
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
20
 *
21
 
 * $Id: ui_utils.c 828 2006-09-21 09:55:50Z ntrel $
 
21
 * $Id: ui_utils.c 2472 2008-04-11 15:39:44Z eht16 $
22
22
 */
23
23
 
 
24
/*
 
25
 * User Interface general utility functions.
 
26
 */
24
27
 
25
28
#include "geany.h"
26
29
 
27
30
#include <string.h>
28
31
 
29
32
#include "ui_utils.h"
 
33
#include "prefs.h"
30
34
#include "sciwrappers.h"
31
35
#include "document.h"
 
36
#include "filetypes.h"
32
37
#include "support.h"
33
38
#include "msgwindow.h"
34
39
#include "utils.h"
36
41
#include "encodings.h"
37
42
#include "images.c"
38
43
#include "treeviews.h"
39
 
#include "keybindings.h"
 
44
#include "win32.h"
 
45
#include "project.h"
 
46
#include "editor.h"
 
47
#include "plugins.h"
 
48
 
 
49
 
 
50
UIPrefs                 ui_prefs;
 
51
UIWidgets               ui_widgets;
 
52
 
 
53
static struct
 
54
{
 
55
        /* widgets only sensitive when there is at least one document */
 
56
        GtkWidget *document_buttons[45];
 
57
}
 
58
widgets;
40
59
 
41
60
 
42
61
static gchar *menu_item_get_text(GtkMenuItem *menu_item);
43
62
 
44
 
static void update_recent_menu();
 
63
static void update_recent_menu(void);
45
64
static void recent_file_loaded(const gchar *utf8_filename);
46
65
static void
47
66
recent_file_activate_cb                (GtkMenuItem     *menuitem,
48
67
                                        gpointer         user_data);
49
68
 
50
 
static GtkWidget *create_build_menu_tex(gint idx);
51
 
static GtkWidget *create_build_menu_gen(gint idx);
52
 
 
53
69
 
54
70
/* allow_override is TRUE if text can be ignored when another message has been set
55
71
 * that didn't use allow_override and has not timed out. */
56
 
void ui_set_statusbar(const gchar *text, gboolean allow_override)
 
72
static void set_statusbar(const gchar *text, gboolean allow_override)
57
73
{
58
74
        static glong last_time = 0;
59
75
        GTimeVal timeval;
60
76
        const gint GEANY_STATUS_TIMEOUT = 1;
61
77
 
 
78
        if (! prefs.statusbar_visible)
 
79
                return; /* just do nothing if statusbar is not visible */
 
80
 
62
81
        g_get_current_time(&timeval);
63
82
 
64
83
        if (! allow_override)
76
95
}
77
96
 
78
97
 
79
 
/* updates the status bar */
 
98
/* Display text on the statusbar.
 
99
 * log is whether the message should be recorded in the Status window. */
 
100
void ui_set_statusbar(gboolean log, const gchar *format, ...)
 
101
{
 
102
        gchar string[512];
 
103
        va_list args;
 
104
 
 
105
        va_start(args, format);
 
106
        g_vsnprintf(string, 512, format, args);
 
107
        va_end(args);
 
108
 
 
109
        if (! prefs.suppress_status_messages)
 
110
                set_statusbar(string, FALSE);
 
111
 
 
112
        if (log || prefs.suppress_status_messages)
 
113
                msgwin_status_add("%s", string);
 
114
}
 
115
 
 
116
 
 
117
/* updates the status bar document statistics */
80
118
void ui_update_statusbar(gint idx, gint pos)
81
119
{
82
 
        gchar *text;
83
 
        const gchar *cur_tag;
84
 
        guint line, col;
 
120
        if (! prefs.statusbar_visible)
 
121
                return; /* just do nothing if statusbar is not visible */
85
122
 
86
123
        if (idx == -1) idx = document_get_cur_idx();
87
124
 
88
 
        if (idx >= 0 && doc_list[idx].is_valid)
 
125
        if (DOC_IDX_VALID(idx))
89
126
        {
90
 
                utils_get_current_function(idx, &cur_tag);
 
127
                static GString *stats_str = NULL;
 
128
                const gchar sp[] = "      ";
 
129
                guint line, col;
 
130
                const gchar *cur_tag;
 
131
                gchar *filetype_name;
 
132
 
 
133
                /* workaround to make the name of filetype GEANY_FILETYPES_ALL translatable */
 
134
                if (doc_list[idx].file_type == NULL || doc_list[idx].file_type->id == GEANY_FILETYPES_ALL)
 
135
                        filetype_name = _("None");
 
136
                else
 
137
                        filetype_name = doc_list[idx].file_type->name;
 
138
 
 
139
                if (stats_str == NULL)
 
140
                        stats_str = g_string_sized_new(120);
91
141
 
92
142
                if (pos == -1) pos = sci_get_current_position(doc_list[idx].sci);
93
143
                line = sci_get_line_from_position(doc_list[idx].sci, pos);
94
 
                col = sci_get_col_from_position(doc_list[idx].sci, pos);
95
 
 
96
 
                text = g_strdup_printf(_("%c  line: % 4d column: % 3d  selection: % 4d   %s      mode: %s%s      cur. function: %s      encoding: %s %s     filetype: %s"),
97
 
                        (doc_list[idx].changed) ? 42 : 32,
98
 
                        (line + 1), (col + 1),
99
 
                        sci_get_selected_text_length(doc_list[idx].sci) - 1,
100
 
                        doc_list[idx].do_overwrite ? _("OVR") : _("INS"),
101
 
                        document_get_eol_mode(idx),
102
 
                        (doc_list[idx].readonly) ? ", read only" : "",
103
 
                        cur_tag,
 
144
 
 
145
                /* Add temporary fix for sci infinite loop in Document::GetColumn(int)
 
146
                 * when current pos is beyond document end (can occur when removing
 
147
                 * blocks of selected lines especially esp. brace sections near end of file). */
 
148
                if (pos <= sci_get_length(doc_list[idx].sci))
 
149
                        col = sci_get_col_from_position(doc_list[idx].sci, pos);
 
150
                else
 
151
                        col = 0;
 
152
 
 
153
                /* Status bar statistics: col = column, sel = selection. */
 
154
                g_string_printf(stats_str, _("line: %d\t col: %d\t sel: %d\t "),
 
155
                        (line + 1), col,
 
156
                        sci_get_selected_text_length(doc_list[idx].sci) - 1);
 
157
 
 
158
                g_string_append(stats_str,
 
159
                        /* RO = read-only */
 
160
                        (doc_list[idx].readonly) ? _("RO ") :
 
161
                                /* OVR = overwrite/overtype, INS = insert */
 
162
                                (sci_get_overtype(doc_list[idx].sci) ? _("OVR") : _("INS")));
 
163
                g_string_append(stats_str, sp);
 
164
                g_string_append(stats_str,
 
165
                        (doc_list[idx].use_tabs) ? _("TAB") : _("SP "));        /* SP = space */
 
166
                g_string_append(stats_str, sp);
 
167
                g_string_append_printf(stats_str, _("mode: %s"),
 
168
                        document_get_eol_mode(idx));
 
169
                g_string_append(stats_str, sp);
 
170
                g_string_append_printf(stats_str, _("encoding: %s %s"),
104
171
                        (doc_list[idx].encoding) ? doc_list[idx].encoding : _("unknown"),
105
 
                        (utils_is_unicode_charset(doc_list[idx].encoding)) ? ((doc_list[idx].has_bom) ? _("(with BOM)") : _("(without BOM)")) : "",
106
 
                        (doc_list[idx].file_type) ? doc_list[idx].file_type->title : _("unknown"));
107
 
                ui_set_statusbar(text, TRUE); //can be overridden by status messages
108
 
                g_free(text);
 
172
                        (encodings_is_unicode_charset(doc_list[idx].encoding)) ?
 
173
                                /* BOM = byte order mark */
 
174
                                ((doc_list[idx].has_bom) ? _("(with BOM)") : "") : "");
 
175
                g_string_append(stats_str, sp);
 
176
                g_string_append_printf(stats_str, _("filetype: %s"), filetype_name);
 
177
                g_string_append(stats_str, sp);
 
178
                if (doc_list[idx].changed)
 
179
                {
 
180
                        g_string_append(stats_str, _("MOD"));   /* MOD = modified */
 
181
                        g_string_append(stats_str, sp);
 
182
                }
 
183
 
 
184
                utils_get_current_function(idx, &cur_tag);
 
185
                g_string_append_printf(stats_str, _("scope: %s"),
 
186
                        cur_tag);
 
187
 
 
188
                /* can be overridden by status messages */
 
189
                set_statusbar(stats_str->str, TRUE);
109
190
        }
110
 
        else
 
191
        else    /* no documents */
111
192
        {
112
 
                ui_set_statusbar("", TRUE); //can be overridden by status messages
 
193
                set_statusbar("", TRUE);        /* can be overridden by status messages */
113
194
        }
114
195
}
115
196
 
116
197
 
117
198
/* This sets the window title according to the current filename. */
118
 
void ui_set_window_title(gint index)
 
199
void ui_set_window_title(gint idx)
119
200
{
120
 
        gchar *title;
121
 
 
122
 
        if (index >= 0)
123
 
        {
124
 
                title = g_strdup_printf ("%s: %s %s",
125
 
                                PACKAGE,
126
 
                                (doc_list[index].file_name != NULL) ? g_filename_to_utf8(doc_list[index].file_name, -1, NULL, NULL, NULL) : _("untitled"),
127
 
                                doc_list[index].changed ? _("(Unsaved)") : "");
128
 
                gtk_window_set_title(GTK_WINDOW(app->window), title);
129
 
                g_free(title);
130
 
        }
131
 
        else
132
 
                gtk_window_set_title(GTK_WINDOW(app->window), PACKAGE);
 
201
        GString *str;
 
202
        GeanyProject *project = app->project;
 
203
 
 
204
        if (idx < 0)
 
205
                idx = document_get_cur_idx();
 
206
 
 
207
        str = g_string_new(NULL);
 
208
 
 
209
        if (idx >= 0)
 
210
        {
 
211
                g_string_append(str, doc_list[idx].changed ? "*" : "");
 
212
 
 
213
                if (doc_list[idx].file_name == NULL)
 
214
                        g_string_append(str, DOC_FILENAME(idx));
 
215
                else
 
216
                {
 
217
                        gchar *base_name = g_path_get_basename(DOC_FILENAME(idx));
 
218
                        gchar *dirname = g_path_get_dirname(DOC_FILENAME(idx));
 
219
 
 
220
                        g_string_append(str, base_name);
 
221
                        g_string_append(str, " - ");
 
222
                        g_string_append(str, dirname ? dirname : "");
 
223
                        g_free(base_name);
 
224
                        g_free(dirname);
 
225
                }
 
226
                g_string_append(str, " - ");
 
227
        }
 
228
        if (project)
 
229
        {
 
230
                g_string_append_c(str, '[');
 
231
                g_string_append(str, project->name);
 
232
                g_string_append(str, "] - ");
 
233
        }
 
234
        g_string_append(str, "Geany");
 
235
        gtk_window_set_title(GTK_WINDOW(app->window), str->str);
 
236
        g_string_free(str, TRUE);
133
237
}
134
238
 
135
239
 
136
240
void ui_set_editor_font(const gchar *font_name)
137
241
{
138
 
        gint i, size;
 
242
        guint i;
 
243
        gint size;
139
244
        gchar *fname;
140
245
        PangoFontDescription *font_desc;
141
246
 
142
247
        g_return_if_fail(font_name != NULL);
143
 
        // do nothing if font has not changed
144
 
        if (app->editor_font != NULL)
145
 
                if (strcmp(font_name, app->editor_font) == 0) return;
146
 
 
147
 
        g_free(app->editor_font);
148
 
        app->editor_font = g_strdup(font_name);
149
 
 
150
 
        font_desc = pango_font_description_from_string(app->editor_font);
 
248
        /* do nothing if font has not changed */
 
249
        if (prefs.editor_font != NULL)
 
250
                if (strcmp(font_name, prefs.editor_font) == 0) return;
 
251
 
 
252
        g_free(prefs.editor_font);
 
253
        prefs.editor_font = g_strdup(font_name);
 
254
 
 
255
        font_desc = pango_font_description_from_string(prefs.editor_font);
151
256
 
152
257
        fname = g_strdup_printf("!%s", pango_font_description_get_family(font_desc));
153
258
        size = pango_font_description_get_size(font_desc) / PANGO_SCALE;
154
259
 
155
260
        /* We copy the current style, and update the font in all open tabs. */
156
 
        for(i = 0; i < GEANY_MAX_OPEN_FILES; i++)
 
261
        for(i = 0; i < doc_array->len; i++)
157
262
        {
158
263
                if (doc_list[i].sci)
159
264
                {
162
267
        }
163
268
        pango_font_description_free(font_desc);
164
269
 
165
 
        msgwin_status_add(_("Font updated (%s)."), app->editor_font);
 
270
        ui_set_statusbar(TRUE, _("Font updated (%s)."), prefs.editor_font);
166
271
        g_free(fname);
167
272
}
168
273
 
169
274
 
170
 
void ui_set_fullscreen()
 
275
void ui_set_fullscreen(void)
171
276
{
172
 
        if (app->fullscreen)
 
277
        if (ui_prefs.fullscreen)
173
278
        {
174
279
                gtk_window_fullscreen(GTK_WINDOW(app->window));
175
280
        }
180
285
}
181
286
 
182
287
 
183
 
void ui_update_tag_list(gint idx, gboolean update)
184
 
{
185
 
        GList *tmp;
186
 
        const GList *tags;
187
 
 
188
 
        if (gtk_bin_get_child(GTK_BIN(app->tagbar)))
189
 
                gtk_container_remove(GTK_CONTAINER(app->tagbar), gtk_bin_get_child(GTK_BIN(app->tagbar)));
190
 
 
191
 
        if (app->default_tag_tree == NULL)
192
 
        {
193
 
                GtkTreeIter iter;
194
 
                GtkTreeStore *store = gtk_tree_store_new(1, G_TYPE_STRING);
195
 
                app->default_tag_tree = gtk_tree_view_new();
196
 
                treeviews_prepare_taglist(app->default_tag_tree, store);
197
 
                gtk_tree_store_append(store, &iter, NULL);
198
 
                gtk_tree_store_set(store, &iter, 0, _("No tags found"), -1);
199
 
                gtk_widget_show(app->default_tag_tree);
200
 
                g_object_ref((gpointer)app->default_tag_tree);  // to hold it after removing
201
 
        }
202
 
 
203
 
        // make all inactive, because there is no more tab left, or something strange occured
204
 
        if (idx == -1 || doc_list[idx].file_type == NULL || ! doc_list[idx].file_type->has_tags)
205
 
        {
206
 
                gtk_widget_set_sensitive(app->tagbar, FALSE);
207
 
                gtk_container_add(GTK_CONTAINER(app->tagbar), app->default_tag_tree);
208
 
                return;
209
 
        }
210
 
 
211
 
        if (update)
212
 
        {       // updating the tag list in the left tag window
213
 
                if (doc_list[idx].tag_tree == NULL)
214
 
                {
215
 
                        doc_list[idx].tag_store = gtk_tree_store_new(1, G_TYPE_STRING);
216
 
                        doc_list[idx].tag_tree = gtk_tree_view_new();
217
 
                        treeviews_prepare_taglist(doc_list[idx].tag_tree, doc_list[idx].tag_store);
218
 
                        gtk_widget_show(doc_list[idx].tag_tree);
219
 
                        g_object_ref((gpointer)doc_list[idx].tag_tree); // to hold it after removing
220
 
                }
221
 
 
222
 
                tags = utils_get_tag_list(idx, tm_tag_max_t);
223
 
                if (doc_list[idx].tm_file != NULL && tags != NULL)
224
 
                {
225
 
                        GtkTreeIter iter;
226
 
                        GtkTreeModel *model;
227
 
 
228
 
                        doc_list[idx].has_tags = TRUE;
229
 
                        gtk_tree_store_clear(doc_list[idx].tag_store);
230
 
                        // unref the store to speed up the filling(from TreeView Tutorial)
231
 
                        model = gtk_tree_view_get_model(GTK_TREE_VIEW(doc_list[idx].tag_tree));
232
 
                        g_object_ref(model); // Make sure the model stays with us after the tree view unrefs it
233
 
                        gtk_tree_view_set_model(GTK_TREE_VIEW(doc_list[idx].tag_tree), NULL); // Detach model from view
234
 
 
235
 
                        treeviews_init_tag_list(idx);
236
 
                        for (tmp = (GList*)tags; tmp; tmp = g_list_next(tmp))
237
 
                        {
238
 
                                switch (((GeanySymbol*)tmp->data)->type)
239
 
                                {
240
 
                                        case tm_tag_prototype_t:
241
 
                                        case tm_tag_function_t:
242
 
                                        {
243
 
                                                if (tv.tag_function.stamp == -1) break;
244
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_function));
245
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
246
 
                                                break;
247
 
                                        }
248
 
                                        case tm_tag_macro_t:
249
 
                                        case tm_tag_macro_with_arg_t:
250
 
                                        {
251
 
                                                if (tv.tag_macro.stamp == -1) break;
252
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_macro));
253
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
254
 
                                                break;
255
 
                                        }
256
 
                                        case tm_tag_class_t:
257
 
                                        {
258
 
                                                if (tv.tag_class.stamp == -1) break;
259
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_class));
260
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
261
 
                                                break;
262
 
                                        }
263
 
                                        case tm_tag_member_t:
264
 
                                        {
265
 
                                                if (tv.tag_member.stamp == -1) break;
266
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_member));
267
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
268
 
                                                break;
269
 
                                        }
270
 
                                        case tm_tag_typedef_t:
271
 
                                        case tm_tag_enum_t:
272
 
                                        case tm_tag_union_t:
273
 
                                        case tm_tag_struct_t:
274
 
                                        {
275
 
                                                if (tv.tag_struct.stamp == -1) break;
276
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_struct));
277
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
278
 
                                                break;
279
 
                                        }
280
 
                                        case tm_tag_variable_t:
281
 
                                        {
282
 
                                                if (tv.tag_variable.stamp == -1) break;
283
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_variable));
284
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
285
 
                                                break;
286
 
                                        }
287
 
                                        case tm_tag_namespace_t:
288
 
                                        {
289
 
                                                if (tv.tag_namespace.stamp == -1) break;
290
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_namespace));
291
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
292
 
                                                break;
293
 
                                        }
294
 
                                        default:
295
 
                                        {
296
 
                                                if (tv.tag_other.stamp == -1) break;
297
 
                                                gtk_tree_store_append(doc_list[idx].tag_store, &iter, &(tv.tag_other));
298
 
                                                gtk_tree_store_set(doc_list[idx].tag_store, &iter, 0, ((GeanySymbol*)tmp->data)->str, -1);
299
 
                                        }
300
 
                                }
301
 
                        }
302
 
                        gtk_tree_view_set_model(GTK_TREE_VIEW(doc_list[idx].tag_tree), model); // Re-attach model to view
303
 
                        g_object_unref(model);
304
 
                        gtk_tree_view_expand_all(GTK_TREE_VIEW(doc_list[idx].tag_tree));
305
 
 
306
 
                        gtk_widget_set_sensitive(app->tagbar, TRUE);
307
 
                        gtk_container_add(GTK_CONTAINER(app->tagbar), doc_list[idx].tag_tree);
308
 
                        /// TODO why I have to do this here?
309
 
                        g_object_ref((gpointer)doc_list[idx].tag_tree);
310
 
                }
311
 
                else
312
 
                {       // tags == NULL
313
 
                        gtk_widget_set_sensitive(app->tagbar, FALSE);
314
 
                        gtk_container_add(GTK_CONTAINER(app->tagbar), app->default_tag_tree);
315
 
                }
316
 
        }
317
 
        else
318
 
        {       // update == FALSE
319
 
                if (doc_list[idx].has_tags)
320
 
                {
321
 
                        gtk_widget_set_sensitive(app->tagbar, TRUE);
322
 
                        gtk_container_add(GTK_CONTAINER(app->tagbar), doc_list[idx].tag_tree);
323
 
                }
324
 
                else
325
 
                {
326
 
                        gtk_widget_set_sensitive(app->tagbar, FALSE);
327
 
                        gtk_container_add(GTK_CONTAINER(app->tagbar), app->default_tag_tree);
328
 
                }
329
 
        }
330
 
}
331
 
 
332
 
 
333
 
void ui_update_popup_reundo_items(gint index)
 
288
void ui_update_popup_reundo_items(gint idx)
334
289
{
335
290
        gboolean enable_undo;
336
291
        gboolean enable_redo;
337
292
 
338
 
        if (index == -1)
 
293
        if (idx == -1)
339
294
        {
340
295
                enable_undo = FALSE;
341
296
                enable_redo = FALSE;
342
297
        }
343
298
        else
344
299
        {
345
 
                enable_undo = document_can_undo(index);
346
 
                enable_redo = document_can_redo(index);
 
300
                enable_undo = document_can_undo(idx);
 
301
                enable_redo = document_can_redo(idx);
347
302
        }
348
303
 
349
 
        // index 0 is the popup menu, 1 is the menubar, 2 is the toolbar
350
 
        gtk_widget_set_sensitive(app->undo_items[0], enable_undo);
351
 
        gtk_widget_set_sensitive(app->undo_items[1], enable_undo);
352
 
        gtk_widget_set_sensitive(app->undo_items[2], enable_undo);
 
304
        /* index 0 is the popup menu, 1 is the menubar, 2 is the toolbar */
 
305
        gtk_widget_set_sensitive(ui_widgets.undo_items[0], enable_undo);
 
306
        gtk_widget_set_sensitive(ui_widgets.undo_items[1], enable_undo);
 
307
        gtk_widget_set_sensitive(ui_widgets.undo_items[2], enable_undo);
353
308
 
354
 
        gtk_widget_set_sensitive(app->redo_items[0], enable_redo);
355
 
        gtk_widget_set_sensitive(app->redo_items[1], enable_redo);
356
 
        gtk_widget_set_sensitive(app->redo_items[2], enable_redo);
 
309
        gtk_widget_set_sensitive(ui_widgets.redo_items[0], enable_redo);
 
310
        gtk_widget_set_sensitive(ui_widgets.redo_items[1], enable_redo);
 
311
        gtk_widget_set_sensitive(ui_widgets.redo_items[2], enable_redo);
357
312
}
358
313
 
359
314
 
360
 
void ui_update_popup_copy_items(gint index)
 
315
void ui_update_popup_copy_items(gint idx)
361
316
{
362
317
        gboolean enable;
363
318
        guint i;
364
319
 
365
 
        if (index == -1) enable = FALSE;
366
 
        else enable = sci_can_copy(doc_list[index].sci);
 
320
        if (idx == -1) enable = FALSE;
 
321
        else enable = sci_can_copy(doc_list[idx].sci);
367
322
 
368
 
        for(i = 0; i < (sizeof(app->popup_items)/sizeof(GtkWidget*)); i++)
369
 
                gtk_widget_set_sensitive(app->popup_items[i], enable);
 
323
        for (i = 0; i < G_N_ELEMENTS(ui_widgets.popup_copy_items); i++)
 
324
                gtk_widget_set_sensitive(ui_widgets.popup_copy_items[i], enable);
370
325
}
371
326
 
372
327
 
373
328
void ui_update_popup_goto_items(gboolean enable)
374
329
{
375
 
        gtk_widget_set_sensitive(app->popup_goto_items[0], enable);
376
 
        gtk_widget_set_sensitive(app->popup_goto_items[1], enable);
377
 
        gtk_widget_set_sensitive(app->popup_goto_items[2], enable);
 
330
        gtk_widget_set_sensitive(ui_widgets.popup_goto_items[0], enable);
 
331
        gtk_widget_set_sensitive(ui_widgets.popup_goto_items[1], enable);
 
332
        gtk_widget_set_sensitive(ui_widgets.popup_goto_items[2], enable);
378
333
}
379
334
 
380
335
 
397
352
                enable = gtk_text_buffer_get_selection_bounds(buffer, NULL, NULL);
398
353
        }
399
354
 
400
 
        for(i = 0; i < (sizeof(app->menu_copy_items)/sizeof(GtkWidget*)); i++)
401
 
                gtk_widget_set_sensitive(app->menu_copy_items[i], enable);
 
355
        for (i = 0; i < G_N_ELEMENTS(ui_widgets.menu_copy_items); i++)
 
356
                gtk_widget_set_sensitive(ui_widgets.menu_copy_items[i], enable);
402
357
}
403
358
 
404
359
 
412
367
        {
413
368
                enable = TRUE;
414
369
        }
415
 
        gtk_widget_set_sensitive(app->menu_insert_include_item[item], enable);
 
370
        gtk_widget_set_sensitive(ui_widgets.menu_insert_include_items[item], enable);
416
371
}
417
372
 
418
373
 
419
 
void ui_update_fold_items()
 
374
void ui_update_fold_items(void)
420
375
{
421
 
        gtk_widget_set_sensitive(lookup_widget(app->window, "menu_fold_all1"), app->pref_editor_folding);
422
 
        gtk_widget_set_sensitive(lookup_widget(app->window, "menu_unfold_all1"), app->pref_editor_folding);
 
376
        ui_widget_show_hide(lookup_widget(app->window, "menu_fold_all1"), editor_prefs.folding);
 
377
        ui_widget_show_hide(lookup_widget(app->window, "menu_unfold_all1"), editor_prefs.folding);
 
378
        ui_widget_show_hide(lookup_widget(app->window, "separator22"), editor_prefs.folding);
423
379
}
424
380
 
425
381
 
444
400
                tmp_popup = gtk_menu_item_new_with_label(includes[i]);
445
401
                gtk_container_add(GTK_CONTAINER(edit_menu), tmp_menu);
446
402
                gtk_container_add(GTK_CONTAINER(popup_menu), tmp_popup);
447
 
                g_signal_connect((gpointer) tmp_menu, "activate", G_CALLBACK(on_insert_include_activate),
448
 
                                                                                                                                        (gpointer) includes[i]);
449
 
                g_signal_connect((gpointer) tmp_popup, "activate", G_CALLBACK(on_insert_include_activate),
450
 
                                                                                                                                         (gpointer) includes[i]);
 
403
                g_signal_connect((gpointer) tmp_menu, "activate",
 
404
                                        G_CALLBACK(on_menu_insert_include_activate), (gpointer) includes[i]);
 
405
                g_signal_connect((gpointer) tmp_popup, "activate",
 
406
                                        G_CALLBACK(on_insert_include_activate), (gpointer) includes[i]);
451
407
                i++;
452
408
        }
453
409
        gtk_widget_show_all(edit_menu_item);
457
413
}
458
414
 
459
415
 
460
 
void ui_create_insert_menu_items()
 
416
void ui_create_insert_menu_items(void)
461
417
{
462
418
        GtkMenu *menu_edit = GTK_MENU(lookup_widget(app->window, "insert_include2_menu"));
463
419
        GtkMenu *menu_popup = GTK_MENU(lookup_widget(app->popup_menu, "insert_include1_menu"));
485
441
        blank = gtk_menu_item_new_with_label("#include \"...\"");
486
442
        gtk_container_add(GTK_CONTAINER(menu_edit), blank);
487
443
        gtk_widget_show(blank);
488
 
        g_signal_connect((gpointer) blank, "activate", G_CALLBACK(on_insert_include_activate),
 
444
        g_signal_connect((gpointer) blank, "activate", G_CALLBACK(on_menu_insert_include_activate),
489
445
                                                                                                                                        (gpointer) "blank");
490
446
        blank = gtk_separator_menu_item_new ();
491
447
        gtk_container_add(GTK_CONTAINER(menu_edit), blank);
512
468
{
513
469
        GtkWidget *item;
514
470
 
515
 
        item = gtk_menu_item_new_with_label(label);
 
471
        item = gtk_menu_item_new_with_mnemonic(label);
516
472
        gtk_container_add(GTK_CONTAINER(me), item);
517
473
        gtk_widget_show(item);
518
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_insert_date_activate), label);
 
474
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_menu_insert_date_activate), label);
519
475
 
520
 
        item = gtk_menu_item_new_with_label(label);
 
476
        item = gtk_menu_item_new_with_mnemonic(label);
521
477
        gtk_container_add(GTK_CONTAINER(mp), item);
522
478
        gtk_widget_show(item);
523
479
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_insert_date_activate), label);
524
480
}
525
481
 
526
482
 
527
 
void ui_create_insert_date_menu_items()
 
483
void ui_create_insert_date_menu_items(void)
528
484
{
529
485
        GtkMenu *menu_edit = GTK_MENU(lookup_widget(app->window, "insert_date1_menu"));
530
486
        GtkMenu *menu_popup = GTK_MENU(lookup_widget(app->popup_menu, "insert_date2_menu"));
531
487
        GtkWidget *item;
 
488
        gchar *str;
532
489
 
533
490
        insert_date_items(menu_edit, menu_popup, _("dd.mm.yyyy"));
534
491
        insert_date_items(menu_edit, menu_popup, _("mm.dd.yyyy"));
552
509
        gtk_container_add(GTK_CONTAINER(menu_popup), item);
553
510
        gtk_widget_show(item);
554
511
 
555
 
        item = gtk_menu_item_new_with_label(_("Use custom date format"));
 
512
        str = _("_Use Custom Date Format");
 
513
        item = gtk_menu_item_new_with_mnemonic(str);
556
514
        gtk_container_add(GTK_CONTAINER(menu_edit), item);
557
515
        gtk_widget_show(item);
558
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_insert_date_activate),
559
 
                                                                                                        _("Use custom date format"));
 
516
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_menu_insert_date_activate),
 
517
                str);
560
518
        g_object_set_data_full(G_OBJECT(app->window), "insert_date_custom1", gtk_widget_ref(item),
561
519
                                                                                                        (GDestroyNotify)gtk_widget_unref);
562
520
 
563
 
        item = gtk_menu_item_new_with_label(_("Use custom date format"));
 
521
        item = gtk_menu_item_new_with_mnemonic(str);
564
522
        gtk_container_add(GTK_CONTAINER(menu_popup), item);
565
523
        gtk_widget_show(item);
566
524
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_insert_date_activate),
567
 
                                                                                                        _("Use custom date format"));
 
525
                str);
568
526
        g_object_set_data_full(G_OBJECT(app->popup_menu), "insert_date_custom2", gtk_widget_ref(item),
569
527
                                                                                                        (GDestroyNotify)gtk_widget_unref);
570
528
 
571
 
        insert_date_items(menu_edit, menu_popup, _("Set custom date format"));
 
529
        insert_date_items(menu_edit, menu_popup, _("_Set Custom Date Format"));
572
530
}
573
531
 
574
532
 
577
535
        guint i;
578
536
        gboolean dirty_tabs = FALSE;
579
537
 
580
 
        gtk_widget_set_sensitive(app->save_buttons[0], enable);
581
 
        gtk_widget_set_sensitive(app->save_buttons[1], enable);
 
538
        gtk_widget_set_sensitive(ui_widgets.save_buttons[0], enable);
 
539
        gtk_widget_set_sensitive(ui_widgets.save_buttons[1], enable);
582
540
 
583
 
        // save all menu item and tool button
584
 
        for (i = 0; i < (guint) gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)); i++)
 
541
        /* save all menu item and tool button */
 
542
        for (i = 0; i < doc_array->len; i++)
585
543
        {
586
 
                // count the amount of files where changes were made and if there are some,
587
 
                // we need the save all button / item
588
 
                if (! dirty_tabs && doc_list[i].is_valid && doc_list[i].changed)
 
544
                /* check whether there are files where changes were made and if there are some,
 
545
                 * we need the save all button / item */
 
546
                if (doc_list[i].is_valid && doc_list[i].changed)
 
547
                {
589
548
                        dirty_tabs = TRUE;
 
549
                        break;
 
550
                }
590
551
        }
591
552
 
592
 
        gtk_widget_set_sensitive(app->save_buttons[2], (dirty_tabs > 0) ? TRUE : FALSE);
593
 
        gtk_widget_set_sensitive(app->save_buttons[3], (dirty_tabs > 0) ? TRUE : FALSE);
594
 
}
595
 
 
596
 
 
597
 
void ui_close_buttons_toggle()
 
553
        gtk_widget_set_sensitive(ui_widgets.save_buttons[2], dirty_tabs);
 
554
        gtk_widget_set_sensitive(ui_widgets.save_buttons[3], dirty_tabs);
 
555
}
 
556
 
 
557
 
 
558
static void init_document_widgets(void)
 
559
{
 
560
        /* Cache the document-sensitive widgets so we don't have to keep looking them up
 
561
         * when using ui_document_buttons_update(). */
 
562
        widgets.document_buttons[0] = lookup_widget(app->window, "menu_close1");
 
563
        widgets.document_buttons[1] = lookup_widget(app->window, "toolbutton15");
 
564
        widgets.document_buttons[2] = lookup_widget(app->window, "menu_change_font1");
 
565
        widgets.document_buttons[3] = lookup_widget(app->window, "entry1");
 
566
        widgets.document_buttons[4] = lookup_widget(app->window, "toolbutton18");
 
567
        widgets.document_buttons[5] = lookup_widget(app->window, "toolbutton20");
 
568
        widgets.document_buttons[6] = lookup_widget(app->window, "toolbutton21");
 
569
        widgets.document_buttons[7] = lookup_widget(app->window, "menu_close_all1");
 
570
        widgets.document_buttons[8] = lookup_widget(app->window, "menu_save_all1");
 
571
        widgets.document_buttons[9] = lookup_widget(app->window, "toolbutton22");
 
572
        widgets.document_buttons[10] = lookup_widget(app->window, "toolbutton13"); /* compile_button */
 
573
        widgets.document_buttons[11] = lookup_widget(app->window, "menu_save_as1");
 
574
        widgets.document_buttons[12] = lookup_widget(app->window, "toolbutton23");
 
575
        widgets.document_buttons[13] = lookup_widget(app->window, "menu_count_words1");
 
576
        widgets.document_buttons[14] = lookup_widget(app->window, "menu_build1");
 
577
        widgets.document_buttons[15] = lookup_widget(app->window, "add_comments1");
 
578
        widgets.document_buttons[16] = lookup_widget(app->window, "menu_paste1");
 
579
        widgets.document_buttons[17] = lookup_widget(app->window, "menu_undo2");
 
580
        widgets.document_buttons[18] = lookup_widget(app->window, "preferences2");
 
581
        widgets.document_buttons[19] = lookup_widget(app->window, "menu_reload1");
 
582
        widgets.document_buttons[20] = lookup_widget(app->window, "menu_document1");
 
583
        widgets.document_buttons[21] = lookup_widget(app->window, "menu_markers_margin1");
 
584
        widgets.document_buttons[22] = lookup_widget(app->window, "menu_linenumber_margin1");
 
585
        widgets.document_buttons[23] = lookup_widget(app->window, "menu_choose_color1");
 
586
        widgets.document_buttons[24] = lookup_widget(app->window, "menu_zoom_in1");
 
587
        widgets.document_buttons[25] = lookup_widget(app->window, "menu_zoom_out1");
 
588
        widgets.document_buttons[26] = lookup_widget(app->window, "normal_size1");
 
589
        widgets.document_buttons[27] = lookup_widget(app->window, "toolbutton24");
 
590
        widgets.document_buttons[28] = lookup_widget(app->window, "toolbutton25");
 
591
        widgets.document_buttons[29] = lookup_widget(app->window, "entry_goto_line");
 
592
        widgets.document_buttons[30] = lookup_widget(app->window, "treeview6");
 
593
        widgets.document_buttons[31] = lookup_widget(app->window, "print1");
 
594
        widgets.document_buttons[32] = lookup_widget(app->window, "menu_reload_as1");
 
595
        widgets.document_buttons[33] = lookup_widget(app->window, "menu_select_all1");
 
596
        widgets.document_buttons[34] = lookup_widget(app->window, "insert_date1");
 
597
        widgets.document_buttons[35] = lookup_widget(app->window, "menu_format1");
 
598
        widgets.document_buttons[36] = lookup_widget(app->window, "menu_open_selected_file1");
 
599
        widgets.document_buttons[37] = lookup_widget(app->window, "page_setup1");
 
600
        widgets.document_buttons[38] = lookup_widget(app->window, "find1");
 
601
        widgets.document_buttons[39] = lookup_widget(app->window, "find_next1");
 
602
        widgets.document_buttons[40] = lookup_widget(app->window, "find_previous1");
 
603
        widgets.document_buttons[41] = lookup_widget(app->window, "replace1");
 
604
        widgets.document_buttons[42] = lookup_widget(app->window, "find_nextsel1");
 
605
        widgets.document_buttons[43] = lookup_widget(app->window, "find_prevsel1");
 
606
        widgets.document_buttons[44] = lookup_widget(app->window, "go_to_line1");
 
607
}
 
608
 
 
609
 
 
610
void ui_document_buttons_update(void)
598
611
{
599
612
        guint i;
600
613
        gboolean enable = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) ? TRUE : FALSE;
601
614
 
602
 
        for(i = 0; i < (sizeof(app->sensitive_buttons)/sizeof(GtkWidget*)); i++)
603
 
                        gtk_widget_set_sensitive(app->sensitive_buttons[i], enable);
 
615
        for (i = 0; i < G_N_ELEMENTS(widgets.document_buttons); i++)
 
616
                gtk_widget_set_sensitive(widgets.document_buttons[i], enable);
 
617
 
 
618
#ifdef HAVE_PLUGINS
 
619
        plugins_update_document_sensitive(enable);
 
620
#endif
604
621
}
605
622
 
606
623
 
617
634
}
618
635
 
619
636
 
620
 
void ui_build_show_hide(gint idx)
621
 
{
622
 
        gboolean is_header = FALSE;
623
 
        gchar *ext = NULL;
624
 
        filetype *ft;
625
 
 
626
 
        if (idx == -1 || doc_list[idx].file_type == NULL)
627
 
        {
628
 
                gtk_widget_set_sensitive(lookup_widget(app->window, "menu_build1"), FALSE);
629
 
                gtk_menu_item_remove_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")));
630
 
                gtk_widget_set_sensitive(app->compile_button, FALSE);
631
 
                gtk_widget_set_sensitive(app->run_button, FALSE);
632
 
                return;
633
 
        }
634
 
        else
635
 
                gtk_widget_set_sensitive(lookup_widget(app->window, "menu_build1"), TRUE);
636
 
 
637
 
        ft = doc_list[idx].file_type;
638
 
 
639
 
#ifdef G_OS_WIN32
640
 
        // disable compile and link under Windows until it is implemented
641
 
        ft->menu_items->can_compile = FALSE;
642
 
        ft->menu_items->can_link = FALSE;
643
 
#endif
644
 
 
645
 
        if (doc_list[idx].file_name)
646
 
        {
647
 
                ext = strrchr(doc_list[idx].file_name, '.');
648
 
        }
649
 
 
650
 
        /// TODO: separate function for matching headers, perhaps based on file extensions
651
 
        if (! ext || utils_strcmp(ext + 1, "h") || utils_strcmp(ext + 1, "hpp") ||
652
 
                utils_strcmp(ext + 1, "hxx"))
653
 
        {
654
 
                is_header = TRUE;
655
 
        }
656
 
 
657
 
        gtk_menu_item_remove_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")));
658
 
 
659
 
        switch (ft->id)
660
 
        {
661
 
                case GEANY_FILETYPES_C: // intended fallthrough, C and C++ behave equal
662
 
                case GEANY_FILETYPES_CPP:
663
 
                {
664
 
                        if (ft->menu_items->menu == NULL)
665
 
                        {
666
 
                                ft->menu_items->menu = create_build_menu_gen(idx);
667
 
                                g_object_ref((gpointer)ft->menu_items->menu);   // to hold it after removing
668
 
 
669
 
                        }
670
 
                        gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
671
 
                                                                ft->menu_items->menu);
672
 
 
673
 
                        if (is_header)
674
 
                        {
675
 
                                gtk_widget_set_sensitive(app->compile_button, FALSE);
676
 
                                gtk_widget_set_sensitive(app->run_button, FALSE);
677
 
                                if (ft->menu_items->can_compile)
678
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_compile, FALSE);
679
 
                                if (ft->menu_items->can_link)
680
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_link, FALSE);
681
 
                                if (ft->menu_items->can_exec)
682
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_exec, FALSE);
683
 
                        }
684
 
                        else
685
 
                        {
686
 
                                gtk_widget_set_sensitive(app->compile_button, TRUE);
687
 
                                gtk_widget_set_sensitive(app->run_button, TRUE);
688
 
                                if (ft->menu_items->can_compile)
689
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_compile, TRUE);
690
 
                                if (ft->menu_items->can_link)
691
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_link, TRUE);
692
 
                                if (ft->menu_items->can_exec)
693
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_exec, TRUE);
694
 
                        }
695
 
 
696
 
                        break;
697
 
                }
698
 
                case GEANY_FILETYPES_LATEX:
699
 
                {
700
 
                        if (ft->menu_items->menu == NULL)
701
 
                        {
702
 
                                ft->menu_items->menu = create_build_menu_tex(idx);
703
 
                                g_object_ref((gpointer)ft->menu_items->menu);   // to hold it after removing
704
 
                        }
705
 
                        if (doc_list[idx].file_name == NULL)
706
 
                        {
707
 
                                gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
708
 
                                                                ft->menu_items->menu);
709
 
                                gtk_widget_set_sensitive(app->compile_button, FALSE);
710
 
                                gtk_widget_set_sensitive(app->run_button, FALSE);
711
 
                }
712
 
                        else
713
 
                        {
714
 
                                gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
715
 
                                                                ft->menu_items->menu);
716
 
                                gtk_widget_set_sensitive(app->compile_button, ft->menu_items->can_compile);
717
 
                                gtk_widget_set_sensitive(app->run_button, ft->menu_items->can_exec);
718
 
                        }
719
 
 
720
 
                        break;
721
 
                }
722
 
                default:
723
 
                {
724
 
                        if (ft->menu_items->menu == NULL)
725
 
                        {
726
 
                                ft->menu_items->menu = create_build_menu_gen(idx);
727
 
                                g_object_ref((gpointer)ft->menu_items->menu);   // to hold it after removing
728
 
                        }
729
 
                        if (doc_list[idx].file_name == NULL)
730
 
                        {
731
 
                                gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
732
 
                                                                ft->menu_items->menu);
733
 
                                gtk_widget_set_sensitive(app->compile_button, FALSE);
734
 
                                gtk_widget_set_sensitive(app->run_button, FALSE);
735
 
                                if (ft->menu_items->can_compile)
736
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_compile, FALSE);
737
 
                                if (ft->menu_items->can_link)
738
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_link, FALSE);
739
 
                                if (ft->menu_items->can_exec) gtk_widget_set_sensitive(ft->menu_items->item_exec, FALSE);
740
 
                        }
741
 
                        else
742
 
                        {
743
 
                                gtk_menu_item_set_submenu(GTK_MENU_ITEM(lookup_widget(app->window, "menu_build1")),
744
 
                                                                ft->menu_items->menu);
745
 
                                gtk_widget_set_sensitive(app->compile_button, ft->menu_items->can_compile);
746
 
                                gtk_widget_set_sensitive(app->run_button, ft->menu_items->can_exec);
747
 
                                if (ft->menu_items->can_compile)
748
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_compile, TRUE);
749
 
                                if (ft->menu_items->can_link)
750
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_link, TRUE);
751
 
                                if (ft->menu_items->can_exec)
752
 
                                        gtk_widget_set_sensitive(ft->menu_items->item_exec, TRUE);
753
 
                        }
754
 
                }
755
 
        }
756
 
}
757
 
 
758
 
 
759
 
#define GEANY_ADD_WIDGET_ACCEL(gkey, menuitem) \
760
 
        if (keys[(gkey)]->key != 0) \
761
 
                gtk_widget_add_accelerator(menuitem, "activate", accel_group, \
762
 
                        keys[(gkey)]->key, keys[(gkey)]->mods, GTK_ACCEL_VISIBLE)
763
 
 
764
 
static GtkWidget *create_build_menu_gen(gint idx)
765
 
{
766
 
        GtkWidget *menu, *item = NULL, *image, *separator;
767
 
        GtkAccelGroup *accel_group = gtk_accel_group_new();
768
 
        GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
769
 
        filetype *ft = doc_list[idx].file_type;
770
 
 
771
 
        menu = gtk_menu_new();
772
 
 
773
 
#ifndef G_OS_WIN32
774
 
        if (ft->menu_items->can_compile)
775
 
        {
776
 
                // compile the code
777
 
                item = gtk_image_menu_item_new_with_mnemonic(_("_Compile"));
778
 
                gtk_widget_show(item);
779
 
                gtk_container_add(GTK_CONTAINER(menu), item);
780
 
                gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file"), NULL);
781
 
                GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_COMPILE, item);
782
 
                image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
783
 
                gtk_widget_show(image);
784
 
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
785
 
                g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_compile_activate), NULL);
786
 
                ft->menu_items->item_compile = item;
787
 
        }
788
 
 
789
 
        if (ft->menu_items->can_link)
790
 
        {       // build the code
791
 
                item = gtk_image_menu_item_new_with_mnemonic(_("_Build"));
792
 
                gtk_widget_show(item);
793
 
                gtk_container_add(GTK_CONTAINER(menu), item);
794
 
                gtk_tooltips_set_tip(tooltips, item,
795
 
                                        _("Builds the current file (generate an executable file)"), NULL);
796
 
                GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_LINK, item);
797
 
                g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_build_activate), NULL);
798
 
                ft->menu_items->item_link = item;
799
 
        }
800
 
 
801
 
        if (item != NULL)
802
 
        {
803
 
                item = gtk_separator_menu_item_new();
804
 
                gtk_widget_show(item);
805
 
                gtk_container_add(GTK_CONTAINER(menu), item);
806
 
        }
807
 
 
808
 
        // build the code with make all
809
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_Make all"));
810
 
        gtk_widget_show(item);
811
 
        gtk_container_add(GTK_CONTAINER(menu), item);
812
 
        gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
813
 
                                                                                   "make tool and the default target"), NULL);
814
 
        GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKE, item);
815
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate), GINT_TO_POINTER(0));
816
 
 
817
 
        // build the code with make
818
 
        item = gtk_image_menu_item_new_with_mnemonic(_("Make custom _target"));
819
 
        gtk_widget_show(item);
820
 
        GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOWNTARGET, item);
821
 
        gtk_container_add(GTK_CONTAINER(menu), item);
822
 
        gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
823
 
                                                                                   "make tool and the specified target"), NULL);
824
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate), GINT_TO_POINTER(1));
825
 
 
826
 
        // build the code with make object
827
 
        item = gtk_image_menu_item_new_with_mnemonic(_("Make _object"));
828
 
        gtk_widget_show(item);
829
 
        GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOBJECT, item);
830
 
        gtk_container_add(GTK_CONTAINER(menu), item);
831
 
        gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file using the "
832
 
                                                                                   "make tool"), NULL);
833
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate), GINT_TO_POINTER(2));
834
 
#endif
835
 
 
836
 
        if (ft->menu_items->can_exec)
837
 
        {       // execute the code
838
 
                item = gtk_separator_menu_item_new();
839
 
                gtk_widget_show(item);
840
 
                gtk_container_add(GTK_CONTAINER(menu), item);
841
 
 
842
 
                item = gtk_image_menu_item_new_from_stock("gtk-execute", accel_group);
843
 
                gtk_widget_show(item);
844
 
                gtk_container_add(GTK_CONTAINER(menu), item);
845
 
                gtk_tooltips_set_tip(tooltips, item, _("Run or view the current file"), NULL);
846
 
                GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_RUN, item);
847
 
                g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_execute_activate), NULL);
848
 
                ft->menu_items->item_exec = item;
849
 
        }
850
 
 
851
 
        // arguments
852
 
        if (ft->menu_items->can_compile || ft->menu_items->can_link || ft->menu_items->can_exec)
853
 
        {
854
 
                // separator
855
 
                separator = gtk_separator_menu_item_new();
856
 
                gtk_widget_show(separator);
857
 
                gtk_container_add(GTK_CONTAINER(menu), separator);
858
 
                gtk_widget_set_sensitive(separator, FALSE);
859
 
 
860
 
                item = gtk_image_menu_item_new_with_mnemonic(_("_Set Includes and Arguments"));
861
 
                gtk_widget_show(item);
862
 
                GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_OPTIONS, item);
863
 
                gtk_container_add(GTK_CONTAINER(menu), item);
864
 
                gtk_tooltips_set_tip(tooltips, item,
865
 
                                        _("Sets the includes and library paths for the compiler and "
866
 
                                          "the program arguments for execution"), NULL);
867
 
                image = gtk_image_new_from_stock("gtk-preferences", GTK_ICON_SIZE_MENU);
868
 
                gtk_widget_show(image);
869
 
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
870
 
                g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_arguments_activate), NULL);
871
 
        }
872
 
 
873
 
        return menu;
874
 
}
875
 
 
876
 
 
877
 
static GtkWidget *create_build_menu_tex(gint idx)
878
 
{
879
 
        GtkWidget *menu, *item, *image, *separator;
880
 
        GtkAccelGroup *accel_group = gtk_accel_group_new();
881
 
        GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
882
 
 
883
 
        menu = gtk_menu_new();
884
 
 
885
 
#ifndef G_OS_WIN32
886
 
        // DVI
887
 
        item = gtk_image_menu_item_new_with_mnemonic(_("LaTeX -> DVI"));
888
 
        gtk_widget_show(item);
889
 
        gtk_container_add(GTK_CONTAINER(menu), item);
890
 
        gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file into a DVI file"), NULL);
891
 
        if (keys[GEANY_KEYS_BUILD_COMPILE]->key)
892
 
                gtk_widget_add_accelerator(item, "activate", accel_group, keys[GEANY_KEYS_BUILD_COMPILE]->key,
893
 
                        keys[GEANY_KEYS_BUILD_COMPILE]->mods, GTK_ACCEL_VISIBLE);
894
 
        image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
895
 
        gtk_widget_show(image);
896
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
897
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(0));
898
 
 
899
 
        // PDF
900
 
        item = gtk_image_menu_item_new_with_mnemonic(_("LaTeX -> PDF"));
901
 
        gtk_widget_show(item);
902
 
        gtk_container_add(GTK_CONTAINER(menu), item);
903
 
        gtk_tooltips_set_tip(tooltips, item, _("Compiles the current file into a PDF file"), NULL);
904
 
        if (keys[GEANY_KEYS_BUILD_LINK]->key)
905
 
                gtk_widget_add_accelerator(item, "activate", accel_group, keys[GEANY_KEYS_BUILD_LINK]->key,
906
 
                        keys[GEANY_KEYS_BUILD_LINK]->mods, GTK_ACCEL_VISIBLE);
907
 
        image = gtk_image_new_from_stock("gtk-convert", GTK_ICON_SIZE_MENU);
908
 
        gtk_widget_show(image);
909
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
910
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(1));
911
 
 
912
 
        if (item != NULL)
913
 
        {
914
 
                item = gtk_separator_menu_item_new();
915
 
                gtk_widget_show(item);
916
 
                gtk_container_add(GTK_CONTAINER(menu), item);
917
 
        }
918
 
 
919
 
        // build the code with make all
920
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_Make all"));
921
 
        gtk_widget_show(item);
922
 
        gtk_container_add(GTK_CONTAINER(menu), item);
923
 
        gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
924
 
                                                                                   "make tool and the default target"), NULL);
925
 
        GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKE, item);
926
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate), GINT_TO_POINTER(0));
927
 
 
928
 
        // build the code with make
929
 
        item = gtk_image_menu_item_new_with_mnemonic(_("Make custom _target"));
930
 
        gtk_widget_show(item);
931
 
        GEANY_ADD_WIDGET_ACCEL(GEANY_KEYS_BUILD_MAKEOWNTARGET, item);
932
 
        gtk_container_add(GTK_CONTAINER(menu), item);
933
 
        gtk_tooltips_set_tip(tooltips, item, _("Builds the current file with the "
934
 
                                                                                   "make tool and the specified target"), NULL);
935
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_make_activate), GINT_TO_POINTER(1));
936
 
 
937
 
        if (item != NULL)
938
 
        {
939
 
                item = gtk_separator_menu_item_new();
940
 
                gtk_widget_show(item);
941
 
                gtk_container_add(GTK_CONTAINER(menu), item);
942
 
        }
943
 
#endif
944
 
 
945
 
        // DVI view
946
 
        item = gtk_image_menu_item_new_with_mnemonic(_("View DVI file"));
947
 
        gtk_widget_show(item);
948
 
        gtk_container_add(GTK_CONTAINER(menu), item);
949
 
        if (keys[GEANY_KEYS_BUILD_RUN]->key)
950
 
                gtk_widget_add_accelerator(item, "activate", accel_group, keys[GEANY_KEYS_BUILD_RUN]->key,
951
 
                        keys[GEANY_KEYS_BUILD_RUN]->mods, GTK_ACCEL_VISIBLE);
952
 
        gtk_tooltips_set_tip(tooltips, item, _("Compiles and view the current file"), NULL);
953
 
        image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU);
954
 
        gtk_widget_show(image);
955
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
956
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(2));
957
 
 
958
 
        // PDF view
959
 
        item = gtk_image_menu_item_new_with_mnemonic(_("View PDF file"));
960
 
        gtk_widget_show(item);
961
 
        gtk_container_add(GTK_CONTAINER(menu), item);
962
 
        if (keys[GEANY_KEYS_BUILD_RUN2]->key)
963
 
                gtk_widget_add_accelerator(item, "activate", accel_group, keys[GEANY_KEYS_BUILD_RUN2]->key,
964
 
                        keys[GEANY_KEYS_BUILD_RUN2]->mods, GTK_ACCEL_VISIBLE);
965
 
        gtk_tooltips_set_tip(tooltips, item, _("Compiles and view the current file"), NULL);
966
 
        image = gtk_image_new_from_stock("gtk-find", GTK_ICON_SIZE_MENU);
967
 
        gtk_widget_show(image);
968
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
969
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_tex_activate), GINT_TO_POINTER(3));
970
 
 
971
 
        // separator
972
 
        separator = gtk_separator_menu_item_new();
973
 
        gtk_widget_show(separator);
974
 
        gtk_container_add(GTK_CONTAINER(menu), separator);
975
 
        gtk_widget_set_sensitive(separator, FALSE);
976
 
 
977
 
        // arguments
978
 
        item = gtk_image_menu_item_new_with_mnemonic(_("Set Arguments"));
979
 
        gtk_widget_show(item);
980
 
        if (keys[GEANY_KEYS_BUILD_OPTIONS]->key)
981
 
                gtk_widget_add_accelerator(item, "activate", accel_group, keys[GEANY_KEYS_BUILD_OPTIONS]->key,
982
 
                        keys[GEANY_KEYS_BUILD_OPTIONS]->mods, GTK_ACCEL_VISIBLE);
983
 
        gtk_container_add(GTK_CONTAINER(menu), item);
984
 
        gtk_tooltips_set_tip(tooltips, item,
985
 
                                _("Sets the program paths and arguments"), NULL);
986
 
        image = gtk_image_new_from_stock("gtk-preferences", GTK_ICON_SIZE_MENU);
987
 
        gtk_widget_show(image);
988
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
989
 
        g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_build_tex_arguments_activate), NULL);
990
 
 
991
 
        gtk_window_add_accel_group(GTK_WINDOW(app->window), accel_group);
992
 
 
993
 
        return menu;
994
 
}
995
 
 
996
 
 
997
 
void ui_treeviews_show_hide(gboolean force)
 
637
void ui_sidebar_show_hide(void)
998
638
{
999
639
        GtkWidget *widget;
1000
640
 
1001
 
/*      geany_debug("\nSidebar: %s\nSymbol: %s\nFiles: %s", ui_btoa(app->sidebar_visible),
1002
 
                                        ui_btoa(app->sidebar_symbol_visible), ui_btoa(app->sidebar_openfiles_visible));
1003
 
*/
1004
 
 
1005
 
        if (! force && ! app->sidebar_visible && (app->sidebar_openfiles_visible ||
1006
 
                app->sidebar_symbol_visible))
1007
 
        {
1008
 
                app->sidebar_visible = TRUE;
1009
 
        }
1010
 
        else if (! app->sidebar_openfiles_visible && ! app->sidebar_symbol_visible)
1011
 
        {
1012
 
                app->sidebar_visible = FALSE;
 
641
        /* check that there are no other notebook pages before hiding the sidebar completely
 
642
         * other pages could be e.g. the file browser plugin */
 
643
        if (! prefs.sidebar_openfiles_visible && ! prefs.sidebar_symbol_visible &&
 
644
                gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->treeview_notebook)) <= 2)
 
645
        {
 
646
                ui_prefs.sidebar_visible = FALSE;
1013
647
        }
1014
648
 
1015
649
        widget = lookup_widget(app->window, "menu_show_sidebar1");
1016
 
        if (app->sidebar_visible != gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
 
650
        if (ui_prefs.sidebar_visible != gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1017
651
        {
1018
652
                app->ignore_callback = TRUE;
1019
 
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), app->sidebar_visible);
 
653
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ui_prefs.sidebar_visible);
1020
654
                app->ignore_callback = FALSE;
1021
655
        }
1022
656
 
1023
 
        ui_widget_show_hide(app->treeview_notebook, app->sidebar_visible);
 
657
        ui_widget_show_hide(app->treeview_notebook, ui_prefs.sidebar_visible);
1024
658
 
1025
659
        ui_widget_show_hide(gtk_notebook_get_nth_page(
1026
 
                                        GTK_NOTEBOOK(app->treeview_notebook), 0), app->sidebar_symbol_visible);
 
660
                                        GTK_NOTEBOOK(app->treeview_notebook), 0), prefs.sidebar_symbol_visible);
1027
661
        ui_widget_show_hide(gtk_notebook_get_nth_page(
1028
 
                                        GTK_NOTEBOOK(app->treeview_notebook), 1), app->sidebar_openfiles_visible);
 
662
                                        GTK_NOTEBOOK(app->treeview_notebook), 1), prefs.sidebar_openfiles_visible);
1029
663
}
1030
664
 
1031
665
 
1032
666
void ui_document_show_hide(gint idx)
1033
667
{
1034
668
        gchar *widget_name;
1035
 
 
1036
 
        if (idx == -1 || ! doc_list[idx].is_valid) return;
 
669
        GtkWidget *item;
 
670
 
 
671
        if (idx == -1)
 
672
                idx = document_get_cur_idx();
 
673
 
 
674
        if (! DOC_IDX_VALID(idx))
 
675
                return;
 
676
 
1037
677
        app->ignore_callback = TRUE;
1038
678
 
1039
679
        gtk_check_menu_item_set_active(
1040
680
                        GTK_CHECK_MENU_ITEM(lookup_widget(app->window, "menu_line_breaking1")),
1041
 
                        doc_list[idx].line_breaking);
1042
 
        gtk_check_menu_item_set_active(
1043
 
                        GTK_CHECK_MENU_ITEM(lookup_widget(app->window, "menu_use_auto_indention1")),
1044
 
                        doc_list[idx].use_auto_indention);
 
681
                        doc_list[idx].line_wrapping);
 
682
 
 
683
        item = lookup_widget(app->window, "menu_use_auto_indentation1");
 
684
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
 
685
                doc_list[idx].auto_indent);
 
686
        gtk_widget_set_sensitive(item, editor_prefs.indent_mode != INDENT_NONE);
 
687
 
 
688
        item = lookup_widget(app->window,
 
689
                doc_list[idx].use_tabs ? "tabs1" : "spaces1");
 
690
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
 
691
 
1045
692
        gtk_check_menu_item_set_active(
1046
693
                        GTK_CHECK_MENU_ITEM(lookup_widget(app->window, "set_file_readonly1")),
1047
694
                        doc_list[idx].readonly);
1048
 
        gtk_check_menu_item_set_active(
1049
 
                        GTK_CHECK_MENU_ITEM(lookup_widget(app->window, "menu_write_unicode_bom1")),
1050
 
                        doc_list[idx].has_bom);
 
695
 
 
696
        item = lookup_widget(app->window, "menu_write_unicode_bom1");
 
697
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item),
 
698
                doc_list[idx].has_bom);
 
699
        gtk_widget_set_sensitive(item, encodings_is_unicode_charset(doc_list[idx].encoding));
1051
700
 
1052
701
        switch (sci_get_eol_mode(doc_list[idx].sci))
1053
702
        {
1055
704
                case SC_EOL_LF: widget_name = "lf"; break;
1056
705
                default: widget_name = "crlf"; break;
1057
706
        }
1058
 
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(app->window, widget_name)),
1059
 
                                                                                                                                                                        TRUE);
1060
 
 
1061
 
        gtk_widget_set_sensitive(lookup_widget(app->window, "menu_write_unicode_bom1"),
1062
 
                        utils_is_unicode_charset(doc_list[idx].encoding));
 
707
        gtk_check_menu_item_set_active(
 
708
                GTK_CHECK_MENU_ITEM(lookup_widget(app->window, widget_name)), TRUE);
1063
709
 
1064
710
        encodings_select_radio_item(doc_list[idx].encoding);
1065
711
        filetypes_select_radio_item(doc_list[idx].file_type);
1066
712
 
1067
713
        app->ignore_callback = FALSE;
1068
 
 
1069
714
}
1070
715
 
1071
716
 
1075
720
        GtkWidget *widget = NULL;
1076
721
        GtkWidget *oldwidget = NULL;
1077
722
 
1078
 
        // destroy old widget
 
723
        /* destroy old widget */
1079
724
        widget = lookup_widget(app->window, "toolbutton22");
1080
725
        oldwidget = gtk_tool_button_get_icon_widget(GTK_TOOL_BUTTON(widget));
1081
726
        if (oldwidget && GTK_IS_WIDGET(oldwidget)) gtk_widget_destroy(oldwidget);
1082
 
        // create new widget
 
727
        /* create new widget */
1083
728
        button_image = ui_new_image_from_inline(GEANY_IMAGE_SAVE_ALL, FALSE);
1084
729
        gtk_widget_show(button_image);
1085
730
        gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(widget), button_image);
1088
733
}
1089
734
 
1090
735
 
1091
 
void ui_update_toolbar_items()
 
736
void ui_update_toolbar_items(void)
1092
737
{
1093
 
        // show toolbar
 
738
        /* show toolbar */
1094
739
        GtkWidget *widget = lookup_widget(app->window, "menu_show_toolbar1");
1095
 
        if (app->toolbar_visible && ! gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1096
 
        {
1097
 
                app->toolbar_visible = ! app->toolbar_visible;  // will be changed by the toggled callback
 
740
        if (prefs.toolbar_visible && ! gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
 
741
        {       /* will be changed by the toggled callback */
 
742
                prefs.toolbar_visible = ! prefs.toolbar_visible;
1098
743
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
1099
744
        }
1100
 
        else if (! app->toolbar_visible && gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
1101
 
        {
1102
 
                app->toolbar_visible = ! app->toolbar_visible;  // will be changed by the toggled callback
 
745
        else if (! prefs.toolbar_visible && gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
 
746
        {       /* will be changed by the toggled callback */
 
747
                prefs.toolbar_visible = ! prefs.toolbar_visible;
1103
748
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), FALSE);
1104
749
        }
1105
750
 
1106
 
        // fileops
1107
 
        ui_widget_show_hide(lookup_widget(app->window, "menutoolbutton1"), app->pref_toolbar_show_fileops);
1108
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton9"), app->pref_toolbar_show_fileops);
1109
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton10"), app->pref_toolbar_show_fileops);
1110
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton22"), app->pref_toolbar_show_fileops);
1111
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton23"), app->pref_toolbar_show_fileops);
1112
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton15"), app->pref_toolbar_show_fileops);
1113
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem7"), app->pref_toolbar_show_fileops);
1114
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem2"), app->pref_toolbar_show_fileops);
1115
 
        // search
1116
 
        ui_widget_show_hide(lookup_widget(app->window, "entry1"), app->pref_toolbar_show_search);
1117
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton18"), app->pref_toolbar_show_search);
1118
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem5"), app->pref_toolbar_show_search);
1119
 
        // goto line
1120
 
        ui_widget_show_hide(lookup_widget(app->window, "entry_goto_line"), app->pref_toolbar_show_goto);
1121
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton25"), app->pref_toolbar_show_goto);
1122
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem8"), app->pref_toolbar_show_goto);
1123
 
        // compile
1124
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton13"), app->pref_toolbar_show_compile);
1125
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton26"), app->pref_toolbar_show_compile);
1126
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem6"), app->pref_toolbar_show_compile);
1127
 
        // colour
1128
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton24"), app->pref_toolbar_show_colour);
1129
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem3"), app->pref_toolbar_show_colour);
1130
 
        // zoom
1131
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton20"), app->pref_toolbar_show_zoom);
1132
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton21"), app->pref_toolbar_show_zoom);
1133
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem4"), app->pref_toolbar_show_zoom);
1134
 
        // undo
1135
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_undo"), app->pref_toolbar_show_undo);
1136
 
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_redo"), app->pref_toolbar_show_undo);
1137
 
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem9"), app->pref_toolbar_show_undo);
 
751
        /* fileops */
 
752
        ui_widget_show_hide(lookup_widget(app->window, "menutoolbutton1"), prefs.toolbar_show_fileops);
 
753
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton9"), prefs.toolbar_show_fileops);
 
754
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton10"), prefs.toolbar_show_fileops);
 
755
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton22"), prefs.toolbar_show_fileops);
 
756
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton23"), prefs.toolbar_show_fileops);
 
757
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton15"), prefs.toolbar_show_fileops);
 
758
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem7"), prefs.toolbar_show_fileops);
 
759
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem2"), prefs.toolbar_show_fileops);
 
760
        /* search */
 
761
        ui_widget_show_hide(lookup_widget(app->window, "entry1"), prefs.toolbar_show_search);
 
762
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton18"), prefs.toolbar_show_search);
 
763
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem5"), prefs.toolbar_show_search);
 
764
        /* goto line */
 
765
        ui_widget_show_hide(lookup_widget(app->window, "entry_goto_line"), prefs.toolbar_show_goto);
 
766
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton25"), prefs.toolbar_show_goto);
 
767
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem8"), prefs.toolbar_show_goto);
 
768
        /* compile */
 
769
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton13"), prefs.toolbar_show_compile);
 
770
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton26"), prefs.toolbar_show_compile);
 
771
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem6"), prefs.toolbar_show_compile);
 
772
        /* colour */
 
773
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton24"), prefs.toolbar_show_colour);
 
774
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem3"), prefs.toolbar_show_colour);
 
775
        /* zoom */
 
776
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton20"), prefs.toolbar_show_zoom);
 
777
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton21"), prefs.toolbar_show_zoom);
 
778
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem4"), prefs.toolbar_show_zoom);
 
779
        /* indent */
 
780
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_indent_dec"), prefs.toolbar_show_indent);
 
781
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_indent_inc"), prefs.toolbar_show_indent);
 
782
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem11"), prefs.toolbar_show_indent);
 
783
        /* undo */
 
784
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_undo"), prefs.toolbar_show_undo);
 
785
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_redo"), prefs.toolbar_show_undo);
 
786
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem9"), prefs.toolbar_show_undo);
 
787
        /* navigation */
 
788
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_back"), prefs.toolbar_show_navigation);
 
789
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton_forward"), prefs.toolbar_show_navigation);
 
790
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem10"), prefs.toolbar_show_navigation);
 
791
        /* quit */
 
792
        ui_widget_show_hide(lookup_widget(app->window, "toolbutton19"), prefs.toolbar_show_quit);
 
793
        ui_widget_show_hide(lookup_widget(app->window, "separatortoolitem8"), prefs.toolbar_show_quit);
1138
794
}
1139
795
 
1140
796
 
 
797
/* Note: remember to unref the pixbuf once an image or window has added a reference. */
1141
798
GdkPixbuf *ui_new_pixbuf_from_inline(gint img, gboolean small_img)
1142
799
{
1143
800
        switch(img)
1146
803
                case GEANY_IMAGE_LOGO: return gdk_pixbuf_new_from_inline(-1, aladin_inline, FALSE, NULL); break;
1147
804
                case GEANY_IMAGE_SAVE_ALL:
1148
805
                {
1149
 
                        if ((app->toolbar_icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR) || small_img)
 
806
                        if ((prefs.toolbar_icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR) || small_img)
1150
807
                        {
1151
808
                                return gdk_pixbuf_scale_simple(gdk_pixbuf_new_from_inline(-1, save_all_inline, FALSE, NULL),
1152
809
                                             16, 16, GDK_INTERP_HYPER);
1159
816
                }
1160
817
                case GEANY_IMAGE_NEW_ARROW:
1161
818
                {
1162
 
                        if ((app->toolbar_icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR) || small_img)
 
819
                        if ((prefs.toolbar_icon_size == GTK_ICON_SIZE_SMALL_TOOLBAR) || small_img)
1163
820
                        {
1164
821
                                return gdk_pixbuf_scale_simple(gdk_pixbuf_new_from_inline(-1, newfile_inline, FALSE, NULL),
1165
822
                                             16, 16, GDK_INTERP_HYPER);
1173
830
                default: return NULL;
1174
831
        }
1175
832
 
1176
 
        //return gtk_image_new_from_pixbuf(pixbuf);
 
833
        /*return gtk_image_new_from_pixbuf(pixbuf);*/
1177
834
}
1178
835
 
1179
836
 
1180
837
GtkWidget *ui_new_image_from_inline(gint img, gboolean small_img)
1181
838
{
1182
 
        return gtk_image_new_from_pixbuf(ui_new_pixbuf_from_inline(img, small_img));
 
839
        GtkWidget *wid;
 
840
        GdkPixbuf *pb;
 
841
 
 
842
        pb = ui_new_pixbuf_from_inline(img, small_img);
 
843
        wid = gtk_image_new_from_pixbuf(pb);
 
844
        g_object_unref(pb);     /* the image doesn't adopt our reference, so remove our ref. */
 
845
        return wid;
1183
846
}
1184
847
 
1185
848
 
1186
 
void ui_create_recent_menu()
 
849
void ui_create_recent_menu(void)
1187
850
{
1188
 
        GtkWidget *recent_menu = lookup_widget(app->window, "recent_files1_menu");
1189
851
        GtkWidget *tmp;
1190
852
        guint i;
1191
853
        gchar *filename;
1192
854
 
1193
 
        if (g_queue_get_length(app->recent_queue) == 0)
 
855
        if (g_queue_get_length(ui_prefs.recent_queue) > 0)
1194
856
        {
1195
 
                gtk_widget_set_sensitive(lookup_widget(app->window, "recent_files1"), FALSE);
1196
 
                return;
 
857
                gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(
 
858
                                lookup_widget(app->window, "toolbutton9")), ui_widgets.recent_files_toolbar);
1197
859
        }
1198
860
 
1199
 
        for (i = 0; i < MIN(app->mru_length, g_queue_get_length(app->recent_queue));
1200
 
                i++)
 
861
        for (i = 0; i < MIN(prefs.mru_length, g_queue_get_length(ui_prefs.recent_queue)); i++)
1201
862
        {
1202
 
                filename = g_queue_peek_nth(app->recent_queue, i);
1203
 
                tmp = gtk_menu_item_new_with_label(filename);
1204
 
                gtk_widget_show(tmp);
1205
 
                gtk_menu_shell_append(GTK_MENU_SHELL(recent_menu), tmp);
 
863
                filename = g_queue_peek_nth(ui_prefs.recent_queue, i);
 
864
                /* create menu item for the recent files menu in the menu bar */
 
865
                tmp = gtk_menu_item_new_with_label(filename);
 
866
                gtk_widget_show(tmp);
 
867
                gtk_menu_shell_append(GTK_MENU_SHELL(ui_widgets.recent_files_menubar), tmp);
 
868
                g_signal_connect((gpointer) tmp, "activate",
 
869
                                        G_CALLBACK(recent_file_activate_cb), NULL);
 
870
                /* create menu item for the recent files menu in the toolbar bar */
 
871
                tmp = gtk_menu_item_new_with_label(filename);
 
872
                gtk_widget_show(tmp);
 
873
                gtk_menu_shell_append(GTK_MENU_SHELL(ui_widgets.recent_files_toolbar), tmp);
1206
874
                g_signal_connect((gpointer) tmp, "activate",
1207
875
                                        G_CALLBACK(recent_file_activate_cb), NULL);
1208
876
        }
1216
884
        gchar *utf8_filename = menu_item_get_text(menuitem);
1217
885
        gchar *locale_filename = utils_get_locale_from_utf8(utf8_filename);
1218
886
 
1219
 
        if (document_open_file(-1, locale_filename, 0, FALSE, NULL, NULL) > -1)
 
887
        if (document_open_file(locale_filename, FALSE, NULL, NULL) > -1)
1220
888
                recent_file_loaded(utf8_filename);
1221
889
 
1222
890
        g_free(locale_filename);
1226
894
 
1227
895
void ui_add_recent_file(const gchar *utf8_filename)
1228
896
{
1229
 
        if (g_queue_find_custom(app->recent_queue, utf8_filename, (GCompareFunc) strcmp) == NULL)
 
897
        if (g_queue_find_custom(ui_prefs.recent_queue, utf8_filename, (GCompareFunc) strcmp) == NULL)
1230
898
        {
1231
 
                g_queue_push_head(app->recent_queue, g_strdup(utf8_filename));
1232
 
                if (g_queue_get_length(app->recent_queue) > app->mru_length)
1233
 
                {
1234
 
                        g_free(g_queue_pop_tail(app->recent_queue));
 
899
#if GTK_CHECK_VERSION(2, 10, 0)
 
900
                GtkRecentManager *manager = gtk_recent_manager_get_default();
 
901
                gchar *uri = g_filename_to_uri(utf8_filename, NULL, NULL);
 
902
                if (uri != NULL)
 
903
                {
 
904
                        gtk_recent_manager_add_item(manager, uri);
 
905
                        g_free(uri);
 
906
                }
 
907
#endif
 
908
                g_queue_push_head(ui_prefs.recent_queue, g_strdup(utf8_filename));
 
909
                if (g_queue_get_length(ui_prefs.recent_queue) > prefs.mru_length)
 
910
                {
 
911
                        g_free(g_queue_pop_tail(ui_prefs.recent_queue));
1235
912
                }
1236
913
                update_recent_menu();
1237
914
        }
1238
 
        else recent_file_loaded(utf8_filename); // filename already in recent list
 
915
        else recent_file_loaded(utf8_filename); /* filename already in recent list */
1239
916
}
1240
917
 
1241
918
 
1242
 
// Returns: newly allocated string with the UTF-8 menu text.
 
919
/* Returns: newly allocated string with the UTF-8 menu text. */
1243
920
static gchar *menu_item_get_text(GtkMenuItem *menu_item)
1244
921
{
1245
922
        const gchar *text = NULL;
1246
923
 
1247
 
        if (GTK_BIN (menu_item)->child)
 
924
        if (GTK_BIN(menu_item)->child)
1248
925
        {
1249
 
                GtkWidget *child = GTK_BIN (menu_item)->child;
 
926
                GtkWidget *child = GTK_BIN(menu_item)->child;
1250
927
 
1251
 
                if (GTK_IS_LABEL (child))
 
928
                if (GTK_IS_LABEL(child))
1252
929
                        text = gtk_label_get_text(GTK_LABEL(child));
1253
930
        }
1254
 
        // GTK owns text so it's much safer to return a copy of it in case the memory is reallocated
 
931
        /* GTK owns text so it's much safer to return a copy of it in case the memory is reallocated */
1255
932
        return g_strdup(text);
1256
933
}
1257
934
 
1258
935
 
 
936
static gint find_recent_file_item(gconstpointer list_data, gconstpointer user_data)
 
937
{
 
938
        gchar *menu_text = menu_item_get_text(GTK_MENU_ITEM(list_data));
 
939
        gint result;
 
940
 
 
941
        if (utils_str_equal(menu_text, user_data))
 
942
                result = 0;
 
943
        else
 
944
                result = 1;
 
945
 
 
946
        g_free(menu_text);
 
947
        return result;
 
948
}
 
949
 
 
950
 
1259
951
static void recent_file_loaded(const gchar *utf8_filename)
1260
952
{
1261
953
        GList *item, *children;
1262
954
        void *data;
1263
 
        GtkWidget *recent_menu, *tmp;
 
955
        GtkWidget *tmp;
1264
956
 
1265
 
        // first reorder the queue
1266
 
        item = g_queue_find_custom(app->recent_queue, utf8_filename, (GCompareFunc) strcmp);
 
957
        /* first reorder the queue */
 
958
        item = g_queue_find_custom(ui_prefs.recent_queue, utf8_filename, (GCompareFunc) strcmp);
1267
959
        g_return_if_fail(item != NULL);
1268
960
 
1269
961
        data = item->data;
1270
 
        g_queue_remove(app->recent_queue, data);
1271
 
        g_queue_push_head(app->recent_queue, data);
1272
 
 
1273
 
        // now reorder the recent files menu
1274
 
        recent_menu = lookup_widget(app->window, "recent_files1_menu");
1275
 
        children = gtk_container_get_children(GTK_CONTAINER(recent_menu));
1276
 
 
1277
 
        // remove the old menuitem for the filename
1278
 
        for (item = children; item != NULL; item = g_list_next(item))
1279
 
        {
1280
 
                gchar *menu_text;
1281
 
 
1282
 
                data = item->data;
1283
 
                if (! GTK_IS_MENU_ITEM(data)) continue;
1284
 
                menu_text = menu_item_get_text(GTK_MENU_ITEM(data));
1285
 
 
1286
 
                if (g_str_equal(menu_text, utf8_filename))
1287
 
                {
1288
 
                        gtk_widget_destroy(GTK_WIDGET(data));
1289
 
                        g_free(menu_text);
1290
 
                        break;
1291
 
                }
1292
 
                g_free(menu_text);
1293
 
        }
1294
 
        // now prepend a new menuitem for the filename
1295
 
        tmp = gtk_menu_item_new_with_label(utf8_filename);
1296
 
        gtk_widget_show(tmp);
1297
 
        gtk_menu_shell_prepend(GTK_MENU_SHELL(recent_menu), tmp);
 
962
        g_queue_remove(ui_prefs.recent_queue, data);
 
963
        g_queue_push_head(ui_prefs.recent_queue, data);
 
964
 
 
965
        /* remove the old menuitem for the filename */
 
966
        children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_files_menubar));
 
967
        item = g_list_find_custom(children, utf8_filename, (GCompareFunc) find_recent_file_item);
 
968
        if (item != NULL) gtk_widget_destroy(GTK_WIDGET(item->data));
 
969
 
 
970
        children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_files_toolbar));
 
971
        item = g_list_find_custom(children, utf8_filename, (GCompareFunc) find_recent_file_item);
 
972
        if (item != NULL) gtk_widget_destroy(GTK_WIDGET(item->data));
 
973
 
 
974
        /* now prepend a new menuitem for the filename,
 
975
         * first for the recent files menu in the menu bar */
 
976
        tmp = gtk_menu_item_new_with_label(utf8_filename);
 
977
        gtk_widget_show(tmp);
 
978
        gtk_menu_shell_prepend(GTK_MENU_SHELL(ui_widgets.recent_files_menubar), tmp);
 
979
        g_signal_connect((gpointer) tmp, "activate",
 
980
                                G_CALLBACK(recent_file_activate_cb), NULL);
 
981
        /* then for the recent files menu in the tool bar */
 
982
        tmp = gtk_menu_item_new_with_label(utf8_filename);
 
983
        gtk_widget_show(tmp);
 
984
        gtk_menu_shell_prepend(GTK_MENU_SHELL(ui_widgets.recent_files_toolbar), tmp);
1298
985
        g_signal_connect((gpointer) tmp, "activate",
1299
986
                                G_CALLBACK(recent_file_activate_cb), NULL);
1300
987
}
1301
988
 
1302
989
 
1303
 
static void update_recent_menu()
 
990
static void update_recent_menu(void)
1304
991
{
1305
 
        GtkWidget *recent_menu = lookup_widget(app->window, "recent_files1_menu");
1306
 
        GtkWidget *recent_files_item = lookup_widget(app->window, "recent_files1");
1307
992
        GtkWidget *tmp;
 
993
        static GtkMenuToolButton *menu = NULL;
1308
994
        gchar *filename;
1309
 
        GList *children;
1310
 
 
1311
 
        if (g_queue_get_length(app->recent_queue) == 0)
1312
 
        {
1313
 
                gtk_widget_set_sensitive(recent_files_item, FALSE);
1314
 
                return;
1315
 
        }
1316
 
        else if (! GTK_WIDGET_SENSITIVE(recent_files_item))
1317
 
        {
1318
 
                gtk_widget_set_sensitive(recent_files_item, TRUE);
1319
 
        }
1320
 
 
1321
 
        // clean the MRU list before adding an item
1322
 
        children = gtk_container_get_children(GTK_CONTAINER(recent_menu));
1323
 
        if (g_list_length(children) > app->mru_length - 1)
1324
 
        {
1325
 
                GList *item = g_list_nth(children, app->mru_length - 1);
1326
 
                while (item != NULL)
1327
 
                {
1328
 
                        if (GTK_IS_MENU_ITEM(item->data)) gtk_widget_destroy(GTK_WIDGET(item->data));
1329
 
                        item = g_list_next(item);
1330
 
                }
1331
 
        }
1332
 
 
1333
 
        filename = g_queue_peek_head(app->recent_queue);
1334
 
        tmp = gtk_menu_item_new_with_label(filename);
1335
 
        gtk_widget_show(tmp);
1336
 
        gtk_menu_shell_prepend(GTK_MENU_SHELL(recent_menu), tmp);
1337
 
        g_signal_connect((gpointer) tmp, "activate",
1338
 
                                G_CALLBACK(recent_file_activate_cb), NULL);
1339
 
}
1340
 
 
1341
 
 
1342
 
void ui_show_markers_margin()
1343
 
{
1344
 
        gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
1345
 
 
1346
 
        for(i = 0; i < max; i++)
1347
 
        {
1348
 
                idx = document_get_n_idx(i);
1349
 
                sci_set_symbol_margin(doc_list[idx].sci, app->show_markers_margin);
1350
 
        }
1351
 
}
1352
 
 
1353
 
 
1354
 
void ui_show_linenumber_margin()
1355
 
{
1356
 
        gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
1357
 
 
1358
 
        for(i = 0; i < max; i++)
1359
 
        {
1360
 
                idx = document_get_n_idx(i);
1361
 
                sci_set_line_numbers(doc_list[idx].sci, app->show_linenumber_margin, 0);
1362
 
        }
1363
 
}
1364
 
 
1365
 
 
1366
 
/* Creates a GNOME HIG style frame (with no border and indented child alignment)
1367
 
 * and packs it into the parent container.
1368
 
 * Returns: the alignment container for the frame */
1369
 
GtkContainer *ui_frame_new(GtkContainer *parent, const gchar *label_text)
 
995
        GList *children, *item;
 
996
 
 
997
        if (menu == NULL)
 
998
                menu = GTK_MENU_TOOL_BUTTON(lookup_widget(app->window, "toolbutton9"));
 
999
 
 
1000
        if (gtk_menu_tool_button_get_menu(menu) == NULL)
 
1001
        {
 
1002
                gtk_menu_tool_button_set_menu(menu, ui_widgets.recent_files_toolbar);
 
1003
        }
 
1004
 
 
1005
        /* clean the MRU list before adding an item (menubar) */
 
1006
        children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_files_menubar));
 
1007
        if (g_list_length(children) > prefs.mru_length - 1)
 
1008
        {
 
1009
                item = g_list_nth(children, prefs.mru_length - 1);
 
1010
                while (item != NULL)
 
1011
                {
 
1012
                        if (GTK_IS_MENU_ITEM(item->data)) gtk_widget_destroy(GTK_WIDGET(item->data));
 
1013
                        item = g_list_next(item);
 
1014
                }
 
1015
        }
 
1016
 
 
1017
        /* clean the MRU list before adding an item (toolbar) */
 
1018
        children = gtk_container_get_children(GTK_CONTAINER(ui_widgets.recent_files_toolbar));
 
1019
        if (g_list_length(children) > prefs.mru_length - 1)
 
1020
        {
 
1021
                item = g_list_nth(children, prefs.mru_length - 1);
 
1022
                while (item != NULL)
 
1023
                {
 
1024
                        if (GTK_IS_MENU_ITEM(item->data)) gtk_widget_destroy(GTK_WIDGET(item->data));
 
1025
                        item = g_list_next(item);
 
1026
                }
 
1027
        }
 
1028
 
 
1029
        filename = g_queue_peek_head(ui_prefs.recent_queue);
 
1030
        /* create item for the menu bar menu */
 
1031
        tmp = gtk_menu_item_new_with_label(filename);
 
1032
        gtk_widget_show(tmp);
 
1033
        gtk_menu_shell_prepend(GTK_MENU_SHELL(ui_widgets.recent_files_menubar), tmp);
 
1034
        g_signal_connect((gpointer) tmp, "activate",
 
1035
                                G_CALLBACK(recent_file_activate_cb), NULL);
 
1036
        /* create item for the tool bar menu */
 
1037
        tmp = gtk_menu_item_new_with_label(filename);
 
1038
        gtk_widget_show(tmp);
 
1039
        gtk_menu_shell_prepend(GTK_MENU_SHELL(ui_widgets.recent_files_toolbar), tmp);
 
1040
        g_signal_connect((gpointer) tmp, "activate",
 
1041
                                G_CALLBACK(recent_file_activate_cb), NULL);
 
1042
}
 
1043
 
 
1044
 
 
1045
void ui_show_markers_margin(void)
 
1046
{
 
1047
        gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
 
1048
 
 
1049
        for(i = 0; i < max; i++)
 
1050
        {
 
1051
                idx = document_get_n_idx(i);
 
1052
                sci_set_symbol_margin(doc_list[idx].sci, editor_prefs.show_markers_margin);
 
1053
        }
 
1054
}
 
1055
 
 
1056
 
 
1057
void ui_show_linenumber_margin(void)
 
1058
{
 
1059
        gint i, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
 
1060
 
 
1061
        for(i = 0; i < max; i++)
 
1062
        {
 
1063
                idx = document_get_n_idx(i);
 
1064
                sci_set_line_numbers(doc_list[idx].sci, editor_prefs.show_linenumber_margin, 0);
 
1065
        }
 
1066
}
 
1067
 
 
1068
 
 
1069
/* Creates a GNOME HIG style frame (with no border and indented child alignment).
 
1070
 * Returns the frame widget, setting the alignment container for packing child widgets */
 
1071
GtkWidget *ui_frame_new_with_alignment(const gchar *label_text, GtkWidget **alignment)
1370
1072
{
1371
1073
        GtkWidget *label, *align;
1372
1074
        GtkWidget *frame = gtk_frame_new (NULL);
1373
1075
        gchar *label_markup;
1374
1076
 
1375
 
        gtk_container_add(GTK_CONTAINER(parent), frame);
1376
1077
        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
1377
1078
 
1378
1079
        align = gtk_alignment_new (0.5, 0.5, 1, 1);
1379
1080
        gtk_container_add (GTK_CONTAINER (frame), align);
1380
 
        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 0); 
 
1081
        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 0);
1381
1082
 
1382
1083
        label_markup = g_strconcat("<b>", label_text, "</b>", NULL);
1383
1084
        label = gtk_label_new (label_markup);
1385
1086
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1386
1087
        g_free(label_markup);
1387
1088
 
1388
 
        return GTK_CONTAINER(align);
1389
 
}
1390
 
 
1391
 
 
1392
 
 
 
1089
        *alignment = align;
 
1090
        return frame;
 
1091
}
 
1092
 
 
1093
 
 
1094
const gint BUTTON_BOX_BORDER = 5;
 
1095
 
 
1096
/* Convenience function for getting a fixed border for dialogs that doesn't
 
1097
 * increase the button box border.
 
1098
 * dialog is the parent container for the vbox.
 
1099
 * Returns: the vbox. */
 
1100
GtkWidget *ui_dialog_vbox_new(GtkDialog *dialog)
 
1101
{
 
1102
        GtkWidget *vbox = gtk_vbox_new(FALSE, 12);      /* need child vbox to set a separate border. */
 
1103
 
 
1104
        gtk_container_set_border_width(GTK_CONTAINER(vbox), BUTTON_BOX_BORDER);
 
1105
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
 
1106
        return vbox;
 
1107
}
 
1108
 
 
1109
 
 
1110
/* Create a GtkButton with custom text and a stock image, aligned like
 
1111
 * gtk_button_new_from_stock */
 
1112
GtkWidget *ui_button_new_with_image(const gchar *stock_id, const gchar *text)
 
1113
{
 
1114
        GtkWidget *image, *label, *align, *hbox, *button;
 
1115
 
 
1116
        hbox = gtk_hbox_new(FALSE, 2);
 
1117
        image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_BUTTON);
 
1118
        label = gtk_label_new_with_mnemonic(text);
 
1119
        gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
 
1120
        gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1121
 
 
1122
        button = gtk_button_new();
 
1123
        align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
 
1124
        gtk_container_add(GTK_CONTAINER(align), hbox);
 
1125
        gtk_container_add(GTK_CONTAINER(button), align);
 
1126
        gtk_widget_show_all(align);
 
1127
        return button;
 
1128
}
 
1129
 
 
1130
 
 
1131
static void add_to_size_group(GtkWidget *widget, gpointer size_group)
 
1132
{
 
1133
        g_return_if_fail(GTK_IS_SIZE_GROUP(size_group));
 
1134
        gtk_size_group_add_widget(GTK_SIZE_GROUP(size_group), widget);
 
1135
}
 
1136
 
 
1137
 
 
1138
/* Copies the spacing and layout of the master GtkHButtonBox and synchronises
 
1139
 * the width of each button box's children.
 
1140
 * Should be called after all child widgets have been packed. */
 
1141
void ui_hbutton_box_copy_layout(GtkButtonBox *master, GtkButtonBox *copy)
 
1142
{
 
1143
        GtkSizeGroup *size_group;
 
1144
 
 
1145
        /* set_spacing is deprecated but there seems to be no alternative,
 
1146
        * GTK 2.6 defaults to no spacing, unlike dialog button box */
 
1147
        gtk_button_box_set_spacing(copy, 10);
 
1148
        gtk_button_box_set_layout(copy, gtk_button_box_get_layout(master));
 
1149
 
 
1150
        /* now we need to put the widest widget from each button box in a size group,
 
1151
        * but we don't know the width before they are drawn, and for different label
 
1152
        * translations the widest widget can vary, so we just add all widgets. */
 
1153
        size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
1154
        gtk_container_foreach(GTK_CONTAINER(master), add_to_size_group, size_group);
 
1155
        gtk_container_foreach(GTK_CONTAINER(copy), add_to_size_group, size_group);
 
1156
        g_object_unref(size_group);
 
1157
}
 
1158
 
 
1159
 
 
1160
/* Prepends the active text to the drop down list, unless the first element in
 
1161
 * the list is identical, ensuring there are <= history_len elements. */
 
1162
void ui_combo_box_add_to_history(GtkComboBox *combo, const gchar *text)
 
1163
{
 
1164
        const gint history_len = 30;
 
1165
        GtkTreeModel *model;
 
1166
        GtkTreeIter iter;
 
1167
        gchar *combo_text;
 
1168
        gboolean equal = FALSE;
 
1169
        GtkTreePath *path;
 
1170
 
 
1171
        model = gtk_combo_box_get_model(combo);
 
1172
        if (gtk_tree_model_get_iter_first(model, &iter))
 
1173
        {
 
1174
                gtk_tree_model_get(model, &iter, 0, &combo_text, -1);
 
1175
                equal = utils_str_equal(combo_text, text);
 
1176
                g_free(combo_text);
 
1177
        }
 
1178
        if (equal) return;      /* don't prepend duplicate */
 
1179
 
 
1180
        gtk_combo_box_prepend_text(combo, text);
 
1181
 
 
1182
        /* limit history */
 
1183
        path = gtk_tree_path_new_from_indices(history_len, -1);
 
1184
        if (gtk_tree_model_get_iter(model, &iter, path))
 
1185
        {
 
1186
                gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
 
1187
        }
 
1188
        gtk_tree_path_free(path);
 
1189
}
 
1190
 
 
1191
 
 
1192
/* Changes the color of the notebook tab text and open files items according to
 
1193
 * document status. */
 
1194
void ui_update_tab_status(gint idx)
 
1195
{
 
1196
        GdkColor *color = document_get_status(idx);
 
1197
 
 
1198
        /* NULL color will reset to default */
 
1199
        gtk_widget_modify_fg(doc_list[idx].tab_label, GTK_STATE_NORMAL, color);
 
1200
        gtk_widget_modify_fg(doc_list[idx].tab_label, GTK_STATE_ACTIVE, color);
 
1201
        gtk_widget_modify_fg(doc_list[idx].tabmenu_label, GTK_STATE_NORMAL, color);
 
1202
        gtk_widget_modify_fg(doc_list[idx].tabmenu_label, GTK_STATE_ACTIVE, color);
 
1203
 
 
1204
        treeviews_openfiles_update(idx);
 
1205
}
 
1206
 
 
1207
 
 
1208
/* Returns FALSE if the treeview has items but no matching next item. */
 
1209
gboolean ui_tree_view_find_next(GtkTreeView *treeview, TVMatchCallback cb)
 
1210
{
 
1211
        GtkTreeSelection *treesel;
 
1212
        GtkTreeIter iter;
 
1213
        GtkTreeModel *model;
 
1214
 
 
1215
        treesel = gtk_tree_view_get_selection(treeview);
 
1216
        if (gtk_tree_selection_get_selected(treesel, &model, &iter))
 
1217
        {
 
1218
                /* get the next selected item */
 
1219
                if (! gtk_tree_model_iter_next(model, &iter))
 
1220
                        return FALSE;   /* no more items */
 
1221
        }
 
1222
        else    /* no selection */
 
1223
        {
 
1224
                if (! gtk_tree_model_get_iter_first(model, &iter))
 
1225
                        return TRUE;    /* no items */
 
1226
        }
 
1227
        while (TRUE)
 
1228
        {
 
1229
                gtk_tree_selection_select_iter(treesel, &iter);
 
1230
                if (cb())
 
1231
                        break;  /* found next message */
 
1232
 
 
1233
                if (! gtk_tree_model_iter_next(model, &iter))
 
1234
                        return FALSE;   /* no more items */
 
1235
        }
 
1236
        /* scroll item in view */
 
1237
        if (ui_prefs.msgwindow_visible)
 
1238
        {
 
1239
                GtkTreePath *path = gtk_tree_model_get_path(
 
1240
                        gtk_tree_view_get_model(treeview), &iter);
 
1241
 
 
1242
                gtk_tree_view_scroll_to_cell(treeview, path, NULL, TRUE, 0.5, 0.5);
 
1243
                gtk_tree_path_free(path);
 
1244
        }
 
1245
        return TRUE;
 
1246
}
 
1247
 
 
1248
 
 
1249
void ui_widget_modify_font_from_string(GtkWidget *wid, const gchar *str)
 
1250
{
 
1251
        PangoFontDescription *pfd;
 
1252
 
 
1253
        pfd = pango_font_description_from_string(str);
 
1254
        gtk_widget_modify_font(wid, pfd);
 
1255
        pango_font_description_free(pfd);
 
1256
}
 
1257
 
 
1258
 
 
1259
/* Creates a GtkHBox with entry packed into it and an open button which runs a
 
1260
 * file chooser, replacing entry text if successful.
 
1261
 * entry can be the child of an unparented widget, such as GtkComboBoxEntry.
 
1262
 * See ui_setup_open_button_callback() for details. */
 
1263
GtkWidget *ui_path_box_new(const gchar *title, GtkFileChooserAction action, GtkEntry *entry)
 
1264
{
 
1265
        GtkWidget *vbox, *dirbtn, *openimg, *hbox, *path_entry;
 
1266
 
 
1267
        hbox = gtk_hbox_new(FALSE, 6);
 
1268
        path_entry = GTK_WIDGET(entry);
 
1269
 
 
1270
        /* prevent path_entry being vertically stretched to the height of dirbtn */
 
1271
        vbox = gtk_vbox_new(FALSE, 0);
 
1272
        if (gtk_widget_get_parent(path_entry))  /* entry->parent may be a GtkComboBoxEntry */
 
1273
        {
 
1274
                GtkWidget *parent = gtk_widget_get_parent(path_entry);
 
1275
 
 
1276
                gtk_box_pack_start(GTK_BOX(vbox), parent, TRUE, FALSE, 0);
 
1277
        }
 
1278
        else
 
1279
                gtk_box_pack_start(GTK_BOX(vbox), path_entry, TRUE, FALSE, 0);
 
1280
 
 
1281
        dirbtn = gtk_button_new();
 
1282
        openimg = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
 
1283
        gtk_container_add(GTK_CONTAINER(dirbtn), openimg);
 
1284
        ui_setup_open_button_callback(dirbtn, title, action, entry);
 
1285
 
 
1286
        gtk_box_pack_end(GTK_BOX(hbox), dirbtn, FALSE, FALSE, 0);
 
1287
        gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
 
1288
        return hbox;
 
1289
}
 
1290
 
 
1291
 
 
1292
static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data);
 
1293
 
 
1294
 
 
1295
/* Setup a GtkButton to run a GtkFileChooser, setting entry text if successful.
 
1296
 * title can be NULL.
 
1297
 * action is the file chooser mode to use. */
 
1298
void ui_setup_open_button_callback(GtkWidget *open_btn, const gchar *title,
 
1299
                GtkFileChooserAction action, GtkEntry *entry)
 
1300
{
 
1301
        GtkWidget *path_entry = GTK_WIDGET(entry);
 
1302
 
 
1303
        if (title)
 
1304
                g_object_set_data_full(G_OBJECT(open_btn), "title",
 
1305
                        g_strdup(title), (GDestroyNotify) g_free);
 
1306
        g_object_set_data(G_OBJECT(open_btn), "action", (gpointer) action);
 
1307
        g_object_set_data_full(G_OBJECT(open_btn), "entry",
 
1308
                gtk_widget_ref(path_entry), (GDestroyNotify) gtk_widget_unref);
 
1309
        g_signal_connect(G_OBJECT(open_btn), "clicked",
 
1310
                G_CALLBACK(ui_path_box_open_clicked), open_btn);
 
1311
}
 
1312
 
 
1313
 
 
1314
#ifndef G_OS_WIN32
 
1315
static gchar *run_file_chooser(const gchar *title, GtkFileChooserAction action,
 
1316
                const gchar *utf8_path)
 
1317
{
 
1318
        GtkWidget *dialog = gtk_file_chooser_dialog_new(title,
 
1319
                GTK_WINDOW(app->window), action,
 
1320
                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1321
                GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
 
1322
        gchar *locale_path;
 
1323
        gchar *ret_path = NULL;
 
1324
 
 
1325
        gtk_widget_set_name(dialog, "GeanyDialog");
 
1326
        locale_path = utils_get_locale_from_utf8(utf8_path);
 
1327
        if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
 
1328
        {
 
1329
                if (g_path_is_absolute(locale_path) && g_file_test(locale_path, G_FILE_TEST_IS_DIR))
 
1330
                        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path);
 
1331
        }
 
1332
        g_free(locale_path);
 
1333
 
 
1334
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
 
1335
        {
 
1336
                gchar *dir_locale;
 
1337
 
 
1338
                dir_locale = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
 
1339
                ret_path = utils_get_utf8_from_locale(dir_locale);
 
1340
                g_free(dir_locale);
 
1341
        }
 
1342
        gtk_widget_destroy(dialog);
 
1343
        return ret_path;
 
1344
}
 
1345
#endif
 
1346
 
 
1347
 
 
1348
static void ui_path_box_open_clicked(GtkButton *button, gpointer user_data)
 
1349
{
 
1350
        GtkWidget *path_box = GTK_WIDGET(user_data);
 
1351
        GtkFileChooserAction action =
 
1352
                (GtkFileChooserAction) g_object_get_data(G_OBJECT(path_box), "action");
 
1353
        GtkEntry *entry =
 
1354
                (GtkEntry *) g_object_get_data(G_OBJECT(path_box), "entry");
 
1355
        const gchar *title = g_object_get_data(G_OBJECT(path_box), "title");
 
1356
        gchar *utf8_path;
 
1357
 
 
1358
        /* TODO: extend for other actions */
 
1359
        g_return_if_fail(action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
 
1360
 
 
1361
        if (title == NULL)
 
1362
                title = (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ?
 
1363
                        _("Select Folder") : _("Select File");
 
1364
 
 
1365
#ifdef G_OS_WIN32
 
1366
        utf8_path = win32_show_project_folder_dialog(ui_widgets.prefs_dialog, title,
 
1367
                                                gtk_entry_get_text(GTK_ENTRY(entry)));
 
1368
#else
 
1369
        utf8_path = run_file_chooser(title, action, gtk_entry_get_text(GTK_ENTRY(entry)));
 
1370
#endif
 
1371
 
 
1372
        if (utf8_path != NULL)
 
1373
        {
 
1374
                gtk_entry_set_text(GTK_ENTRY(entry), utf8_path);
 
1375
                g_free(utf8_path);
 
1376
        }
 
1377
}
 
1378
 
 
1379
 
 
1380
void ui_statusbar_showhide(gboolean state)
 
1381
{
 
1382
        /* handle statusbar visibility */
 
1383
        if (state)
 
1384
        {
 
1385
                gtk_widget_show(app->statusbar);
 
1386
                ui_update_statusbar(-1, -1);
 
1387
        }
 
1388
        else
 
1389
                gtk_widget_hide(app->statusbar);
 
1390
}
 
1391
 
 
1392
 
 
1393
/* Pack all GtkWidgets passed after the row argument into a table, using
 
1394
 * one widget per cell. The first widget is not expanded, as this is usually
 
1395
 * a label. */
 
1396
void ui_table_add_row(GtkTable *table, gint row, ...)
 
1397
{
 
1398
        va_list args;
 
1399
        gint i;
 
1400
        GtkWidget *widget;
 
1401
 
 
1402
        va_start(args, row);
 
1403
        for (i = 0; (widget = va_arg(args, GtkWidget*), widget != NULL); i++)
 
1404
        {
 
1405
                gint options = (i == 0) ? GTK_FILL : GTK_EXPAND | GTK_FILL;
 
1406
 
 
1407
                gtk_table_attach(GTK_TABLE(table), widget, i, i + 1, row, row + 1,
 
1408
                        options, 0, 0, 0);
 
1409
        }
 
1410
        va_end(args);
 
1411
}
 
1412
 
 
1413
 
 
1414
void ui_init(void)
 
1415
{
 
1416
        init_document_widgets();
 
1417
}