aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/Makefile.am6
-rw-r--r--shell/e-shell-shortcut.c159
-rw-r--r--shell/e-shell-shortcut.h11
-rw-r--r--shell/e-shell-view.c81
-rw-r--r--shell/e-shell.c103
-rw-r--r--shell/e-shell.h8
-rw-r--r--shell/e-shortcut.c204
-rw-r--r--shell/e-shortcut.h59
8 files changed, 606 insertions, 25 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index e80ba3fde1..1aea62ce1e 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -23,10 +23,14 @@ evolution_SOURCES = \
e-init.h \
e-shell.c \
e-shell.h \
+ e-shell-shortcut.c \
+ e-shell-shortcut.h \
e-shell-view.c \
e-shell-view.h \
e-shell-view-menu.c \
e-shell-view-menu.h \
+ e-shortcut.c \
+ e-shortcut.h \
$(EVOLUTION_CORBA_GENERATED)
Evolution-impl.o: Evolution.h
@@ -39,4 +43,4 @@ evolution_LDADD = \
../e-util/libeutil.a \
$(BONOBO_GNOME_LIBS)
-EXTRA_DIST = Evolution.idl \ No newline at end of file
+EXTRA_DIST = Evolution.idl
diff --git a/shell/e-shell-shortcut.c b/shell/e-shell-shortcut.c
new file mode 100644
index 0000000000..6e6aaf8260
--- /dev/null
+++ b/shell/e-shell-shortcut.c
@@ -0,0 +1,159 @@
+/*
+ * e-shell-shortcut.c: Handles events from the shortcut bar widget on the
+ * e-shell-view
+ *
+ * Authors:
+ * Damon Chaplin (damon@gtk.org)
+ * Miguel de Icaza (miguel@kernel.org)
+ *
+ * (C) 1999, 2000 Helix Code, Inc.
+ */
+#include <config.h>
+#include <gnome.h>
+#include "shortcut-bar/e-shortcut-bar.h"
+#include "e-shell-shortcut.h"
+
+#define SMALL_ICONS 1
+#define LARGE_ICONS 2
+
+static void
+set_large_icons (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static void
+set_small_icons (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static void
+add_group (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static void
+remove_group (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static void
+rename_group (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static void
+add_shortcut (GtkMenu *menu, EShellView *eshell_view)
+{
+}
+
+static struct {
+ char *label;
+ int flags;
+ GtkSignalFunc callback;
+} shortcut_menu [] = {
+ { N_("Large Icons"), SMALL_ICONS, GTK_SIGNAL_FUNC (set_large_icons) },
+ { N_("Small Icons"), LARGE_ICONS, GTK_SIGNAL_FUNC (set_small_icons) },
+ { NULL, 0, NULL },
+ { N_("Add New Group"), 0, GTK_SIGNAL_FUNC (add_group) },
+ { N_("Remove Group"), 0, GTK_SIGNAL_FUNC (remove_group) },
+ { N_("Rename Group"), 0, GTK_SIGNAL_FUNC (rename_group) },
+ { NULL, 0, NULL },
+ { N_("Add Shortcut"), 0, GTK_SIGNAL_FUNC (add_shortcut) },
+};
+
+#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
+
+static void
+shortcut_bar_show_standard_popup (EShellView *eshell_view, GdkEvent *event, EShortcutGroup *shortcut_group)
+{
+ GtkWidget *menu, *menuitem;
+ int i;
+
+ menu = gtk_menu_new ();
+
+ for (i = 0; i < ELEMENTS (shortcut_menu); i++){
+ if (shortcut_menu [i].flags & SMALL_ICONS)
+ if (!shortcut_group->small_icons)
+ continue;
+
+ if (shortcut_menu [i].flags & LARGE_ICONS)
+ if (shortcut_group->small_icons)
+ continue;
+
+ if (shortcut_menu [i].label == NULL){
+ menuitem = gtk_menu_item_new ();
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ } else
+ menuitem = gtk_menu_item_new_with_label (_(shortcut_menu [i].label));
+
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (menu), menuitem);
+
+ gtk_signal_connect (
+ GTK_OBJECT (menuitem), "activate",
+ shortcut_menu [i].callback, eshell_view);
+ gtk_object_set_data (
+ GTK_OBJECT (menuitem), "shortcut_group",
+ shortcut_group);
+ }
+
+ gtk_signal_connect (GTK_OBJECT (menu), "deactivate",
+ GTK_SIGNAL_FUNC (gtk_object_destroy), NULL);
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button.button, event->button.time);
+}
+
+static void
+shortcut_bar_show_context_popup (EShellView *eshell_view, GdkEvent *event, EShortcutGroup *shortcut_group)
+{
+ printf ("Context popup\n");
+}
+
+static EShortcut *
+shortcut_from_pos (EShellView *eshell_view, int group_num, int item_num, EShortcutGroup **group_result)
+{
+ EShell *eshell = eshell_view->eshell;
+ EShortcutGroup *group;
+ EShortcut *shortcut;
+
+ if (item_num == -1)
+ return NULL;
+
+ g_assert (group_num < eshell->shortcut_groups->len);
+ group = g_array_index (eshell->shortcut_groups, EShortcutGroup *, group_num);
+
+ g_assert (item_num < group->shortcuts->len);
+ shortcut = g_array_index (group->shortcuts, EShortcut *, item_num);
+
+ *group_result = group;
+
+ return shortcut;
+}
+
+void
+shortcut_bar_item_selected (EShortcutBar *shortcut_bar,
+ GdkEvent *event, gint group_num, gint item_num,
+ EShellView *eshell_view)
+{
+ EShortcut *shortcut;
+ EShortcutGroup *shortcut_group;
+
+ shortcut = shortcut_from_pos (eshell_view, group_num, item_num, &shortcut_group);
+
+ if (group_num == -1)
+ return;
+
+ if (event->button.button == 1) {
+ printf ("Item Selected - %i:%i", group_num + 1, item_num + 1);
+ } else if (event->button.button == 3) {
+
+ if (shortcut == NULL)
+ shortcut_bar_show_standard_popup (
+ eshell_view, event, shortcut_group);
+ else
+ shortcut_bar_show_context_popup (
+ eshell_view, event, shortcut);
+ }
+}
+
diff --git a/shell/e-shell-shortcut.h b/shell/e-shell-shortcut.h
new file mode 100644
index 0000000000..2f526be6ab
--- /dev/null
+++ b/shell/e-shell-shortcut.h
@@ -0,0 +1,11 @@
+#ifndef E_SHELL_SHORTCUT_H
+#define E_SHELL_SHORTCUT_H
+
+#include "e-shell-view.h"
+
+
+void shortcut_bar_item_selected (EShortcutBar *shortcut_bar,
+ GdkEvent *event, gint group_num, gint item_num,
+ EShellView *eshell_view);
+
+#endif /* E_SHELL_SHORTCUT_H */
diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c
index 5962e0686f..34438e4556 100644
--- a/shell/e-shell-view.c
+++ b/shell/e-shell-view.c
@@ -12,6 +12,7 @@
#include "e-util/e-util.h"
#include "e-shell-view.h"
#include "e-shell-view-menu.h"
+#include "e-shell-shortcut.h"
#define PARENT_TYPE gnome_app_get_type ()
@@ -45,12 +46,6 @@ e_shell_view_setup (EShellView *eshell_view)
}
static void
-e_shell_view_load_shortcut_bar (EShellView *eshell_view)
-{
- gtk_paned_set_position (GTK_PANED (eshell_view->shortcut_hpaned), 100);
-}
-
-static void
e_shell_view_setup_shortcut_display (EShellView *eshell_view)
{
gtk_widget_push_visual (gdk_rgb_get_visual ());
@@ -60,7 +55,7 @@ e_shell_view_setup_shortcut_display (EShellView *eshell_view)
gtk_widget_show (eshell_view->shortcut_hpaned);
eshell_view->shortcut_bar = e_shortcut_bar_new ();
- e_shell_view_load_shortcut_bar (eshell_view);
+ gtk_paned_set_position (GTK_PANED (eshell_view->shortcut_hpaned), 100);
gtk_paned_pack1 (GTK_PANED (eshell_view->shortcut_hpaned),
eshell_view->shortcut_bar, FALSE, TRUE);
@@ -70,6 +65,72 @@ e_shell_view_setup_shortcut_display (EShellView *eshell_view)
gtk_widget_pop_colormap ();
gnome_app_set_contents (GNOME_APP (eshell_view), eshell_view->shortcut_hpaned);
+
+ gtk_signal_connect (
+ GTK_OBJECT (eshell_view->shortcut_bar), "item_selected",
+ GTK_SIGNAL_FUNC (shortcut_bar_item_selected), eshell_view);
+
+}
+
+static void
+e_shell_view_load_group (EShell *eshell, EShellView *eshell_view, EShortcutGroup *esg)
+{
+ EShortcutBar *bar = E_SHORTCUT_BAR (eshell_view->shortcut_bar);
+ int group_num, i;
+ const int items = esg->shortcuts->len;
+
+ group_num = e_shortcut_bar_add_group (bar, esg->title);
+ if (esg->small_icons)
+ e_shortcut_bar_set_view_type (bar, group_num, E_ICON_BAR_SMALL_ICONS);
+
+ for (i = 0; i < items; i++){
+ EShortcut *shortcut = E_SHORTCUT (g_array_index (esg->shortcuts, EShortcut *, i));
+ EFolder *folder = shortcut->efolder;
+ char *type = NULL;
+
+ switch (folder->type){
+ case E_FOLDER_MAIL:
+ type = "folder:";
+ break;
+
+ case E_FOLDER_CONTACTS:
+ type = "contacts:";
+ break;
+
+ case E_FOLDER_CALENDAR:
+ type = "calendar:";
+ break;
+
+ case E_FOLDER_TASKS:
+ type = "todo:";
+ break;
+
+ case E_FOLDER_OTHER:
+ type = "file:";
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ e_shortcut_bar_add_item (bar, group_num, type, folder->name);
+ }
+}
+
+static void
+e_shell_view_load_shortcut_bar (EShellView *eshell_view)
+{
+ EShell *eshell = eshell_view->eshell;
+ const int groups = eshell->shortcut_groups->len;
+ int i;
+
+ for (i = 0; i < groups; i++){
+ EShortcutGroup *esg;
+
+ esg = g_array_index (eshell->shortcut_groups, EShortcutGroup *, i);
+
+ e_shell_view_load_group (eshell, eshell_view, esg);
+ }
}
GtkWidget *
@@ -81,12 +142,14 @@ e_shell_view_new (EShell *eshell, gboolean show_shortcut_bar)
gnome_app_construct (GNOME_APP (eshell_view), "Evolution", "Evolution");
+ eshell_view->eshell = eshell;
e_shell_view_setup (eshell_view);
e_shell_view_setup_menus (eshell_view);
- if (show_shortcut_bar)
+ if (show_shortcut_bar){
e_shell_view_setup_shortcut_display (eshell_view);
- else {
+ e_shell_view_load_shortcut_bar (eshell_view);
+ } else {
g_error ("Non-shortcut bar code not written yet");
}
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 53a2df771e..4382dc7ed9 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -153,10 +153,27 @@ es_destroy_default_folders (EShell *eshell)
}
static void
+es_destroy_shortcuts (EShell *eshell)
+{
+ const int len = eshell->shortcut_groups->len;
+ int i;
+
+ for (i = 0; i < len; i++){
+ EShortcutGroup *g = g_array_index (eshell->shortcut_groups, EShortcutGroup *, i);
+
+ gtk_object_unref (GTK_OBJECT (g));
+ }
+
+ g_array_free (eshell->shortcut_groups, TRUE);
+}
+
+static void
e_shell_destroy (GtkObject *object)
{
EShell *eshell = E_SHELL (object);
+ es_destroy_shortcuts (eshell);
+
es_destroy_default_folders (eshell);
GTK_OBJECT_CLASS (e_shell_parent_class)->destroy (object);
}
@@ -175,8 +192,12 @@ e_shell_destroy_views (EShell *eshell)
{
GSList *l;
- for (l = eshell->views; l; l = l->next){
- EShellView *view = l->data;
+ /*
+ * Notice that eshell->views is updated by the various views
+ * during unregistration
+ */
+ while (eshell->views){
+ EShellView *view = eshell->views->data;
gtk_object_destroy (GTK_OBJECT (view));
}
@@ -217,19 +238,11 @@ create_corba_eshell (GnomeObject *object)
}
static void
-e_shell_init (GtkObject *object)
-{
-}
-
-static void
-e_shell_construct (EShell *eshell, GNOME_Evolution_Shell corba_eshell)
-{
- gnome_object_construct (GNOME_OBJECT (eshell), corba_eshell);
-}
-
-static void
e_shell_setup_default_folders (EShell *eshell)
{
+ eshell->default_folders.summary = e_folder_new (
+ E_FOLDER_MAIL, "internal:summary", _("Today"), _("Executive Summary"),
+ NULL, "internal:");
eshell->default_folders.inbox = e_folder_new (
E_FOLDER_MAIL, "internal:inbox", _("Inbox"), _("New mail messages"),
NULL, "internal:mail_view");
@@ -242,11 +255,73 @@ e_shell_setup_default_folders (EShell *eshell)
eshell->default_folders.calendar = e_folder_new (
E_FOLDER_CALENDAR, "internal:personal_calendar", _("Calendar"), _("Your calendar"),
NULL, "internal:calendar_daily");
+ eshell->default_folders.contacts = e_folder_new (
+ E_FOLDER_CONTACTS, "internal:personal_contacts", _("Contacts"), _("Your contacts list"),
+ NULL, "internal:contact_view");
eshell->default_folders.tasks = e_folder_new (
E_FOLDER_TASKS, "internal:personal_calendar", _("Tasks"), _("Tasks list"),
NULL, "internal:tasks_view");
}
+static EShortcutGroup *
+setup_main_shortcuts (EShell *eshell)
+{
+ EShortcutGroup *m;
+
+ m = e_shortcut_group_new (_("Main Shortcuts"), FALSE);
+ e_shortcut_group_append (m, e_shortcut_new (eshell->default_folders.summary));
+ e_shortcut_group_append (m, e_shortcut_new (eshell->default_folders.inbox));
+ e_shortcut_group_append (m, e_shortcut_new (eshell->default_folders.calendar));
+ e_shortcut_group_append (m, e_shortcut_new (eshell->default_folders.contacts));
+ e_shortcut_group_append (m, e_shortcut_new (eshell->default_folders.tasks));
+
+ return m;
+}
+
+static EShortcutGroup *
+setup_secondary_shortcuts (EShell *eshell)
+{
+ EShortcutGroup *sec;
+
+ sec = e_shortcut_group_new (_("Other Shortcuts"), TRUE);
+
+ e_shortcut_group_append (sec, e_shortcut_new (eshell->default_folders.drafts));
+ e_shortcut_group_append (sec, e_shortcut_new (eshell->default_folders.outbox));
+
+ return sec;
+}
+
+static void
+e_shell_setup_default_shortcuts (EShell *eshell)
+{
+ GArray *esg;
+ EShortcutGroup *g;
+
+ esg = g_array_new (FALSE, FALSE, sizeof (EShortcutGroup *));
+
+ g = setup_main_shortcuts (eshell);
+ g_array_append_val (esg, g);
+ g = setup_secondary_shortcuts (eshell);
+ g_array_append_val (esg, g);
+
+ eshell->shortcut_groups = esg;
+}
+
+static void
+e_shell_init (GtkObject *object)
+{
+ EShell *eshell = E_SHELL (object);
+
+ e_shell_setup_default_folders (eshell);
+ e_shell_setup_default_shortcuts (eshell);
+}
+
+static void
+e_shell_construct (EShell *eshell, GNOME_Evolution_Shell corba_eshell)
+{
+ gnome_object_construct (GNOME_OBJECT (eshell), corba_eshell);
+}
+
EShell *
e_shell_new (void)
{
@@ -263,8 +338,6 @@ e_shell_new (void)
e_shell_construct (eshell, corba_eshell);
- e_shell_setup_default_folders (eshell);
-
return eshell;
}
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 7cd5ac08eb..213f6deb14 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -4,6 +4,7 @@
#include <bonobo/gnome-object.h>
#include "evolution.h"
#include "e-folder.h"
+#include "e-shortcut.h"
#define E_SHELL_GOAD_ID "GOADID:GNOME:Evolution:Shell:1.0"
#define E_SHELL_FACTORY_GOAD_ID "GOADID:GNOME:Evolution:ShellFactory:1.0"
@@ -26,7 +27,14 @@ struct _EShell {
EFolder *drafts;
EFolder *calendar;
EFolder *tasks;
+ EFolder *summary;
+ EFolder *contacts;
} default_folders;
+
+ /*
+ * An array of EShortcutGroups
+ */
+ GArray *shortcut_groups;
};
typedef struct {
diff --git a/shell/e-shortcut.c b/shell/e-shortcut.c
new file mode 100644
index 0000000000..ec83bc3854
--- /dev/null
+++ b/shell/e-shortcut.c
@@ -0,0 +1,204 @@
+/*
+ * Shortcut.c: implements shortcuts and shortcut group models
+ *
+ * Author:
+ * Miguel de Icaza (miguel@kernel.org)
+ *
+ * (C) 2000 Helix Code, Inc.
+ *
+ */
+#include <config.h>
+#include <gtk/gtksignal.h>
+#include "e-util/e-util.h"
+#include "e-shortcut.h"
+
+#define SHORTCUT_PARENT_TYPE gtk_object_get_type ()
+#define SHORTCUT_GROUP_PARENT_TYPE gtk_object_get_type ()
+
+static GtkObjectClass *shortcut_parent_class;
+static GtkObjectClass *shortcut_group_parent_class;
+
+enum {
+ STRUCTURE_CHANGED,
+ LAST_SIGNAL
+};
+
+static unsigned int sg_signals [LAST_SIGNAL] = { 0, };
+
+static void
+es_destroy (GtkObject *object)
+{
+ EShortcut *ef = E_SHORTCUT (object);
+
+ gtk_object_unref (GTK_OBJECT (ef->efolder));
+
+ shortcut_parent_class->destroy (object);
+}
+
+static void
+e_shortcut_class_init (GtkObjectClass *object_class)
+{
+ object_class->destroy = es_destroy;
+ shortcut_parent_class = gtk_type_class (SHORTCUT_PARENT_TYPE);
+}
+
+static void
+esg_destroy (GtkObject *object)
+{
+ EShortcutGroup *efg = E_SHORTCUT_GROUP (object);
+ const int shortcut_count = efg->shortcuts->len;
+ int i;
+
+ g_free (efg->title);
+
+ for (i = 0; i < shortcut_count; i++){
+ EShortcut *es = g_array_index (efg->shortcuts, EShortcut *, i);
+
+ gtk_object_unref (GTK_OBJECT (es));
+ }
+
+ g_array_free (efg->shortcuts, TRUE);
+
+ shortcut_group_parent_class->destroy (object);
+}
+
+typedef void (*MyGtkSignal_NONE__INT_INT_INT) (GtkObject * object,
+ int arg1,
+ int arg2,
+ int arg3,
+ gpointer user_data);
+static void
+mygtk_marshal_NONE__INT_INT_INT (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args)
+{
+ MyGtkSignal_NONE__INT_INT_INT rfunc;
+ rfunc = (MyGtkSignal_NONE__INT_INT_INT) func;
+
+ (*rfunc) (object,
+ GTK_VALUE_INT (args[0]),
+ GTK_VALUE_INT (args[1]),
+ GTK_VALUE_INT (args[2]),
+ func_data);
+}
+
+static void
+e_shortcut_group_class_init (GtkObjectClass *object_class)
+{
+ object_class->destroy = esg_destroy;
+ shortcut_parent_class = gtk_type_class (SHORTCUT_GROUP_PARENT_TYPE);
+
+ sg_signals [STRUCTURE_CHANGED] =
+ gtk_signal_new ("structure_changed",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EShortcutGroupClass, structure_changed),
+ mygtk_marshal_NONE__INT_INT_INT,
+ GTK_TYPE_NONE,
+ 3,
+ GTK_TYPE_ENUM, GTK_TYPE_INT, GTK_TYPE_INT);
+ gtk_object_class_add_signals (
+ object_class, sg_signals, LAST_SIGNAL);
+
+}
+
+static void
+e_shortcut_group_init (GtkObject *object)
+{
+ EShortcutGroup *esg = E_SHORTCUT_GROUP (object);
+
+ esg->shortcuts = g_array_new (FALSE, FALSE, sizeof (EShortcut *));
+}
+
+E_MAKE_TYPE (e_shortcut, "EShortcut", EShortcut, e_shortcut_class_init, NULL, SHORTCUT_PARENT_TYPE);
+E_MAKE_TYPE (e_shortcut_group, "EShortcutGroup", EShortcutGroup, e_shortcut_group_class_init, e_shortcut_group_init, SHORTCUT_GROUP_PARENT_TYPE);
+
+EShortcut *
+e_shortcut_new (EFolder *efolder)
+{
+ EShortcut *shortcut = gtk_type_new (e_shortcut_get_type ());
+
+ shortcut->efolder = efolder;
+ gtk_object_ref (GTK_OBJECT (efolder));
+
+ return shortcut;
+}
+
+EShortcutGroup *
+e_shortcut_group_new (const char *title, gboolean small_icons)
+{
+ EShortcutGroup *shortcut_group = gtk_type_new (e_shortcut_group_get_type ());
+
+ shortcut_group->title = g_strdup (title);
+ shortcut_group->small_icons = small_icons;
+ return shortcut_group;
+}
+
+static void
+es_emit (EShortcutGroup *sg, EShortcutGroupChange change, int arg1, int arg2)
+{
+ gtk_signal_emit (GTK_OBJECT (sg), sg_signals [STRUCTURE_CHANGED], change, arg1, arg2);
+}
+
+void
+e_shortcut_group_append (EShortcutGroup *sg, EShortcut *shortcut)
+{
+ g_return_if_fail (sg != NULL);
+ g_return_if_fail (E_IS_SHORTCUT_GROUP (sg));
+ g_return_if_fail (shortcut != NULL);
+ g_return_if_fail (E_IS_SHORTCUT (shortcut));
+
+ gtk_object_ref (GTK_OBJECT (shortcut));
+ g_array_append_val (sg->shortcuts, shortcut);
+
+ es_emit (sg, E_SHORTCUT_GROUP_ITEM_ADDED, sg->shortcuts->len-1, 0);
+}
+
+void
+e_shortcut_group_remove (EShortcutGroup *sg, EShortcut *shortcut)
+{
+ g_return_if_fail (sg != NULL);
+ g_return_if_fail (E_IS_SHORTCUT_GROUP (sg));
+ g_return_if_fail (shortcut != NULL);
+ g_return_if_fail (E_IS_SHORTCUT (sg));
+
+ {
+ const int len = sg->shortcuts->len;
+ int i;
+
+ for (i = 0; i < len; i++){
+ EShortcut *es = g_array_index (sg->shortcuts, EShortcut *, i);
+
+ if (es == shortcut){
+ g_array_remove_index (sg->shortcuts, i);
+ es_emit (sg, E_SHORTCUT_GROUP_ITEM_REMOVED, i, 0);
+ return;
+ }
+ }
+ }
+}
+
+void
+e_shortcut_group_move (EShortcutGroup *sg, int from, int to)
+{
+ EShortcut *t;
+
+ g_return_if_fail (sg != NULL);
+ g_return_if_fail (E_IS_SHORTCUT_GROUP (sg));
+
+ g_return_if_fail (from < sg->shortcuts->len);
+ g_return_if_fail (to < sg->shortcuts->len);
+ g_return_if_fail (from >= 0);
+ g_return_if_fail (to >= 0);
+
+ if (from == to)
+ return;
+
+ t = g_array_index (sg->shortcuts, EShortcut *, from);
+ g_array_index (sg->shortcuts, EShortcut *, from) =
+ g_array_index (sg->shortcuts, EShortcut *, to);
+ g_array_index (sg->shortcuts, EShortcut *, to) = t;
+
+ es_emit (sg, E_SHORTCUT_GROUP_ITEM_MOVED, from, to);
+}
diff --git a/shell/e-shortcut.h b/shell/e-shortcut.h
new file mode 100644
index 0000000000..1087fb0847
--- /dev/null
+++ b/shell/e-shortcut.h
@@ -0,0 +1,59 @@
+#ifndef SHELL_SHORTCUT_H
+#define SHELL_SHORTCUT_H
+
+#include <gtk/gtkobject.h>
+#include "e-folder.h"
+
+#define E_SHORTCUT_TYPE (e_shortcut_get_type ())
+#define E_SHORTCUT(o) (GTK_CHECK_CAST ((o), E_SHORTCUT_TYPE, EShortcut))
+#define E_SHORTCUT_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_SHORTCUT_TYPE, EShortcutClass))
+#define E_IS_SHORTCUT(o) (GTK_CHECK_TYPE ((o), E_SHORTCUT_TYPE))
+#define E_IS_SHORTCUT_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_SHORTCUT_TYPE))
+
+typedef struct {
+ GtkObject object;
+ EFolder *efolder;
+} EShortcut;
+
+typedef struct {
+ GtkObjectClass parent_class;
+} EShortcutClass;
+
+#define E_SHORTCUT_GROUP_TYPE (e_shortcut_group_get_type ())
+#define E_SHORTCUT_GROUP(o) (GTK_CHECK_CAST ((o), E_SHORTCUT_GROUP_TYPE, EShortcutGroup))
+#define E_SHORTCUT_GROUP_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_SHORTCUT_GROUP_TYPE, EShortcutGroupClass))
+#define E_IS_SHORTCUT_GROUP(o) (GTK_CHECK_TYPE ((o), E_SHORTCUT_GROUP_TYPE))
+#define E_IS_SHORTCUT_GROUP_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_SHORTCUT_GROUP_TYPE))
+
+typedef struct {
+ GtkObject object;
+ char *group_name;
+ GArray *shortcuts;
+ char *title;
+ gboolean small_icons;
+} EShortcutGroup;
+
+typedef enum {
+ E_SHORTCUT_GROUP_ITEM_ADDED,
+ E_SHORTCUT_GROUP_ITEM_REMOVED,
+ E_SHORTCUT_GROUP_ITEM_MOVED,
+} EShortcutGroupChange;
+
+typedef struct {
+ GtkObjectClass parent_class;
+
+ void (*structure_changed) (EShortcutGroup *, EShortcutGroupChange change, int arg1, int arg2);
+} EShortcutGroupClass;
+
+GtkType e_shortcut_get_type (void);
+EShortcut *e_shortcut_new (EFolder *efolder);
+
+GtkType e_shortcut_group_get_type (void);
+EShortcutGroup *e_shortcut_group_new (const char *name, gboolean small_icons);
+void e_shortcut_group_append (EShortcutGroup *sg, EShortcut *shortcut);
+void e_shortcut_group_destroy (EShortcutGroup *sg);
+void e_shortcut_group_remove (EShortcutGroup *sg, EShortcut *shortcut);
+void e_shortcut_group_move (EShortcutGroup *sg, int from, int to);
+
+
+#endif