1 | /* |
---|
2 | * This program is free software; you can redistribute it and/or modify |
---|
3 | * it under the terms of the GNU General Public License as published by |
---|
4 | * the Free Software Foundation; either version 2 of the License, or |
---|
5 | * (at your option) any later version. |
---|
6 | * |
---|
7 | * This program is distributed in the hope that it will be useful, |
---|
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
10 | * GNU General Public License for more details. |
---|
11 | * |
---|
12 | * You should have received a copy of the GNU General Public License |
---|
13 | * along with this program; if not, write to the Free Software |
---|
14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
15 | */ |
---|
16 | |
---|
17 | #ifdef HAVE_CONFIG_H |
---|
18 | #include <config.h> |
---|
19 | #endif |
---|
20 | |
---|
21 | #include <stdio.h> |
---|
22 | #include <glib.h> |
---|
23 | #include <gtk/gtk.h> |
---|
24 | #include <libgnome/libgnome.h> |
---|
25 | #include <libgnomeui/libgnomeui.h> |
---|
26 | #include <panel-applet.h> |
---|
27 | |
---|
28 | #include "drivemount.h" |
---|
29 | #include "properties.h" |
---|
30 | |
---|
31 | #include "floppy_v_in.xpm" |
---|
32 | #include "floppy_v_out.xpm" |
---|
33 | #include "floppy_h_in.xpm" |
---|
34 | #include "floppy_h_out.xpm" |
---|
35 | |
---|
36 | #include "cdrom_v_in.xpm" |
---|
37 | #include "cdrom_v_out.xpm" |
---|
38 | #include "cdrom_h_in.xpm" |
---|
39 | #include "cdrom_h_out.xpm" |
---|
40 | |
---|
41 | #include "cdburn_v_in.xpm" |
---|
42 | #include "cdburn_v_out.xpm" |
---|
43 | #include "cdburn_h_in.xpm" |
---|
44 | #include "cdburn_h_out.xpm" |
---|
45 | |
---|
46 | #include "zipdrive_v_in.xpm" |
---|
47 | #include "zipdrive_v_out.xpm" |
---|
48 | #include "zipdrive_h_in.xpm" |
---|
49 | #include "zipdrive_h_out.xpm" |
---|
50 | |
---|
51 | #include "harddisk_v_in.xpm" |
---|
52 | #include "harddisk_v_out.xpm" |
---|
53 | #include "harddisk_h_in.xpm" |
---|
54 | #include "harddisk_h_out.xpm" |
---|
55 | |
---|
56 | #include "jazdrive_h_in.xpm" |
---|
57 | #include "jazdrive_h_out.xpm" |
---|
58 | #include "jazdrive_v_in.xpm" |
---|
59 | #include "jazdrive_v_out.xpm" |
---|
60 | |
---|
61 | #include "usbstick_v_in.xpm" |
---|
62 | #include "usbstick_v_out.xpm" |
---|
63 | #include "usbstick_h_in.xpm" |
---|
64 | #include "usbstick_h_out.xpm" |
---|
65 | |
---|
66 | |
---|
67 | static gboolean applet_factory (PanelApplet *applet, const gchar *iid, |
---|
68 | gpointer data); |
---|
69 | static gboolean applet_fill (PanelApplet *applet); |
---|
70 | static DriveData *create_drive_widget (PanelApplet *applet); |
---|
71 | static void dnd_init (DriveData *dd); |
---|
72 | static void dnd_drag_begin_cb (GtkWidget *widget, GdkDragContext *context, |
---|
73 | gpointer data); |
---|
74 | static void dnd_set_data_cb (GtkWidget *widget, GdkDragContext *context, |
---|
75 | GtkSelectionData *selection_data, guint info, |
---|
76 | guint time, gpointer data); |
---|
77 | static void applet_change_orient (GtkWidget *w, PanelAppletOrient o, |
---|
78 | gpointer data); |
---|
79 | static void applet_change_pixel_size (GtkWidget *w, int size, gpointer data); |
---|
80 | static gboolean button_press_hack (GtkWidget *widget, |
---|
81 | GdkEventButton *event, |
---|
82 | GtkWidget *applet); |
---|
83 | static void destroy_drive_widget (GtkWidget *widget, gpointer data); |
---|
84 | static gint device_is_in_mountlist (DriveData *dd); |
---|
85 | static gint get_device (const gchar *file); |
---|
86 | static gint device_is_mounted (DriveData *dd); |
---|
87 | static void update_pixmap (DriveData *dd, gint t); |
---|
88 | static gint drive_update_cb (gpointer data); |
---|
89 | static void mount_cb (GtkWidget *widget, DriveData *dd); |
---|
90 | static void eject (DriveData *dd); |
---|
91 | static gboolean key_press_cb (GtkWidget *widget, GdkEventKey *event, DriveData *dd); |
---|
92 | |
---|
93 | static void browse_cb (BonoboUIComponent *uic, |
---|
94 | DriveData *drivemount, |
---|
95 | const char *verb); |
---|
96 | static void eject_cb (BonoboUIComponent *uic, |
---|
97 | DriveData *drivemount, |
---|
98 | const char *verb); |
---|
99 | static void help_cb (BonoboUIComponent *uic, |
---|
100 | DriveData *drivemount, |
---|
101 | const char *verb); |
---|
102 | static void about_cb (BonoboUIComponent *uic, |
---|
103 | DriveData *drivemount, |
---|
104 | const char *verb); |
---|
105 | |
---|
106 | /* |
---|
107 | *------------------------------------------------------------------------- |
---|
108 | *icon struct |
---|
109 | *------------------------------------------------------------------------- |
---|
110 | */ |
---|
111 | |
---|
112 | typedef struct _IconData IconData; |
---|
113 | struct _IconData { |
---|
114 | char **pmap_h_in; |
---|
115 | char **pmap_h_out; |
---|
116 | char **pmap_v_in; |
---|
117 | char **pmap_v_out; |
---|
118 | }; |
---|
119 | |
---|
120 | static IconData icon_list[] = { |
---|
121 | { |
---|
122 | floppy_h_in_xpm, |
---|
123 | floppy_h_out_xpm, |
---|
124 | floppy_v_in_xpm, |
---|
125 | floppy_v_out_xpm}, |
---|
126 | { |
---|
127 | cdrom_h_in_xpm, |
---|
128 | cdrom_h_out_xpm, |
---|
129 | cdrom_v_in_xpm, |
---|
130 | cdrom_v_out_xpm}, |
---|
131 | { |
---|
132 | cdburn_h_in_xpm, |
---|
133 | cdburn_h_out_xpm, |
---|
134 | cdburn_v_in_xpm, |
---|
135 | cdburn_v_out_xpm}, |
---|
136 | { |
---|
137 | zipdrive_h_in_xpm, |
---|
138 | zipdrive_h_out_xpm, |
---|
139 | zipdrive_v_in_xpm, |
---|
140 | zipdrive_v_out_xpm}, |
---|
141 | { |
---|
142 | harddisk_h_in_xpm, |
---|
143 | harddisk_h_out_xpm, |
---|
144 | harddisk_v_in_xpm, |
---|
145 | harddisk_v_out_xpm}, |
---|
146 | { |
---|
147 | jazdrive_h_in_xpm, |
---|
148 | jazdrive_h_out_xpm, |
---|
149 | jazdrive_v_in_xpm, |
---|
150 | jazdrive_v_out_xpm}, |
---|
151 | { |
---|
152 | usbstick_h_in_xpm, |
---|
153 | usbstick_h_out_xpm, |
---|
154 | usbstick_v_in_xpm, |
---|
155 | usbstick_v_out_xpm}, |
---|
156 | { |
---|
157 | NULL, |
---|
158 | NULL, |
---|
159 | NULL, |
---|
160 | NULL} |
---|
161 | }; |
---|
162 | |
---|
163 | const int icon_list_count = 7; |
---|
164 | |
---|
165 | /* Bonobo Verbs for our popup menu */ |
---|
166 | static const BonoboUIVerb applet_menu_verbs [] = { |
---|
167 | BONOBO_UI_UNSAFE_VERB ("Browse", browse_cb), |
---|
168 | BONOBO_UI_UNSAFE_VERB ("Eject", eject_cb), |
---|
169 | BONOBO_UI_UNSAFE_VERB ("Properties", properties_show), |
---|
170 | BONOBO_UI_UNSAFE_VERB ("Help", help_cb), |
---|
171 | BONOBO_UI_UNSAFE_VERB ("About", about_cb), |
---|
172 | BONOBO_UI_VERB_END |
---|
173 | }; |
---|
174 | |
---|
175 | enum { |
---|
176 | TARGET_URI_LIST, |
---|
177 | TARGET_TEXT_PLAIN |
---|
178 | }; |
---|
179 | |
---|
180 | static GtkTargetEntry button_drag_types[] = { |
---|
181 | {"text/uri-list", 0, TARGET_URI_LIST}, |
---|
182 | {"text/plain", 0, TARGET_TEXT_PLAIN} |
---|
183 | }; |
---|
184 | static gint n_button_drag_types = 2; |
---|
185 | |
---|
186 | |
---|
187 | PANEL_APPLET_BONOBO_FACTORY ("OAFIID:GNOME_DriveMountApplet_Factory", PANEL_TYPE_APPLET, |
---|
188 | "Drive-Mount-Applet", "0", applet_factory, NULL) |
---|
189 | |
---|
190 | static gboolean |
---|
191 | applet_factory (PanelApplet *applet, |
---|
192 | const gchar *iid, gpointer data) |
---|
193 | { |
---|
194 | gboolean retval = FALSE; |
---|
195 | |
---|
196 | if (!strcmp (iid, "OAFIID:GNOME_DriveMountApplet")) { |
---|
197 | retval = applet_fill (applet); |
---|
198 | } |
---|
199 | return retval; |
---|
200 | } |
---|
201 | |
---|
202 | static gboolean |
---|
203 | applet_fill (PanelApplet *applet) |
---|
204 | { |
---|
205 | DriveData *dd; |
---|
206 | BonoboUIComponent *component; |
---|
207 | gchar *tmp_path; |
---|
208 | AtkObject *atk_obj; |
---|
209 | |
---|
210 | gnome_window_icon_set_default_from_file (GNOME_ICONDIR"/drivemount-applet.png"); |
---|
211 | panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR); |
---|
212 | |
---|
213 | panel_applet_add_preferences (applet, |
---|
214 | "/schemas/apps/drivemount-applet/prefs", |
---|
215 | NULL); |
---|
216 | dd = create_drive_widget (applet); |
---|
217 | |
---|
218 | gtk_container_add (GTK_CONTAINER (applet), dd->button); |
---|
219 | |
---|
220 | dd->applet = GTK_WIDGET (applet); |
---|
221 | dd->tooltips = gtk_tooltips_new (); |
---|
222 | dd->orient = panel_applet_get_orient (PANEL_APPLET (applet)); |
---|
223 | dd->sizehint = panel_applet_get_size (PANEL_APPLET (applet)); |
---|
224 | g_signal_connect (G_OBJECT (dd->button), "button_press_event", |
---|
225 | G_CALLBACK (button_press_hack), applet); |
---|
226 | |
---|
227 | g_signal_connect (G_OBJECT (applet), "change_orient", |
---|
228 | G_CALLBACK (applet_change_orient), dd); |
---|
229 | g_signal_connect (G_OBJECT (applet), "change_size", |
---|
230 | G_CALLBACK (applet_change_pixel_size), dd); |
---|
231 | g_signal_connect (GTK_OBJECT (applet), "destroy", |
---|
232 | G_CALLBACK (destroy_drive_widget), dd); |
---|
233 | |
---|
234 | g_signal_connect (applet, "key_press_event", |
---|
235 | G_CALLBACK (key_press_cb), dd); |
---|
236 | |
---|
237 | panel_applet_setup_menu_from_file (PANEL_APPLET (applet), |
---|
238 | NULL, |
---|
239 | "GNOME_DriveMountApplet.xml", |
---|
240 | NULL, |
---|
241 | applet_menu_verbs, |
---|
242 | dd); |
---|
243 | |
---|
244 | if (panel_applet_get_locked_down (PANEL_APPLET (applet))) { |
---|
245 | BonoboUIComponent *popup_component; |
---|
246 | |
---|
247 | popup_component = panel_applet_get_popup_component (PANEL_APPLET (applet)); |
---|
248 | |
---|
249 | bonobo_ui_component_set_prop (popup_component, |
---|
250 | "/commands/Properties", |
---|
251 | "hidden", "1", |
---|
252 | NULL); |
---|
253 | } |
---|
254 | |
---|
255 | component = panel_applet_get_popup_component (PANEL_APPLET (applet)); |
---|
256 | |
---|
257 | tmp_path = gnome_is_program_in_path ("eject"); |
---|
258 | if (!tmp_path) |
---|
259 | bonobo_ui_component_set_prop (component, "/commands/Eject", |
---|
260 | "hidden", "1", NULL); |
---|
261 | else |
---|
262 | g_free (tmp_path); |
---|
263 | |
---|
264 | redraw_pixmap (dd); |
---|
265 | |
---|
266 | atk_obj = gtk_widget_get_accessible (dd->button); |
---|
267 | atk_object_set_name (atk_obj, _("Disk Mounter")); |
---|
268 | |
---|
269 | gtk_widget_show (GTK_WIDGET (applet)); |
---|
270 | start_callback_update (dd); |
---|
271 | return TRUE; |
---|
272 | } |
---|
273 | |
---|
274 | static DriveData * |
---|
275 | create_drive_widget (PanelApplet *applet) |
---|
276 | { |
---|
277 | DriveData *dd; |
---|
278 | |
---|
279 | dd = g_new0 (DriveData, 1); |
---|
280 | dd->applet = GTK_WIDGET (applet); |
---|
281 | |
---|
282 | dd->about_dialog = NULL; |
---|
283 | dd->prop_dialog = NULL; |
---|
284 | |
---|
285 | properties_load (dd); |
---|
286 | |
---|
287 | dd->button = gtk_button_new (); |
---|
288 | gtk_widget_show (dd->button); |
---|
289 | g_signal_connect (G_OBJECT (dd->button), "clicked", |
---|
290 | G_CALLBACK (mount_cb), dd); |
---|
291 | dnd_init (dd); |
---|
292 | return dd; |
---|
293 | } |
---|
294 | |
---|
295 | /* This is a hack around the fact that gtk+ doesn't |
---|
296 | * propogate button presses on button2/3. |
---|
297 | */ |
---|
298 | static gboolean |
---|
299 | button_press_hack (GtkWidget *widget, |
---|
300 | GdkEventButton *event, |
---|
301 | GtkWidget *applet) |
---|
302 | { |
---|
303 | if (event->button == 3 || event->button == 2) { |
---|
304 | gtk_propagate_event (applet, (GdkEvent *) event); |
---|
305 | |
---|
306 | return TRUE; |
---|
307 | } |
---|
308 | |
---|
309 | return FALSE; |
---|
310 | } |
---|
311 | |
---|
312 | static void |
---|
313 | dnd_init (DriveData *dd) |
---|
314 | { |
---|
315 | gtk_drag_source_set (dd->button, GDK_BUTTON1_MASK, |
---|
316 | button_drag_types, n_button_drag_types, |
---|
317 | GDK_ACTION_COPY | GDK_ACTION_LINK | |
---|
318 | GDK_ACTION_ASK); |
---|
319 | g_signal_connect (G_OBJECT (dd->button), "drag_data_get", |
---|
320 | G_CALLBACK (dnd_set_data_cb), dd); |
---|
321 | g_signal_connect (G_OBJECT (dd->button), "drag_begin", |
---|
322 | G_CALLBACK (dnd_drag_begin_cb), dd); |
---|
323 | } |
---|
324 | |
---|
325 | static void |
---|
326 | dnd_drag_begin_cb (GtkWidget *widget, GdkDragContext *context, gpointer data) |
---|
327 | { |
---|
328 | DriveData *dd = data; |
---|
329 | |
---|
330 | gtk_drag_set_icon_pixbuf (context, |
---|
331 | gtk_image_get_pixbuf (GTK_IMAGE |
---|
332 | (dd->button_pixmap)), |
---|
333 | -5, -5); |
---|
334 | } |
---|
335 | |
---|
336 | static void |
---|
337 | dnd_set_data_cb (GtkWidget *widget, GdkDragContext *context, |
---|
338 | GtkSelectionData *selection_data, guint info, |
---|
339 | guint time, gpointer data) |
---|
340 | { |
---|
341 | DriveData *dd = data; |
---|
342 | |
---|
343 | if (dd && dd->mount_point) { |
---|
344 | gchar *text = NULL; |
---|
345 | |
---|
346 | switch (info) { |
---|
347 | case TARGET_URI_LIST: |
---|
348 | text = g_strconcat ("file:", dd->mount_point, "\r\n", |
---|
349 | NULL); |
---|
350 | break; |
---|
351 | case TARGET_TEXT_PLAIN: |
---|
352 | text = g_strdup (dd->mount_point); |
---|
353 | break; |
---|
354 | } |
---|
355 | gtk_selection_data_set (selection_data, selection_data->target, |
---|
356 | 8, text, strlen (text)); |
---|
357 | g_free (text); |
---|
358 | } else { |
---|
359 | gtk_selection_data_set (selection_data, selection_data->target, |
---|
360 | 8, NULL, 0); |
---|
361 | } |
---|
362 | } |
---|
363 | |
---|
364 | void |
---|
365 | start_callback_update (DriveData *dd) |
---|
366 | { |
---|
367 | gint delay; |
---|
368 | |
---|
369 | delay = dd->interval *1000; |
---|
370 | if (dd->timeout_id) |
---|
371 | gtk_timeout_remove (dd->timeout_id); |
---|
372 | dd->timeout_id = |
---|
373 | gtk_timeout_add (delay, (GtkFunction) drive_update_cb, dd); |
---|
374 | } |
---|
375 | |
---|
376 | static void |
---|
377 | applet_change_orient (GtkWidget *w, PanelAppletOrient o, gpointer data) |
---|
378 | { |
---|
379 | /* resize the applet and set the proper pixmaps */ |
---|
380 | DriveData *dd = data; |
---|
381 | |
---|
382 | if (dd->orient == o) |
---|
383 | return; |
---|
384 | |
---|
385 | dd->orient = o; |
---|
386 | |
---|
387 | redraw_pixmap (dd); |
---|
388 | } |
---|
389 | |
---|
390 | static void |
---|
391 | applet_change_pixel_size (GtkWidget *w, int size, gpointer data) |
---|
392 | { |
---|
393 | DriveData *dd = data; |
---|
394 | |
---|
395 | if (dd->sizehint != size) { |
---|
396 | dd->sizehint = size; |
---|
397 | redraw_pixmap (dd); |
---|
398 | } |
---|
399 | } |
---|
400 | |
---|
401 | static void |
---|
402 | destroy_drive_widget (GtkWidget *widget, gpointer data) |
---|
403 | { |
---|
404 | DriveData *dd = data; |
---|
405 | |
---|
406 | gtk_timeout_remove (dd->timeout_id); |
---|
407 | |
---|
408 | if (dd->error_dialog != NULL) |
---|
409 | gtk_widget_destroy (dd->error_dialog); |
---|
410 | |
---|
411 | if (dd->about_dialog != NULL) |
---|
412 | gtk_widget_destroy (dd->about_dialog); |
---|
413 | |
---|
414 | if (dd->prop_dialog != NULL) |
---|
415 | gtk_widget_destroy (dd->prop_dialog); |
---|
416 | |
---|
417 | g_free (dd->custom_icon_in); |
---|
418 | g_free (dd->custom_icon_out); |
---|
419 | |
---|
420 | g_free (dd->mount_point); |
---|
421 | g_free (dd->mount_base); |
---|
422 | g_free (dd); |
---|
423 | } |
---|
424 | |
---|
425 | static void |
---|
426 | browse_cb (BonoboUIComponent *uic, |
---|
427 | DriveData *drivemount, |
---|
428 | const char *verb) |
---|
429 | { |
---|
430 | GError *error = NULL; |
---|
431 | char *command; |
---|
432 | |
---|
433 | if (!drivemount->mounted) |
---|
434 | mount_cb (NULL, drivemount); |
---|
435 | |
---|
436 | if (!drivemount->mounted) |
---|
437 | return; |
---|
438 | |
---|
439 | command = g_strdup_printf ("nautilus %s", drivemount->mount_point); |
---|
440 | |
---|
441 | gdk_spawn_command_line_on_screen (gtk_widget_get_screen (GTK_WIDGET (drivemount->applet)), |
---|
442 | command, &error); |
---|
443 | |
---|
444 | g_free (command); |
---|
445 | |
---|
446 | if (error) { |
---|
447 | GtkWidget *dialog; |
---|
448 | char *msg; |
---|
449 | |
---|
450 | msg = g_strdup_printf (_("There was an error executing %s: %s"), |
---|
451 | command, |
---|
452 | error->message); |
---|
453 | dialog = hig_dialog_new (NULL /* parent */, |
---|
454 | 0 /* flags */, |
---|
455 | GTK_MESSAGE_ERROR, |
---|
456 | GTK_BUTTONS_OK, |
---|
457 | _("Cannot browse device"), |
---|
458 | msg); |
---|
459 | g_free (msg); |
---|
460 | |
---|
461 | g_signal_connect (dialog, "response", |
---|
462 | G_CALLBACK (gtk_widget_destroy), |
---|
463 | NULL); |
---|
464 | |
---|
465 | gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); |
---|
466 | gtk_window_set_screen (GTK_WINDOW (dialog), |
---|
467 | gtk_widget_get_screen (drivemount->applet)); |
---|
468 | |
---|
469 | gtk_widget_show (dialog); |
---|
470 | |
---|
471 | g_error_free (error); |
---|
472 | } |
---|
473 | } |
---|
474 | |
---|
475 | static void |
---|
476 | eject_cb (BonoboUIComponent *uic, |
---|
477 | DriveData *drivemount, |
---|
478 | const char *verb) |
---|
479 | { |
---|
480 | eject (drivemount); |
---|
481 | } |
---|
482 | |
---|
483 | static void |
---|
484 | help_cb (BonoboUIComponent *uic, |
---|
485 | DriveData *drivemount, |
---|
486 | const char *verb) |
---|
487 | |
---|
488 | { |
---|
489 | GError *error = NULL; |
---|
490 | static GnomeProgram *applet_program = NULL; |
---|
491 | |
---|
492 | if (!applet_program) { |
---|
493 | int argc = 1; |
---|
494 | char *argv[2] = { "drivemount" }; |
---|
495 | applet_program = gnome_program_init ("drivemount", VERSION, |
---|
496 | LIBGNOME_MODULE, argc, argv, |
---|
497 | GNOME_PROGRAM_STANDARD_PROPERTIES, NULL); |
---|
498 | } |
---|
499 | |
---|
500 | gnome_help_display_desktop_on_screen ( |
---|
501 | applet_program, "drivemount", "drivemount", NULL, |
---|
502 | gtk_widget_get_screen (GTK_WIDGET (drivemount->applet)), |
---|
503 | &error); |
---|
504 | |
---|
505 | if (error) { |
---|
506 | GtkWidget *error_dialog; |
---|
507 | char *msg; |
---|
508 | |
---|
509 | msg = g_strdup_printf (_("There was an error displaying help: %s"), |
---|
510 | error->message); |
---|
511 | error_dialog = hig_dialog_new (NULL /* parent */, |
---|
512 | 0 /* flags */, |
---|
513 | GTK_MESSAGE_ERROR, |
---|
514 | GTK_BUTTONS_OK, |
---|
515 | _("Error displaying help"), |
---|
516 | msg); |
---|
517 | g_free (msg); |
---|
518 | |
---|
519 | g_signal_connect (error_dialog, "response", |
---|
520 | G_CALLBACK (gtk_widget_destroy), |
---|
521 | NULL); |
---|
522 | |
---|
523 | gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE); |
---|
524 | gtk_window_set_screen (GTK_WINDOW (error_dialog), |
---|
525 | gtk_widget_get_screen (GTK_WIDGET (uic))); |
---|
526 | gtk_widget_show (error_dialog); |
---|
527 | g_error_free (error); |
---|
528 | } |
---|
529 | } |
---|
530 | |
---|
531 | static void |
---|
532 | about_cb (BonoboUIComponent *uic, |
---|
533 | DriveData *drivemount, |
---|
534 | const char *verb) |
---|
535 | { |
---|
536 | GdkPixbuf *pixbuf; |
---|
537 | GError *error = NULL; |
---|
538 | gchar *file; |
---|
539 | |
---|
540 | static const gchar *authors[] = { |
---|
541 | "John Ellis <johne@bellatlantic.net>", |
---|
542 | "Chris Phelps <chicane@renient.com>", |
---|
543 | NULL |
---|
544 | }; |
---|
545 | |
---|
546 | const gchar *documenters[] = { |
---|
547 | "Dan Mueth <muet@alumni.uchicago.edu>", |
---|
548 | "John Fleck <jfleck@inkstain.net>", |
---|
549 | NULL |
---|
550 | }; |
---|
551 | |
---|
552 | const gchar *translator_credits = _("translator_credits"); |
---|
553 | |
---|
554 | if (drivemount->about_dialog) { |
---|
555 | gtk_window_set_screen (GTK_WINDOW (drivemount->about_dialog), |
---|
556 | gtk_widget_get_screen (GTK_WIDGET (drivemount->applet))); |
---|
557 | |
---|
558 | gtk_window_present (GTK_WINDOW (drivemount->about_dialog)); |
---|
559 | return; |
---|
560 | } |
---|
561 | |
---|
562 | file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP, "drivemount-applet.png", FALSE, NULL); |
---|
563 | pixbuf = gdk_pixbuf_new_from_file (file, &error); |
---|
564 | g_free (file); |
---|
565 | |
---|
566 | if (error) { |
---|
567 | g_warning (G_STRLOC ": cannot open %s: %s", file, error->message); |
---|
568 | g_error_free (error); |
---|
569 | } |
---|
570 | |
---|
571 | drivemount->about_dialog = gnome_about_new (_("Disk Mounter"), VERSION, |
---|
572 | _("(C) 1999-2001 The GNOME Hackers\n"), |
---|
573 | _ |
---|
574 | ("Applet for mounting and unmounting block volumes."), |
---|
575 | authors, |
---|
576 | documenters, |
---|
577 | strcmp (translator_credits, "translator_credits") != 0 ? translator_credits : NULL, |
---|
578 | pixbuf); |
---|
579 | if (pixbuf) |
---|
580 | gdk_pixbuf_unref (pixbuf); |
---|
581 | |
---|
582 | gtk_window_set_wmclass (GTK_WINDOW (drivemount->about_dialog), "disk mounter", "Disk Mounter"); |
---|
583 | gtk_window_set_screen (GTK_WINDOW (drivemount->about_dialog), |
---|
584 | gtk_widget_get_screen (drivemount->applet)); |
---|
585 | |
---|
586 | g_signal_connect (G_OBJECT (drivemount->about_dialog), "destroy", |
---|
587 | G_CALLBACK (gtk_widget_destroyed), &drivemount->about_dialog); |
---|
588 | |
---|
589 | gtk_widget_show (drivemount->about_dialog); |
---|
590 | } |
---|
591 | |
---|
592 | /* |
---|
593 | *------------------------------------------------------------------------- |
---|
594 | *mount status checks |
---|
595 | *------------------------------------------------------------------------- |
---|
596 | */ |
---|
597 | |
---|
598 | static gint |
---|
599 | device_is_in_mountlist (DriveData *dd) |
---|
600 | { |
---|
601 | FILE *fp; |
---|
602 | gchar *command_line = "mount"; |
---|
603 | gchar buf[256]; |
---|
604 | gint found = FALSE; |
---|
605 | |
---|
606 | if (!dd->mount_point) |
---|
607 | return FALSE; |
---|
608 | |
---|
609 | fp = popen (command_line, "r"); |
---|
610 | if (!fp) { |
---|
611 | g_print ("unable to run command: %s\n", command_line); |
---|
612 | return FALSE; |
---|
613 | } |
---|
614 | while (fgets (buf, sizeof (buf), fp)) { |
---|
615 | gchar *ptr; |
---|
616 | ptr = strstr (buf, dd->mount_point); |
---|
617 | if (ptr != NULL) { |
---|
618 | gchar *p; |
---|
619 | p = ptr + strlen (dd->mount_point); |
---|
620 | if (*p == ' ' || *p == '\0' || *p == '\n') { |
---|
621 | found = TRUE; |
---|
622 | break; |
---|
623 | } |
---|
624 | } |
---|
625 | } |
---|
626 | pclose (fp); |
---|
627 | return found; |
---|
628 | } |
---|
629 | |
---|
630 | static gint |
---|
631 | get_device (const gchar *file) |
---|
632 | { |
---|
633 | struct stat file_info; |
---|
634 | gint t; |
---|
635 | |
---|
636 | if (stat (file, &file_info) == -1) |
---|
637 | t = -1; |
---|
638 | else |
---|
639 | t = (gint) file_info.st_dev; |
---|
640 | return t; |
---|
641 | } |
---|
642 | |
---|
643 | static gint |
---|
644 | device_is_mounted (DriveData *dd) |
---|
645 | { |
---|
646 | if (!dd->mount_point || !dd->mount_base) |
---|
647 | return FALSE; |
---|
648 | |
---|
649 | if (!dd->autofs_friendly) { |
---|
650 | gint b, p; |
---|
651 | |
---|
652 | b = get_device (dd->mount_base); |
---|
653 | p = get_device (dd->mount_point); |
---|
654 | if (b == p || p == -1 || b == -1) |
---|
655 | return FALSE; |
---|
656 | else |
---|
657 | return TRUE; |
---|
658 | } else { |
---|
659 | if (device_is_in_mountlist (dd)) |
---|
660 | return TRUE; |
---|
661 | else |
---|
662 | return FALSE; |
---|
663 | } |
---|
664 | } |
---|
665 | |
---|
666 | /* |
---|
667 | *------------------------------------------------------------------------- |
---|
668 | *image / widget setup and size changes |
---|
669 | *------------------------------------------------------------------------- |
---|
670 | */ |
---|
671 | |
---|
672 | static void |
---|
673 | update_pixmap (DriveData *dd, gint t) |
---|
674 | { |
---|
675 | GdkPixbuf *pixbuf; |
---|
676 | GdkPixbuf *scaled; |
---|
677 | char **pmap_d_in; |
---|
678 | char **pmap_d_out; |
---|
679 | gint pixmap; |
---|
680 | |
---|
681 | gint width; |
---|
682 | gint height; |
---|
683 | |
---|
684 | gchar *tiptext; |
---|
685 | gchar *text; |
---|
686 | |
---|
687 | gint hint = dd->sizehint; |
---|
688 | |
---|
689 | pixmap = dd->device_pixmap; |
---|
690 | if (dd->device_pixmap > icon_list_count - 1) |
---|
691 | pixmap = 0; |
---|
692 | if (dd->device_pixmap < 0 |
---|
693 | && (!dd->custom_icon_in || !dd->custom_icon_out)) |
---|
694 | pixmap = 0; |
---|
695 | |
---|
696 | if (!dd->button_pixmap) { |
---|
697 | dd->button_pixmap = gtk_image_new (); |
---|
698 | gtk_container_add (GTK_CONTAINER (dd->button), |
---|
699 | dd->button_pixmap); |
---|
700 | gtk_widget_show (dd->button_pixmap); |
---|
701 | } |
---|
702 | |
---|
703 | if (pixmap < 0) { |
---|
704 | if (t) { |
---|
705 | pixbuf = gdk_pixbuf_new_from_file (dd->custom_icon_in, |
---|
706 | NULL); |
---|
707 | } else { |
---|
708 | pixbuf = gdk_pixbuf_new_from_file (dd->custom_icon_out, |
---|
709 | NULL); |
---|
710 | } |
---|
711 | |
---|
712 | if (pixbuf) { |
---|
713 | width = gdk_pixbuf_get_width (pixbuf); |
---|
714 | height = gdk_pixbuf_get_height (pixbuf); |
---|
715 | |
---|
716 | if (dd->orient == PANEL_APPLET_ORIENT_LEFT |
---|
717 | || dd->orient == PANEL_APPLET_ORIENT_RIGHT) { |
---|
718 | if (width > hint || dd->scale_applet) { |
---|
719 | height = (float) height *hint / width; |
---|
720 | |
---|
721 | width = hint; |
---|
722 | } |
---|
723 | } else { |
---|
724 | if (height > hint || dd->scale_applet) { |
---|
725 | width = (float) width *hint / height; |
---|
726 | |
---|
727 | height = hint; |
---|
728 | } |
---|
729 | } |
---|
730 | scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, |
---|
731 | GDK_INTERP_BILINEAR); |
---|
732 | gtk_image_set_from_pixbuf (GTK_IMAGE |
---|
733 | (dd->button_pixmap), scaled); |
---|
734 | g_object_unref (G_OBJECT (pixbuf)); |
---|
735 | g_object_unref (scaled); |
---|
736 | } |
---|
737 | } else { |
---|
738 | if (dd->scale_applet) { |
---|
739 | width = hint; |
---|
740 | height = (float) hint / ICON_WIDTH *ICON_HEIGHT; |
---|
741 | } else { |
---|
742 | width = ICON_WIDTH; |
---|
743 | height = ICON_HEIGHT; |
---|
744 | } |
---|
745 | |
---|
746 | if ((dd->orient == PANEL_APPLET_ORIENT_LEFT |
---|
747 | || dd->orient == PANEL_APPLET_ORIENT_RIGHT) && hint > 36) { |
---|
748 | pmap_d_in = icon_list[pixmap].pmap_h_in; |
---|
749 | pmap_d_out = icon_list[pixmap].pmap_h_out; |
---|
750 | } else if ((dd->orient == PANEL_APPLET_ORIENT_UP |
---|
751 | || dd->orient == PANEL_APPLET_ORIENT_DOWN) && hint <= 36) { |
---|
752 | pmap_d_in = icon_list[pixmap].pmap_h_in; |
---|
753 | pmap_d_out = icon_list[pixmap].pmap_h_out; |
---|
754 | } else { |
---|
755 | gint tmp; |
---|
756 | |
---|
757 | tmp = width; |
---|
758 | width = height; |
---|
759 | height = tmp; |
---|
760 | |
---|
761 | pmap_d_in = icon_list[pixmap].pmap_v_in; |
---|
762 | pmap_d_out = icon_list[pixmap].pmap_v_out; |
---|
763 | } |
---|
764 | |
---|
765 | if (t) |
---|
766 | pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) |
---|
767 | pmap_d_in); |
---|
768 | else |
---|
769 | pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) |
---|
770 | pmap_d_out); |
---|
771 | scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, |
---|
772 | GDK_INTERP_BILINEAR); |
---|
773 | gtk_image_set_from_pixbuf (GTK_IMAGE (dd->button_pixmap), |
---|
774 | scaled); |
---|
775 | g_object_unref (G_OBJECT (pixbuf)); |
---|
776 | g_object_unref (scaled); |
---|
777 | } |
---|
778 | |
---|
779 | if (t) { |
---|
780 | text = _(" mounted"); |
---|
781 | } else { |
---|
782 | text = _(" not mounted"); |
---|
783 | } |
---|
784 | tiptext = g_strconcat (dd->mount_point, text, NULL); |
---|
785 | gtk_tooltips_set_tip (dd->tooltips, dd->button, tiptext, NULL); |
---|
786 | g_free (tiptext); |
---|
787 | } |
---|
788 | |
---|
789 | void |
---|
790 | redraw_pixmap (DriveData *dd) |
---|
791 | { |
---|
792 | if (!device_is_mounted (dd)) { |
---|
793 | update_pixmap (dd, FALSE); |
---|
794 | dd->mounted = FALSE; |
---|
795 | } else { |
---|
796 | update_pixmap (dd, TRUE); |
---|
797 | dd->mounted = TRUE; |
---|
798 | } |
---|
799 | } |
---|
800 | |
---|
801 | /* |
---|
802 | *------------------------------------------------------------------------- |
---|
803 | *main callback loop |
---|
804 | *------------------------------------------------------------------------- |
---|
805 | */ |
---|
806 | |
---|
807 | static gint |
---|
808 | drive_update_cb (gpointer data) |
---|
809 | { |
---|
810 | DriveData *dd = data; |
---|
811 | |
---|
812 | if (!device_is_mounted (dd)) { |
---|
813 | /* device not mounted */ |
---|
814 | if (dd->mounted) { |
---|
815 | update_pixmap (dd, FALSE); |
---|
816 | dd->mounted = FALSE; |
---|
817 | } |
---|
818 | } else { |
---|
819 | /* device mounted */ |
---|
820 | if (!dd->mounted) { |
---|
821 | update_pixmap (dd, TRUE); |
---|
822 | dd->mounted = TRUE; |
---|
823 | } |
---|
824 | } |
---|
825 | return TRUE; |
---|
826 | } |
---|
827 | |
---|
828 | /* |
---|
829 | *------------------------------------------------------------------------- |
---|
830 | *mount calls |
---|
831 | *------------------------------------------------------------------------- |
---|
832 | */ |
---|
833 | |
---|
834 | static void |
---|
835 | mount_cb (GtkWidget *widget, |
---|
836 | DriveData *dd) |
---|
837 | { |
---|
838 | gchar *command_line; |
---|
839 | gchar buf[512]; |
---|
840 | FILE *fp; |
---|
841 | GString *str; |
---|
842 | gint check = device_is_mounted (dd); |
---|
843 | |
---|
844 | /* Stop the user from displaying zillions of error messages */ |
---|
845 | if (dd->error_dialog) { |
---|
846 | gtk_window_set_screen (GTK_WINDOW (dd->error_dialog), |
---|
847 | gtk_widget_get_screen (dd->applet)); |
---|
848 | gtk_window_present (GTK_WINDOW (dd->error_dialog)); |
---|
849 | return; |
---|
850 | } |
---|
851 | |
---|
852 | if (!check) { |
---|
853 | command_line = |
---|
854 | g_strdup_printf ("mount %s 2>&1", dd->mount_point); |
---|
855 | } else { |
---|
856 | command_line = |
---|
857 | g_strdup_printf ("umount %s 2>&1", dd->mount_point); |
---|
858 | } |
---|
859 | |
---|
860 | fp = popen (command_line, "r"); |
---|
861 | |
---|
862 | if (!fp) { |
---|
863 | printf ("unable to run command: %s\n", command_line); |
---|
864 | g_free (command_line); |
---|
865 | return; |
---|
866 | } |
---|
867 | |
---|
868 | str = g_string_new (NULL); |
---|
869 | |
---|
870 | while (fgets (buf, sizeof (buf), fp) != NULL) { |
---|
871 | gchar *b = buf; |
---|
872 | const gchar *charset; |
---|
873 | if (!g_get_charset (&charset)) { |
---|
874 | b = g_convert (buf, -1, "UTF-8", charset, NULL, NULL, NULL); |
---|
875 | } else { |
---|
876 | b =g_strdup (buf); |
---|
877 | } |
---|
878 | g_string_append (str, b); |
---|
879 | g_free (b); |
---|
880 | } |
---|
881 | pclose (fp); |
---|
882 | |
---|
883 | dd->mounted = device_is_mounted (dd); |
---|
884 | |
---|
885 | if (check != dd->mounted) { |
---|
886 | /* success! */ |
---|
887 | update_pixmap (dd, dd->mounted); |
---|
888 | |
---|
889 | /* eject after unmounting, if enabled */ |
---|
890 | if (check && dd->auto_eject) { |
---|
891 | eject (dd); |
---|
892 | } |
---|
893 | } else { |
---|
894 | g_string_prepend (str, _("\" reported:\n")); |
---|
895 | g_string_prepend (str, command_line); |
---|
896 | g_string_prepend (str, _("Drivemount command failed.\n\"")); |
---|
897 | |
---|
898 | dd->error_dialog = hig_dialog_new (NULL /* parent */, |
---|
899 | GTK_DIALOG_MODAL /* flags */, |
---|
900 | GTK_MESSAGE_ERROR, |
---|
901 | GTK_BUTTONS_OK, |
---|
902 | _("Cannot mount device"), |
---|
903 | str->str); |
---|
904 | gtk_window_set_screen (GTK_WINDOW (dd->error_dialog), |
---|
905 | gtk_widget_get_screen (dd->applet)); |
---|
906 | |
---|
907 | gtk_widget_show_all (dd->error_dialog); |
---|
908 | gtk_dialog_run (GTK_DIALOG (dd->error_dialog)); |
---|
909 | gtk_widget_destroy (dd->error_dialog); |
---|
910 | dd->error_dialog = NULL; |
---|
911 | } |
---|
912 | g_string_free (str, TRUE); |
---|
913 | g_free (command_line); |
---|
914 | return; |
---|
915 | } |
---|
916 | |
---|
917 | static void |
---|
918 | eject (DriveData *dd) |
---|
919 | { |
---|
920 | gchar *command_line; |
---|
921 | gchar buffer[512]; |
---|
922 | gchar dn[256]; /* Devicename */ |
---|
923 | gchar mp[256]; /* Mountpoint */ |
---|
924 | FILE *ml; /* Mountlist */ |
---|
925 | gint found = FALSE; |
---|
926 | |
---|
927 | if (!dd->mount_point) |
---|
928 | return; |
---|
929 | |
---|
930 | /* |
---|
931 | * Search the output of mount for dd->mount_point |
---|
932 | * and use the corresponting device name |
---|
933 | * as argument for eject |
---|
934 | * if the device is not mounted currently, use |
---|
935 | * /etc/fstab for the check |
---|
936 | */ |
---|
937 | |
---|
938 | if (dd->mounted) { |
---|
939 | ml = popen ("mount", "r"); |
---|
940 | while (ml && fgets (buffer, sizeof (buffer), ml)) { |
---|
941 | if (sscanf (buffer, "%255s %*s %255s", dn, mp) == 2 && |
---|
942 | (mp && strcmp (mp, dd->mount_point) == 0)) { |
---|
943 | found = TRUE; |
---|
944 | break; |
---|
945 | } |
---|
946 | } |
---|
947 | if (ml) |
---|
948 | pclose (ml); |
---|
949 | } else { |
---|
950 | ml = fopen ("/etc/fstab", "r"); |
---|
951 | |
---|
952 | while (ml && fgets (buffer, sizeof (buffer), ml)) { |
---|
953 | if (sscanf (buffer, "%255s %255s", dn, mp) == 2 && |
---|
954 | strcmp (mp, dd->mount_point) == 0) { |
---|
955 | found = TRUE; |
---|
956 | break; |
---|
957 | } |
---|
958 | } |
---|
959 | if (ml) |
---|
960 | fclose (ml); |
---|
961 | } |
---|
962 | |
---|
963 | if (!found) { /* mp != dd->mount_point */ |
---|
964 | printf ("WARNING: drivemount.c ... dd->mount_point not found in list\ |
---|
965 | (output of mount, or /etc/fstab) \n"); |
---|
966 | return; |
---|
967 | } |
---|
968 | |
---|
969 | if (dd->mounted) { |
---|
970 | command_line = g_strdup_printf ("eject -u '%s'", dn); |
---|
971 | /* perhaps it doesn't like the -u option */ |
---|
972 | if (system (command_line) != 0) { |
---|
973 | g_free (command_line); |
---|
974 | command_line = g_strdup_printf ("eject '%s'", dn); |
---|
975 | gnome_execute_shell (NULL, command_line); |
---|
976 | } |
---|
977 | g_free (command_line); |
---|
978 | } else { |
---|
979 | command_line = g_strdup_printf ("eject '%s'", dn); |
---|
980 | gnome_execute_shell (NULL, command_line); |
---|
981 | g_free (command_line); |
---|
982 | } |
---|
983 | } |
---|
984 | |
---|
985 | static gboolean |
---|
986 | key_press_cb (GtkWidget *widget, GdkEventKey *event, DriveData *dd) |
---|
987 | { |
---|
988 | if (event->state != GDK_CONTROL_MASK) |
---|
989 | return FALSE; |
---|
990 | else { |
---|
991 | switch (event->keyval) { |
---|
992 | |
---|
993 | case GDK_e: |
---|
994 | eject (dd); |
---|
995 | return TRUE; |
---|
996 | case GDK_b: |
---|
997 | browse_cb (NULL, dd, NULL); |
---|
998 | return TRUE; |
---|
999 | default: |
---|
1000 | break; |
---|
1001 | } |
---|
1002 | } |
---|
1003 | |
---|
1004 | return FALSE; |
---|
1005 | |
---|
1006 | |
---|
1007 | } |
---|
1008 | |
---|
1009 | /* stolen from gsearchtool */ |
---|
1010 | GtkWidget* |
---|
1011 | hig_dialog_new (GtkWindow *parent, |
---|
1012 | GtkDialogFlags flags, |
---|
1013 | GtkMessageType type, |
---|
1014 | GtkButtonsType buttons, |
---|
1015 | const gchar *header, |
---|
1016 | const gchar *message) |
---|
1017 | { |
---|
1018 | GtkWidget *dialog; |
---|
1019 | GtkWidget *dialog_vbox; |
---|
1020 | GtkWidget *dialog_action_area; |
---|
1021 | GtkWidget *hbox; |
---|
1022 | GtkWidget *vbox; |
---|
1023 | GtkWidget *label; |
---|
1024 | GtkWidget *button; |
---|
1025 | GtkWidget *image; |
---|
1026 | gchar *title; |
---|
1027 | |
---|
1028 | dialog = gtk_dialog_new (); |
---|
1029 | |
---|
1030 | gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); |
---|
1031 | gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); |
---|
1032 | gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); |
---|
1033 | gtk_window_set_title (GTK_WINDOW (dialog), ""); |
---|
1034 | |
---|
1035 | dialog_vbox = GTK_DIALOG (dialog)->vbox; |
---|
1036 | gtk_box_set_spacing (GTK_BOX (dialog_vbox), 14); |
---|
1037 | |
---|
1038 | hbox = gtk_hbox_new (FALSE, 12); |
---|
1039 | gtk_box_pack_start (GTK_BOX (dialog_vbox), hbox, FALSE, FALSE, 0); |
---|
1040 | gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); |
---|
1041 | gtk_widget_show (hbox); |
---|
1042 | |
---|
1043 | if (type == GTK_MESSAGE_ERROR) { |
---|
1044 | image = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_DIALOG); |
---|
1045 | } else if (type == GTK_MESSAGE_QUESTION) { |
---|
1046 | image = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_DIALOG); |
---|
1047 | } else { |
---|
1048 | g_assert_not_reached (); |
---|
1049 | } |
---|
1050 | gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); |
---|
1051 | gtk_widget_show (image); |
---|
1052 | |
---|
1053 | vbox = gtk_vbox_new (FALSE, 6); |
---|
1054 | gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); |
---|
1055 | gtk_widget_show (vbox); |
---|
1056 | |
---|
1057 | title = g_strconcat ("<b>", header, "</b>", NULL); |
---|
1058 | label = gtk_label_new (title); |
---|
1059 | gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); |
---|
1060 | gtk_label_set_use_markup (GTK_LABEL (label), TRUE); |
---|
1061 | gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); |
---|
1062 | gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); |
---|
1063 | gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); |
---|
1064 | gtk_widget_show (label); |
---|
1065 | g_free (title); |
---|
1066 | |
---|
1067 | label = gtk_label_new (message); |
---|
1068 | gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); |
---|
1069 | gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); |
---|
1070 | gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); |
---|
1071 | gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); |
---|
1072 | gtk_widget_show (label); |
---|
1073 | |
---|
1074 | dialog_action_area = GTK_DIALOG (dialog)->action_area; |
---|
1075 | gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area), GTK_BUTTONBOX_END); |
---|
1076 | |
---|
1077 | switch (buttons) |
---|
1078 | { |
---|
1079 | case GTK_BUTTONS_OK_CANCEL: |
---|
1080 | |
---|
1081 | button = gtk_button_new_from_stock ("gtk-cancel"); |
---|
1082 | gtk_widget_show (button); |
---|
1083 | gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CANCEL); |
---|
1084 | GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); |
---|
1085 | |
---|
1086 | button = gtk_button_new_from_stock ("gtk-ok"); |
---|
1087 | gtk_widget_show (button); |
---|
1088 | gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); |
---|
1089 | GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); |
---|
1090 | break; |
---|
1091 | |
---|
1092 | case GTK_BUTTONS_OK: |
---|
1093 | |
---|
1094 | button = gtk_button_new_from_stock ("gtk-ok"); |
---|
1095 | gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK); |
---|
1096 | GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); |
---|
1097 | gtk_widget_show (button); |
---|
1098 | break; |
---|
1099 | |
---|
1100 | default: |
---|
1101 | g_warning ("Unhandled GtkButtonsType"); |
---|
1102 | break; |
---|
1103 | } |
---|
1104 | |
---|
1105 | if (parent != NULL) { |
---|
1106 | gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent)); |
---|
1107 | } |
---|
1108 | if (flags & GTK_DIALOG_MODAL) { |
---|
1109 | gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); |
---|
1110 | } |
---|
1111 | if (flags & GTK_DIALOG_DESTROY_WITH_PARENT) { |
---|
1112 | gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); |
---|
1113 | } |
---|
1114 | |
---|
1115 | return dialog; |
---|
1116 | } |
---|
1117 | |
---|