diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-08-30 06:32:46 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-08-30 06:32:46 +0800 |
commit | e0c501b7018f12d37b10e32923f95b7a01c7982c (patch) | |
tree | 0114cbe9529000ec06dbe4ebe927e8c6cafbf0ba | |
parent | 02a9eb68308537fe712e757017ae4bb372863a8c (diff) | |
download | gsoc2013-evolution-e0c501b7018f12d37b10e32923f95b7a01c7982c.tar.gz gsoc2013-evolution-e0c501b7018f12d37b10e32923f95b7a01c7982c.tar.zst gsoc2013-evolution-e0c501b7018f12d37b10e32923f95b7a01c7982c.zip |
Progress update:
- Contacts module partially working!
- Implement UI merging. Also merge EInfoLabel into ESidebar.
The shell window now manages the icon and labels and keeps
them up-to-date via EShellView properties.
svn path=/branches/kill-bonobo/; revision=36214
34 files changed, 1021 insertions, 891 deletions
diff --git a/Makefile.am b/Makefile.am index 7f5097db82..fc1db9f378 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,6 +61,7 @@ SUBDIRS = \ a11y \ widgets \ shell \ + $(SMIME_DIR) \ addressbook \ art \ ui \ diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index 6726d2b050..7eaa46b079 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -20,7 +20,7 @@ INCLUDES = \ $(LDAP_CFLAGS) \ $(EVOLUTION_ADDRESSBOOK_CFLAGS) -component_LTLIBRARIES = libevolution-addressbook.la +module_LTLIBRARIES = libevolution-addressbook.la libevolution_addressbook_la_SOURCES = \ addressbook-config.c \ @@ -31,9 +31,6 @@ libevolution_addressbook_la_SOURCES = \ autocompletion-config.h \ addressbook.c \ addressbook.h \ - addressbook-view.c \ - addressbook-view.h \ - component-factory.c \ e-book-shell-module.c \ e-book-shell-view.c \ e-book-shell-view.h \ diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c index 740e2c0575..3907f6648d 100644 --- a/addressbook/gui/component/addressbook-config.c +++ b/addressbook/gui/component/addressbook-config.c @@ -53,8 +53,6 @@ #define LDAPS_PORT_STRING "636" #define GLADE_FILE_NAME "ldap-config.glade" -#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory:" BASE_VERSION -#define LDAP_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl:" BASE_VERSION GtkWidget* supported_bases_create_table (char *name, char *string1, char *string2, int num1, int num2); diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c index b45329b37e..34a15c2921 100644 --- a/addressbook/gui/component/addressbook-view.c +++ b/addressbook/gui/component/addressbook-view.c @@ -111,10 +111,6 @@ static void activate_source (AddressbookView *view, ESource *source); static void addressbook_view_init (AddressbookView *view); static void addressbook_view_class_init (AddressbookViewClass *klass); -static void addressbook_view_dispose (GObject *object); - -static ESource *find_first_source (ESourceList *source_list); -static ESource *get_primary_source (AddressbookView *view); static void set_status_message (EABView *eav, const char *message, AddressbookView *view) @@ -234,26 +230,6 @@ load_uri_for_selection (ESourceSelector *selector, activate_source (view, selected_source); } -static ESource * -find_first_source (ESourceList *source_list) -{ - GSList *groups, *sources, *l, *m; - - groups = e_source_list_peek_groups (source_list); - for (l = groups; l; l = l->next) { - ESourceGroup *group = l->data; - - sources = e_source_group_peek_sources (group); - for (m = sources; m; m = m->next) { - ESource *source = m->data; - - return source; - } - } - - return NULL; -} - static void save_primary_selection (AddressbookView *view) { @@ -270,38 +246,6 @@ save_primary_selection (AddressbookView *view) e_source_peek_uid (source), NULL); } -static ESource * -get_primary_source (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - char *uid; - - uid = gconf_client_get_string (priv->gconf_client, - "/apps/evolution/addressbook/display/primary_addressbook", - NULL); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - } else { - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - } - - return source; -} - -static void -load_primary_selection (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - - source = get_primary_source (view); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->selector), source); -} - /* Folder popup menu callbacks */ typedef struct { AddressbookView *view; @@ -377,31 +321,6 @@ delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) } static void -new_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - addressbook_config_create_new_source (gtk_widget_get_toplevel(ep->target->widget)); -} - -static void -save_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - EABView *v = get_current_view (view); - if (v) - eab_view_save_as (v, TRUE); -} - -static void -edit_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - if (view) - edit_addressbook_folder (view); -} - -/* Callbacks. */ - -static void primary_source_selection_changed_callback (ESourceSelector *selector, AddressbookView *view) { @@ -409,55 +328,6 @@ primary_source_selection_changed_callback (ESourceSelector *selector, save_primary_selection (view); } -static EPopupItem abv_source_popups[] = { - { E_POPUP_ITEM, "10.new", N_("_New Address Book"), new_addressbook_cb, NULL, "address-book-new", 0, 0 }, - { E_POPUP_ITEM, "20.saveasvcard", N_("Save As vCard..."), save_addressbook_cb, NULL,"document-save-as", 0, EAB_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, "30.bar" }, - { E_POPUP_ITEM, "30.delete", N_("_Delete"), delete_addressbook_cb, NULL, "edit-delete", 0, EAB_POPUP_SOURCE_USER|EAB_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, "99.bar" }, - { E_POPUP_ITEM, "99.properties", N_("_Properties"), edit_addressbook_cb, NULL,"document-properties", 0, EAB_POPUP_SOURCE_PRIMARY }, -}; - -static void -abv_source_popup_free(EPopup *ep, GSList *list, void *data) -{ - g_slist_free(list); -} - -static gboolean -popup_event_callback(ESourceSelector *selector, ESource *source, GdkEventButton *event, AddressbookView *view) -{ - EABPopup *ep; - EABPopupTargetSource *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - - /** @HookPoint-EABPopup:Addressbook Source Selector Context Menu - * @Id: org.gnome.evolution.addressbook.source.popup - * @Class: org.gnome.evolution.addresbook.popup:1.0 - * @Target: EABPopupTargetSource - * - * The context menu on the source selector in the contacts window. - */ - - ep = eab_popup_new("org.gnome.evolution.addressbook.source.popup"); - t = eab_popup_target_new_source(ep, selector); - t->target.widget = (GtkWidget *)view->priv->notebook; - - for (i=0;i<sizeof(abv_source_popups)/sizeof(abv_source_popups[0]);i++) - menus = g_slist_prepend(menus, &abv_source_popups[i]); - - e_popup_add_items((EPopup *)ep, menus, NULL, abv_source_popup_free, view); - - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time()); - - return TRUE; -} - static gboolean selector_tree_drag_drop (GtkWidget *widget, GdkDragContext *context, @@ -696,58 +566,6 @@ selector_tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); } - -static void -destroy_callback(gpointer data, GObject *where_object_was) -{ - AddressbookView *view = data; - g_object_unref (view); -} - -GType -addressbook_view_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (AddressbookViewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) addressbook_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EABView), - 0, /* n_preallocs */ - (GInstanceInitFunc) addressbook_view_init, - }; - - type = g_type_register_static (PARENT_TYPE, "AddressbookView", &info, 0); - } - - return type; -} - -static void -addressbook_view_class_init (AddressbookViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = addressbook_view_dispose; - - parent_class = g_type_class_peek_parent (klass); -} - -static gboolean -source_selector_key_press_event_callback (GtkWidget *widget, GdkEventKey *event, AddressbookView *view) -{ - if (event->keyval == GDK_Delete) { - delete_addressbook_folder (view); - return TRUE; - } - return FALSE; -} - static void addressbook_view_init (AddressbookView *view) { @@ -755,84 +573,21 @@ addressbook_view_init (AddressbookView *view) GtkWidget *selector_scrolled_window; AtkObject *a11y; - view->priv = - priv = g_new0 (AddressbookViewPrivate, 1); - - priv->gconf_client = addressbook_component_peek_gconf_client (addressbook_component_peek ()); - - priv->uid_to_view = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_object_unref); - priv->uid_to_editor = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify)g_free, (GDestroyNotify)g_free); - - priv->notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE); - - g_object_weak_ref (G_OBJECT (priv->notebook), destroy_callback, view); - - /* Create the control. */ - priv->folder_view_control = bonobo_control_new (priv->notebook); - - gtk_widget_show (priv->notebook); - - e_book_get_addressbooks (&priv->source_list, NULL); - g_signal_connect (priv->source_list, - "changed", - G_CALLBACK (source_list_changed_cb), view); - - priv->creatable_items_handler = e_user_creatable_items_handler_new ("contacts", NULL, NULL); priv->menu = eab_menu_new("org.gnome.evolution.addressbook.view"); g_signal_connect (priv->folder_view_control, "activate", G_CALLBACK (control_activate_cb), view); - priv->activity_handler = e_activity_handler_new (); - - priv->statusbar_widget = e_task_bar_new (); - gtk_widget_show (priv->statusbar_widget); - - e_activity_handler_attach_task_bar (priv->activity_handler, - E_TASK_BAR (priv->statusbar_widget)); - - priv->info_widget = e_info_label_new("x-office-address-book"); - e_info_label_set_info((EInfoLabel*)priv->info_widget, _("Contacts"), ""); - gtk_widget_show (priv->info_widget); - - priv->selector = e_source_selector_new (priv->source_list); - g_signal_connect (priv->selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion), view); g_signal_connect (priv->selector, "drag-leave", G_CALLBACK (selector_tree_drag_leave), view); g_signal_connect (priv->selector, "drag-drop", G_CALLBACK (selector_tree_drag_drop), view); g_signal_connect (priv->selector, "drag-data-received", G_CALLBACK (selector_tree_drag_data_received), view); gtk_drag_dest_set (priv->selector, GTK_DEST_DEFAULT_ALL, drag_types, num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE); - a11y = gtk_widget_get_accessible (GTK_WIDGET (priv->selector)); - atk_object_set_name (a11y, _("Contact Source Selector")); - - e_source_selector_show_selection (E_SOURCE_SELECTOR (priv->selector), FALSE); - gtk_widget_show (priv->selector); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), priv->selector); - gtk_widget_show (selector_scrolled_window); - - priv->sidebar_widget = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), priv->info_widget, FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX (priv->sidebar_widget), selector_scrolled_window, TRUE, TRUE, 0); - gtk_widget_show (priv->sidebar_widget); g_signal_connect_object (priv->selector, "primary_selection_changed", G_CALLBACK (primary_source_selection_changed_callback), G_OBJECT (view), 0); - g_signal_connect_after (priv->selector, "key_press_event", - G_CALLBACK (source_selector_key_press_event_callback), - G_OBJECT (view)); - g_signal_connect_object (priv->selector, "popup_event", - G_CALLBACK (popup_event_callback), - G_OBJECT (view), 0); - load_primary_selection (view); load_uri_for_selection (E_SOURCE_SELECTOR (priv->selector), view, TRUE); } @@ -849,43 +604,6 @@ destroy_editor (char *key, gtk_widget_destroy (GTK_WIDGET (closure->editor)); } -static void -addressbook_view_dispose (GObject *object) -{ - AddressbookView *view = ADDRESSBOOK_VIEW (object); - AddressbookViewPrivate *priv = view->priv; - - if (view->priv) { - if (priv->book) - g_object_unref (priv->book); - - g_free(priv->passwd); - - if (priv->source_list) - g_object_unref (priv->source_list); - - if (priv->uid_to_view) - g_hash_table_destroy (priv->uid_to_view); - - if (priv->uid_to_editor) { - g_hash_table_foreach (priv->uid_to_editor, (GHFunc)destroy_editor, NULL); - g_hash_table_destroy (priv->uid_to_editor); - } - - if (priv->creatable_items_handler) - g_object_unref (priv->creatable_items_handler); - - if (priv->menu) - g_object_unref (priv->menu); - - g_free (view->priv); - view->priv = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - typedef struct { EABView *view; ESource *source; @@ -1033,52 +751,6 @@ activate_source (AddressbookView *view, } } -AddressbookView * -addressbook_view_new (void) -{ - return g_object_new (ADDRESSBOOK_TYPE_VIEW, NULL); -} - -EActivityHandler* -addressbook_view_peek_activity_handler (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->activity_handler; -} - -GtkWidget* -addressbook_view_peek_info_label (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->info_widget; -} - -GtkWidget* -addressbook_view_peek_sidebar (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->sidebar_widget; -} - -GtkWidget* -addressbook_view_peek_statusbar (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->statusbar_widget; -} - -BonoboControl* -addressbook_view_peek_folder_view (AddressbookView *view) -{ - g_return_val_if_fail (ADDRESSBOOK_IS_VIEW (view), NULL); - - return view->priv->folder_view_control; -} - void addressbook_view_edit_contact (AddressbookView* view, const char* source_uid, diff --git a/addressbook/gui/component/autocompletion-config.c b/addressbook/gui/component/autocompletion-config.c index b410d74634..060ce01aee 100644 --- a/addressbook/gui/component/autocompletion-config.c +++ b/addressbook/gui/component/autocompletion-config.c @@ -16,47 +16,32 @@ * License along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. - * - * Authors: Chris Toshok <toshok@ximian.com> */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - #include "autocompletion-config.h" -#include "Evolution.h" - -#include <bonobo/bonobo-exception.h> - -#include <libedataserver/e-source-list.h> -#include <libedataserverui/e-source-selector.h> +#include <e-shell.h> #include <gtk/gtk.h> #include <glib/gi18n.h> - - -typedef struct { - EvolutionConfigControl *config_control; - - GtkWidget *control_widget; - - ESourceList *source_list; -} AutocompletionConfig; +#include <e-preferences-window.h> +#include <libedataserver/e-source-list.h> +#include <libedataserverui/e-source-selector.h> static void -source_selection_changed (ESourceSelector *selector, - AutocompletionConfig *ac) +source_selection_changed_cb (ESourceSelector *source_selector) { + ESourceList *source_list; GSList *selection; GSList *l; GSList *groups; + source_list = e_source_selector_get_source_list (source_selector); + /* first we clear all the completion flags from all sources */ - for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) { + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { ESourceGroup *group = E_SOURCE_GROUP (groups->data); GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { ESource *source = E_SOURCE (sources->data); @@ -66,86 +51,78 @@ source_selection_changed (ESourceSelector *selector, /* then we loop over the selector's selection, setting the property on those sources */ - selection = e_source_selector_get_selection (selector); + selection = e_source_selector_get_selection (source_selector); for (l = selection; l; l = l->next) { - e_source_set_property (E_SOURCE (l->data), "completion", "true"); + ESource *source = E_SOURCE (l->data); + + e_source_set_property (source, "completion", "true"); } e_source_selector_free_selection (selection); - e_source_list_sync (ac->source_list, NULL); /* XXX we should pop up a dialog if this fails */ + /* XXX we should pop up a dialog if this fails */ + e_source_list_sync (source_list, NULL); } static void -config_control_destroy_notify (void *data, - GObject *where_the_config_control_was) -{ - AutocompletionConfig *ac = (AutocompletionConfig *) data; - - g_object_unref (ac->source_list); - - g_free (ac); -} - -static void -initialize_selection (AutocompletionConfig *ac) +initialize_selection (ESourceSelector *source_selector) { + ESourceList *source_list; GSList *groups; - for (groups = e_source_list_peek_groups (ac->source_list); groups; groups = groups->next) { + source_list = e_source_selector_get_source_list (source_selector); + + for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { ESourceGroup *group = E_SOURCE_GROUP (groups->data); GSList *sources; + for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { ESource *source = E_SOURCE (sources->data); - const char *completion = e_source_get_property (source, "completion"); + const char *completion; + + completion = e_source_get_property (source, "completion"); if (completion && !g_ascii_strcasecmp (completion, "true")) - e_source_selector_select_source (E_SOURCE_SELECTOR (ac->control_widget), - source); + e_source_selector_select_source (source_selector, source); } } } -EvolutionConfigControl* -autocompletion_config_control_new (void) +void +autocompletion_config_init (void) { - AutocompletionConfig *ac; - CORBA_Environment ev; - GtkWidget *scrolledwin; - - ac = g_new0 (AutocompletionConfig, 1); + ESourceList *source_list; + GtkWidget *scrolled_window; + GtkWidget *source_selector; + GtkWidget *preferences_window; - CORBA_exception_init (&ev); + source_list = e_source_list_new_for_gconf_default ( + "/apps/evolution/addressbook/sources"); - ac->source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources"); /* XXX should we watch for the source list to change and update it in the control? what about our local changes? */ /* g_signal_connect (ac->source_list, "changed", G_CALLBACK (source_list_changed), ac); */ - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_SHADOW_IN); - - ac->control_widget = e_source_selector_new (ac->source_list); - - gtk_container_add (GTK_CONTAINER (scrolledwin), ac->control_widget); - - initialize_selection (ac); - - gtk_widget_show (ac->control_widget); - gtk_widget_show (scrolledwin); - - ac->config_control = evolution_config_control_new (scrolledwin); - - g_signal_connect (ac->control_widget, "selection_changed", - G_CALLBACK (source_selection_changed), ac); - - g_object_weak_ref (G_OBJECT (ac->config_control), config_control_destroy_notify, ac); - - CORBA_exception_free (&ev); - - return ac->config_control; + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); + gtk_widget_show (scrolled_window); + + source_selector = e_source_selector_new (source_list); + g_signal_connect ( + source_selector, "selection_changed", + G_CALLBACK (source_selection_changed_cb), NULL); + gtk_container_add (GTK_CONTAINER (scrolled_window), source_selector); + gtk_widget_show (source_selector); + + initialize_selection (E_SOURCE_SELECTOR (source_selector)); + + e_preferences_window_add_page ( + e_shell_get_preferences_window (), + "autocompletion", + "preferences-autocompletion", + _("Autocompletion"), + scrolled_window, + 200); } - diff --git a/addressbook/gui/component/autocompletion-config.h b/addressbook/gui/component/autocompletion-config.h index d55ef2cd79..1ad958235e 100644 --- a/addressbook/gui/component/autocompletion-config.h +++ b/addressbook/gui/component/autocompletion-config.h @@ -23,8 +23,12 @@ #ifndef _AUTOCOMPLETION_CONFIG_H #define _AUTOCOMPLETION_CONFIG_H -#include "evolution-config-control.h" +#include <glib.h> -EvolutionConfigControl* autocompletion_config_control_new (void); +G_BEGIN_DECLS + +void autocompletion_config_init (void); + +G_END_DECLS #endif /* _AUTOCOMPLETION_CONFIG_H */ diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index 25693234ee..aaaa6fecdb 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -18,11 +18,22 @@ * Boston, MA 02110-1301, USA. */ +#include <string.h> +#include <glib/gi18n.h> +#include <libebook/e-book.h> +#include <libedataserver/e-url.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-list.h> +#include <libedataserver/e-source-group.h> + #include <e-shell.h> #include <e-shell-module.h> #include <e-shell-window.h> -#include "e-book-shell-view.h" +#include <eab-gui-util.h> +#include <e-book-shell-view.h> +#include <addressbook-config.h> +#include <autocompletion-config.h> #define MODULE_NAME "addressbook" #define MODULE_ALIASES "" @@ -174,7 +185,7 @@ book_module_book_loaded_cb (EBook *book, if (g_str_equal (action_name, "contact-new")) eab_show_contact_editor (book, contact, TRUE, TRUE); - if (g_str_equal (action_name, "contact-list-new") == 0) + if (g_str_equal (action_name, "contact-list-new")) eab_show_contact_list_editor (book, contact, TRUE, TRUE); g_object_unref (contact); @@ -189,6 +200,7 @@ action_contact_new_cb (GtkAction *action, GConfClient *client; ESourceList *source_list; const gchar *key; + gchar *uid; /* This callback is used for both contacts and contact lists. */ @@ -260,6 +272,8 @@ book_module_is_busy (EShellModule *shell_module) static gboolean book_module_shutdown (EShellModule *shell_module) { + /* FIXME */ + return TRUE; } static gboolean @@ -282,7 +296,7 @@ book_module_handle_uri (EShellModule *shell_module, return FALSE; } - while (*cp != NULL) { + while (*cp != '\0') { gchar *header; gchar *content; gsize length; @@ -345,7 +359,7 @@ book_module_window_created (EShellModule *shell_module, source_entries, G_N_ELEMENTS (source_entries)); } -static EShellmoduleInfo module_info = { +static EShellModuleInfo module_info = { MODULE_NAME, MODULE_ALIASES, @@ -378,4 +392,6 @@ e_shell_module_init (GTypeModule *type_module) g_signal_connect_swapped ( shell, "window-created", G_CALLBACK (book_module_window_created), shell_module); + + autocompletion_config_init (); } diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c index 8d2d1a7739..d5f961ec66 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.c +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -20,8 +20,11 @@ #include "e-book-shell-view-private.h" +#include <e-util/e-error.h> #include <e-util/e-util.h> +#include <addressbook-config.h> + static void action_address_book_copy_cb (GtkAction *action, EBookShellView *book_shell_view) @@ -101,6 +104,19 @@ action_address_book_move_cb (GtkAction *action, } static void +action_address_book_new_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_window (shell_view); + + addressbook_config_create_new_source (GTK_WIDGET (shell_window)); +} + +static void action_address_book_properties_cb (GtkAction *action, EBookShellView *book_shell_view) { @@ -127,7 +143,7 @@ action_address_book_properties_cb (GtkAction *action, GtkWidget *editor; editor = addressbook_config_edit_source ( - GTK_WINDOW (shell_window), source); + GTK_WIDGET (shell_window), source); closure = g_new (EditorUidClosure, 1); closure->editor = editor; @@ -342,19 +358,26 @@ static GtkActionEntry contact_entries[] = { N_("Move the contacts of the selected address book to another"), G_CALLBACK (action_address_book_move_cb) }, + { "address-book-new", + "address-book-new", + N_("_New Address Book"), + NULL, + N_("Create a new address book"), + G_CALLBACK (action_address_book_new_cb) }, + { "address-book-properties", GTK_STOCK_PROPERTIES, N_("Address _Book Properties"), NULL, - N_("Change the properties of the selected address book"), + N_("Show properties of the selected address book"), G_CALLBACK (action_address_book_properties_cb) }, { "address-book-save-as", GTK_STOCK_SAVE_AS, - N_("S_ave Address Book as VCard"), + N_("S_ave Address Book as vCard"), NULL, - N_("Save the contacts of the selected address book as a VCard"), - G_CALLBACK (action_address_book_save_as) }, + N_("Save the contacts of the selected address book as a vCard"), + G_CALLBACK (action_address_book_save_as_cb) }, { "address-book-stop", GTK_STOCK_STOP, @@ -435,9 +458,9 @@ static GtkActionEntry contact_entries[] = { { "contact-save-as", GTK_STOCK_SAVE_AS, - N_("Save as VCard..."), + N_("Save as vCard..."), NULL, - N_("Save selected contacts as a VCard"), + N_("Save selected contacts as a vCard"), G_CALLBACK (action_contact_save_as_cb) }, { "contact-select-all", @@ -452,7 +475,39 @@ static GtkActionEntry contact_entries[] = { N_("_Send Message to Contact..."), NULL, N_("Send a message to the selected contacts"), - G_CALLBACK (action_contact_send_message_cb) } + G_CALLBACK (action_contact_send_message_cb) }, + + /*** Menus ***/ + + { "actions-menu", + NULL, + N_("_Actions"), + NULL, + NULL, + NULL }, + + /*** Address Book Popup Actions ***/ + + { "address-book-popup-delete", + GTK_STOCK_DELETE, + NULL, + NULL, + N_("Delete this address book"), + G_CALLBACK (action_address_book_delete_cb) }, + + { "address-book-popup-properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + N_("Show properties of this address book"), + G_CALLBACK (action_address_book_properties_cb) }, + + { "address-book-popup-save-as", + GTK_STOCK_SAVE_AS, + N_("_Save as vCard..."), + NULL, + N_("Save the contents of this address book as a vCard"), + G_CALLBACK (action_address_book_save_as_cb) } }; static GtkToggleActionEntry contact_toggle_entries[] = { @@ -473,6 +528,7 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) EShellWindow *shell_window; GtkActionGroup *action_group; GtkUIManager *manager; + GtkAction *action; const gchar *domain; shell_view = E_SHELL_VIEW (book_shell_view); @@ -491,4 +547,9 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) action_group, contact_toggle_entries, G_N_ELEMENTS (contact_toggle_entries), book_shell_view); gtk_ui_manager_insert_action_group (manager, action_group, 0); + + /* Fine tuning. */ + + action = ACTION (CONTACT_DELETE); + g_object_set (action, "short-label", _("Delete"), NULL); } diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index cfc12662f0..0bf0832c58 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -20,12 +20,70 @@ #include "e-book-shell-view-private.h" +static gboolean +book_shell_view_show_popup_menu (GdkEventButton *event, + EShellView *shell_view) +{ + GtkWidget *menu; + EShellWindow *shell_window; + const gchar *widget_path; + + widget_path = "/address-book-popup"; + shell_window = e_shell_view_get_window (shell_view); + menu = e_shell_window_get_managed_widget (shell_window, widget_path); + + if (event != NULL) + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + event->button, event->time); + else + gtk_menu_popup ( + GTK_MENU (menu), NULL, NULL, NULL, NULL, + 0, gtk_get_current_event_time ()); + + return TRUE; +} + +static gboolean +book_shell_view_selector_button_press_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + return book_shell_view_show_popup_menu (event, shell_view); + + return FALSE; +} + +static gboolean +book_shell_view_selector_popup_menu_cb (EShellView *shell_view) +{ + return book_shell_view_show_popup_menu (NULL, shell_view); +} + +static gboolean +book_shell_view_selector_key_press_event_cb (EShellView *shell_view, + GdkEventKey *event) +{ + EShellWindow *shell_window; + + /* Needed for the ACTION() macro. */ + shell_window = e_shell_view_get_window (shell_view); + + if (event->keyval == GDK_Delete) { + gtk_action_activate (ACTION (ADDRESS_BOOK_DELETE)); + return TRUE; + } + + return FALSE; +} + void e_book_shell_view_private_init (EBookShellView *book_shell_view) { EBookShellViewPrivate *priv = book_shell_view->priv; GHashTable *uid_to_view; GHashTable *uid_to_editor; + GtkWidget *container; GtkWidget *widget; uid_to_view = g_hash_table_new_full ( @@ -39,8 +97,11 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) (GDestroyNotify) g_free); priv->contact_actions = gtk_action_group_new ("contacts"); + priv->activity_handler = e_activity_handler_new (); + priv->uid_to_view = uid_to_view; + priv->uid_to_editor = uid_to_editor; - e_book_shell_view_actions_init (book_shell_view); + e_book_get_addressbooks (&priv->source_list, NULL); widget = gtk_notebook_new (); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); @@ -48,7 +109,43 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) priv->notebook = g_object_ref_sink (widget); gtk_widget_show (widget); - e_book_get_addressbooks (&priv->source_list, NULL); + widget = e_task_bar_new (); + e_activity_handler_attach_task_bar ( + priv->activity_handler, E_TASK_BAR (widget)); + priv->task_bar = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + priv->scrolled_window = g_object_ref_sink (widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_source_selector_new (priv->source_list); + e_source_selector_show_selection (E_SOURCE_SELECTOR (widget), FALSE); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "button-press-event", + G_CALLBACK (book_shell_view_selector_button_press_event_cb), + book_shell_view); + + g_signal_connect_swapped ( + widget, "key-press-event", + G_CALLBACK (book_shell_view_selector_key_press_event_cb), + book_shell_view); + + g_signal_connect_swapped ( + widget, "popup-menu", + G_CALLBACK (book_shell_view_selector_popup_menu_cb), + book_shell_view); } void @@ -56,11 +153,20 @@ e_book_shell_view_private_dispose (EBookShellView *book_shell_view) { EBookShellViewPrivate *priv = book_shell_view->priv; + DISPOSE (priv->contact_actions); + DISPOSE (priv->notebook); - DISPOSE (priv->source_list); + DISPOSE (priv->scrolled_window); + DISPOSE (priv->selector); + DISPOSE (priv->task_bar); + + DISPOSE (priv->activity_handler); g_hash_table_remove_all (priv->uid_to_view); g_hash_table_remove_all (priv->uid_to_editor); + + DISPOSE (priv->book); + DISPOSE (priv->source_list); } void @@ -70,6 +176,8 @@ e_book_shell_view_private_finalize (EBookShellView *book_shell_view) g_hash_table_destroy (priv->uid_to_view); g_hash_table_destroy (priv->uid_to_editor); + + g_free (priv->password); } EABView * @@ -87,3 +195,13 @@ e_book_shell_view_get_current_view (EBookShellView *book_shell_view) return EAB_VIEW (widget); } + +void +e_book_shell_view_editor_weak_notify (EditorUidClosure *closure, + GObject *where_the_object_was) +{ + GHashTable *hash_table; + + hash_table = closure->view->priv->uid_to_editor; + g_hash_table_remove (hash_table, closure->uid); +} diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index 025efd26fc..426b8e9d11 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -23,6 +23,16 @@ #include "e-book-shell-view.h" +#include <string.h> +#include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> +#include <libebook/e-book.h> +#include <libedataserverui/e-source-selector.h> + +#include <eab-menu.h> +#include <e-activity-handler.h> +#include <e-addressbook-view.h> + #include <e-book-shell-view-actions.h> #define E_BOOK_SHELL_VIEW_GET_PRIVATE(obj) \ @@ -60,15 +70,12 @@ struct _EBookShellViewPrivate { /*** Other Stuff ***/ GtkWidget *notebook; - BonoboControl *folder_view_control; + GtkWidget *scrolled_window; + GtkWidget *selector; + GtkWidget *task_bar; - GtkWidget *statusbar_widget; EActivityHandler *activity_handler; - GtkWidget *info_widget; - GtkWidget *sidebar_widget; - GtkWidget *selector; - GHashTable *uid_to_view; GHashTable *uid_to_editor; @@ -76,7 +83,6 @@ struct _EBookShellViewPrivate { guint activity_id; ESourceList *source_list; gchar *password; - EUserCreatableItemsHandler *creatable_items_handler; EABMenu *menu; }; @@ -94,6 +100,9 @@ void e_book_shell_view_actions_init (EBookShellView *book_shell_view); EABView * e_book_shell_view_get_current_view (EBookShellView *book_shell_view); +void e_book_shell_view_editor_weak_notify + (EditorUidClosure *closure, + GObject *where_the_object_was); G_END_DECLS diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c index 9a55cb0667..13098ab84a 100644 --- a/addressbook/gui/component/e-book-shell-view.c +++ b/addressbook/gui/component/e-book-shell-view.c @@ -23,6 +23,48 @@ GType e_book_shell_view_type = 0; static gpointer parent_class; +static ESource * +book_shell_view_get_primary_source (EBookShellView *book_shell_view) +{ + GConfClient *client; + ESourceList *source_list; + ESource *source = NULL; + const gchar *key; + gchar *uid; + + source_list = book_shell_view->priv->source_list; + + client = gconf_client_get_default (); + key = "/apps/evolution/addressbook/display/primary_addressbook"; + uid = gconf_client_get_string (client, key, NULL); + g_object_unref (client); + + if (uid != NULL) { + source = e_source_list_peek_source_by_uid (source_list, uid); + g_free (uid); + } else { + GSList *groups; + + /* Dig up the first source in the source list. + * XXX libedataserver should provide API for this. */ + groups = e_source_list_peek_groups (source_list); + while (groups != NULL) { + ESourceGroup *source_group = groups->data; + GSList *sources; + + sources = e_source_group_peek_sources (source_group); + if (sources != NULL) { + source = sources->data; + break; + } + + groups = g_slist_next (groups); + } + } + + return source; +} + static void book_shell_view_update_actions (EBookShellView *book_shell_view, EABView *view) @@ -111,16 +153,6 @@ book_shell_view_update_actions (EBookShellView *book_shell_view, } static void -book_shell_view_editor_weak_notify (EditorUidClosure *closure, - GObject *where_the_object_was) -{ - GHashTable *hash_table; - - hash_table = closure->view->priv->uid_to_editor; - g_hash_table_remove (hash_table, closure->uid); -} - -static void book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view, ESourceList *source_list) { @@ -162,7 +194,7 @@ book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view, closure = g_hash_table_lookup (priv->uid_to_editor, uid); g_object_weak_unref ( G_OBJECT (closure->editor), (GWeakNotify) - book_shell_view_editor_weak_notify, closure); + e_book_shell_view_editor_weak_notify, closure); gtk_widget_destroy (closure->editor); g_hash_table_remove (priv->uid_to_editor, uid); } @@ -196,19 +228,56 @@ book_shell_view_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +book_shell_view_constructed (GObject *object) +{ + e_book_shell_view_actions_init (E_BOOK_SHELL_VIEW (object)); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); +} + static GtkWidget * book_shell_view_get_content_widget (EShellView *shell_view) { + EBookShellViewPrivate *priv; + + priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); + + return priv->notebook; } static GtkWidget * book_shell_view_get_sidebar_widget (EShellView *shell_view) { + EBookShellViewPrivate *priv; + + priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); + + return priv->scrolled_window; } static GtkWidget * book_shell_view_get_status_widget (EShellView *shell_view) { + EBookShellViewPrivate *priv; + + priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); + + return priv->task_bar; +} + +static void +book_shell_view_changed (EShellView *shell_view, + gboolean visible) +{ + EBookShellViewPrivate *priv; + GtkActionGroup *action_group; + + priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); + + action_group = priv->contact_actions; + gtk_action_group_set_visible (action_group, visible); } static void @@ -218,17 +287,19 @@ book_shell_view_class_init (EBookShellViewClass *class, GObjectClass *object_class; EShellViewClass *shell_view_class; - parent_class = g_type_class_peek-parent (class); + parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EBookShellViewPrivate)); object_class = G_OBJECT_CLASS (class); object_class->dispose = book_shell_view_dispose; object_class->finalize = book_shell_view_finalize; + object_class->constructed = book_shell_view_constructed; shell_view_class = E_SHELL_VIEW_CLASS (class); shell_view_class->label = N_("Contacts"); shell_view_class->icon_name = "x-office-address-book"; shell_view_class->type_module = type_module; + shell_view_class->changed = book_shell_view_changed; shell_view_class->get_content_widget = book_shell_view_get_content_widget; @@ -241,15 +312,23 @@ book_shell_view_class_init (EBookShellViewClass *class, static void book_shell_view_init (EBookShellView *book_shell_view) { + ESourceSelector *selector; + ESource *source; + book_shell_view->priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (book_shell_view); e_book_shell_view_private_init (book_shell_view); g_signal_connect_swapped ( - priv->source_list, "changed", + book_shell_view->priv->source_list, "changed", G_CALLBACK (book_shell_view_source_list_changed_cb), book_shell_view); + + selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); + source = book_shell_view_get_primary_source (book_shell_view); + if (source != NULL) + e_source_selector_set_primary_selection (selector, source); } GType diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h index 27bdefedb5..c6dd17a6ac 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.h +++ b/addressbook/gui/contact-editor/e-contact-editor.h @@ -22,7 +22,6 @@ #include <libgnomeui/gnome-app.h> #include <libgnomeui/gnome-app-helper.h> -#include <bonobo/bonobo-ui-component.h> #include <glade/glade.h> #include "addressbook/gui/contact-editor/eab-editor.h" @@ -62,9 +61,6 @@ struct _EContactEditor EBook *target_book; EContact *contact; - /* UI handler */ - BonoboUIComponent *uic; - GladeXML *gui; GtkWidget *app; diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h index 7736403546..aad4e9bf54 100644 --- a/addressbook/gui/contact-editor/eab-editor.h +++ b/addressbook/gui/contact-editor/eab-editor.h @@ -22,7 +22,6 @@ #include <libgnomeui/gnome-app.h> #include <libgnomeui/gnome-app-helper.h> -#include <bonobo/bonobo-ui-component.h> #include <glade/glade.h> #include <libebook/e-book.h> diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am index 88c7f07011..99a875d278 100644 --- a/addressbook/gui/widgets/Makefile.am +++ b/addressbook/gui/widgets/Makefile.am @@ -61,6 +61,9 @@ libeabwidgets_la_SOURCES = \ gal-view-factory-minicard.c \ gal-view-factory-minicard.h +libeabwidgets_la_LIBADD = \ + $(top_builddir)/widgets/misc/libemiscwidgets.la + MARSHAL_GENERATED = eab-marshal.c eab-marshal.h @EVO_MARSHAL_RULE@ diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c index 42ce9cd8f2..651a44bfa7 100644 --- a/addressbook/gui/widgets/eab-gui-util.c +++ b/addressbook/gui/widgets/eab-gui-util.c @@ -48,7 +48,6 @@ #include "addressbook/gui/contact-editor/eab-editor.h" #include "addressbook/gui/contact-editor/e-contact-editor.h" #include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" -#include "addressbook/gui/component/addressbook-component.h" #include "addressbook/gui/component/addressbook.h" /* the NULL's in this table correspond to the status codes @@ -781,6 +780,7 @@ typedef struct { static void eab_send_to_contact_and_email_num_list (GList *contact_list) { +#if 0 /* NOT READY FOR COMPOSER YET */ EMsgComposer *composer; EComposerHeaderTable *table; GPtrArray *to_array; @@ -844,6 +844,7 @@ eab_send_to_contact_and_email_num_list (GList *contact_list) e_destination_freev (convert.destinations); gtk_widget_show (GTK_WIDGET (composer)); +#endif } static const char * @@ -868,6 +869,7 @@ get_email (EContact *contact, EContactField field_id, gchar **to_free) static void eab_send_contact_list_as_attachment (GList *contacts) { +#if 0 /* NOT READY FOR COMPOSER YET */ EMsgComposer *composer; EComposerHeaderTable *table; CamelMimePart *attachment; @@ -943,6 +945,7 @@ eab_send_contact_list_as_attachment (GList *contacts) } gtk_widget_show (GTK_WIDGET (composer)); +#endif } void diff --git a/addressbook/gui/widgets/eab-popup-control.h b/addressbook/gui/widgets/eab-popup-control.h index 75fff81471..09ae811e1d 100644 --- a/addressbook/gui/widgets/eab-popup-control.h +++ b/addressbook/gui/widgets/eab-popup-control.h @@ -28,6 +28,7 @@ #ifndef __EAB_POPUP_CONTROL_H__ #define __EAB_POPUP_CONTROL_H__ +#include <bonobo/bonobo-control.h> #include <bonobo/bonobo-event-source.h> #include <libebook/e-book.h> #include <libebook/e-contact.h> diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index e1615073e6..dd3a228fb9 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -109,8 +109,6 @@ #include "e-composer-private.h" #include "e-composer-header-table.h" -#include "evolution-shell-component-utils.h" - #ifdef HAVE_XFREE #include <X11/XF86keysym.h> #endif diff --git a/mail/importers/mail-importer.c b/mail/importers/mail-importer.c index d91583f421..ead046ec22 100644 --- a/mail/importers/mail-importer.c +++ b/mail/importers/mail-importer.c @@ -49,7 +49,6 @@ #include "e-util/e-util-private.h" #include "mail/mail-mt.h" -#include "mail/mail-component.h" #include "mail/mail-tools.h" #include "mail-importer.h" diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index af2e9eeb0a..02d53e0696 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -31,6 +31,9 @@ ((obj), E_TYPE_SHELL_VIEW, EShellViewPrivate)) struct _EShellViewPrivate { + gchar *icon_name; + gchar *primary_text; + gchar *secondary_text; gchar *title; gint page_num; gpointer window; /* weak pointer */ @@ -38,12 +41,21 @@ struct _EShellViewPrivate { enum { PROP_0, + PROP_ICON_NAME, PROP_PAGE_NUM, + PROP_PRIMARY_TEXT, + PROP_SECONDARY_TEXT, PROP_TITLE, PROP_WINDOW }; +enum { + CHANGED, + LAST_SIGNAL +}; + static gpointer parent_class; +static gulong signals[LAST_SIGNAL]; static void shell_view_set_page_num (EShellView *shell_view, @@ -71,12 +83,30 @@ shell_view_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_ICON_NAME: + e_shell_view_set_icon_name ( + E_SHELL_VIEW (object), + g_value_get_string (value)); + return; + case PROP_PAGE_NUM: shell_view_set_page_num ( E_SHELL_VIEW (object), g_value_get_int (value)); return; + case PROP_PRIMARY_TEXT: + e_shell_view_set_primary_text ( + E_SHELL_VIEW (object), + g_value_get_string (value)); + return; + + case PROP_SECONDARY_TEXT: + e_shell_view_set_secondary_text ( + E_SHELL_VIEW (object), + g_value_get_string (value)); + return; + case PROP_TITLE: e_shell_view_set_title ( E_SHELL_VIEW (object), @@ -100,12 +130,30 @@ shell_view_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_ICON_NAME: + g_value_set_string ( + value, e_shell_view_get_icon_name ( + E_SHELL_VIEW (object))); + return; + case PROP_PAGE_NUM: g_value_set_int ( value, e_shell_view_get_page_num ( E_SHELL_VIEW (object))); return; + case PROP_PRIMARY_TEXT: + g_value_set_string ( + value, e_shell_view_get_primary_text ( + E_SHELL_VIEW (object))); + return; + + case PROP_SECONDARY_TEXT: + g_value_set_string ( + value, e_shell_view_get_secondary_text ( + E_SHELL_VIEW (object))); + return; + case PROP_TITLE: g_value_set_string ( value, e_shell_view_get_title ( @@ -146,6 +194,9 @@ shell_view_finalize (GObject *object) priv = E_SHELL_VIEW_GET_PRIVATE (object); + g_free (priv->icon_name); + g_free (priv->primary_text); + g_free (priv->secondary_text); g_free (priv->title); /* Chain up to parent's finalize() method. */ @@ -153,6 +204,16 @@ shell_view_finalize (GObject *object) } static void +shell_view_constructed (GObject *object) +{ + /* XXX GObjectClass doesn't implement constructed(), so we will. + * Then subclasses won't have to check the function pointer + * before chaining up. + * + * http://bugzilla.gnome.org/show_bug?id=546593 */ +} + +static void shell_view_class_init (EShellViewClass *class) { GObjectClass *object_class; @@ -165,6 +226,18 @@ shell_view_class_init (EShellViewClass *class) object_class->get_property = shell_view_get_property; object_class->dispose = shell_view_dispose; object_class->finalize = shell_view_finalize; + object_class->constructed = shell_view_constructed; + + g_object_class_install_property ( + object_class, + PROP_ICON_NAME, + g_param_spec_string ( + "icon-name", + _("Icon Name"), + _("The icon name for the sidebar header"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, @@ -181,6 +254,28 @@ shell_view_class_init (EShellViewClass *class) g_object_class_install_property ( object_class, + PROP_PRIMARY_TEXT, + g_param_spec_string ( + "primary-text", + _("Primary Text"), + _("The primary text for the sidebar header"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SECONDARY_TEXT, + g_param_spec_string ( + "secondary-text", + _("Secondary Text"), + _("The secondary text for the sidebar header"), + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, PROP_TITLE, g_param_spec_string ( "title", @@ -200,6 +295,16 @@ shell_view_class_init (EShellViewClass *class) GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EShellViewClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); } static void @@ -253,6 +358,83 @@ e_shell_view_get_name (EShellView *shell_view) } const gchar * +e_shell_view_get_icon_name (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->icon_name; +} + +void +e_shell_view_set_icon_name (EShellView *shell_view, + const gchar *icon_name) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + + if (icon_name == NULL) { + EShellViewClass *class; + + /* Fall back to the switcher icon. */ + class = E_SHELL_VIEW_GET_CLASS (shell_view); + icon_name = class->icon_name; + } + + g_free (shell_view->priv->icon_name); + shell_view->priv->icon_name = g_strdup (icon_name); + + g_object_notify (G_OBJECT (shell_view), "icon-name"); +} + +const gchar * +e_shell_view_get_primary_text (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->primary_text; +} + +void +e_shell_view_set_primary_text (EShellView *shell_view, + const gchar *primary_text) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + + if (primary_text == NULL) { + EShellViewClass *class; + + /* Fall back to the switcher label. */ + class = E_SHELL_VIEW_GET_CLASS (shell_view); + primary_text = class->label; + } + + g_free (shell_view->priv->primary_text); + shell_view->priv->primary_text = g_strdup (primary_text); + + g_object_notify (G_OBJECT (shell_view), "primary-text"); +} + +const gchar * +e_shell_view_get_secondary_text (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->secondary_text; +} + +void +e_shell_view_set_secondary_text (EShellView *shell_view, + const gchar *secondary_text) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + + g_free (shell_view->priv->secondary_text); + shell_view->priv->secondary_text = g_strdup (secondary_text); + g_debug ("%s: %s", G_STRFUNC, secondary_text); + + g_object_notify (G_OBJECT (shell_view), "secondary-text"); +} + +const gchar * e_shell_view_get_title (EShellView *shell_view) { g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); @@ -345,3 +527,21 @@ e_shell_view_get_status_widget (EShellView *shell_view) return class->get_status_widget (shell_view); } + +void +e_shell_view_changed (EShellView *shell_view) +{ + EShellWindow *shell_window; + EShellView *current_view; + const gchar *view_name; + gboolean visible; + + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + + shell_window = e_shell_view_get_window (shell_view); + view_name = e_shell_window_get_current_view (shell_window); + current_view = e_shell_window_get_view (shell_window, view_name); + visible = (current_view == shell_view); + + g_signal_emit (shell_view, signals[CHANGED], 0, visible); +} diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 0c98e32eb4..b474c0aa36 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -68,10 +68,24 @@ struct _EShellViewClass { GtkWidget * (*get_content_widget) (EShellView *shell_view); GtkWidget * (*get_sidebar_widget) (EShellView *shell_view); GtkWidget * (*get_status_widget) (EShellView *shell_view); + + /* Signals */ + + void (*changed) (EShellView *shell_view, + gboolean visible); }; GType e_shell_view_get_type (void); const gchar * e_shell_view_get_name (EShellView *shell_view); +const gchar * e_shell_view_get_icon_name (EShellView *shell_view); +void e_shell_view_set_icon_name (EShellView *shell_view, + const gchar *icon_name); +const gchar * e_shell_view_get_primary_text (EShellView *shell_view); +void e_shell_view_set_primary_text (EShellView *shell_view, + const gchar *primary_text); +const gchar * e_shell_view_get_secondary_text (EShellView *shell_view); +void e_shell_view_set_secondary_text (EShellView *shell_view, + const gchar *secondary_text); const gchar * e_shell_view_get_title (EShellView *shell_view); void e_shell_view_set_title (EShellView *shell_view, const gchar *title); @@ -81,6 +95,7 @@ gint e_shell_view_get_page_num (EShellView *shell_view); GtkWidget * e_shell_view_get_content_widget (EShellView *shell_view); GtkWidget * e_shell_view_get_sidebar_widget (EShellView *shell_view); GtkWidget * e_shell_view_get_status_widget (EShellView *shell_view); +void e_shell_view_changed (EShellView *shell_view); G_END_DECLS diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index 063b0ff8e8..312307c2f7 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -41,6 +41,31 @@ enum { static gpointer parent_class; +static void +shell_window_update_sidebar (EShellWindow *shell_window) +{ + ESidebar *sidebar; + EShellView *shell_view; + const gchar *view_name; + const gchar *icon_name; + const gchar *primary_text; + const gchar *secondary_text; + + sidebar = E_SIDEBAR (shell_window->priv->sidebar); + view_name = e_shell_window_get_current_view (shell_window); + shell_view = e_shell_window_get_view (shell_window, view_name); + + /* Update the sidebar header. */ + + icon_name = e_shell_view_get_icon_name (shell_view); + primary_text = e_shell_view_get_primary_text (shell_view); + secondary_text = e_shell_view_get_secondary_text (shell_view); + + e_sidebar_set_icon_name (sidebar, icon_name); + e_sidebar_set_primary_text (sidebar, primary_text); + e_sidebar_set_secondary_text (sidebar, secondary_text); +} + static EShellView * shell_window_new_view (EShellWindow *shell_window, GType shell_view_type, @@ -51,6 +76,7 @@ shell_window_new_view (EShellWindow *shell_window, GtkNotebook *notebook; GtkWidget *widget; const gchar *name; + gulong handler_id; gint page_num; /* Determine the page number for the new shell view. */ @@ -79,6 +105,13 @@ shell_window_new_view (EShellWindow *shell_window, widget = e_shell_view_get_status_widget (shell_view); gtk_notebook_append_page (notebook, widget, NULL); + handler_id = g_signal_connect_swapped ( + shell_view, "notify", + G_CALLBACK (shell_window_update_sidebar), shell_window); + + /* This will be unblocked when the shell view is selected. */ + g_signal_handler_block (shell_view, handler_id); + return shell_view; } @@ -327,8 +360,6 @@ e_shell_window_get_view (EShellWindow *shell_window, continue; } - g_debug ("Comparing %s to %s (%s)", view_name, class->type_module->name, g_type_name (shell_view_type)); - if (strcmp (view_name, class->type_module->name) == 0) shell_view = shell_window_new_view ( shell_window, shell_view_type, class->label); @@ -444,23 +475,31 @@ e_shell_window_set_current_view (EShellWindow *shell_window, { GtkNotebook *notebook; EShellView *shell_view; - const gchar *current_view; + GList *list; + const gchar *view_name; gint page_num; g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); - current_view = name_or_alias; + if (shell_window->priv->current_view != NULL) { + view_name = e_shell_window_get_current_view (shell_window); + shell_view = e_shell_window_get_view (shell_window, view_name); + + g_signal_handlers_block_by_func ( + shell_view, shell_window_update_sidebar, shell_window); + } + + view_name = name_or_alias; - if (current_view != NULL) - current_view = - e_shell_registry_get_canonical_name (current_view); + if (view_name != NULL) + view_name = e_shell_registry_get_canonical_name (view_name); - if (current_view == NULL) - current_view = shell_window->priv->default_view; + if (view_name == NULL) + view_name = shell_window->priv->default_view; - g_return_if_fail (current_view != NULL); + g_return_if_fail (view_name != NULL); - shell_view = e_shell_window_get_view (shell_window, current_view); + shell_view = e_shell_window_get_view (shell_window, view_name); page_num = e_shell_view_get_page_num (shell_view); g_return_if_fail (page_num >= 0); @@ -473,9 +512,18 @@ e_shell_window_set_current_view (EShellWindow *shell_window, notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook); gtk_notebook_set_current_page (notebook, page_num); - shell_window->priv->current_view = current_view; - + shell_window->priv->current_view = view_name; g_object_notify (G_OBJECT (shell_window), "current-view"); + + g_signal_handlers_unblock_by_func ( + shell_view, shell_window_update_sidebar, shell_window); + + shell_window_update_sidebar (shell_window); + + /* Notify all loaded views. */ + list = g_hash_table_get_values (shell_window->priv->loaded_views); + g_list_foreach (list, (GFunc) e_shell_view_changed, NULL); + g_list_free (list); } gboolean diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c index 6c773a76de..977196187e 100644 --- a/shell/e-sidebar.c +++ b/shell/e-sidebar.c @@ -28,6 +28,16 @@ #define V_PADDING 6 struct _ESidebarPrivate { + + /* Header */ + GtkWidget *event_box; + GtkWidget *image; + GtkWidget *primary_label; + GtkWidget *secondary_label; + gchar *primary_text; + gchar *secondary_text; + + /* Switcher */ GList *proxies; gboolean actions_visible; gboolean style_set; @@ -39,6 +49,9 @@ struct _ESidebarPrivate { enum { PROP_0, PROP_ACTIONS_VISIBLE, + PROP_ICON_NAME, + PROP_PRIMARY_TEXT, + PROP_SECONDARY_TEXT, PROP_TOOLBAR_STYLE }; @@ -63,7 +76,6 @@ sidebar_layout_actions (ESidebar *sidebar) int x, y; int i; - /*y = allocation->y + allocation->height - V_PADDING - 1;*/ y = allocation->y + allocation->height - 1; if (num_btns == 0) @@ -172,6 +184,24 @@ sidebar_set_property (GObject *object, g_value_get_boolean (value)); return; + case PROP_ICON_NAME: + e_sidebar_set_icon_name ( + E_SIDEBAR (object), + g_value_get_string (value)); + return; + + case PROP_PRIMARY_TEXT: + e_sidebar_set_primary_text ( + E_SIDEBAR (object), + g_value_get_string (value)); + return; + + case PROP_SECONDARY_TEXT: + e_sidebar_set_secondary_text ( + E_SIDEBAR (object), + g_value_get_string (value)); + return; + case PROP_TOOLBAR_STYLE: e_sidebar_set_style ( E_SIDEBAR (object), @@ -195,6 +225,24 @@ sidebar_get_property (GObject *object, E_SIDEBAR (object))); return; + case PROP_ICON_NAME: + g_value_set_string ( + value, e_sidebar_get_icon_name ( + E_SIDEBAR (object))); + return; + + case PROP_PRIMARY_TEXT: + g_value_set_string ( + value, e_sidebar_get_primary_text ( + E_SIDEBAR (object))); + return; + + case PROP_SECONDARY_TEXT: + g_value_set_string ( + value, e_sidebar_get_secondary_text ( + E_SIDEBAR (object))); + return; + case PROP_TOOLBAR_STYLE: g_value_set_enum ( value, e_sidebar_get_style ( @@ -208,7 +256,29 @@ sidebar_get_property (GObject *object, static void sidebar_dispose (GObject *object) { - ESidebarPrivate *priv = E_SIDEBAR (object)->priv; + ESidebarPrivate *priv; + + priv = E_SIDEBAR_GET_PRIVATE (object); + + if (priv->event_box != NULL) { + g_object_unref (priv->event_box); + priv->event_box = NULL; + } + + if (priv->image != NULL) { + g_object_unref (priv->image); + priv->image = NULL; + } + + if (priv->primary_label != NULL) { + g_object_unref (priv->primary_label); + priv->image = NULL; + } + + if (priv->secondary_label != NULL) { + g_object_unref (priv->secondary_label); + priv->secondary_label = NULL; + } while (priv->proxies != NULL) { GtkWidget *widget = priv->proxies->data; @@ -220,10 +290,25 @@ sidebar_dispose (GObject *object) } static void +sidebar_finalize (GObject *object) +{ + ESidebarPrivate *priv; + + priv = E_SIDEBAR_GET_PRIVATE (object); + + g_free (priv->primary_text); + g_free (priv->secondary_text); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void sidebar_size_request (GtkWidget *widget, GtkRequisition *requisition) { ESidebarPrivate *priv; + GtkRequisition child_requisition; GtkWidget *child; GList *iter; @@ -237,6 +322,11 @@ sidebar_size_request (GtkWidget *widget, gtk_widget_size_request (child, requisition); } + child = priv->event_box; + gtk_widget_size_request (child, &child_requisition); + requisition->width = MAX (requisition->width, child_requisition.width); + requisition->height += child_requisition.height; + if (!priv->actions_visible) return; @@ -260,6 +350,8 @@ sidebar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { ESidebarPrivate *priv; + GtkAllocation child_allocation; + GtkRequisition child_requisition; GtkWidget *child; gint y; @@ -267,6 +359,18 @@ sidebar_size_allocate (GtkWidget *widget, widget->allocation = *allocation; + child = priv->event_box; + gtk_widget_size_request (child, &child_requisition); + + child_allocation.x = allocation->x; + child_allocation.y = allocation->y; + child_allocation.width = allocation->width; + child_allocation.height = child_requisition.height; + + gtk_widget_size_allocate (child, &child_allocation); + + allocation->y += child_requisition.height; + if (priv->actions_visible) y = sidebar_layout_actions (E_SIDEBAR (widget)); else @@ -275,8 +379,6 @@ sidebar_size_allocate (GtkWidget *widget, child = gtk_bin_get_child (GTK_BIN (widget)); if (child != NULL) { - GtkAllocation child_allocation; - child_allocation.x = allocation->x; child_allocation.y = allocation->y; child_allocation.width = allocation->width; @@ -330,6 +432,13 @@ sidebar_remove (GtkContainer *container, priv = E_SIDEBAR_GET_PRIVATE (container); /* Look in the internal widgets first. */ + + if (widget == priv->event_box) { + gtk_widget_unparent (priv->event_box); + gtk_widget_queue_resize (GTK_WIDGET (container)); + return; + } + link = g_list_find (priv->proxies, widget); if (link != NULL) { GtkWidget *widget = link->data; @@ -354,9 +463,11 @@ sidebar_forall (GtkContainer *container, priv = E_SIDEBAR_GET_PRIVATE (container); - if (include_internals) + if (include_internals) { + callback (priv->event_box, callback_data); g_list_foreach ( priv->proxies, (GFunc) callback, callback_data); + } /* Chain up to parent's forall() method. */ GTK_CONTAINER_CLASS (parent_class)->forall ( @@ -418,6 +529,7 @@ sidebar_class_init (ESidebarClass *class) object_class->set_property = sidebar_set_property; object_class->get_property = sidebar_get_property; object_class->dispose = sidebar_dispose; + object_class->finalize = sidebar_finalize; widget_class = GTK_WIDGET_CLASS (class); widget_class->size_request = sidebar_size_request; @@ -438,8 +550,41 @@ sidebar_class_init (ESidebarClass *class) NULL, NULL, TRUE, - G_PARAM_CONSTRUCT | - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_ICON_NAME, + g_param_spec_string ( + "icon-name", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_PRIMARY_TEXT, + g_param_spec_string ( + "primary-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SECONDARY_TEXT, + g_param_spec_string ( + "secondary-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, @@ -450,8 +595,8 @@ sidebar_class_init (ESidebarClass *class) NULL, GTK_TYPE_TOOLBAR_STYLE, E_SIDEBAR_DEFAULT_TOOLBAR_STYLE, - G_PARAM_CONSTRUCT | - G_PARAM_READWRITE)); + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); signals[STYLE_CHANGED] = g_signal_new ( "style-changed", @@ -467,9 +612,51 @@ sidebar_class_init (ESidebarClass *class) static void sidebar_init (ESidebar *sidebar) { + GtkStyle *style; + GtkWidget *container; + GtkWidget *widget; + const GdkColor *color; + sidebar->priv = E_SIDEBAR_GET_PRIVATE (sidebar); GTK_WIDGET_SET_FLAGS (sidebar, GTK_NO_WINDOW); + + widget = gtk_event_box_new (); + style = gtk_widget_get_style (widget); + color = &style->bg[GTK_STATE_ACTIVE]; + gtk_container_set_border_width (GTK_CONTAINER (widget), 1); + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, color); + gtk_widget_set_parent (widget, GTK_WIDGET (sidebar)); + sidebar->priv->event_box = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_hbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (widget), 6); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_image_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + sidebar->priv->image = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + sidebar->priv->primary_label = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_MIDDLE); + gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + sidebar->priv->secondary_label = g_object_ref (widget); + gtk_widget_show (widget); } static void @@ -570,6 +757,102 @@ e_sidebar_set_actions_visible (ESidebar *sidebar, g_object_notify (G_OBJECT (sidebar), "actions-visible"); } +const gchar * +e_sidebar_get_icon_name (ESidebar *sidebar) +{ + GtkImage *image; + const gchar *icon_name; + + g_return_val_if_fail (E_IS_SIDEBAR (sidebar), NULL); + + image = GTK_IMAGE (sidebar->priv->image); + gtk_image_get_icon_name (image, &icon_name, NULL); + + return icon_name; +} + +void +e_sidebar_set_icon_name (ESidebar *sidebar, + const gchar *icon_name) +{ + GtkImage *image; + + g_return_if_fail (E_IS_SIDEBAR (sidebar)); + + if (icon_name == NULL) + icon_name = "image-missing"; + + image = GTK_IMAGE (sidebar->priv->image); + gtk_image_set_from_icon_name (image, icon_name, GTK_ICON_SIZE_MENU); + + gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + g_object_notify (G_OBJECT (sidebar), "icon-name"); +} + +const gchar * +e_sidebar_get_primary_text (ESidebar *sidebar) +{ + g_return_val_if_fail (E_IS_SIDEBAR (sidebar), NULL); + + return sidebar->priv->primary_text; +} + +void +e_sidebar_set_primary_text (ESidebar *sidebar, + const gchar *primary_text) +{ + GtkLabel *label; + gchar *markup; + + g_return_if_fail (E_IS_SIDEBAR (sidebar)); + + g_free (sidebar->priv->primary_text); + sidebar->priv->primary_text = g_strdup (primary_text); + + if (primary_text == NULL) + primary_text = ""; + + label = GTK_LABEL (sidebar->priv->primary_label); + markup = g_markup_printf_escaped ("<b>%s</b>", primary_text); + gtk_label_set_markup (label, markup); + g_free (markup); + + gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + g_object_notify (G_OBJECT (sidebar), "primary-text"); +} + +const gchar * +e_sidebar_get_secondary_text (ESidebar *sidebar) +{ + g_return_val_if_fail (E_IS_SIDEBAR (sidebar), NULL); + + return sidebar->priv->secondary_text; +} + +void +e_sidebar_set_secondary_text (ESidebar *sidebar, + const gchar *secondary_text) +{ + GtkLabel *label; + gchar *markup; + + g_return_if_fail (E_IS_SIDEBAR (sidebar)); + + g_free (sidebar->priv->secondary_text); + sidebar->priv->secondary_text = g_strdup (secondary_text); + + if (secondary_text == NULL) + secondary_text = ""; + + label = GTK_LABEL (sidebar->priv->secondary_label); + markup = g_markup_printf_escaped ("<small>%s</small>", secondary_text); + gtk_label_set_markup (label, markup); + g_free (markup); + + gtk_widget_queue_resize (GTK_WIDGET (sidebar)); + g_object_notify (G_OBJECT (sidebar), "secondary-text"); +} + GtkToolbarStyle e_sidebar_get_style (ESidebar *sidebar) { diff --git a/shell/e-sidebar.h b/shell/e-sidebar.h index b2cefbca4a..0386a431bc 100644 --- a/shell/e-sidebar.h +++ b/shell/e-sidebar.h @@ -69,6 +69,15 @@ void e_sidebar_add_action (ESidebar *sidebar, gboolean e_sidebar_get_actions_visible (ESidebar *sidebar); void e_sidebar_set_actions_visible (ESidebar *sidebar, gboolean visible); +const gchar * e_sidebar_get_icon_name (ESidebar *sidebar); +void e_sidebar_set_icon_name (ESidebar *sidebar, + const gchar *icon_name); +const gchar * e_sidebar_get_primary_text (ESidebar *sidebar); +void e_sidebar_set_primary_text (ESidebar *sidebar, + const gchar *primary_text); +const gchar * e_sidebar_get_secondary_text (ESidebar *sidebar); +void e_sidebar_set_secondary_text (ESidebar *sidebar, + const gchar *secondary_text); GtkToolbarStyle e_sidebar_get_style (ESidebar *sidebar); void e_sidebar_set_style (ESidebar *sidebar, GtkToolbarStyle style); diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c index 05d19c13f1..e2514ec236 100644 --- a/shell/test/e-test-shell-view.c +++ b/shell/test/e-test-shell-view.c @@ -90,6 +90,13 @@ test_shell_view_get_status_widget (EShellView *shell_view) } static void +test_shell_view_changed (EShellView *shell_view, + gboolean visible) +{ + g_debug ("%s (visible=%d)", G_STRFUNC, visible); +} + +static void test_shell_view_class_init (ETestShellViewClass *class, GTypeModule *type_module) { @@ -102,6 +109,7 @@ test_shell_view_class_init (ETestShellViewClass *class, shell_view_class->label = "Test"; shell_view_class->icon_name = "face-monkey"; shell_view_class->type_module = type_module; + shell_view_class->changed = test_shell_view_changed; shell_view_class->get_content_widget = test_shell_view_get_content_widget; diff --git a/smime/gui/Makefile.am b/smime/gui/Makefile.am index 44667d88a2..5a8640c57d 100644 --- a/smime/gui/Makefile.am +++ b/smime/gui/Makefile.am @@ -6,6 +6,8 @@ INCLUDES = \ -I$(top_builddir)/smime/lib \ -I$(top_srcdir)/shell \ -I$(top_builddir)/shell \ + -I$(top_srcdir)/widgets/misc \ + -I$(top_builddir)/widgets/misc \ -DEVOLUTION_DATADIR=\""$(datadir)"\" \ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c index dfd2bf48e9..64623a7176 100644 --- a/smime/gui/certificate-manager.c +++ b/smime/gui/certificate-manager.c @@ -32,7 +32,6 @@ #include <glib/gi18n.h> #include <glade/glade.h> -#include "evolution-config-control.h" #include "ca-trust-dialog.h" #include "cert-trust-dialog.h" #include "certificate-manager.h" @@ -49,7 +48,9 @@ #include <pkcs11.h> #include <pk11func.h> -#include "e-util/e-util-private.h" +#include <e-shell.h> +#include <e-preferences-window.h> +#include <e-util/e-util-private.h> typedef struct { GladeXML *gui; @@ -975,11 +976,11 @@ populate_ui (CertificateManagerData *cfm) gtk_tree_view_expand_all (GTK_TREE_VIEW (cfm->contactcerts_treeview)); } -EvolutionConfigControl* -certificate_manager_config_control_new (void) +void +certificate_manager_config_init (void) { CertificateManagerData *cfm_data; - GtkWidget *control_widget; + GtkWidget *widget; char *gladefile; /* We need to peek the db here to make sure it (and NSS) are fully initialized. */ @@ -1019,14 +1020,19 @@ certificate_manager_config_control_new (void) populate_ui (cfm_data); - control_widget = glade_xml_get_widget (cfm_data->gui, "cert-manager-notebook"); - g_object_ref (control_widget); + widget = glade_xml_get_widget (cfm_data->gui, "cert-manager-notebook"); + g_object_ref (widget); - gtk_container_remove (GTK_CONTAINER (control_widget->parent), control_widget); + gtk_container_remove (GTK_CONTAINER (widget->parent), widget); /* FIXME: remove when implemented */ gtk_widget_set_sensitive(cfm_data->backup_your_button, FALSE); gtk_widget_set_sensitive(cfm_data->backup_all_your_button, FALSE); - return evolution_config_control_new (control_widget); + e_preferences_window_add_page ( + e_shell_get_preferences_window (), + "certificates", + "preferences-certificates", + _("Certificates"), + widget, 700); } diff --git a/smime/gui/certificate-manager.h b/smime/gui/certificate-manager.h index 888f92a752..92e4fa3085 100644 --- a/smime/gui/certificate-manager.h +++ b/smime/gui/certificate-manager.h @@ -23,8 +23,12 @@ #ifndef _CERTIFICATE_MANAGER_H_ #define _CERTIFICATE_MANAGER_H -#include "evolution-config-control.h" +#include <glib.h> -EvolutionConfigControl* certificate_manager_config_control_new (void); +G_BEGIN_DECLS + +void certificate_manager_config_init (void); + +G_END_DECLS #endif /* _CERTIFICATE_MANAGER_H_ */ diff --git a/ui/evolution-contacts.ui b/ui/evolution-contacts.ui index 18496acc42..84676a44f5 100644 --- a/ui/evolution-contacts.ui +++ b/ui/evolution-contacts.ui @@ -27,7 +27,7 @@ <menuitem action='contact-preview'/> </menu> <placeholder name='custom-menus'> - <menu action='action-menu'> + <menu action='actions-menu'> <menuitem action='contact-forward'/> <menuitem action='contact-send-message'/> <menuitem action='address-book-stop'/> @@ -42,4 +42,17 @@ </menu> </placeholder> </menubar> + <toolbar name='main-toolbar'> + <toolitem action='contact-print'/> + <toolitem action='contact-delete'/> + <toolitem action='address-book-stop'/> + </toolbar> + <popup name="address-book-popup"> + <menuitem action='address-book-new'/> + <menuitem action='address-book-popup-save-as'/> + <separator/> + <menuitem action='address-book-popup-delete'/> + <separator/> + <menuitem action='address-book-popup-properties'/> + </popup> </ui> diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 2365fe668d..a59e16a811 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -52,7 +52,6 @@ widgetsinclude_HEADERS = \ e-expander.h \ e-icon-entry.h \ e-image-chooser.h \ - e-info-label.h \ e-map.h \ e-menu-tool-button.h \ e-preferences-window.h \ @@ -99,7 +98,6 @@ libemiscwidgets_la_SOURCES = \ e-expander.c \ e-icon-entry.c \ e-image-chooser.c \ - e-info-label.c \ e-map.c \ e-menu-tool-button.c \ e-preferences-window.c \ @@ -156,8 +154,7 @@ noinst_PROGRAMS = \ test-calendar \ test-dateedit \ test-dropdown-button \ - test-preferences-window \ - test-info-label + test-preferences-window # test-calendar @@ -199,16 +196,6 @@ test_preferences_window_LDADD = \ $(top_builddir)/e-util/libeutil.la \ $(E_WIDGETS_LIBS) -# test-info-label - -test_info_label_SOURCES = \ - test-info-label.c - -test_info_label_LDADD = \ - libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(E_WIDGETS_LIBS) - EXTRA_DIST = \ $(glade_DATA) \ diff --git a/widgets/misc/e-info-label.c b/widgets/misc/e-info-label.c deleted file mode 100644 index 4c3c04069f..0000000000 --- a/widgets/misc/e-info-label.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "e-info-label.h" - -static GtkHBoxClass *el_parent; - -static void -el_init(GObject *o) -{ - /*EInfoLabel *el = (EInfoLabel *)o;*/ -} - -static void -el_finalise(GObject *o) -{ - ((GObjectClass *)el_parent)->finalize(o); -} - -static void -el_destroy (GtkObject *o) -{ - ((EInfoLabel *)o)->location = NULL; - ((EInfoLabel *)o)->info = NULL; - - ((GtkObjectClass *)el_parent)->destroy(o); -} - -static int -el_expose_event(GtkWidget *w, GdkEventExpose *event) -{ - int x = ((GtkContainer *)w)->border_width; - - /* This seems a hack to me, but playing with styles wouldn't affect the background */ - gtk_paint_flat_box(w->style, w->window, - GTK_STATE_ACTIVE, GTK_SHADOW_NONE, - &event->area, w, "EInfoLabel", - w->allocation.x+x, w->allocation.y+x, - w->allocation.width-x*2, w->allocation.height-x*2); - - return ((GtkWidgetClass *)el_parent)->expose_event(w, event); -} - -static int -get_text_full_width (GtkWidget *label) -{ - PangoLayout *layout; - PangoRectangle rect; - int width; - - g_return_val_if_fail (GTK_IS_LABEL (label), 0); - - layout = gtk_label_get_layout (GTK_LABEL (label)); - - if (!layout) - return 0; - - width = pango_layout_get_width (layout); - pango_layout_set_width (layout, -1); - pango_layout_get_extents (layout, NULL, &rect); - pango_layout_set_width (layout, width); - - return PANGO_PIXELS (rect.width); -} - -static void -el_size_allocate (GtkWidget *widget, GtkAllocation *pallocation) -{ - EInfoLabel *el; - GtkAllocation allocation; - int full_loc, full_nfo; - gint diff; - - /* let calculate parent class first, and then just make it not divide evenly */ - ((GtkWidgetClass *)el_parent)->size_allocate (widget, pallocation); - - g_return_if_fail (widget!= NULL); - - el = (EInfoLabel*) widget; - - if (!el->location) - return; - - full_loc = get_text_full_width (el->location) + 1; - full_nfo = get_text_full_width (el->info) + 1; - - /* do not know the width of text, thus return */ - if (full_loc == 1 && full_nfo == 1) - return; - - if (el->location->allocation.width + el->info->allocation.width >= full_loc + full_nfo) { - /* allocate for location only as many pixels as it requires to not ellipsize - and keep rest for the info part */ - diff = el->location->allocation.width - full_loc; - } else { - /* make both shorter, but based on the ratio of its full widths */ - gint total_have = el->location->allocation.width + el->info->allocation.width; - gint total_full = full_loc + full_nfo; - - diff = el->location->allocation.width - full_loc * total_have / total_full; - } - - if (!diff) - return; - - allocation = el->location->allocation; - allocation.width -= diff; - gtk_widget_size_allocate (el->location, &allocation); - - allocation = el->info->allocation; - allocation.x -= diff; - allocation.width += diff; - gtk_widget_size_allocate (el->info, &allocation); -} - -static void -el_class_init(GObjectClass *klass) -{ - klass->finalize = el_finalise; - - ((GtkObjectClass *)klass)->destroy = el_destroy; - ((GtkWidgetClass *)klass)->expose_event = el_expose_event; - ((GtkWidgetClass *)klass)->size_allocate = el_size_allocate; -} - -GType -e_info_label_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof(EInfoLabelClass), - NULL, NULL, - (GClassInitFunc)el_class_init, - NULL, NULL, - sizeof(EInfoLabel), 0, - (GInstanceInitFunc)el_init - }; - el_parent = g_type_class_ref(gtk_hbox_get_type()); - type = g_type_register_static(gtk_hbox_get_type(), "EInfoLabel", &info, 0); - } - - return type; -} - -/** - * e_info_label_new: - * @icon: - * - * Create a new info label widget. @icon is the name of the icon - * (from the icon theme) to use for the icon image. - * - * Return value: - **/ -GtkWidget * -e_info_label_new(const char *icon) -{ - EInfoLabel *el = g_object_new(e_info_label_get_type(), NULL); - GtkWidget *image; - - image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); - gtk_misc_set_padding((GtkMisc *)image, 6, 6); - gtk_box_pack_start((GtkBox *)el, image, FALSE, TRUE, 0); - gtk_widget_show(image); - - gtk_container_set_border_width((GtkContainer *)el, 3); - - return (GtkWidget *)el; -} - -/** - * e_info_label_set_info: - * @el: - * @location: - * @info: - * - * Set the information to show on the label. @location is some - * context about the current view. e.g. the folder name. If the - * label is too wide, this will be truncated. - * - * @info is some info about this location. - **/ -void -e_info_label_set_info(EInfoLabel *el, const char *location, const char *info) -{ - gchar *markup; - - if (el->location == NULL) { - el->location = gtk_label_new (NULL); - el->info = gtk_label_new (NULL); - - gtk_label_set_ellipsize (GTK_LABEL (el->location), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment (GTK_MISC (el->location), 0.0, 0.0); - gtk_misc_set_padding (GTK_MISC (el->location), 0, 6); - - gtk_label_set_ellipsize (GTK_LABEL (el->info), PANGO_ELLIPSIZE_MIDDLE); - gtk_misc_set_alignment (GTK_MISC (el->info), 1.0, 1.0); - gtk_misc_set_padding (GTK_MISC (el->info), 0, 6); - - gtk_widget_show (el->location); - gtk_widget_show (el->info); - - gtk_box_pack_start ( - GTK_BOX (el), GTK_WIDGET (el->location), - TRUE, TRUE, 0); - gtk_box_pack_end ( - GTK_BOX (el), GTK_WIDGET (el->info), - TRUE, TRUE, 6); - gtk_widget_set_state (GTK_WIDGET (el), GTK_STATE_ACTIVE); - } - - markup = g_markup_printf_escaped ("<b>%s</b>", location); - gtk_label_set_markup (GTK_LABEL (el->location), markup); - g_free (markup); - - markup = g_markup_printf_escaped ("<small>%s</small>", info); - gtk_label_set_markup (GTK_LABEL (el->info), markup); - g_free (markup); -} - diff --git a/widgets/misc/e-info-label.h b/widgets/misc/e-info-label.h deleted file mode 100644 index 7122138cf8..0000000000 --- a/widgets/misc/e-info-label.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * - * - * Authors: Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#ifndef _E_INFO_LABEL_H -#define _E_INFO_LABEL_H - -#include <gtk/gtk.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_INFO_LABEL_GET_CLASS(emfv) ((EInfoLabelClass *) G_OBJECT_GET_CLASS (emfv)) - -typedef struct _EInfoLabel EInfoLabel; -typedef struct _EInfoLabelClass EInfoLabelClass; - -struct _EInfoLabel { - GtkHBox parent; - - struct _GtkWidget *location; - struct _GtkWidget *info; -}; - -struct _EInfoLabelClass { - GtkHBoxClass parent_class; -}; - -GType e_info_label_get_type(void); - -GtkWidget *e_info_label_new(const char *icon); -void e_info_label_set_info(EInfoLabel *, const char *loc, const char *info); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! _E_INFO_LABEL_H */ diff --git a/widgets/misc/e-preferences-window.c b/widgets/misc/e-preferences-window.c index 883d6df280..988d065d76 100644 --- a/widgets/misc/e-preferences-window.c +++ b/widgets/misc/e-preferences-window.c @@ -303,8 +303,8 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, const gchar *page_name, const gchar *icon_name, const gchar *caption, - gint sort_order, - GtkWidget *widget) + GtkWidget *widget, + gint sort_order) { GtkTreeRowReference *reference; GtkIconView *icon_view; @@ -346,6 +346,8 @@ e_preferences_window_add_page (EPreferencesWindow *dialog, if (page == 0) e_preferences_window_show_page (dialog, page_name); + + gtk_widget_queue_resize (GTK_WIDGET (dialog)); } void diff --git a/widgets/misc/e-preferences-window.h b/widgets/misc/e-preferences-window.h index 133bf8cdb3..379d41a977 100644 --- a/widgets/misc/e-preferences-window.h +++ b/widgets/misc/e-preferences-window.h @@ -63,8 +63,8 @@ void e_preferences_window_add_page (EPreferencesWindow *window, const gchar *page_name, const gchar *icon_name, const gchar *caption, - gint sort_order, - GtkWidget *widget); + GtkWidget *widget, + gint sort_order); void e_preferences_window_show_page (EPreferencesWindow *window, const gchar *page_name); diff --git a/widgets/misc/test-info-label.c b/widgets/misc/test-info-label.c deleted file mode 100644 index 890dfc2082..0000000000 --- a/widgets/misc/test-info-label.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-title-bar.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-ui-init.h> -#include "e-info-label.h" - -static void -delete_event_cb (GtkWidget *widget, - GdkEventAny *event, - gpointer data) -{ - gtk_main_quit (); -} - -int -main (int argc, char **argv) -{ - GtkWidget *app; - GtkWidget *info_label; - GtkWidget *label; - GtkWidget *vbox; - - gnome_program_init ( - "test-title-bar", "0.0", LIBGNOMEUI_MODULE, - argc, argv, GNOME_PARAM_NONE); - - app = gnome_app_new ("Test", "Test"); - gtk_window_set_default_size (GTK_WINDOW (app), 400, 400); - gtk_window_set_resizable (GTK_WINDOW (app), TRUE); - - g_signal_connect (app, "delete_event", G_CALLBACK (delete_event_cb), NULL); - - info_label = e_info_label_new ("stock_default-folder"); - e_info_label_set_info ((EInfoLabel *) info_label, "Component Name", "An annoyingly long component message"); - gtk_widget_show (info_label); - - label = gtk_label_new ("boo"); - gtk_widget_show (label); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), info_label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - gnome_app_set_contents (GNOME_APP (app), vbox); - gtk_widget_show (app); - - gtk_main (); - - return 0; -} |