diff options
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/menus/gal-view-collection.c | 178 | ||||
-rw-r--r-- | widgets/menus/gal-view-collection.h | 36 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance.c | 338 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance.h | 93 |
4 files changed, 573 insertions, 72 deletions
diff --git a/widgets/menus/gal-view-collection.c b/widgets/menus/gal-view-collection.c index fe555ee5bd..89cd4deab7 100644 --- a/widgets/menus/gal-view-collection.c +++ b/widgets/menus/gal-view-collection.c @@ -88,6 +88,61 @@ gal_view_collection_item_free (GalViewCollectionItem *item) g_free(item); } +static char * +gal_view_generate_string (GalViewCollection *collection, + GalView *view, + int which) +{ + char *ret_val; + char *pointer; + + if (which == 1) + ret_val = g_strdup(gal_view_get_title(view)); + else + ret_val = g_strdup_printf("%s_%d", gal_view_get_title(view), which); + for (pointer = ret_val; *pointer; pointer++) { + if (!isalnum((guint) *pointer)) { + *pointer = '_'; + } + } + return ret_val; +} + +static gint +gal_view_check_string (GalViewCollection *collection, + char *string) +{ + int i; + + if (!strcmp (string, "current_view")) + return FALSE; + + for (i = 0; i < collection->view_count; i++) { + if (!strcmp(string, collection->view_data[i]->id)) + return FALSE; + } + for (i = 0; i < collection->removed_view_count; i++) { + if (!strcmp(string, collection->removed_view_data[i]->id)) + return FALSE; + } + return TRUE; +} + +static char * +gal_view_generate_id (GalViewCollection *collection, + GalView *view) +{ + int i; + for (i = 1; TRUE; i++) { + char *try; + + try = gal_view_generate_string(collection, view, i); + if (gal_view_check_string(collection, try)) + return try; + g_free(try); + } +} + static void gal_view_collection_destroy (GtkObject *object) { @@ -154,6 +209,8 @@ gal_view_collection_init (GalViewCollection *collection) collection->system_dir = NULL; collection->local_dir = NULL; + + collection->loaded = FALSE; } /** @@ -255,6 +312,40 @@ view_changed (GalView *view, gal_view_collection_changed(item->collection); } +/* Use factory list to load a GalView file. */ +static GalView * +gal_view_collection_real_load_view_from_file (GalViewCollection *collection, const char *type, const char *title, const char *dir, const char *filename) +{ + GalViewFactory *factory; + GList *factories; + + factory = NULL; + for (factories = collection->factory_list; factories; factories = factories->next) { + if (type && !strcmp(gal_view_factory_get_type_code(factories->data), type)) { + factory = factories->data; + break; + } + } + if (factory) { + char *fullpath; + GalView *view; + + fullpath = g_concat_dir_and_file(dir, filename); + view = gal_view_factory_new_view (factory, title); + gal_view_set_title (view, title); + gal_view_load(view, fullpath); + g_free(fullpath); + return view; + } + return NULL; +} + +GalView * +gal_view_collection_load_view_from_file (GalViewCollection *collection, const char *type, const char *filename) +{ + return gal_view_collection_real_load_view_from_file (collection, type, "", collection->local_dir, filename); +} + static GalViewCollectionItem * load_single_file (GalViewCollection *collection, gchar *dir, @@ -273,28 +364,11 @@ load_single_file (GalViewCollection *collection, item->collection = collection; if (item->filename) { - GalViewFactory *factory; - GList *factories; - - factory = NULL; - for (factories = collection->factory_list; factories; factories = factories->next) { - if (item->type && !strcmp(gal_view_factory_get_type_code(factories->data), item->type)) { - factory = factories->data; - break; - } - } - if (factory) { - char *filename; - - filename = g_concat_dir_and_file(dir, item->filename); - item->view = gal_view_factory_new_view (factory, item->title); - gal_view_load(item->view, filename); - gal_view_set_title (item->view, item->title); + item->view = gal_view_collection_real_load_view_from_file (collection, item->type, item->title, dir, item->filename); + if (item->view) { gtk_signal_connect(GTK_OBJECT(item->view), "changed", GTK_SIGNAL_FUNC(view_changed), item); - g_free(filename); } - } return item; } @@ -373,9 +447,13 @@ gal_view_collection_load (GalViewCollection *collection) g_return_if_fail (GAL_IS_VIEW_COLLECTION (collection)); g_return_if_fail (collection->local_dir != NULL); g_return_if_fail (collection->system_dir != NULL); + g_return_if_fail (!collection->loaded); load_single_dir(collection, collection->local_dir, TRUE); load_single_dir(collection, collection->system_dir, FALSE); + gal_view_collection_changed(collection); + + collection->loaded = TRUE; } /** @@ -403,6 +481,7 @@ gal_view_collection_save (GalViewCollection *collection) doc = xmlNewDoc("1.0"); root = xmlNewNode(NULL, "GalViewCollection"); xmlDocSetRootElement(doc, root); + for (i = 0; i < collection->view_count; i++) { xmlNode *child; GalViewCollectionItem *item; @@ -494,58 +573,29 @@ gal_view_collection_get_view_item (GalViewCollection *collection, return collection->view_data[n]; } -static char * -gal_view_generate_string (GalViewCollection *collection, - GalView *view, - int which) -{ - char *ret_val; - char *pointer; - - if (which == 1) - ret_val = g_strdup(gal_view_get_title(view)); - else - ret_val = g_strdup_printf("%s_%d", gal_view_get_title(view), which); - for (pointer = ret_val; *pointer; pointer++) { - if (!isalnum((guint) *pointer)) { - *pointer = '_'; - } - } - return ret_val; -} - -static gint -gal_view_check_string (GalViewCollection *collection, - char *string) +int +gal_view_collection_get_view_index_by_id (GalViewCollection *collection, const char *view_id) { int i; - for (i = 0; i < collection->view_count; i++) { - if (!strcmp(string, collection->view_data[i]->id)) - return FALSE; + if (!strcmp (collection->view_data[i]->id, view_id)) + return i; } - for (i = 0; i < collection->removed_view_count; i++) { - if (!strcmp(string, collection->removed_view_data[i]->id)) - return FALSE; - } - return TRUE; + return -1; } -static char * -gal_view_generate_id (GalViewCollection *collection, - GalView *view) +char * +gal_view_collection_get_view_id_by_index (GalViewCollection *collection, int n) { - int i; - for (i = 1; TRUE; i++) { - char *try; + g_return_val_if_fail (collection != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); + g_return_val_if_fail(n < collection->view_count, NULL); + g_return_val_if_fail(n >= 0, NULL); - try = gal_view_generate_string(collection, view, i); - if (gal_view_check_string(collection, try)) - return try; - g_free(try); - } + return g_strdup (collection->view_data[n]->id); } + void gal_view_collection_append (GalViewCollection *collection, GalView *view) @@ -638,3 +688,9 @@ gal_view_collection_copy_view (GalViewCollection *collection, gal_view_collection_changed(collection); } + +gboolean +gal_view_collection_loaded (GalViewCollection *collection) +{ + return collection->loaded; +} diff --git a/widgets/menus/gal-view-collection.h b/widgets/menus/gal-view-collection.h index 9df00557cd..42ecf4d550 100644 --- a/widgets/menus/gal-view-collection.h +++ b/widgets/menus/gal-view-collection.h @@ -26,10 +26,9 @@ #include <gtk/gtkobject.h> #include <gal/menus/gal-view-factory.h> +#include <libgnome/gnome-defs.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +BEGIN_GNOME_DECLS #define GAL_VIEW_COLLECTION_TYPE (gal_view_collection_get_type ()) @@ -45,11 +44,14 @@ typedef struct { GalViewCollectionItem **view_data; int view_count; + GList *factory_list; GalViewCollectionItem **removed_view_data; int removed_view_count; + guint loaded : 1; + char *system_dir; char *local_dir; } GalViewCollection; @@ -68,9 +70,9 @@ typedef struct { struct GalViewCollectionItem { GalView *view; char *id; - gboolean changed; - gboolean ever_changed; - gboolean built_in; + guint changed : 1; + guint ever_changed : 1; + guint built_in : 1; char *filename; char *title; char *type; @@ -81,22 +83,30 @@ struct GalViewCollectionItem { GtkType gal_view_collection_get_type (void); GalViewCollection *gal_view_collection_new (void); -/* Set up the view collection */ +/* Set up the view collection. Call these three functions before ever doing load or save and never call them again. */ void gal_view_collection_set_storage_directories (GalViewCollection *collection, const char *system_dir, const char *local_dir); void gal_view_collection_add_factory (GalViewCollection *collection, GalViewFactory *factory); -/* Send the display view signal. */ +/* Send the display view signal. This function is deprecated. */ void gal_view_collection_display_view (GalViewCollection *collection, GalView *view); + + +/* Query the view collection. */ gint gal_view_collection_get_count (GalViewCollection *collection); GalView *gal_view_collection_get_view (GalViewCollection *collection, int n); GalViewCollectionItem *gal_view_collection_get_view_item (GalViewCollection *collection, int n); +int gal_view_collection_get_view_index_by_id (GalViewCollection *collection, + const char *view_id); +char *gal_view_collection_get_view_id_by_index (GalViewCollection *collection, + int n); +/* Manipulate the view collection */ void gal_view_collection_append (GalViewCollection *collection, GalView *view); void gal_view_collection_delete_view (GalViewCollection *collection, @@ -107,11 +117,15 @@ void gal_view_collection_copy_view (GalViewColl * might be found there before doing either of these. */ void gal_view_collection_load (GalViewCollection *collection); void gal_view_collection_save (GalViewCollection *collection); +gboolean gal_view_collection_loaded (GalViewCollection *collection); + +/* Use factory list to load a GalView file. */ +GalView *gal_view_collection_load_view_from_file (GalViewCollection *collection, + const char *type, + const char *filename); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +END_GNOME_DECLS #endif /* _GAL_VIEW_COLLECTION_H_ */ diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c new file mode 100644 index 0000000000..0deaf91c60 --- /dev/null +++ b/widgets/menus/gal-view-instance.c @@ -0,0 +1,338 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * gal-view-instance.c + * Copyright 2000, 2001, Ximian, Inc. + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License, version 2, as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <config.h> + +#include <util/e-i18n.h> +#include <ctype.h> +#include <string.h> +#include <gtk/gtksignal.h> +#include <gnome-xml/parser.h> +#include <libgnome/gnome-defs.h> +#include <libgnome/gnome-util.h> +#include <gal/util/e-util.h> +#include <gal/util/e-xml-utils.h> +#include <gal/widgets/e-unicode.h> +#include "gal-view-instance.h" + +#define GVI_CLASS(e) ((GalViewInstanceClass *)((GtkObject *)e)->klass) + +#define PARENT_TYPE gtk_object_get_type () + +static GtkObjectClass *gal_view_instance_parent_class; + +enum { + DISPLAY_VIEW, + CHANGED, + LAST_SIGNAL +}; + +static guint gal_view_instance_signals [LAST_SIGNAL] = { 0, }; + +static void +gal_view_instance_changed (GalViewInstance *instance) +{ + g_return_if_fail (instance != NULL); + g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); + + gtk_signal_emit (GTK_OBJECT (instance), + gal_view_instance_signals [CHANGED]); +} + +static void +gal_view_instance_display_view (GalViewInstance *instance, GalView *view) +{ + g_return_if_fail (instance != NULL); + g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); + + gtk_signal_emit (GTK_OBJECT (instance), + gal_view_instance_signals [DISPLAY_VIEW], + view); +} + +static void +gal_view_instance_destroy (GtkObject *object) +{ + GalViewInstance *instance = GAL_VIEW_INSTANCE(object); + + if (instance->collection) + gtk_object_unref (GTK_OBJECT (instance->collection)); + + g_free (instance->instance_id); + g_free (instance->custom_filename); + g_free (instance->current_view_filename); + + g_free (instance->current_title); + g_free (instance->current_type); + g_free (instance->current_id); + if (instance->current_view) + gtk_object_unref (GTK_OBJECT (instance->current_view)); + + if (gal_view_instance_parent_class->destroy) + (*gal_view_instance_parent_class->destroy)(object); +} + +static void +gal_view_instance_class_init (GtkObjectClass *object_class) +{ + GalViewInstanceClass *klass = GAL_VIEW_INSTANCE_CLASS(object_class); + gal_view_instance_parent_class = gtk_type_class (PARENT_TYPE); + + object_class->destroy = gal_view_instance_destroy; + + gal_view_instance_signals [DISPLAY_VIEW] = + gtk_signal_new ("display_view", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (GalViewInstanceClass, display_view), + gtk_marshal_NONE__OBJECT, + GTK_TYPE_NONE, 1, GAL_VIEW_TYPE); + + gal_view_instance_signals [CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_LAST, + E_OBJECT_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (GalViewInstanceClass, changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + E_OBJECT_CLASS_ADD_SIGNALS (object_class, gal_view_instance_signals, LAST_SIGNAL); + + klass->display_view = NULL; + klass->changed = NULL; +} + +static void +gal_view_instance_init (GalViewInstance *instance) +{ + instance->collection = NULL; + + instance->instance_id = NULL; + instance->custom_filename = NULL; + instance->current_view_filename = NULL; + + instance->current_title = NULL; + instance->current_type = NULL; + instance->current_id = NULL; + instance->current_view = NULL; + +} + +/** + * gal_view_instance_get_type: + * + */ +guint +gal_view_instance_get_type (void) +{ + static guint type = 0; + + if (!type) + { + GtkTypeInfo info = + { + "GalViewInstance", + sizeof (GalViewInstance), + sizeof (GalViewInstanceClass), + (GtkClassInitFunc) gal_view_instance_class_init, + (GtkObjectInitFunc) gal_view_instance_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +static void +save_current_view (GalViewInstance *instance) +{ + xmlDoc *doc; + xmlNode *root; + + doc = xmlNewDoc("1.0"); + root = xmlNewNode (NULL, "GalViewCurrentView"); + xmlDocSetRootElement(doc, root); + + if (instance->current_id) + e_xml_set_string_prop_by_name (root, "current_view", instance->current_id); + if (instance->current_type) + e_xml_set_string_prop_by_name (root, "current_view_type", instance->current_type); + + xmlSaveFile(instance->current_view_filename, doc); + xmlFreeDoc(doc); +} + +static void +view_changed (GalView *view, GalViewInstance *instance) +{ + if (instance->current_id != NULL) { + instance->current_view = NULL; + save_current_view (instance); + gal_view_instance_changed(instance); + } + + gal_view_save (view, instance->custom_filename); +} + +static void +load_current_view (GalViewInstance *instance) +{ + xmlDoc *doc; + xmlNode *root; + + doc = xmlParseFile(instance->current_view_filename); + + if (!doc) + return; + + root = xmlDocGetRootElement(doc); + instance->current_id = e_xml_get_string_prop_by_name_with_default (root, "current_view", NULL); + instance->current_type = e_xml_get_string_prop_by_name_with_default (root, "current_view_type", NULL); + xmlFreeDoc(doc); + + if (instance->current_id == NULL) { + instance->current_view = + gal_view_collection_load_view_from_file (instance->collection, + instance->current_type, + instance->custom_filename); + + } else { + int index = gal_view_collection_get_view_index_by_id (instance->collection, + instance->current_id); + GalView *view = gal_view_collection_get_view (instance->collection, + index); + instance->current_view = gal_view_clone(view); + + } + + instance->current_title = g_strdup (gal_view_get_title(instance->current_view)); + gtk_signal_connect(GTK_OBJECT(instance->current_view), "changed", + GTK_SIGNAL_FUNC(view_changed), instance); + + gal_view_instance_display_view (instance, instance->current_view); +} + +/** + * gal_view_instance_new: + * @collection: This %GalViewCollection should be loaded before being passed to this function. + * @instance_id: Which instance of this type of object is this (for most of evo, this is the folder id.) + * + * Create a new %GalViewInstance. + * + * Return value: The new %GalViewInstance. + **/ +GalViewInstance * +gal_view_instance_new (GalViewCollection *collection, const char *instance_id) +{ + GalViewInstance *instance = gtk_type_new(gal_view_instance_get_type()); + if (gal_view_instance_construct (instance, collection, instance_id)) + return instance; + else { + gtk_object_unref (GTK_OBJECT (instance)); + return NULL; + } +} + +GalViewInstance * +gal_view_instance_construct (GalViewInstance *instance, GalViewCollection *collection, const char *instance_id) +{ + char *filename; + char *safe_id; + + g_return_val_if_fail (gal_view_collection_loaded (collection), NULL); + + instance->collection = collection; + if (collection) + gtk_object_ref (GTK_OBJECT (collection)); + instance->instance_id = g_strdup (instance_id); + + safe_id = g_strdup (instance->instance_id); + e_filename_make_safe (safe_id); + + filename = g_strdup_printf ("custom_view-%s.xml", safe_id); + instance->custom_filename = g_concat_dir_and_file (instance->collection->local_dir, filename); + g_free (filename); + + filename = g_strdup_printf ("current_view-%s.xml", safe_id); + instance->current_view_filename = g_concat_dir_and_file (instance->collection->local_dir, filename); + g_free (filename); + + g_free (safe_id); + + load_current_view (instance); + + return instance; +} + +/* Manipulate the current view. */ +char * +gal_view_instance_get_current_view_id (GalViewInstance *instance) +{ + return g_strdup (instance->current_id); +} + +void +gal_view_instance_set_current_view_id (GalViewInstance *instance, char *view_id) +{ + GalView *view; + int index; + + g_return_if_fail (instance != NULL); + g_return_if_fail (GAL_IS_VIEW_INSTANCE (instance)); + + if (instance->current_view && !strcmp (instance->current_id, view_id)) + return; + + if (instance->current_view) { + gtk_object_unref (GTK_OBJECT (instance->current_view)); + } + + g_free (instance->current_type); + g_free (instance->current_title); + g_free (instance->current_id); + + index = gal_view_collection_get_view_index_by_id (instance->collection, view_id); + view = gal_view_collection_get_view (instance->collection, index); + + instance->current_title = g_strdup (gal_view_get_title(view)); + instance->current_type = g_strdup (gal_view_get_type_code(view)); + instance->current_id = g_strdup (view_id); + instance->current_view = gal_view_clone(view); + + gtk_signal_connect(GTK_OBJECT(instance->current_view), "changed", + GTK_SIGNAL_FUNC(view_changed), instance); + + save_current_view (instance); + gal_view_instance_changed(instance); + gal_view_instance_display_view (instance, view); +} + +GalView * +gal_view_instance_get_current_view (GalViewInstance *instance) +{ + return instance->current_view; +} diff --git a/widgets/menus/gal-view-instance.h b/widgets/menus/gal-view-instance.h new file mode 100644 index 0000000000..9243448768 --- /dev/null +++ b/widgets/menus/gal-view-instance.h @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * gal-view-instance.h + * Copyright 2000, 2001, Ximian, Inc. + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License, version 2, as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _GAL_VIEW_INSTANCE_H_ +#define _GAL_VIEW_INSTANCE_H_ + +#include <gtk/gtkobject.h> +#include <gal/menus/gal-view-collection.h> +#include <libgnome/gnome-defs.h> + +BEGIN_GNOME_DECLS + + +#define GAL_VIEW_INSTANCE_TYPE (gal_view_instance_get_type ()) +#define GAL_VIEW_INSTANCE(o) (GTK_CHECK_CAST ((o), GAL_VIEW_INSTANCE_TYPE, GalViewInstance)) +#define GAL_VIEW_INSTANCE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_INSTANCE_TYPE, GalViewInstanceClass)) +#define GAL_IS_VIEW_INSTANCE(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_INSTANCE_TYPE)) +#define GAL_IS_VIEW_INSTANCE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_INSTANCE_TYPE)) + +typedef struct { + GtkObject base; + + GalViewCollection *collection; + + char *instance_id; + char *current_view_filename; + char *custom_filename; + + char *current_title; + char *current_type; + char *current_id; + + GalView *current_view; +} GalViewInstance; + +typedef struct { + GtkObjectClass parent_class; + + /* + * Signals + */ + void (*display_view) (GalViewInstance *instance, + GalView *view); + void (*changed) (GalViewInstance *instance); +} GalViewInstanceClass; + +/* Standard functions */ +GtkType gal_view_instance_get_type (void); + +/* */ +/*collection should be loaded when you call this. + instance_id: Which instance of this type of object is this (for most of evo, this is the folder id.) */ +GalViewInstance *gal_view_instance_new (GalViewCollection *collection, + const char *instance_id); +GalViewInstance *gal_view_instance_construct (GalViewInstance *instance, + GalViewCollection *collection, + const char *instance_id); + +/* Manipulate the current view. */ +char *gal_view_instance_get_current_view_id (GalViewInstance *instance); +void gal_view_instance_set_current_view_id (GalViewInstance *instance, + char *view_id); +GalView *gal_view_instance_get_current_view (GalViewInstance *instance); + +/* Manipulate the view collection */ +void gal_view_instance_save_current_view (GalViewInstance *instance); +void gal_view_instance_set_default (GalViewInstance *instance); + + +END_GNOME_DECLS + + +#endif /* _GAL_VIEW_INSTANCE_H_ */ |