source: trunk/third/evolution/shell/e-shortcuts-view.c @ 16787

Revision 16787, 16.9 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16786, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* e-shortcuts-view.c
3 *
4 * Copyright (C) 2000, 2001 Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Ettore Perazzoli
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <glib.h>
28#include <gtk/gtkcheckmenuitem.h>
29#include <gtk/gtkentry.h>
30#include <gtk/gtklabel.h>
31#include <libgnome/gnome-defs.h>
32#include <libgnome/gnome-i18n.h>
33#include <libgnomeui/gnome-app.h>
34#include <libgnomeui/gnome-app-helper.h>
35#include <libgnomeui/gnome-dialog.h>
36#include <libgnomeui/gnome-messagebox.h>
37#include <libgnomeui/gnome-popup-menu.h>
38#include <libgnomeui/gnome-stock.h>
39#include <libgnomeui/gnome-uidefs.h>
40#include <gal/util/e-util.h>
41#include <gal/widgets/e-unicode.h>
42
43#include "e-util/e-request.h"
44
45#include "e-shell-constants.h"
46
47#include "e-shortcuts-view-model.h"
48
49#include "e-shortcuts-view.h"
50
51
52#define PARENT_TYPE E_TYPE_SHORTCUT_BAR
53static EShortcutBarClass *parent_class = NULL;
54
55struct _EShortcutsViewPrivate {
56        EShortcuts *shortcuts;
57};
58
59enum {
60        ACTIVATE_SHORTCUT,
61        HIDE_REQUESTED,
62        LAST_SIGNAL
63};
64
65static guint signals[LAST_SIGNAL] = { 0 };
66
67
68static void
69show_new_group_dialog (EShortcutsView *view)
70{
71        char *group_name;
72
73        group_name = e_request_string (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
74                                       _("Create new shortcut group"),
75                                       _("Group name:"),
76                                       NULL);
77
78        if (group_name == NULL)
79                return;
80
81        e_shortcuts_add_group (view->priv->shortcuts, -1, group_name);
82
83        g_free (group_name);
84}
85
86
87/* Shortcut bar right-click menu.  */
88
89struct _RightClickMenuData {
90        EShortcutsView *shortcuts_view;
91        int group_num;
92};
93typedef struct _RightClickMenuData RightClickMenuData;
94
95static void
96toggle_large_icons_cb (GtkWidget *widget,
97                       void *data)
98{
99        RightClickMenuData *menu_data;
100
101        menu_data = (RightClickMenuData *) data;
102
103        if (menu_data == NULL)
104                return;
105
106        if (! GTK_CHECK_MENU_ITEM (widget)->active)
107                return;
108
109        e_shortcut_bar_set_view_type (E_SHORTCUT_BAR (menu_data->shortcuts_view),
110                                      menu_data->group_num,
111                                      E_ICON_BAR_LARGE_ICONS);
112}
113
114static void
115toggle_small_icons_cb (GtkWidget *widget,
116                       void *data)
117{
118        RightClickMenuData *menu_data;
119
120        menu_data = (RightClickMenuData *) data;
121        if (menu_data == NULL)
122                return;
123
124        if (! GTK_CHECK_MENU_ITEM (widget)->active)
125                return;
126
127        e_shortcut_bar_set_view_type (E_SHORTCUT_BAR (menu_data->shortcuts_view),
128                                      menu_data->group_num,
129                                      E_ICON_BAR_SMALL_ICONS);
130}
131
132static void
133hide_shortcut_bar_cb (GtkWidget *widget,
134                      void *data)
135{
136        RightClickMenuData *menu_data;
137        EShortcutsView *shortcut_view;
138
139        menu_data = (RightClickMenuData *) data;
140
141        shortcut_view = E_SHORTCUTS_VIEW (menu_data->shortcuts_view);
142
143        gtk_signal_emit (GTK_OBJECT (shortcut_view), signals[HIDE_REQUESTED]);
144}
145
146static void
147create_new_group_cb (GtkWidget *widget,
148                     void *data)
149{
150        RightClickMenuData *menu_data;
151
152        menu_data = (RightClickMenuData *) data;
153
154        show_new_group_dialog (menu_data->shortcuts_view);
155}
156
157static void
158destroy_group_cb (GtkWidget *widget,
159                  void *data)
160{
161        RightClickMenuData *menu_data;
162        EShortcuts *shortcuts;
163        EShortcutsView *shortcuts_view;
164        EShortcutsViewPrivate *priv;
165        GtkWidget *message_box;
166        char *question, *title;
167
168        menu_data = (RightClickMenuData *) data;
169        shortcuts_view = menu_data->shortcuts_view;
170        priv = shortcuts_view->priv;
171        shortcuts = priv->shortcuts;
172
173        title = e_utf8_to_locale_string (e_shortcuts_get_group_title (
174                                         shortcuts, menu_data->group_num));
175        question = g_strdup_printf (_("Do you really want to remove group\n"
176                                      "`%s' from the shortcut bar?"), title);
177        g_free (title);
178
179        message_box = gnome_message_box_new (question, GNOME_MESSAGE_BOX_QUESTION,
180                                             _("Remove"), _("Don't remove"), NULL);
181        gnome_dialog_set_parent (GNOME_DIALOG (message_box),
182                                 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (shortcuts_view))));
183        g_free (question);
184
185        if (gnome_dialog_run_and_close (GNOME_DIALOG (message_box)) != 0)
186                return;
187
188        e_shortcuts_remove_group (shortcuts, menu_data->group_num);
189}
190
191static void
192rename_group_cb (GtkWidget *widget,
193                 void *data)
194{
195        RightClickMenuData *menu_data;
196        EShortcuts *shortcuts;
197        EShortcutsView *shortcuts_view;
198        const char *old_name;
199        char *new_name;
200        int group;
201
202        menu_data = (RightClickMenuData *) data;
203        shortcuts_view = menu_data->shortcuts_view;
204        shortcuts = shortcuts_view->priv->shortcuts;
205
206        old_name = e_shortcuts_get_group_title (shortcuts, menu_data->group_num);
207
208        new_name = e_request_string (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (shortcuts_view))),
209                                     _("Rename Shortcut Group"),
210                                     _("Rename selected shortcut group to:"),
211                                     old_name);
212
213        if (new_name == NULL)
214                return;
215
216        /* Remember the group and flip back to it */
217        group = e_group_bar_get_current_group_num (E_GROUP_BAR (E_SHORTCUT_BAR (shortcuts_view)));
218        e_shortcuts_rename_group (shortcuts, menu_data->group_num, new_name);
219        g_free (new_name);
220        e_group_bar_set_current_group_num (E_GROUP_BAR (E_SHORTCUT_BAR (shortcuts_view)), group, FALSE);
221}
222
223static GnomeUIInfo icon_size_radio_group_uiinfo[] = {
224        { GNOME_APP_UI_ITEM, N_("_Small Icons"),
225          N_("Show the shortcuts as small icons"), toggle_small_icons_cb, NULL,
226          NULL, 0, 0, 0, 0 },
227        { GNOME_APP_UI_ITEM, N_("_Large Icons"),
228          N_("Show the shortcuts as large icons"), toggle_large_icons_cb, NULL,
229          NULL, 0, 0, 0, 0 },
230
231        GNOMEUIINFO_END
232};
233
234static GnomeUIInfo right_click_menu_uiinfo[] = {
235        GNOMEUIINFO_RADIOLIST (icon_size_radio_group_uiinfo),
236
237        GNOMEUIINFO_SEPARATOR,
238
239        { GNOME_APP_UI_ITEM, N_("_New Group..."),
240          N_("Create a new shortcut group"), create_new_group_cb, NULL,
241          NULL, 0, 0, 0, 0 },
242        { GNOME_APP_UI_ITEM, N_("_Remove this Group..."),
243          N_("Remove this shortcut group"), destroy_group_cb, NULL,
244          NULL, 0, 0, 0, 0 },
245        { GNOME_APP_UI_ITEM, N_("Re_name this Group..."),
246          N_("Rename this shortcut group"), rename_group_cb, NULL,
247          NULL, 0, 0, 0, 0 },
248
249        GNOMEUIINFO_SEPARATOR,
250
251        { GNOME_APP_UI_ITEM, N_("_Hide the Shortcut Bar"),
252          N_("Hide the shortcut bar"), hide_shortcut_bar_cb, NULL,
253          NULL, 0, 0, 0, 0 },
254
255        GNOMEUIINFO_END
256};
257
258static void
259pop_up_right_click_menu_for_group (EShortcutsView *shortcuts_view,
260                                   GdkEventButton *event,
261                                   int group_num)
262{
263        RightClickMenuData *menu_data;
264        GtkWidget *popup_menu;
265
266        menu_data = g_new (RightClickMenuData, 1);
267        menu_data->shortcuts_view = shortcuts_view;
268        menu_data->group_num      = group_num;
269
270        popup_menu = gnome_popup_menu_new (right_click_menu_uiinfo);
271
272        if (e_shortcut_bar_get_view_type (E_SHORTCUT_BAR (shortcuts_view), group_num)
273            == E_ICON_BAR_SMALL_ICONS)
274                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (icon_size_radio_group_uiinfo[0].widget),
275                                                TRUE);
276        else
277                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (icon_size_radio_group_uiinfo[1].widget),
278                                                TRUE);
279
280        if (group_num == 0)
281                gtk_widget_set_sensitive (right_click_menu_uiinfo[3].widget, FALSE);
282
283        gnome_popup_menu_do_popup_modal (popup_menu, NULL, NULL, event, menu_data);
284
285        g_free (menu_data);
286        gtk_widget_unref (popup_menu);
287}
288
289
290/* Data to be passed around for the shortcut right-click menu items.  */
291
292struct _ShortcutRightClickMenuData {
293        EShortcutsView *shortcuts_view;
294        int group_num;
295        int item_num;
296};
297typedef struct _ShortcutRightClickMenuData ShortcutRightClickMenuData;
298
299
300/* "Open Shortcut" and "Open Shortcut in New Window" commands.  */
301
302static void
303open_shortcut_helper (ShortcutRightClickMenuData *menu_data,
304                      gboolean in_new_window)
305{
306        EShortcutsView *shortcuts_view;
307        EShortcuts *shortcuts;
308        const EShortcutItem *shortcut_item;
309
310        shortcuts_view = menu_data->shortcuts_view;
311        shortcuts = shortcuts_view->priv->shortcuts;
312
313        shortcut_item = e_shortcuts_get_shortcut (shortcuts, menu_data->group_num, menu_data->item_num);
314        if (shortcut_item == NULL)
315                return;
316
317        gtk_signal_emit (GTK_OBJECT (shortcuts_view), signals[ACTIVATE_SHORTCUT],
318                         shortcuts, shortcut_item->uri, in_new_window);
319}
320
321static void
322open_shortcut_cb (GtkWidget *widget,
323                  void *data)
324{
325        open_shortcut_helper ((ShortcutRightClickMenuData *) data, FALSE);
326}
327
328static void
329open_shortcut_in_new_window_cb (GtkWidget *widget,
330                                void *data)
331{
332        open_shortcut_helper ((ShortcutRightClickMenuData *) data, TRUE);
333}
334
335
336static void
337remove_shortcut_cb (GtkWidget *widget,
338                    void *data)
339{
340        ShortcutRightClickMenuData *menu_data;
341        EShortcutsView *shortcuts_view;
342        EShortcuts *shortcuts;
343
344        menu_data = (ShortcutRightClickMenuData *) data;
345        shortcuts_view = menu_data->shortcuts_view;
346        shortcuts = shortcuts_view->priv->shortcuts;
347
348        e_shortcuts_remove_shortcut (shortcuts, menu_data->group_num, menu_data->item_num);
349}
350
351
352/* "Rename Shortcut"  command.  */
353
354static void
355rename_shortcut_cb (GtkWidget *widget,
356                    void *data)
357{
358        ShortcutRightClickMenuData *menu_data;
359        EShortcutsView *shortcuts_view;
360        EShortcuts *shortcuts;
361        const EShortcutItem *shortcut_item;
362        char *new_name;
363
364        menu_data = (ShortcutRightClickMenuData *) data;
365        shortcuts_view = menu_data->shortcuts_view;
366        shortcuts = shortcuts_view->priv->shortcuts;
367
368        shortcut_item = e_shortcuts_get_shortcut (shortcuts, menu_data->group_num, menu_data->item_num);
369
370        new_name = e_request_string (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (shortcuts_view))),
371                                     _("Rename shortcut"),
372                                     _("Rename selected shortcut to:"),
373                                     shortcut_item->name);
374
375        if (new_name == NULL)
376                return;
377
378        e_shortcuts_update_shortcut (shortcuts, menu_data->group_num, menu_data->item_num,
379                                     shortcut_item->uri, new_name, shortcut_item->unread_count, shortcut_item->type);
380        g_free (new_name);
381}
382
383static GnomeUIInfo shortcut_right_click_menu_uiinfo[] = {
384        GNOMEUIINFO_ITEM_STOCK (N_("_Open"), N_("Open the folder linked to this shortcut"),
385                                open_shortcut_cb, GNOME_STOCK_MENU_OPEN),
386        GNOMEUIINFO_ITEM_NONE  (N_("Open in New _Window"), N_("Open the folder linked to this shortcut in a new window"),
387                                open_shortcut_in_new_window_cb),
388        GNOMEUIINFO_SEPARATOR,
389        GNOMEUIINFO_ITEM_NONE (N_("_Rename"), N_("Rename this shortcut"),
390                                rename_shortcut_cb),
391        GNOMEUIINFO_ITEM_STOCK (N_("Re_move"), N_("Remove this shortcut from the shortcut bar"),
392                                remove_shortcut_cb, GNOME_STOCK_MENU_TRASH),
393        GNOMEUIINFO_END
394};
395
396static void
397pop_up_right_click_menu_for_shortcut (EShortcutsView *shortcuts_view,
398                                      GdkEventButton *event,
399                                      int group_num,
400                                      int item_num)
401{
402        ShortcutRightClickMenuData *menu_data;
403        GtkWidget *popup_menu;
404
405        menu_data = g_new (ShortcutRightClickMenuData, 1);
406        menu_data->shortcuts_view = shortcuts_view;
407        menu_data->group_num      = group_num;
408        menu_data->item_num       = item_num;
409
410        popup_menu = gnome_popup_menu_new (shortcut_right_click_menu_uiinfo);
411
412        gnome_popup_menu_do_popup_modal (popup_menu, NULL, NULL, event, menu_data);
413
414        g_free (menu_data);
415        gtk_widget_destroy (popup_menu);
416}
417
418
419/* GtkObject methods.  */
420
421static void
422destroy (GtkObject *object)
423{
424        EShortcutsViewPrivate *priv;
425        EShortcutsView *shortcuts_view;
426
427        shortcuts_view = E_SHORTCUTS_VIEW (object);
428
429        priv = shortcuts_view->priv;
430
431        gtk_object_unref (GTK_OBJECT (priv->shortcuts));
432
433        g_free (priv);
434
435        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
436}
437
438
439/* EShortcutBar methods.  */
440
441static void
442item_selected (EShortcutBar *shortcut_bar,
443               GdkEvent *event,
444               int group_num,
445               int item_num)
446{
447        EShortcuts *shortcuts;
448        EShortcutsView *shortcuts_view;
449        const EShortcutItem *shortcut_item;
450
451        shortcuts_view = E_SHORTCUTS_VIEW (shortcut_bar);
452        shortcuts = shortcuts_view->priv->shortcuts;
453
454        if (event->button.button == 3) {
455                if (item_num < 0)
456                        pop_up_right_click_menu_for_group (shortcuts_view, &event->button,
457                                                           group_num);
458                else
459                        pop_up_right_click_menu_for_shortcut (shortcuts_view, &event->button,
460                                                              group_num, item_num);
461                return;
462        } else if (event->button.button != 1) {
463                return;
464        }
465
466        if (item_num < 0)
467                return;
468
469        shortcut_item = e_shortcuts_get_shortcut (shortcuts, group_num, item_num);
470        if (shortcut_item == NULL)
471                return;
472
473        gtk_signal_emit (GTK_OBJECT (shortcuts_view), signals[ACTIVATE_SHORTCUT],
474                         shortcuts, shortcut_item->uri, FALSE);
475}
476
477static void
478get_shortcut_info (EShortcutsView *shortcuts_view,
479                   const char *item_url,
480                   int *unread_count_return,
481                   const char **type_return)
482{
483        EShortcutsViewPrivate *priv;
484        EStorageSet *storage_set;
485        EStorage *storage;
486        EFolder *folder;
487        const char *path;
488
489        priv = shortcuts_view->priv;
490
491        if (strncmp (item_url, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) != 0) {
492                *unread_count_return = 0;
493                *type_return = NULL;
494                return;
495        }
496
497        path = strchr (item_url, G_DIR_SEPARATOR);
498        storage_set = e_shortcuts_get_storage_set (priv->shortcuts);
499
500        folder = e_storage_set_get_folder (storage_set, path);
501        if (folder != NULL) {
502                *unread_count_return = e_folder_get_unread_count (folder);
503                *type_return = e_folder_get_type_string (folder);
504                return;
505        }
506
507        storage = e_storage_set_get_storage (storage_set, path + 1);
508        if (storage != NULL) {
509                *unread_count_return = 0;
510                *type_return = e_storage_get_toplevel_node_type (storage);
511                return;
512        }
513
514        *unread_count_return = 0;
515        *type_return = NULL;
516}
517
518static void
519impl_shortcut_dropped (EShortcutBar *shortcut_bar,
520                       int group_num,
521                       int position,
522                       const char *item_url,
523                       const char *item_name)
524{
525        EShortcutsView *shortcuts_view;
526        EShortcutsViewPrivate *priv;
527        int unread_count;
528        const char *type;
529        char *tmp;
530        char *tp;
531        char *name_without_unread;
532
533        shortcuts_view = E_SHORTCUTS_VIEW (shortcut_bar);
534        priv = shortcuts_view->priv;
535
536        get_shortcut_info (shortcuts_view, item_url, &unread_count, &type);
537
538        /* Looks funny, but keeps it from adding the unread count
539           repeatedly when dragging folders around */
540        tmp = g_strdup_printf (" (%d)", unread_count);
541        if ((tp = strstr (item_name, tmp)) != NULL)
542                name_without_unread = g_strndup (item_name, strlen (item_name) - strlen (tp));
543        else
544                name_without_unread = g_strdup (item_name);
545
546        e_shortcuts_add_shortcut (priv->shortcuts,
547                                  group_num, position,
548                                  item_url, name_without_unread, unread_count, type);
549
550        g_free (tmp);
551        g_free (name_without_unread);
552}
553
554static void
555impl_shortcut_dragged (EShortcutBar *shortcut_bar,
556                       gint group_num,
557                       gint item_num)
558{
559        EShortcutsView *shortcuts_view;
560        EShortcutsViewPrivate *priv;
561
562        shortcuts_view = E_SHORTCUTS_VIEW (shortcut_bar);
563        priv = shortcuts_view->priv;
564
565        e_shortcuts_remove_shortcut (priv->shortcuts, group_num, item_num);
566}
567
568
569static void
570class_init (EShortcutsViewClass *klass)
571{
572        GtkObjectClass *object_class;
573        EShortcutBarClass *shortcut_bar_class;
574
575        object_class = GTK_OBJECT_CLASS (klass);
576        object_class->destroy = destroy;
577
578        shortcut_bar_class = E_SHORTCUT_BAR_CLASS (klass);
579        shortcut_bar_class->item_selected    = item_selected;
580        shortcut_bar_class->shortcut_dropped = impl_shortcut_dropped;
581        shortcut_bar_class->shortcut_dragged = impl_shortcut_dragged;
582
583        parent_class = gtk_type_class (e_shortcut_bar_get_type ());
584
585        signals[ACTIVATE_SHORTCUT] =
586                gtk_signal_new ("activate_shortcut",
587                                GTK_RUN_LAST | GTK_RUN_ACTION,
588                                object_class->type,
589                                GTK_SIGNAL_OFFSET (EShortcutsViewClass, activate_shortcut),
590                                e_marshal_NONE__POINTER_POINTER_INT,
591                                GTK_TYPE_NONE, 3,
592                                GTK_TYPE_POINTER,
593                                GTK_TYPE_STRING,
594                                GTK_TYPE_BOOL);
595
596        signals[HIDE_REQUESTED] =
597                gtk_signal_new ("hide_requested",
598                                GTK_RUN_LAST,
599                                object_class->type,
600                                GTK_SIGNAL_OFFSET (EShortcutsViewClass,
601                                                   hide_requested),
602                                gtk_marshal_NONE__NONE,
603                                GTK_TYPE_NONE, 0);
604
605        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
606}
607
608static void
609init (EShortcutsView *shortcuts_view)
610{
611        EShortcutsViewPrivate *priv;
612
613        priv = g_new (EShortcutsViewPrivate, 1);
614        priv->shortcuts = NULL;
615
616        shortcuts_view->priv = priv;
617}
618
619
620void
621e_shortcuts_view_construct (EShortcutsView *shortcuts_view,
622                            EShortcuts *shortcuts)
623{
624        EShortcutsViewPrivate *priv;
625
626        g_return_if_fail (shortcuts != NULL);
627        g_return_if_fail (E_IS_SHORTCUTS (shortcuts));
628
629        priv = shortcuts_view->priv;
630
631        priv->shortcuts = shortcuts;
632        gtk_object_ref (GTK_OBJECT (priv->shortcuts));
633
634        e_shortcut_bar_set_model (E_SHORTCUT_BAR (shortcuts_view),
635                                  E_SHORTCUT_MODEL (e_shortcuts_view_model_new (shortcuts)));
636}
637
638GtkWidget *
639e_shortcuts_view_new (EShortcuts *shortcuts)
640{
641        GtkWidget *new;
642
643        g_return_val_if_fail (shortcuts != NULL, NULL);
644        g_return_val_if_fail (E_IS_SHORTCUTS (shortcuts), NULL);
645
646        new = gtk_type_new (e_shortcuts_view_get_type ());
647        e_shortcuts_view_construct (E_SHORTCUTS_VIEW (new), shortcuts);
648
649        return new;
650}
651
652
653E_MAKE_TYPE (e_shortcuts_view, "EShortcutsView", EShortcutsView, class_init, init, PARENT_TYPE)
Note: See TracBrowser for help on using the repository browser.