1 /**
2 * @file ui_common.c UI helper functions
3 *
4 * Copyright (C) 2008-2014 Lars Windolf <lars.windolf@gmx.de>
5 * Copyright (C) 2009 Hubert Figuiere <hub@figuiere.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #include "ui/ui_common.h"
23
24 #include "common.h"
25 #include "conf.h"
26 #include "ui/liferea_shell.h"
27
28 void
ui_common_setup_combo_menu(GtkWidget * widget,const gchar ** options,GCallback callback,gint defaultValue)29 ui_common_setup_combo_menu (GtkWidget *widget,
30 const gchar **options,
31 GCallback callback,
32 gint defaultValue)
33 {
34 GtkListStore *listStore;
35 GtkTreeIter treeiter;
36 guint i;
37
38 listStore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
39 g_assert (NULL != widget);
40 for (i = 0; options[i] != NULL; i++) {
41 gtk_list_store_append (listStore, &treeiter);
42 gtk_list_store_set (listStore, &treeiter, 0, _(options[i]), 1, i, -1);
43 }
44 gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (listStore));
45 if (-1 <= defaultValue)
46 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), defaultValue);
47
48 if (callback)
49 g_signal_connect (G_OBJECT (widget), "changed", callback, widget);
50 }
51
52 void
ui_common_setup_combo_text(GtkComboBox * combo,gint col)53 ui_common_setup_combo_text (GtkComboBox *combo, gint col)
54 {
55 GtkCellRenderer *rend = gtk_cell_renderer_text_new ();
56 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), rend, TRUE);
57 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), rend, "text", col);
58 }
59
60 void
ui_common_treeview_move_cursor(GtkTreeView * treeview,gint step)61 ui_common_treeview_move_cursor (GtkTreeView *treeview, gint step)
62 {
63 gboolean ret;
64
65 gtk_widget_grab_focus (GTK_WIDGET (treeview));
66 g_signal_emit_by_name (treeview, "move-cursor", GTK_MOVEMENT_DISPLAY_LINES, step, &ret);
67 }
68
69 void
ui_common_treeview_move_cursor_to_first(GtkTreeView * treeview)70 ui_common_treeview_move_cursor_to_first (GtkTreeView *treeview)
71 {
72 GtkTreePath *path;
73
74 path = gtk_tree_path_new_first ();
75 gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
76 gtk_tree_path_free(path);
77 }
78
79 void
ui_show_error_box(const char * format,...)80 ui_show_error_box (const char *format, ...)
81 {
82 GtkWidget *dialog;
83 va_list args;
84 gchar *msg;
85
86 g_return_if_fail (format != NULL);
87
88 va_start (args, format);
89 msg = g_strdup_vprintf (format, args);
90 va_end (args);
91
92 dialog = gtk_message_dialog_new (GTK_WINDOW (liferea_shell_get_window ()),
93 GTK_DIALOG_DESTROY_WITH_PARENT,
94 GTK_MESSAGE_ERROR,
95 GTK_BUTTONS_CLOSE,
96 "%s", msg);
97 (void)gtk_dialog_run (GTK_DIALOG (dialog));
98 gtk_widget_destroy (dialog);
99 g_free (msg);
100 }
101
102 void
ui_show_info_box(const char * format,...)103 ui_show_info_box (const char *format, ...)
104 {
105 GtkWidget *dialog;
106 va_list args;
107 gchar *msg;
108
109 g_return_if_fail (format != NULL);
110
111 va_start (args, format);
112 msg = g_strdup_vprintf (format, args);
113 va_end (args);
114
115 dialog = gtk_message_dialog_new (GTK_WINDOW (liferea_shell_get_window ()),
116 GTK_DIALOG_DESTROY_WITH_PARENT,
117 GTK_MESSAGE_INFO,
118 GTK_BUTTONS_CLOSE,
119 "%s", msg);
120 (void)gtk_dialog_run (GTK_DIALOG (dialog));
121 gtk_widget_destroy (dialog);
122 g_free (msg);
123 }
124
125 struct file_chooser_tuple {
126 GtkWidget *dialog;
127 fileChoosenCallback func;
128 gpointer user_data;
129 };
130
131 static void
ui_choose_file_save_cb(GtkDialog * dialog,gint response_id,gpointer user_data)132 ui_choose_file_save_cb (GtkDialog *dialog, gint response_id, gpointer user_data)
133 {
134 struct file_chooser_tuple *tuple = (struct file_chooser_tuple*)user_data;
135 gchar *filename;
136
137 if (response_id == GTK_RESPONSE_ACCEPT) {
138 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
139 tuple->func (filename, tuple->user_data);
140 g_free (filename);
141 } else {
142 tuple->func (NULL, tuple->user_data);
143 }
144
145 gtk_widget_destroy (GTK_WIDGET (dialog));
146 g_free (tuple);
147 }
148
149 static void
ui_choose_file_or_dir(gchar * title,const gchar * buttonName,gboolean saving,gboolean directory,fileChoosenCallback callback,const gchar * currentPath,const gchar * defaultFilename,const char * filterstring,const char * filtername,gpointer user_data)150 ui_choose_file_or_dir(gchar *title, const gchar *buttonName, gboolean saving, gboolean directory, fileChoosenCallback callback, const gchar *currentPath, const gchar *defaultFilename, const char *filterstring, const char *filtername, gpointer user_data)
151 {
152 GtkWidget *dialog;
153 struct file_chooser_tuple *tuple;
154 GtkWidget *button;
155 gchar *path = NULL;
156
157 g_assert (!(saving & directory));
158 g_assert (!(defaultFilename && !saving));
159
160 if (!currentPath)
161 path = g_strdup (g_get_home_dir ());
162 else
163 path = g_strdup (currentPath);
164
165 dialog = gtk_file_chooser_dialog_new (title, GTK_WINDOW (liferea_shell_get_window ()),
166 (directory?GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
167 (saving ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN)),
168 _("_Cancel"), GTK_RESPONSE_CANCEL,
169 NULL);
170 if (saving)
171 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
172 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
173
174 tuple = g_new0 (struct file_chooser_tuple, 1);
175 tuple->dialog = dialog;
176 tuple->func = callback;
177 tuple->user_data = user_data;
178
179 button = gtk_dialog_add_button (GTK_DIALOG (dialog), buttonName, GTK_RESPONSE_ACCEPT);
180 gtk_widget_set_can_default (button, TRUE);
181 gtk_widget_grab_default (button);
182
183 g_signal_connect (G_OBJECT (dialog), "response",
184 G_CALLBACK (ui_choose_file_save_cb), tuple);
185
186 if (path && g_file_test (path, G_FILE_TEST_EXISTS)) {
187 if (directory || defaultFilename)
188 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path);
189 else
190 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), path);
191 }
192 if (defaultFilename)
193 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), defaultFilename);
194
195 if (filterstring && filtername) {
196 GtkFileFilter *filter, *allfiles;
197 gchar **filterstrings, **f;
198
199 filter = gtk_file_filter_new ();
200
201 filterstrings = g_strsplit (filterstring, "|", 0);
202 for (f = filterstrings; *f != NULL; f++)
203 gtk_file_filter_add_pattern (filter, *f);
204 g_strfreev (filterstrings);
205
206 gtk_file_filter_set_name (filter, filtername);
207 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
208
209 allfiles = gtk_file_filter_new ();
210 gtk_file_filter_add_pattern (allfiles, "*");
211 gtk_file_filter_set_name (allfiles, _("All Files"));
212 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), allfiles);
213 }
214
215 gtk_widget_show_all (dialog);
216 g_free (path);
217 }
218
219 void
ui_choose_file(gchar * title,const gchar * buttonName,gboolean saving,fileChoosenCallback callback,const gchar * currentPath,const gchar * defaultFilename,const char * filterstring,const char * filtername,gpointer user_data)220 ui_choose_file (gchar *title, const gchar *buttonName, gboolean saving, fileChoosenCallback callback, const gchar *currentPath, const gchar *defaultFilename, const char *filterstring, const char *filtername, gpointer user_data)
221 {
222 ui_choose_file_or_dir (title, buttonName, saving, FALSE, callback, currentPath, defaultFilename, filterstring, filtername, user_data);
223 }
224
225 void
ui_common_simple_action_group_set_enabled(GActionGroup * group,gboolean enabled)226 ui_common_simple_action_group_set_enabled (GActionGroup *group, gboolean enabled)
227 {
228 gchar **actions_list = g_action_group_list_actions (group);
229 gint i;
230 for (i=0;actions_list[i] != NULL;i++) {
231 g_simple_action_set_enabled (G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (group), actions_list [i])), enabled);
232 }
233 g_strfreev (actions_list);
234 }
235
236 void
ui_common_add_action_group_to_map(GActionGroup * group,GActionMap * map)237 ui_common_add_action_group_to_map (GActionGroup *group, GActionMap *map)
238 {
239 gchar **actions_list = g_action_group_list_actions (group);
240 gint i;
241 for (i=0;actions_list[i] != NULL;i++) {
242 g_action_map_add_action (map, g_action_map_lookup_action (G_ACTION_MAP (group), actions_list [i]));
243 }
244 g_strfreev (actions_list);
245
246 }
247