diff options
Diffstat (limited to 'widgets/menus')
-rw-r--r-- | widgets/menus/gal-view-menus.c | 356 | ||||
-rw-r--r-- | widgets/menus/gal-view-menus.h | 18 |
2 files changed, 257 insertions, 117 deletions
diff --git a/widgets/menus/gal-view-menus.c b/widgets/menus/gal-view-menus.c index 2b2677a5bd..351308e654 100644 --- a/widgets/menus/gal-view-menus.c +++ b/widgets/menus/gal-view-menus.c @@ -23,48 +23,63 @@ #include <gal/menus/gal-define-views-dialog.h> #include <gal/widgets/e-unicode.h> #include <bonobo/bonobo-ui-util.h> +#include <e-util/e-list.h> struct _GalViewMenusPrivate { - GalViewCollection *collection; + GalViewInstance *instance; int collection_changed_id; - BonoboUIVerb *verbs; + int instance_changed_id; BonoboUIComponent *component; + EList *listenerClosures; }; +typedef struct { + GalViewInstance *instance; + char *id; + int ref_count; +} ListenerClosure; + #define PARENT_TYPE (gtk_object_get_type()) static GtkObjectClass *gvm_parent_class; static void collection_changed (GalViewCollection *collection, GalViewMenus *gvm); +static void instance_changed (GalViewInstance *instance, + GalViewMenus *gvm); -#define d(x) +#define d(x) x -typedef struct { - GalViewCollection *collection; - GalView *view; -} CollectionAndView; +static void +closure_free (void *data, void *user_data) +{ + ListenerClosure *closure = data; + GalViewMenus *gvm = user_data; + + closure->ref_count --; + if (closure->ref_count == 0) { + gtk_object_unref(GTK_OBJECT(closure->instance)); + + bonobo_ui_component_remove_listener (gvm->priv->component, closure->id); + g_free (closure); + } +} + +static void * +closure_copy (const void *data, void *user_data) +{ + ListenerClosure *closure = (void *) data; + + closure->ref_count ++; + return closure; +} static void -free_verbs (GalViewMenus *gvm) +remove_listeners (GalViewMenus *gvm) { - BonoboUIVerb *verbs; - if (gvm->priv->verbs) { - for (verbs = gvm->priv->verbs + 1; verbs->cname; verbs++) { - CollectionAndView *cnv; - - if (gvm->priv->component) - bonobo_ui_component_remove_verb(gvm->priv->component, verbs->cname); - - cnv = verbs->user_data; - g_free(verbs->cname); - - gtk_object_unref(GTK_OBJECT(cnv->collection)); - gtk_object_unref(GTK_OBJECT(cnv->view)); - g_free(cnv); - } - g_free(gvm->priv->verbs); + if (gvm->priv->listenerClosures) { + gtk_object_unref (GTK_OBJECT(gvm->priv->listenerClosures)); } - gvm->priv->verbs = NULL; + gvm->priv->listenerClosures = NULL; } static void @@ -73,20 +88,54 @@ remove_xml (GalViewMenus *gvm) } static void -gvm_destroy (GtkObject *object) +remove_instance (GalViewMenus *gvm) { - GalViewMenus *gvm = GAL_VIEW_MENUS (object); - - if (gvm->priv->collection && gvm->priv->collection_changed_id != 0) { - gtk_signal_disconnect(GTK_OBJECT(gvm->priv->collection), gvm->priv->collection_changed_id); - gvm->priv->collection_changed_id = 0; + if (gvm->priv->instance) { + if (gvm->priv->instance_changed_id != 0) + gtk_signal_disconnect(GTK_OBJECT(gvm->priv->instance), gvm->priv->instance_changed_id); + + if (gvm->priv->instance->collection && gvm->priv->collection_changed_id != 0) + gtk_signal_disconnect(GTK_OBJECT(gvm->priv->instance->collection), gvm->priv->collection_changed_id); } - if (gvm->priv->collection) - gtk_object_unref(GTK_OBJECT(gvm->priv->collection)); + gvm->priv->instance_changed_id = 0; + gvm->priv->collection_changed_id = 0; + + if (gvm->priv->instance) + gtk_object_unref(GTK_OBJECT(gvm->priv->instance)); - free_verbs(gvm); + remove_listeners(gvm); remove_xml(gvm); +} + +static void +add_instance (GalViewMenus *gvm, + GalViewInstance *instance) +{ + gtk_object_ref(GTK_OBJECT(instance)); + + if (gvm->priv->instance != NULL) + remove_instance (gvm); + + gvm->priv->instance = instance; + + gal_view_instance_load (gvm->priv->instance); + + gvm->priv->instance_changed_id = gtk_signal_connect + (GTK_OBJECT(instance), "changed", + GTK_SIGNAL_FUNC(instance_changed), gvm); + gvm->priv->collection_changed_id = gtk_signal_connect + (GTK_OBJECT(instance->collection), "changed", + GTK_SIGNAL_FUNC(collection_changed), gvm); + +} + +static void +gvm_destroy (GtkObject *object) +{ + GalViewMenus *gvm = GAL_VIEW_MENUS (object); + + remove_instance (gvm); if (gvm->priv->component) { bonobo_object_unref (BONOBO_OBJECT (gvm->priv->component)); @@ -111,42 +160,39 @@ static void gvm_init (GalViewMenus *gvm) { gvm->priv = g_new(GalViewMenusPrivate, 1); - gvm->priv->collection = NULL; + gvm->priv->instance = NULL; gvm->priv->collection_changed_id = 0; - gvm->priv->verbs = NULL; + gvm->priv->instance_changed_id = 0; gvm->priv->component = NULL; + gvm->priv->listenerClosures = NULL; } E_MAKE_TYPE(gal_view_menus, "GalViewMenus", GalViewMenus, gvm_class_init, gvm_init, PARENT_TYPE); GalViewMenus * -gal_view_menus_new (GalViewCollection *collection) +gal_view_menus_new (GalViewInstance *instance) { GalViewMenus *gvm; - g_return_val_if_fail (collection != NULL, NULL); - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); + g_return_val_if_fail (instance != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW_INSTANCE (instance), NULL); gvm = gtk_type_new (GAL_VIEW_MENUS_TYPE); - gal_view_menus_construct(gvm, collection); + gal_view_menus_construct(gvm, instance); return gvm; } GalViewMenus * gal_view_menus_construct (GalViewMenus *gvm, - GalViewCollection *collection) + GalViewInstance *instance) { g_return_val_if_fail (gvm != NULL, NULL); g_return_val_if_fail (GAL_IS_VIEW_MENUS (gvm), NULL); - g_return_val_if_fail (collection != NULL, NULL); - g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); + g_return_val_if_fail (instance != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW_INSTANCE (instance), NULL); - gtk_object_ref(GTK_OBJECT(collection)); - gvm->priv->collection = collection; - gvm->priv->collection_changed_id = gtk_signal_connect ( - GTK_OBJECT(collection), "changed", - GTK_SIGNAL_FUNC(collection_changed), gvm); + add_instance (gvm, instance); return gvm; } @@ -155,7 +201,7 @@ static void dialog_clicked(GtkWidget *dialog, int button, GalViewMenus *menus) { if (button == 0) { - gal_view_collection_save(menus->priv->collection); + gal_view_collection_save(menus->priv->instance->collection); } gnome_dialog_close(GNOME_DIALOG(dialog)); } @@ -165,24 +211,53 @@ define_views(BonoboUIComponent *component, GalViewMenus *menus, char *cname) { - GtkWidget *dialog = gal_define_views_dialog_new(menus->priv->collection); + GtkWidget *dialog = gal_define_views_dialog_new(menus->priv->instance->collection); gtk_signal_connect(GTK_OBJECT(dialog), "clicked", GTK_SIGNAL_FUNC(dialog_clicked), menus); gtk_widget_show(dialog); } +static void +save_current_view(BonoboUIComponent *component, + GalViewMenus *menus, + char *cname) +{ + gal_view_instance_save_as (menus->priv->instance); +} + +static void +toggled_cb (BonoboUIComponent *component, + const char *path, + Bonobo_UIComponent_EventType type, + const char *state, + gpointer user_data) +{ + ListenerClosure *closure = user_data; + + /* do nothing on state change to untoggled */ + if (!strcmp (state, "0")) + return; + + g_print ("%s\n", path); + + gal_view_instance_set_current_view_id (closure->instance, closure->id); +} + static char * build_menus(GalViewMenus *menus) { - BonoboUINode *root, *menu, *submenu, *place, *menuitem; + BonoboUINode *root, *menu, *submenu, *place, *menuitem, *commands, *command; char *xml; xmlChar *string; int length; int i; - GalViewCollection *collection = menus->priv->collection; + GalViewInstance *instance = menus->priv->instance; + GalViewCollection *collection = instance->collection; + char *id; root = bonobo_ui_node_new("Root"); menu = bonobo_ui_node_new_child(root, "menu"); + commands = bonobo_ui_node_new_child (root, "commands"); submenu = bonobo_ui_node_new_child(menu, "submenu"); bonobo_ui_node_set_attr(submenu, "name", "View"); @@ -194,34 +269,82 @@ build_menus(GalViewMenus *menus) bonobo_ui_node_set_attr(submenu, "name", "CurrentView"); bonobo_ui_node_set_attr(submenu, "_label", N_("_Current View")); + id = gal_view_instance_get_current_view_id (instance); + length = gal_view_collection_get_count(collection); + + menus->priv->listenerClosures = e_list_new (closure_copy, closure_free, menus); + for (i = 0; i < length; i++) { char *label, *encoded_label; - char *verb; GalViewCollectionItem *item = gal_view_collection_get_view_item(collection, i); + ListenerClosure *closure; + menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); bonobo_ui_node_set_attr(menuitem, "name", item->id); + bonobo_ui_node_set_attr(menuitem, "id", item->id); + bonobo_ui_node_set_attr(menuitem, "group", "GalViewMenus"); + bonobo_ui_node_set_attr(menuitem, "type", "radio"); + + command = bonobo_ui_node_new_child (commands, "cmd"); + bonobo_ui_node_set_attr(command, "name", item->id); + bonobo_ui_node_set_attr(command, "group", "GalViewMenus"); /* bonobo displays this string so it must be in locale */ label = e_utf8_to_locale_string(item->title); encoded_label = bonobo_ui_util_encode_str (label); bonobo_ui_node_set_attr(menuitem, "label", encoded_label); g_free (encoded_label); - g_free(label); + g_free (label); + + closure = g_new (ListenerClosure, 1); + closure->instance = instance; + closure->id = item->id; + closure->ref_count = 1; + + gtk_object_ref (GTK_OBJECT(closure->instance)); + + bonobo_ui_component_add_listener (menus->priv->component, item->id, toggled_cb, closure); + e_list_append (menus->priv->listenerClosures, closure); - verb = g_strdup_printf("DefineViews:%s", item->id); - bonobo_ui_node_set_attr(menuitem, "verb", verb); - g_free(verb); + closure_free (closure, menus); + } + + if (id == NULL) { + + menuitem = bonobo_ui_node_new_child(submenu, "separator"); + + menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); + bonobo_ui_node_set_attr(menuitem, "name", "custom_view"); + bonobo_ui_node_set_attr(menuitem, "id", "custom_view"); + bonobo_ui_node_set_attr(menuitem, "group", "GalViewMenus"); + bonobo_ui_node_set_attr(menuitem, "type", "radio"); + /* bonobo displays this string so it must be in locale */ + bonobo_ui_node_set_attr(menuitem, "_label", N_("Custom View")); + + command = bonobo_ui_node_new_child (commands, "cmd"); + bonobo_ui_node_set_attr(command, "name", "custom_view"); + bonobo_ui_node_set_attr(command, "group", "GalViewMenus"); + + + menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); + bonobo_ui_node_set_attr(menuitem, "name", "SaveCurrentView"); + bonobo_ui_node_set_attr(menuitem, "_label", N_("Save Custom View")); + bonobo_ui_node_set_attr(menuitem, "verb", ""); + + command = bonobo_ui_node_new_child(commands, "cmd"); + bonobo_ui_node_set_attr(command, "name", "SaveCurrentView"); } -#if 0 menuitem = bonobo_ui_node_new_child(submenu, "separator"); menuitem = bonobo_ui_node_new_child(submenu, "menuitem"); bonobo_ui_node_set_attr(menuitem, "name", "DefineViews"); bonobo_ui_node_set_attr(menuitem, "_label", N_("Define Views")); - bonobo_ui_node_set_attr(menuitem, "verb", "DefineViews"); -#endif + bonobo_ui_node_set_attr(menuitem, "verb", ""); + + command = bonobo_ui_node_new_child(commands, "cmd"); + bonobo_ui_node_set_attr(command, "name", "DefineViews"); string = bonobo_ui_node_to_string(root, TRUE); xml = g_strdup(string); @@ -229,76 +352,66 @@ build_menus(GalViewMenus *menus) bonobo_ui_node_free(root); - d(g_print (xml)); + g_free (id); + + /* d(g_print (xml));*/ return xml; } +static BonoboUIVerb verbs [] = { + BONOBO_UI_UNSAFE_VERB ("DefineViews", define_views), + BONOBO_UI_UNSAFE_VERB ("SaveCurrentView", save_current_view), + BONOBO_UI_VERB_END +}; + static void -show_view(BonoboUIComponent *component, - gpointer user_data, - const char *cname) +set_state (GalViewMenus *gvm, char *path, CORBA_Environment *ev) { - CollectionAndView *cnv = user_data; - gal_view_collection_display_view(cnv->collection, cnv->view); + char *full_path = g_strdup_printf ("/commands/%s", path); + bonobo_ui_component_set_prop (gvm->priv->component, full_path, "state", "1", ev); + g_print ("set_prop path: %s\n", full_path); + g_free (full_path); } -static BonoboUIVerb * -build_verbs (GalViewMenus *menus) +static void +set_radio (GalViewMenus *gvm, + CORBA_Environment *ev) { - GalViewCollection *collection = menus->priv->collection; - int count = gal_view_collection_get_count(collection); - BonoboUIVerb *verbs = g_new(BonoboUIVerb, count + 2); - BonoboUIVerb *verb; - int i; - - verb = verbs; - verb->cname = g_strdup("DefineViews"); - verb->cb = (BonoboUIVerbFn) define_views; - verb->user_data = menus; - verb->dummy = NULL; - verb ++; - for (i = 0; i < count; i++) { - CollectionAndView *cnv; - GalViewCollectionItem *item = gal_view_collection_get_view_item(collection, i); - - cnv = g_new(CollectionAndView, 1); - cnv->view = item->view; - cnv->collection = collection; + char *id; - gtk_object_ref(GTK_OBJECT(cnv->view)); - gtk_object_ref(GTK_OBJECT(cnv->collection)); + id = gal_view_instance_get_current_view_id (gvm->priv->instance); - verb->cname = g_strdup_printf("DefineViews:%s", item->id); - verb->cb = show_view; - verb->user_data = cnv; - verb->dummy = NULL; - verb++; + if (id) { + set_state (gvm, id, ev); + } else { + set_state (gvm, "custom_view", ev); } - - verb->cname = NULL; - verb->cb = NULL; - verb->user_data = NULL; - verb->dummy = NULL; - verb++; - - return verbs; + g_free (id); } +#define CURRENT_VIEW_PATH "/menu/View/ViewBegin/CurrentView" static void build_stuff (GalViewMenus *gvm, CORBA_Environment *ev) { char *xml; + d(g_print ("%s:\n", __FUNCTION__)); + if (bonobo_ui_component_path_exists (gvm->priv->component, CURRENT_VIEW_PATH, ev)) { + d(g_print ("%s: Removing path\n", __FUNCTION__)); + bonobo_ui_component_rm (gvm->priv->component, CURRENT_VIEW_PATH, ev); + } + + remove_listeners(gvm); remove_xml(gvm); xml = build_menus(gvm); bonobo_ui_component_set_translate(gvm->priv->component, "/", xml, ev); g_free(xml); - free_verbs(gvm); - gvm->priv->verbs = build_verbs(gvm); - bonobo_ui_component_add_verb_list(gvm->priv->component, gvm->priv->verbs); + bonobo_ui_component_add_verb_list_with_data(gvm->priv->component, verbs, gvm); + + set_radio (gvm, ev); } void @@ -306,15 +419,18 @@ gal_view_menus_apply (GalViewMenus *gvm, BonoboUIComponent *component, CORBA_Environment *ev) { - if (component) - bonobo_object_ref (BONOBO_OBJECT (component)); + if (component != gvm->priv->component) { + if (component) + bonobo_object_ref (BONOBO_OBJECT (component)); - if (gvm->priv->component) - bonobo_object_unref (BONOBO_OBJECT (gvm->priv->component)); + if (gvm->priv->component) + bonobo_object_unref (BONOBO_OBJECT (gvm->priv->component)); + } gvm->priv->component = component; build_stuff (gvm, ev); + set_radio (gvm, ev); } static void @@ -325,5 +441,27 @@ collection_changed (GalViewCollection *collection, CORBA_exception_init (&ev); build_stuff(gvm, &ev); + set_radio (gvm, &ev); CORBA_exception_free (&ev); } + +static void +instance_changed (GalViewInstance *instance, + GalViewMenus *gvm) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + build_stuff(gvm, &ev); + set_radio (gvm, &ev); + CORBA_exception_free (&ev); +} + +void +gal_view_menus_set_instance (GalViewMenus *gvm, + GalViewInstance *instance) +{ + remove_instance (gvm); + add_instance (gvm, instance); + instance_changed (instance, gvm); +} diff --git a/widgets/menus/gal-view-menus.h b/widgets/menus/gal-view-menus.h index bc62d82f54..0ab299e4d7 100644 --- a/widgets/menus/gal-view-menus.h +++ b/widgets/menus/gal-view-menus.h @@ -5,7 +5,7 @@ #include <gtk/gtkobject.h> #include <gnome-xml/tree.h> #include <bonobo/bonobo-ui-component.h> -#include <gal/menus/gal-view-collection.h> +#include <gal/menus/gal-view-instance.h> #define GAL_VIEW_MENUS_TYPE (gal_view_menus_get_type ()) #define GAL_VIEW_MENUS(o) (GTK_CHECK_CAST ((o), GAL_VIEW_MENUS_TYPE, GalViewMenus)) @@ -24,13 +24,15 @@ typedef struct { GtkObjectClass parent_class; } GalViewMenusClass; -GtkType gal_view_menus_get_type (void); -GalViewMenus *gal_view_menus_new (GalViewCollection *collection); -GalViewMenus *gal_view_menus_construct (GalViewMenus *menus, - GalViewCollection *collection); +GtkType gal_view_menus_get_type (void); +GalViewMenus *gal_view_menus_new (GalViewInstance *instance); +GalViewMenus *gal_view_menus_construct (GalViewMenus *menus, + GalViewInstance *instance); -void gal_view_menus_apply (GalViewMenus *menus, - BonoboUIComponent *component, - CORBA_Environment *ev); +void gal_view_menus_apply (GalViewMenus *menus, + BonoboUIComponent *component, + CORBA_Environment *ev); +void gal_view_menus_set_instance (GalViewMenus *gvm, + GalViewInstance *instance); #endif /* _GAL_VIEW_MENUS_H_ */ |