1 /*
2 * plugme.c
3 *
4 * Copyright 2012 Dimitar Toshkov Zhekov <dimitar.zhekov@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <string.h>
25
26 #include "common.h"
27
28 #include <gp_gtkcompat.h>
29
30 #include <geanyplugin.h>
31
32 extern GeanyData *geany_data;
33
34 /* This file must not depend on Scope */
35 #include "plugme.h"
36
run_file_chooser(const gchar * title,GtkFileChooserAction action,const gchar * utf8_path)37 static gchar *run_file_chooser(const gchar *title, GtkFileChooserAction action,
38 const gchar *utf8_path)
39 {
40 GtkWidget *dialog = gtk_file_chooser_dialog_new(title,
41 GTK_WINDOW(geany->main_widgets->window), action,
42 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
43 GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
44 gchar *locale_path;
45 gchar *ret_path = NULL;
46
47 gtk_widget_set_name(dialog, "GeanyDialog");
48 locale_path = utils_get_locale_from_utf8(utf8_path);
49 if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
50 {
51 if (g_path_is_absolute(locale_path) && g_file_test(locale_path, G_FILE_TEST_IS_DIR))
52 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), locale_path);
53 }
54 else if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
55 {
56 if (g_path_is_absolute(locale_path))
57 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), locale_path);
58 }
59 g_free(locale_path);
60
61 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
62 {
63 gchar *dir_locale;
64
65 dir_locale = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
66 ret_path = utils_get_utf8_from_locale(dir_locale);
67 g_free(dir_locale);
68 }
69 gtk_widget_destroy(dialog);
70 return ret_path;
71 }
72
ui_path_box_open_clicked(G_GNUC_UNUSED GtkButton * button,gpointer user_data)73 static void ui_path_box_open_clicked(G_GNUC_UNUSED GtkButton *button, gpointer user_data)
74 {
75 GtkWidget *path_box = GTK_WIDGET(user_data);
76 GtkFileChooserAction action = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(path_box), "action"));
77 GtkEntry *entry = g_object_get_data(G_OBJECT(path_box), "entry");
78 const gchar *title = g_object_get_data(G_OBJECT(path_box), "title");
79 gchar *utf8_path = NULL;
80
81 /* TODO: extend for other actions */
82 g_return_if_fail(action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
83 action == GTK_FILE_CHOOSER_ACTION_OPEN);
84
85 if (title == NULL)
86 title = (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ?
87 _("Select Folder") : _("Select File");
88
89 if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
90 {
91 utf8_path = run_file_chooser(title, action, gtk_entry_get_text(GTK_ENTRY(entry)));
92 }
93 else if (action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
94 {
95 gchar *path = g_path_get_dirname(gtk_entry_get_text(GTK_ENTRY(entry)));
96 utf8_path = run_file_chooser(title, action, path);
97 g_free(path);
98 }
99
100 if (utf8_path != NULL)
101 {
102 gtk_entry_set_text(GTK_ENTRY(entry), utf8_path);
103 g_free(utf8_path);
104 }
105 }
106
107 /* Setup a GtkButton to run a GtkFileChooser, setting entry text if successful.
108 * title can be NULL.
109 * action is the file chooser mode to use. */
plugme_ui_setup_open_button_callback(GtkWidget * open_btn,const gchar * title,GtkFileChooserAction action,GtkEntry * entry)110 void plugme_ui_setup_open_button_callback(GtkWidget *open_btn, const gchar *title,
111 GtkFileChooserAction action, GtkEntry *entry)
112 {
113 GtkWidget *path_entry = GTK_WIDGET(entry);
114
115 if (title)
116 g_object_set_data_full(G_OBJECT(open_btn), "title", g_strdup(title),
117 (GDestroyNotify) g_free);
118 g_object_set_data(G_OBJECT(open_btn), "action", GINT_TO_POINTER(action));
119 ui_hookup_widget(open_btn, path_entry, "entry");
120 g_signal_connect(open_btn, "clicked", G_CALLBACK(ui_path_box_open_clicked), open_btn);
121 }
122
123 /* Note: this is NOT the Geany function, only similar */
plugme_editor_get_default_selection(GeanyEditor * editor,gboolean use_current_word,const gchar * wordchars)124 gchar *plugme_editor_get_default_selection(GeanyEditor *editor, gboolean use_current_word,
125 const gchar *wordchars)
126 {
127 ScintillaObject *sci = editor->sci;
128 gchar *text = NULL;
129
130 if (sci_has_selection(sci))
131 {
132 if (sci_get_selected_text_length(sci) < GEANY_MAX_WORD_LENGTH)
133 {
134 text = sci_get_selection_contents(sci);
135
136 if (strchr(text, '\n') != NULL)
137 *strchr(text, '\n') = '\0';
138 }
139 }
140 else if (use_current_word)
141 text = editor_get_word_at_pos(editor, sci_get_current_position(sci), wordchars);
142
143 return text;
144 }
145
on_config_file_clicked(G_GNUC_UNUSED GtkWidget * widget,gpointer user_data)146 static void on_config_file_clicked(G_GNUC_UNUSED GtkWidget *widget, gpointer user_data)
147 {
148 const gchar *file_name = user_data;
149 GeanyFiletype *ft = NULL;
150
151 if (strstr(file_name, G_DIR_SEPARATOR_S "filetypes."))
152 ft = filetypes_index(GEANY_FILETYPES_CONF);
153
154 if (g_file_test(file_name, G_FILE_TEST_EXISTS))
155 document_open_file(file_name, FALSE, ft, NULL);
156 else
157 {
158 gchar *utf8_filename = utils_get_utf8_from_locale(file_name);
159 gchar *base_name = g_path_get_basename(file_name);
160 gchar *global_file = g_build_filename(geany->app->datadir, base_name, NULL);
161 gchar *global_content = NULL;
162
163 /* if the requested file doesn't exist in the user's config dir, try loading the file
164 * from the global data directory and use its contents for the newly created file */
165 if (g_file_test(global_file, G_FILE_TEST_EXISTS))
166 g_file_get_contents(global_file, &global_content, NULL, NULL);
167
168 document_new_file(utf8_filename, ft, global_content);
169
170 g_free(utf8_filename);
171 g_free(base_name);
172 g_free(global_file);
173 g_free(global_content);
174 }
175 }
176
free_on_closure_notify(gpointer data,G_GNUC_UNUSED GClosure * closure)177 static void free_on_closure_notify(gpointer data, G_GNUC_UNUSED GClosure *closure)
178 {
179 g_free(data);
180 }
181
plugme_ui_add_config_file_menu_item(const gchar * real_path,const gchar * label,GtkContainer * parent)182 GtkWidget *plugme_ui_add_config_file_menu_item(const gchar *real_path, const gchar *label,
183 GtkContainer *parent)
184 {
185 GtkWidget *item;
186
187 if (!parent)
188 {
189 item = ui_lookup_widget(geany->main_widgets->window, "configuration_files1");
190 parent = GTK_CONTAINER(gtk_menu_item_get_submenu(GTK_MENU_ITEM(item)));
191 }
192
193 if (!label)
194 {
195 gchar *base_name;
196
197 base_name = g_path_get_basename(real_path);
198 item = gtk_menu_item_new_with_label(base_name);
199 g_free(base_name);
200 }
201 else
202 item = gtk_menu_item_new_with_mnemonic(label);
203
204 gtk_widget_show(item);
205 gtk_container_add(parent, item);
206 g_signal_connect_data(item, "activate", G_CALLBACK(on_config_file_clicked),
207 g_strdup(real_path), free_on_closure_notify, 0);
208
209 return item;
210 }
211