1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /* caja-ui-utilities.c - helper functions for GtkUIManager stuff
4
5 Copyright (C) 2004 Red Hat, Inc.
6
7 The Mate Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 The Mate Library 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 GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public
18 License along with the Mate Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21
22 Authors: Alexander Larsson <alexl@redhat.com>
23 */
24
25 #include <config.h>
26
27 #include <gtk/gtk.h>
28 #include <gdk-pixbuf/gdk-pixbuf.h>
29 #include <gio/gio.h>
30
31 #include <eel/eel-debug.h>
32 #include <eel/eel-graphic-effects.h>
33
34 #include "caja-ui-utilities.h"
35 #include "caja-file-utilities.h"
36 #include "caja-icon-info.h"
37
38 void
caja_ui_unmerge_ui(GtkUIManager * ui_manager,guint * merge_id,GtkActionGroup ** action_group)39 caja_ui_unmerge_ui (GtkUIManager *ui_manager,
40 guint *merge_id,
41 GtkActionGroup **action_group)
42 {
43 if (*merge_id != 0)
44 {
45 gtk_ui_manager_remove_ui (ui_manager,
46 *merge_id);
47 *merge_id = 0;
48 }
49 if (*action_group != NULL)
50 {
51 gtk_ui_manager_remove_action_group (ui_manager,
52 *action_group);
53 *action_group = NULL;
54 }
55 }
56
57 void
caja_ui_prepare_merge_ui(GtkUIManager * ui_manager,const char * name,guint * merge_id,GtkActionGroup ** action_group)58 caja_ui_prepare_merge_ui (GtkUIManager *ui_manager,
59 const char *name,
60 guint *merge_id,
61 GtkActionGroup **action_group)
62 {
63 *merge_id = gtk_ui_manager_new_merge_id (ui_manager);
64 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
65 *action_group = gtk_action_group_new (name);
66 #ifdef ENABLE_NLS
67 gtk_action_group_set_translation_domain (*action_group, GETTEXT_PACKAGE);
68 #endif /* ENABLE_NLS */
69 G_GNUC_END_IGNORE_DEPRECATIONS;
70 gtk_ui_manager_insert_action_group (ui_manager, *action_group, 0);
71 g_object_unref (*action_group); /* owned by ui manager */
72 }
73
74
75 char *
caja_get_ui_directory(void)76 caja_get_ui_directory (void)
77 {
78 return g_strdup (DATADIR "/caja/ui");
79 }
80
81 char *
caja_ui_file(const char * partial_path)82 caja_ui_file (const char *partial_path)
83 {
84 char *path;
85
86 path = g_build_filename (DATADIR "/caja/ui", partial_path, NULL);
87 if (g_file_test (path, G_FILE_TEST_EXISTS))
88 {
89 return path;
90 }
91 g_free (path);
92 return NULL;
93 }
94
95 const char *
caja_ui_string_get(const char * filename)96 caja_ui_string_get (const char *filename)
97 {
98 static GHashTable *ui_cache = NULL;
99 char *ui;
100
101 if (ui_cache == NULL)
102 {
103 ui_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
104 eel_debug_call_at_shutdown_with_data ((GFreeFunc)g_hash_table_destroy, ui_cache);
105 }
106
107 ui = g_hash_table_lookup (ui_cache, filename);
108 if (ui == NULL)
109 {
110 char *path;
111
112 path = caja_ui_file (filename);
113 if (path == NULL || !g_file_get_contents (path, &ui, NULL, NULL))
114 {
115 g_warning ("Unable to load ui file %s\n", filename);
116 }
117 g_free (path);
118 g_hash_table_insert (ui_cache,
119 g_strdup (filename),
120 ui);
121 }
122
123 return ui;
124 }
125
126 static void
extension_action_callback(GtkAction * action,gpointer callback_data)127 extension_action_callback (GtkAction *action,
128 gpointer callback_data)
129 {
130 caja_menu_item_activate (CAJA_MENU_ITEM (callback_data));
131 }
132
133 static void
extension_action_sensitive_callback(CajaMenuItem * item,GParamSpec * arg1,gpointer user_data)134 extension_action_sensitive_callback (CajaMenuItem *item,
135 GParamSpec *arg1,
136 gpointer user_data)
137 {
138 gboolean value;
139
140 g_object_get (G_OBJECT (item),
141 "sensitive", &value,
142 NULL);
143
144 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
145 gtk_action_set_sensitive (GTK_ACTION (user_data), value);
146 G_GNUC_END_IGNORE_DEPRECATIONS;
147 }
148
149 static cairo_surface_t *
get_action_icon(const char * icon_name,int size,GtkWidget * parent_widget)150 get_action_icon (const char *icon_name,
151 int size,
152 GtkWidget *parent_widget)
153 {
154 CajaIconInfo *info;
155 cairo_surface_t *surface;
156 int scale;
157
158 scale = gtk_widget_get_scale_factor (parent_widget);
159
160 if (g_path_is_absolute (icon_name))
161 {
162 info = caja_icon_info_lookup_from_path (icon_name, size, scale);
163 }
164 else
165 {
166 info = caja_icon_info_lookup_from_name (icon_name, size, scale);
167 }
168 surface = caja_icon_info_get_surface_nodefault_at_size (info, size);
169 g_object_unref (info);
170
171 return surface;
172 }
173
174 GtkAction *
caja_action_from_menu_item(CajaMenuItem * item,GtkWidget * parent_widget)175 caja_action_from_menu_item (CajaMenuItem *item,
176 GtkWidget *parent_widget)
177 {
178 char *name, *label, *tip, *icon_name;
179 gboolean sensitive, priority;
180 GtkAction *action;
181
182 g_object_get (G_OBJECT (item),
183 "name", &name, "label", &label,
184 "tip", &tip, "icon", &icon_name,
185 "sensitive", &sensitive,
186 "priority", &priority,
187 NULL);
188
189 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
190 action = gtk_action_new (name,
191 label,
192 tip,
193 icon_name);
194 G_GNUC_END_IGNORE_DEPRECATIONS;
195
196 if (icon_name != NULL)
197 {
198 cairo_surface_t *surface;
199
200 surface = get_action_icon (icon_name,
201 caja_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU),
202 parent_widget);
203 if (surface != NULL)
204 {
205 g_object_set_data_full (G_OBJECT (action), "menu-icon",
206 surface,
207 (GDestroyNotify)cairo_surface_destroy);
208 }
209 }
210
211 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
212 gtk_action_set_sensitive (action, sensitive);
213 G_GNUC_END_IGNORE_DEPRECATIONS;
214 g_object_set (action, "is-important", priority, NULL);
215
216 g_signal_connect_data (action, "activate",
217 G_CALLBACK (extension_action_callback),
218 g_object_ref (item),
219 (GClosureNotify)g_object_unref, 0);
220
221 g_free (name);
222 g_free (label);
223 g_free (tip);
224 g_free (icon_name);
225
226 return action;
227 }
228
229 GtkAction *
caja_toolbar_action_from_menu_item(CajaMenuItem * item,GtkWidget * parent_widget)230 caja_toolbar_action_from_menu_item (CajaMenuItem *item, GtkWidget *parent_widget)
231 {
232 char *name, *label, *tip, *icon_name;
233 gboolean sensitive, priority;
234 GtkAction *action;
235
236 g_object_get (G_OBJECT (item),
237 "name", &name, "label", &label,
238 "tip", &tip, "icon", &icon_name,
239 "sensitive", &sensitive,
240 "priority", &priority,
241 NULL);
242
243 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
244 action = gtk_action_new (name,
245 label,
246 tip,
247 icon_name);
248 G_GNUC_END_IGNORE_DEPRECATIONS;
249
250 if (icon_name != NULL)
251 {
252 cairo_surface_t *surface;
253
254 surface = get_action_icon (icon_name,
255 caja_get_icon_size_for_stock_size (GTK_ICON_SIZE_LARGE_TOOLBAR),
256 parent_widget);
257 if (surface != NULL)
258 {
259 g_object_set_data_full (G_OBJECT (action), "toolbar-icon",
260 surface,
261 (GDestroyNotify)cairo_surface_destroy);
262 }
263 }
264
265 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
266 gtk_action_set_sensitive (action, sensitive);
267 G_GNUC_END_IGNORE_DEPRECATIONS;
268 g_object_set (action, "is-important", priority, NULL);
269
270 g_signal_connect_data (action, "activate",
271 G_CALLBACK (extension_action_callback),
272 g_object_ref (item),
273 (GClosureNotify)g_object_unref, 0);
274
275 g_signal_connect_object (item, "notify::sensitive",
276 G_CALLBACK (extension_action_sensitive_callback),
277 action,
278 0);
279
280 g_free (name);
281 g_free (label);
282 g_free (tip);
283 g_free (icon_name);
284
285 return action;
286 }
287
288 static GdkPixbuf *
caja_get_thumbnail_frame(void)289 caja_get_thumbnail_frame (void)
290 {
291 static GdkPixbuf *thumbnail_frame = NULL;
292
293 if (thumbnail_frame == NULL)
294 {
295 char *image_path;
296
297 image_path = caja_pixmap_file ("thumbnail_frame.png");
298 if (image_path != NULL)
299 {
300 thumbnail_frame = gdk_pixbuf_new_from_file (image_path, NULL);
301 }
302 g_free (image_path);
303 }
304
305 return thumbnail_frame;
306 }
307
308 #define CAJA_THUMBNAIL_FRAME_LEFT 3
309 #define CAJA_THUMBNAIL_FRAME_TOP 3
310 #define CAJA_THUMBNAIL_FRAME_RIGHT 3
311 #define CAJA_THUMBNAIL_FRAME_BOTTOM 3
312
313 void
caja_ui_frame_image(GdkPixbuf ** pixbuf)314 caja_ui_frame_image (GdkPixbuf **pixbuf)
315 {
316 GdkPixbuf *pixbuf_with_frame, *frame;
317 int left_offset, top_offset, right_offset, bottom_offset;
318
319 frame = caja_get_thumbnail_frame ();
320 if (frame == NULL) {
321 return;
322 }
323
324 left_offset = CAJA_THUMBNAIL_FRAME_LEFT;
325 top_offset = CAJA_THUMBNAIL_FRAME_TOP;
326 right_offset = CAJA_THUMBNAIL_FRAME_RIGHT;
327 bottom_offset = CAJA_THUMBNAIL_FRAME_BOTTOM;
328
329 pixbuf_with_frame = eel_embed_image_in_frame
330 (*pixbuf, frame,
331 left_offset, top_offset, right_offset, bottom_offset);
332 g_object_unref (*pixbuf);
333
334 *pixbuf = pixbuf_with_frame;
335 }
336