diff options
author | Christopher James Lahey <clahey@ximian.com> | 2002-02-07 18:22:59 +0800 |
---|---|---|
committer | Chris Lahey <clahey@src.gnome.org> | 2002-02-07 18:22:59 +0800 |
commit | 9f1ac34671b0446c8eb8855e0aca62d5b69840b0 (patch) | |
tree | ca6f4d720aa6642ddd43c348adb92cb1e5ba0327 | |
parent | 6190f4f6879d8533bdb97a7baba33773a6d71d6c (diff) | |
download | gsoc2013-evolution-9f1ac34671b0446c8eb8855e0aca62d5b69840b0.tar.gz gsoc2013-evolution-9f1ac34671b0446c8eb8855e0aca62d5b69840b0.tar.zst gsoc2013-evolution-9f1ac34671b0446c8eb8855e0aca62d5b69840b0.zip |
Bumped the version number to 0.19.99.5.
2002-02-07 Christopher James Lahey <clahey@ximian.com>
* configure.in: Bumped the version number to 0.19.99.5.
* gal/Makefile.am (libgal_la_LIBADD): Added
menus/gal-view-instance-save-as-dialog.lo.
* gal/e-text/e-text.c (next_word): Contains refactored code from
the E_TEP_FORWARD_WORD case of e_text_command.
(e_text_command): Implemented E_TEP_CAPS.
From gal/menus/ChangeLog:
2002-02-07 Christopher James Lahey <clahey@ximian.com>
* Makefile.am (glade_DATA): Added
gal-view-instance-save-as-dialog.glade.
(libgalmenus_la_SOURCES): Added
gal-view-instance-save-as-dialog.c.
(libgalmenusinclude_HEADERS): Added
gal-view-instance-save-as-dialog.h.
* gal-view-collection.c, gal-view-collection.h
(gal_view_collection_append_with_title): Added this new version of
the append function that sets the title and returns the new id as
well.
(gal_view_collection_set_nth_view): Added this function to save
over another view.
(gal_view_collection_get_default_view,
gal_view_collection_set_default_view): Added the concept of a
default view for GalViewCollections.
* gal-view-etable.c, gal-view-etable.h
(gal_view_etable_attach_table, gal_view_etable_attach_tree,
gal_view_etable_detach): Added functions to set the state of a
table or tree and then send GalView "changed" signals whenever
that state changes.
(gal_view_etable_set_state): New function to set the ETableState
of a GalViewETable.
* gal-view-instance-save-as-dialog.c,
gal-view-instance-save-as-dialog.glade,
gal-view-instance-save-as-dialog.h: New dialog to save the current
custom view as a named view.
* gal-view-instance.c, gal-view-instance.h
(gal_view_instance_set_custom_view): New function to set the state
of an instance to custom view and set the custom view to a
particular GalView.
(gal_view_instance_exists): New function to check if this
particular instance has ever been opened before. Use before
gal_view_instance_load.
(gal_view_instance_save_as): New function to open a save as
dialog.
(gal_view_instance_load): Added this function which used to be
part of _construct. This function can be called multiple times,
and those extra times will be ignored. This is so you can set a
default view before loading.
(gal_view_instance_get_default_view,
gal_view_instance_set_default_view): Set the default view for this
instance. If unset, this falls back to the default view for the
corresponding GalViewCollection.
svn path=/trunk/; revision=15590
-rw-r--r-- | widgets/menus/gal-view-collection.c | 160 | ||||
-rw-r--r-- | widgets/menus/gal-view-collection.h | 17 | ||||
-rw-r--r-- | widgets/menus/gal-view-etable.c | 145 | ||||
-rw-r--r-- | widgets/menus/gal-view-etable.h | 36 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance-save-as-dialog.c | 309 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance-save-as-dialog.glade | 269 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance-save-as-dialog.h | 89 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance.c | 299 | ||||
-rw-r--r-- | widgets/menus/gal-view-instance.h | 28 | ||||
-rw-r--r-- | widgets/text/e-text.c | 101 |
10 files changed, 1295 insertions, 158 deletions
diff --git a/widgets/menus/gal-view-collection.c b/widgets/menus/gal-view-collection.c index 89cd4deab7..9f56de9715 100644 --- a/widgets/menus/gal-view-collection.c +++ b/widgets/menus/gal-view-collection.c @@ -41,6 +41,8 @@ static GtkObjectClass *gal_view_collection_parent_class; +#define d(x) x + enum { DISPLAY_VIEW, CHANGED, @@ -83,8 +85,12 @@ static void gal_view_collection_item_free (GalViewCollectionItem *item) { g_free(item->id); - if (item->view) + if (item->view) { + if (item->view_changed_id) + gtk_signal_disconnect (GTK_OBJECT (item->view), + item->view_changed_id); gtk_object_unref(GTK_OBJECT(item->view)); + } g_free(item); } @@ -163,6 +169,8 @@ gal_view_collection_destroy (GtkObject *object) g_free(collection->system_dir); g_free(collection->local_dir); + g_free (collection->default_view); + if (gal_view_collection_parent_class->destroy) (*gal_view_collection_parent_class->destroy)(object); } @@ -200,17 +208,19 @@ gal_view_collection_class_init (GtkObjectClass *object_class) static void gal_view_collection_init (GalViewCollection *collection) { - collection->view_data = NULL; - collection->view_count = 0; - collection->factory_list = NULL; + collection->view_data = NULL; + collection->view_count = 0; + collection->factory_list = NULL; - collection->removed_view_data = NULL; - collection->removed_view_count = 0; + collection->removed_view_data = NULL; + collection->removed_view_count = 0; - collection->system_dir = NULL; - collection->local_dir = NULL; + collection->system_dir = NULL; + collection->local_dir = NULL; - collection->loaded = FALSE; + collection->loaded = FALSE; + collection->default_view = NULL; + collection->default_view_built_in = TRUE; } /** @@ -327,14 +337,11 @@ gal_view_collection_real_load_view_from_file (GalViewCollection *collection, con } } 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); + gal_view_load(view, filename); return view; } return NULL; @@ -362,12 +369,17 @@ load_single_file (GalViewCollection *collection, item->title = e_xml_get_translated_utf8_string_prop_by_name(node, "title"); item->type = e_xml_get_string_prop_by_name(node, "type"); item->collection = collection; + item->view_changed_id = 0; if (item->filename) { - item->view = gal_view_collection_real_load_view_from_file (collection, item->type, item->title, dir, item->filename); + char *fullpath; + fullpath = g_concat_dir_and_file(dir, item->filename); + item->view = gal_view_collection_real_load_view_from_file (collection, item->type, item->title, dir, fullpath); + g_free(fullpath); if (item->view) { - gtk_signal_connect(GTK_OBJECT(item->view), "changed", - GTK_SIGNAL_FUNC(view_changed), item); + item->view_changed_id = + gtk_signal_connect(GTK_OBJECT(item->view), "changed", + GTK_SIGNAL_FUNC(view_changed), item); } } return item; @@ -382,6 +394,7 @@ load_single_dir (GalViewCollection *collection, xmlNode *root; xmlNode *child; char *filename = g_concat_dir_and_file(dir, "galview.xml"); + char *default_view; doc = xmlParseFile(filename); if (!doc) { @@ -428,6 +441,16 @@ load_single_dir (GalViewCollection *collection, g_free(id); } + default_view = e_xml_get_string_prop_by_name (root, "default-view"); + if (default_view) { + if (local) + collection->default_view_built_in = FALSE; + else + collection->default_view_built_in = TRUE; + g_free (collection->default_view); + collection->default_view = default_view; + } + g_free(filename); xmlFreeDoc(doc); } @@ -482,6 +505,10 @@ gal_view_collection_save (GalViewCollection *collection) root = xmlNewNode(NULL, "GalViewCollection"); xmlDocSetRootElement(doc, root); + if (collection->default_view && !collection->default_view_built_in) { + e_xml_set_string_prop_by_name(root, "default-view", collection->default_view); + } + for (i = 0; i < collection->view_count; i++) { xmlNode *child; GalViewCollectionItem *item; @@ -619,8 +646,9 @@ gal_view_collection_append (GalViewCollection *collection, item->collection = collection; gtk_object_ref(GTK_OBJECT(view)); - gtk_signal_connect(GTK_OBJECT(item->view), "changed", - GTK_SIGNAL_FUNC(view_changed), item); + item->view_changed_id = + gtk_signal_connect(GTK_OBJECT(item->view), "changed", + GTK_SIGNAL_FUNC(view_changed), item); collection->view_data = g_renew(GalViewCollectionItem *, collection->view_data, collection->view_count + 1); collection->view_data[collection->view_count] = item; @@ -641,6 +669,7 @@ gal_view_collection_delete_view (GalViewCollection *collection, item = collection->view_data[i]; memmove(collection->view_data + i, collection->view_data + i + 1, (collection->view_count - i - 1) * sizeof(GalViewCollectionItem *)); + collection->view_count --; if (item->built_in) { g_free(item->filename); item->filename = NULL; @@ -679,8 +708,9 @@ gal_view_collection_copy_view (GalViewCollection *collection, item->view = gal_view_clone(view); item->collection = collection; - gtk_signal_connect(GTK_OBJECT(item->view), "changed", - GTK_SIGNAL_FUNC(view_changed), item); + item->view_changed_id = + gtk_signal_connect(GTK_OBJECT(item->view), "changed", + GTK_SIGNAL_FUNC(view_changed), item); collection->view_data = g_renew(GalViewCollectionItem *, collection->view_data, collection->view_count + 1); collection->view_data[collection->view_count] = item; @@ -694,3 +724,93 @@ gal_view_collection_loaded (GalViewCollection *collection) { return collection->loaded; } + +const char * +gal_view_collection_append_with_title (GalViewCollection *collection, const char *title, GalView *view) +{ + GalViewCollectionItem *item; + + g_return_val_if_fail (collection != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW (view), NULL); + + gal_view_set_title (view, title); + + d(g_print("%s: %p\n", __FUNCTION__, view)); + + item = g_new(GalViewCollectionItem, 1); + item->ever_changed = TRUE; + item->changed = TRUE; + item->built_in = FALSE; + item->title = g_strdup(gal_view_get_title(view)); + item->type = g_strdup(gal_view_get_type_code(view)); + item->id = gal_view_generate_id(collection, view); + item->filename = g_strdup_printf("%s.galview", item->id); + item->view = view; + item->collection = collection; + gtk_object_ref(GTK_OBJECT(view)); + + item->view_changed_id = + gtk_signal_connect(GTK_OBJECT(item->view), "changed", + GTK_SIGNAL_FUNC(view_changed), item); + + collection->view_data = g_renew(GalViewCollectionItem *, collection->view_data, collection->view_count + 1); + collection->view_data[collection->view_count] = item; + collection->view_count ++; + + gal_view_collection_changed(collection); + return item->id; +} + +const char * +gal_view_collection_set_nth_view (GalViewCollection *collection, int i, GalView *view) +{ + GalViewCollectionItem *item; + + g_return_val_if_fail (collection != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW_COLLECTION (collection), NULL); + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (GAL_IS_VIEW (view), NULL); + g_return_val_if_fail (i >= 0, NULL); + g_return_val_if_fail (i < collection->view_count, NULL); + + d(g_print("%s: %p\n", __FUNCTION__, view)); + + item = collection->view_data[i]; + + gal_view_set_title (view, item->title); + gtk_object_ref (GTK_OBJECT (view)); + if (item->view) { + gtk_signal_disconnect (GTK_OBJECT (item->view), + item->view_changed_id); + gtk_object_unref (GTK_OBJECT (item->view)); + } + item->view = view; + + item->ever_changed = TRUE; + item->changed = TRUE; + item->type = g_strdup(gal_view_get_type_code(view)); + + item->view_changed_id = + gtk_signal_connect(GTK_OBJECT(item->view), "changed", + GTK_SIGNAL_FUNC(view_changed), item); + + gal_view_collection_changed (collection); + return item->id; +} + +const char * +gal_view_collection_get_default_view (GalViewCollection *collection) +{ + return collection->default_view; +} + +void +gal_view_collection_set_default_view (GalViewCollection *collection, const char *id) +{ + g_free (collection->default_view); + collection->default_view = g_strdup (id); + gal_view_collection_changed (collection); + collection->default_view_built_in = FALSE; +} diff --git a/widgets/menus/gal-view-collection.h b/widgets/menus/gal-view-collection.h index 42ecf4d550..89501cda4c 100644 --- a/widgets/menus/gal-view-collection.h +++ b/widgets/menus/gal-view-collection.h @@ -51,9 +51,12 @@ typedef struct { int removed_view_count; guint loaded : 1; + guint default_view_built_in : 1; char *system_dir; char *local_dir; + + char *default_view; } GalViewCollection; typedef struct { @@ -77,6 +80,7 @@ struct GalViewCollectionItem { char *title; char *type; GalViewCollection *collection; + guint view_changed_id; }; /* Standard functions */ @@ -124,6 +128,19 @@ GalView *gal_view_collection_load_view_from_file (GalViewColl const char *type, const char *filename); +/* Returns id of the new view. These functions are used for + GalViewInstanceSaveAsDialog. */ +const char *gal_view_collection_append_with_title (GalViewCollection *collection, + const char *title, + GalView *view); +const char *gal_view_collection_set_nth_view (GalViewCollection *collection, + int i, + GalView *view); + +const char *gal_view_collection_get_default_view (GalViewCollection *collection); +void gal_view_collection_set_default_view (GalViewCollection *collection, + const char *id); + END_GNOME_DECLS diff --git a/widgets/menus/gal-view-etable.c b/widgets/menus/gal-view-etable.c index 24d9815034..87351866bd 100644 --- a/widgets/menus/gal-view-etable.c +++ b/widgets/menus/gal-view-etable.c @@ -30,6 +30,31 @@ static GalViewClass *gal_view_etable_parent_class; +static void +detach_table (GalViewEtable *view) +{ + if (view->table == NULL) + return; + if (view->table_state_changed_id) { + gtk_signal_disconnect (GTK_OBJECT (view->table), + view->table_state_changed_id); + } + gtk_object_unref (GTK_OBJECT (view->table)); + view->table = NULL; +} + +static void +detach_tree (GalViewEtable *view) +{ + if (view->tree == NULL) + return; + if (view->tree_state_changed_id) { + gtk_signal_disconnect (GTK_OBJECT (view->tree), + view->tree_state_changed_id); + } + gtk_object_unref (GTK_OBJECT (view->tree)); + view->tree = NULL; +} static void config_changed (ETableConfig *config, GalViewEtable *view) @@ -79,8 +104,8 @@ gal_view_etable_get_title (GalView *view) } static void -gal_view_etable_set_title (GalView *view, - const char *title) +gal_view_etable_set_title (GalView *view, + const char *title) { g_free(GAL_VIEW_ETABLE(view)->title); GAL_VIEW_ETABLE(view)->title = g_strdup(title); @@ -113,6 +138,9 @@ static void gal_view_etable_destroy (GtkObject *object) { GalViewEtable *view = GAL_VIEW_ETABLE(object); + + gal_view_etable_detach (view); + g_free(view->title); if (view->spec) gtk_object_unref(GTK_OBJECT(view->spec)); @@ -148,6 +176,31 @@ gal_view_etable_init (GalViewEtable *gve) gve->title = NULL; } +GtkType +gal_view_etable_get_type (void) +{ + static guint type = 0; + + if (!type) + { + GtkTypeInfo info = + { + "GalViewEtable", + sizeof (GalViewEtable), + sizeof (GalViewEtableClass), + (GtkClassInitFunc) gal_view_etable_class_init, + (GtkObjectInitFunc) gal_view_etable_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + /** * gal_view_etable_new * @spec: The ETableSpecification that this view will be based upon. @@ -194,27 +247,73 @@ gal_view_etable_construct (GalViewEtable *view, return GAL_VIEW(view); } -GtkType -gal_view_etable_get_type (void) +void +gal_view_etable_set_state (GalViewEtable *view, ETableState *state) { - static guint type = 0; - - if (!type) - { - GtkTypeInfo info = - { - "GalViewEtable", - sizeof (GalViewEtable), - sizeof (GalViewEtableClass), - (GtkClassInitFunc) gal_view_etable_class_init, - (GtkObjectInitFunc) gal_view_etable_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (PARENT_TYPE, &info); - } + if (view->state) + gtk_object_unref(GTK_OBJECT(view->state)); + view->state = e_table_state_duplicate(state); - return type; + gal_view_changed(GAL_VIEW(view)); +} + +static void +table_state_changed (ETable *table, GalViewEtable *view) +{ + ETableState *state; + + state = e_table_get_state_object (table); + gtk_object_unref (GTK_OBJECT (view->state)); + view->state = state; + + gal_view_changed(GAL_VIEW(view)); +} + +static void +tree_state_changed (ETree *tree, GalViewEtable *view) +{ + ETableState *state; + + state = e_tree_get_state_object (tree); + gtk_object_unref (GTK_OBJECT (view->state)); + view->state = state; + + gal_view_changed(GAL_VIEW(view)); +} + +void +gal_view_etable_attach_table (GalViewEtable *view, ETable *table) +{ + gal_view_etable_detach (view); + + view->table = table; + + e_table_set_state_object(view->table, view->state); + gtk_object_ref (GTK_OBJECT (view->table)); + view->table_state_changed_id = + gtk_signal_connect(GTK_OBJECT(view->table), "state_change", + GTK_SIGNAL_FUNC (table_state_changed), view); +} + +void +gal_view_etable_attach_tree (GalViewEtable *view, ETree *tree) +{ + gal_view_etable_detach (view); + + view->tree = tree; + + e_tree_set_state_object(view->tree, view->state); + gtk_object_ref (GTK_OBJECT (view->tree)); + view->tree_state_changed_id = + gtk_signal_connect(GTK_OBJECT(view->tree), "state_change", + GTK_SIGNAL_FUNC (tree_state_changed), view); +} + +void +gal_view_etable_detach (GalViewEtable *view) +{ + if (view->table != NULL) + detach_table (view); + if (view->tree != NULL) + detach_tree (view); } diff --git a/widgets/menus/gal-view-etable.h b/widgets/menus/gal-view-etable.h index 8d340c4069..2fd001e583 100644 --- a/widgets/menus/gal-view-etable.h +++ b/widgets/menus/gal-view-etable.h @@ -24,14 +24,15 @@ #ifndef _GAL_VIEW_ETABLE_H_ #define _GAL_VIEW_ETABLE_H_ +#include <libgnome/gnome-defs.h> #include <gtk/gtkobject.h> #include <gal/menus/gal-view.h> #include <gal/e-table/e-table-state.h> #include <gal/e-table/e-table-specification.h> +#include <gal/e-table/e-table.h> +#include <gal/e-table/e-tree.h> -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +BEGIN_GNOME_DECLS #define GAL_VIEW_ETABLE_TYPE (gal_view_etable_get_type ()) #define GAL_VIEW_ETABLE(o) (GTK_CHECK_CAST ((o), GAL_VIEW_ETABLE_TYPE, GalViewEtable)) @@ -45,6 +46,12 @@ typedef struct { ETableSpecification *spec; ETableState *state; char *title; + + ETable *table; + guint table_state_changed_id; + + ETree *tree; + guint tree_state_changed_id; } GalViewEtable; typedef struct { @@ -52,15 +59,20 @@ typedef struct { } GalViewEtableClass; /* Standard functions */ -GtkType gal_view_etable_get_type (void); -GalView *gal_view_etable_new (ETableSpecification *spec, - const gchar *title); -GalView *gal_view_etable_construct (GalViewEtable *view, - ETableSpecification *spec, - const gchar *title); +GtkType gal_view_etable_get_type (void); +GalView *gal_view_etable_new (ETableSpecification *spec, + const gchar *title); +GalView *gal_view_etable_construct (GalViewEtable *view, + ETableSpecification *spec, + const gchar *title); +void gal_view_etable_set_state (GalViewEtable *view, + ETableState *state); +void gal_view_etable_attach_table (GalViewEtable *view, + ETable *table); +void gal_view_etable_attach_tree (GalViewEtable *view, + ETree *tree); +void gal_view_etable_detach (GalViewEtable *view); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +END_GNOME_DECLS #endif /* _GAL_VIEW_ETABLE_H_ */ diff --git a/widgets/menus/gal-view-instance-save-as-dialog.c b/widgets/menus/gal-view-instance-save-as-dialog.c new file mode 100644 index 0000000000..329bc97e37 --- /dev/null +++ b/widgets/menus/gal-view-instance-save-as-dialog.c @@ -0,0 +1,309 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * gal-define-views-dialog.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 <libgnomeui/gnome-dialog.h> +#include <libgnomeui/gnome-stock.h> +#include "gal-view-instance-save-as-dialog.h" +#include "gal-define-views-model.h" +#include "gal-view-new-dialog.h" +#include <gal/e-table/e-table-scrolled.h> + +static GnomeDialogClass *parent_class = NULL; +#define PARENT_TYPE gnome_dialog_get_type() + +/* The arguments we take */ +enum { + ARG_0, + ARG_INSTANCE, +}; + +typedef struct { + char *title; + ETableModel *model; + GalViewInstanceSaveAsDialog *names; +} GalViewInstanceSaveAsDialogChild; + + +/* Static functions */ +static void +gal_view_instance_save_as_dialog_set_instance(GalViewInstanceSaveAsDialog *dialog, + GalViewInstance *instance) +{ + dialog->instance = instance; + if (dialog->model) { + gtk_object_set(GTK_OBJECT(dialog->model), + "collection", instance ? instance->collection : NULL, + NULL); + } +} + +static void +gvisad_setup_radio_buttons (GalViewInstanceSaveAsDialog *dialog) +{ + GtkWidget *radio_replace = glade_xml_get_widget (dialog->gui, "radiobutton-replace"); + GtkWidget *radio_create = glade_xml_get_widget (dialog->gui, "radiobutton-create" ); + GtkWidget *widget; + GtkNotebook *notebook = GTK_NOTEBOOK (glade_xml_get_widget (dialog->gui, "notebook-help")); + + widget = glade_xml_get_widget (dialog->gui, "custom-replace"); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_replace))) { + gtk_widget_set_sensitive (widget, TRUE); + gtk_notebook_set_page (notebook, 0); + dialog->toggle = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE; + } else { + gtk_widget_set_sensitive (widget, FALSE); + } + + widget = glade_xml_get_widget (dialog->gui, "entry-create"); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_create))) { + gtk_widget_set_sensitive (widget, TRUE); + gtk_notebook_set_page (notebook, 1); + dialog->toggle = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE; + } else { + gtk_widget_set_sensitive (widget, FALSE); + } +} + +static void +gvisad_radio_toggled (GtkWidget *widget, GalViewInstanceSaveAsDialog *dialog) +{ + gvisad_setup_radio_buttons (dialog); +} + +static void +gvisad_connect_signal(GalViewInstanceSaveAsDialog *dialog, char *widget_name, char *signal, GtkSignalFunc handler) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget(dialog->gui, widget_name); + + if (widget) + gtk_signal_connect(GTK_OBJECT(widget), signal, handler, dialog); +} + +/* Method override implementations */ +static void +gal_view_instance_save_as_dialog_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) +{ + GalViewInstanceSaveAsDialog *dialog; + + dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (o); + + switch (arg_id){ + case ARG_INSTANCE: + if (GTK_VALUE_OBJECT(*arg)) + gal_view_instance_save_as_dialog_set_instance(dialog, GAL_VIEW_INSTANCE(GTK_VALUE_OBJECT(*arg))); + else + gal_view_instance_save_as_dialog_set_instance(dialog, NULL); + break; + + default: + return; + } +} + +static void +gal_view_instance_save_as_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + GalViewInstanceSaveAsDialog *dialog; + + dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (object); + + switch (arg_id) { + case ARG_INSTANCE: + if (dialog->instance) + GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(dialog->instance); + else + GTK_VALUE_OBJECT(*arg) = NULL; + break; + + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static void +gal_view_instance_save_as_dialog_destroy (GtkObject *object) +{ + GalViewInstanceSaveAsDialog *gal_view_instance_save_as_dialog = GAL_VIEW_INSTANCE_SAVE_AS_DIALOG(object); + + gtk_object_unref(GTK_OBJECT(gal_view_instance_save_as_dialog->gui)); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +/* Init functions */ +static void +gal_view_instance_save_as_dialog_class_init (GalViewInstanceSaveAsDialogClass *klass) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass*) klass; + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class->set_arg = gal_view_instance_save_as_dialog_set_arg; + object_class->get_arg = gal_view_instance_save_as_dialog_get_arg; + object_class->destroy = gal_view_instance_save_as_dialog_destroy; + + gtk_object_add_arg_type("GalViewInstanceSaveAsDialog::instance", GAL_VIEW_INSTANCE_TYPE, + GTK_ARG_READWRITE, ARG_INSTANCE); +} + +static void +gal_view_instance_save_as_dialog_init (GalViewInstanceSaveAsDialog *dialog) +{ + GladeXML *gui; + GtkWidget *widget; + GtkWidget *etable; + + dialog->instance = NULL; + + gui = glade_xml_new_with_domain (GAL_GLADEDIR "/gal-view-instance-save-as-dialog.glade", NULL, PACKAGE); + dialog->gui = gui; + + widget = glade_xml_get_widget(gui, "table-top"); + if (!widget) { + return; + } + gtk_widget_ref(widget); + gtk_widget_unparent(widget); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), widget, TRUE, TRUE, 0); + gtk_widget_unref(widget); + + gnome_dialog_append_buttons(GNOME_DIALOG(dialog), + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, + NULL); + + gvisad_connect_signal(dialog, "radiobutton-replace", "toggled", GTK_SIGNAL_FUNC(gvisad_radio_toggled)); + gvisad_connect_signal(dialog, "radiobutton-create", "toggled", GTK_SIGNAL_FUNC(gvisad_radio_toggled)); + + dialog->model = NULL; + etable = glade_xml_get_widget(dialog->gui, "custom-replace"); + if (etable) { + dialog->model = gtk_object_get_data(GTK_OBJECT(etable), "GalViewInstanceSaveAsDialog::model"); + gtk_object_set(GTK_OBJECT(dialog->model), + "collection", dialog->instance ? dialog->instance->collection : NULL, + NULL); + } + + gvisad_setup_radio_buttons (dialog); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, TRUE, FALSE); +} + + +/* For use from libglade. */ +/* ETable creation */ +#define SPEC "<ETableSpecification no-header=\"true\" cursor-mode=\"line\" draw-grid=\"false\" selection-mode=\"single\">" \ + "<ETableColumn model_col= \"0\" _title=\"Name\" expansion=\"1.0\" minimum_width=\"18\" resizable=\"true\" cell=\"string\" compare=\"string\"/>" \ + "<ETableState> <column source=\"0\"/> <grouping> </grouping> </ETableState>" \ + "</ETableSpecification>" + +GtkWidget *gal_view_instance_save_as_dialog_create_etable(char *name, char *string1, char *string2, int int1, int int2); + +GtkWidget * +gal_view_instance_save_as_dialog_create_etable(char *name, char *string1, char *string2, int int1, int int2) +{ + GtkWidget *table; + ETableModel *model; + model = gal_define_views_model_new(); + table = e_table_scrolled_new(model, NULL, SPEC, NULL); + gtk_object_set_data(GTK_OBJECT(table), "GalViewInstanceSaveAsDialog::model", model); + return table; +} + +/* External methods */ +/** + * gal_view_instance_save_as_dialog_new + * + * Returns a new dialog for defining views. + * + * Returns: The GalViewInstanceSaveAsDialog. + */ +GtkWidget* +gal_view_instance_save_as_dialog_new (GalViewInstance *instance) +{ + GtkWidget *widget = GTK_WIDGET (gtk_type_new (gal_view_instance_save_as_dialog_get_type ())); + gal_view_instance_save_as_dialog_set_instance(GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (widget), instance); + return widget; +} + +GtkType +gal_view_instance_save_as_dialog_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + static const GtkTypeInfo info = + { + "GalViewInstanceSaveAsDialog", + sizeof (GalViewInstanceSaveAsDialog), + sizeof (GalViewInstanceSaveAsDialogClass), + (GtkClassInitFunc) gal_view_instance_save_as_dialog_class_init, + (GtkObjectInitFunc) gal_view_instance_save_as_dialog_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (PARENT_TYPE, &info); + } + + return type; +} + +void +gal_view_instance_save_as_dialog_save (GalViewInstanceSaveAsDialog *dialog) +{ + GalView *view = gal_view_instance_get_current_view (dialog->instance); + GtkWidget *widget; + char *title; + int n; + const char *id = NULL; + switch (dialog->toggle) { + case GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE: + widget = glade_xml_get_widget(dialog->gui, "custom-replace"); + if (widget && E_IS_TABLE_SCROLLED (widget)) { + n = e_table_get_cursor_row (e_table_scrolled_get_table (E_TABLE_SCROLLED (widget))); + id = gal_view_collection_set_nth_view (dialog->instance->collection, n, view); + gal_view_collection_save (dialog->instance->collection); + } + break; + case GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE: + widget = glade_xml_get_widget(dialog->gui, "entry-create"); + if (widget && GTK_IS_ENTRY (widget)) { + title = gtk_entry_get_text (GTK_ENTRY (widget)); + id = gal_view_collection_append_with_title (dialog->instance->collection, title, view); + gal_view_collection_save (dialog->instance->collection); + } + break; + } + + if (id) { + gal_view_instance_set_current_view_id (dialog->instance, id); + } +} diff --git a/widgets/menus/gal-view-instance-save-as-dialog.glade b/widgets/menus/gal-view-instance-save-as-dialog.glade new file mode 100644 index 0000000000..bc5d99dd58 --- /dev/null +++ b/widgets/menus/gal-view-instance-save-as-dialog.glade @@ -0,0 +1,269 @@ +<?xml version="1.0"?> +<GTK-Interface> + +<project> + <name>gal-view-instance-save-as-dialog</name> + <program_name>gal-view-instance-save-as-dialog</program_name> + <directory></directory> + <source_directory>src</source_directory> + <pixmaps_directory>pixmaps</pixmaps_directory> + <language>C</language> + <gnome_support>True</gnome_support> + <gettext_support>True</gettext_support> + <use_widget_names>True</use_widget_names> + <output_main_file>False</output_main_file> + <output_support_files>False</output_support_files> + <output_build_files>False</output_build_files> + <gnome_help_support>True</gnome_help_support> +</project> + +<widget> + <class>GnomeDialog</class> + <name>dialog1</name> + <visible>False</visible> + <type>GTK_WINDOW_TOPLEVEL</type> + <position>GTK_WIN_POS_NONE</position> + <modal>False</modal> + <allow_shrink>False</allow_shrink> + <allow_grow>True</allow_grow> + <auto_shrink>False</auto_shrink> + <auto_close>False</auto_close> + <hide_on_close>False</hide_on_close> + + <widget> + <class>GtkVBox</class> + <child_name>GnomeDialog:vbox</child_name> + <name>dialog-vbox1</name> + <homogeneous>False</homogeneous> + <spacing>8</spacing> + <child> + <padding>4</padding> + <expand>True</expand> + <fill>True</fill> + </child> + + <widget> + <class>GtkHButtonBox</class> + <child_name>GnomeDialog:action_area</child_name> + <name>dialog-action_area1</name> + <layout_style>GTK_BUTTONBOX_END</layout_style> + <spacing>8</spacing> + <child_min_width>85</child_min_width> + <child_min_height>27</child_min_height> + <child_ipad_x>7</child_ipad_x> + <child_ipad_y>0</child_ipad_y> + <child> + <padding>0</padding> + <expand>False</expand> + <fill>True</fill> + <pack>GTK_PACK_END</pack> + </child> + + <widget> + <class>GtkButton</class> + <name>button1</name> + <can_default>True</can_default> + <can_focus>True</can_focus> + <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> + </widget> + + <widget> + <class>GtkButton</class> + <name>button3</name> + <can_default>True</can_default> + <can_focus>True</can_focus> + <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> + </widget> + </widget> + + <widget> + <class>GtkTable</class> + <name>table-top</name> + <rows>5</rows> + <columns>1</columns> + <homogeneous>False</homogeneous> + <row_spacing>0</row_spacing> + <column_spacing>0</column_spacing> + <child> + <padding>0</padding> + <expand>True</expand> + <fill>True</fill> + </child> + + <widget> + <class>GtkNotebook</class> + <name>notebook-help</name> + <show_tabs>False</show_tabs> + <show_border>False</show_border> + <tab_pos>GTK_POS_TOP</tab_pos> + <scrollable>False</scrollable> + <tab_hborder>2</tab_hborder> + <tab_vborder>2</tab_vborder> + <popup_enable>False</popup_enable> + <child> + <left_attach>0</left_attach> + <right_attach>1</right_attach> + <top_attach>4</top_attach> + <bottom_attach>5</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>True</xexpand> + <yexpand>False</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>True</yfill> + </child> + + <widget> + <class>GtkLabel</class> + <name>label6</name> + <label>The current view will replace the given view. Any folders +set to this view wil be replaced with the current view.</label> + <justify>GTK_JUSTIFY_CENTER</justify> + <wrap>False</wrap> + <xalign>0.5</xalign> + <yalign>0.5</yalign> + <xpad>0</xpad> + <ypad>0</ypad> + </widget> + + <widget> + <class>GtkLabel</class> + <child_name>Notebook:tab</child_name> + <name>label4</name> + <label>label4</label> + <justify>GTK_JUSTIFY_CENTER</justify> + <wrap>False</wrap> + <xalign>0.5</xalign> + <yalign>0.5</yalign> + <xpad>0</xpad> + <ypad>0</ypad> + </widget> + + <widget> + <class>GtkLabel</class> + <name>label7</name> + <label>This will create a new View.</label> + <justify>GTK_JUSTIFY_CENTER</justify> + <wrap>False</wrap> + <xalign>0.5</xalign> + <yalign>0.5</yalign> + <xpad>0</xpad> + <ypad>0</ypad> + </widget> + + <widget> + <class>GtkLabel</class> + <child_name>Notebook:tab</child_name> + <name>label5</name> + <label>label5</label> + <justify>GTK_JUSTIFY_CENTER</justify> + <wrap>False</wrap> + <xalign>0.5</xalign> + <yalign>0.5</yalign> + <xpad>0</xpad> + <ypad>0</ypad> + </widget> + </widget> + + <widget> + <class>Custom</class> + <name>custom-replace</name> + <creation_function>gal_view_instance_save_as_dialog_create_etable</creation_function> + <int1>0</int1> + <int2>0</int2> + <last_modification_time>Fri, 01 Feb 2002 20:18:32 GMT</last_modification_time> + <child> + <left_attach>0</left_attach> + <right_attach>1</right_attach> + <top_attach>3</top_attach> + <bottom_attach>4</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>False</xexpand> + <yexpand>True</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>True</yfill> + </child> + </widget> + + <widget> + <class>GtkEntry</class> + <name>entry-create</name> + <sensitive>False</sensitive> + <can_focus>True</can_focus> + <editable>True</editable> + <text_visible>True</text_visible> + <text_max_length>0</text_max_length> + <text></text> + <child> + <left_attach>0</left_attach> + <right_attach>1</right_attach> + <top_attach>1</top_attach> + <bottom_attach>2</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>True</xexpand> + <yexpand>False</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>False</yfill> + </child> + </widget> + + <widget> + <class>GtkRadioButton</class> + <name>radiobutton-replace</name> + <can_focus>True</can_focus> + <label>Replace Existing View</label> + <active>False</active> + <draw_indicator>True</draw_indicator> + <group>choice-group</group> + <child> + <left_attach>0</left_attach> + <right_attach>1</right_attach> + <top_attach>2</top_attach> + <bottom_attach>3</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>False</xexpand> + <yexpand>False</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>False</yfill> + </child> + </widget> + + <widget> + <class>GtkRadioButton</class> + <name>radiobutton-create</name> + <can_focus>True</can_focus> + <label>Create New View Named</label> + <active>True</active> + <draw_indicator>True</draw_indicator> + <group>choice-group</group> + <child> + <left_attach>0</left_attach> + <right_attach>1</right_attach> + <top_attach>0</top_attach> + <bottom_attach>1</bottom_attach> + <xpad>0</xpad> + <ypad>0</ypad> + <xexpand>False</xexpand> + <yexpand>False</yexpand> + <xshrink>False</xshrink> + <yshrink>False</yshrink> + <xfill>True</xfill> + <yfill>False</yfill> + </child> + </widget> + </widget> + </widget> +</widget> + +</GTK-Interface> diff --git a/widgets/menus/gal-view-instance-save-as-dialog.h b/widgets/menus/gal-view-instance-save-as-dialog.h new file mode 100644 index 0000000000..567e00d7b0 --- /dev/null +++ b/widgets/menus/gal-view-instance-save-as-dialog.h @@ -0,0 +1,89 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * gal-define-views-dialog.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_SAVE_AS_DIALOG_H__ +#define __GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_H__ + +#include <libgnomeui/gnome-dialog.h> +#include <glade/glade.h> +#include <gal/e-table/e-table-model.h> +#include <gal/menus/gal-view-collection.h> +#include <gal/menus/gal-view-instance.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +/* GalViewInstanceSaveAsDialog - A dialog displaying information about a contact. + * + * The following arguments are available: + * + * name type read/write description + * -------------------------------------------------------------------------------- + */ + +#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TYPE (gal_view_instance_save_as_dialog_get_type ()) +#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG(obj) (GTK_CHECK_CAST ((obj), GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TYPE, GalViewInstanceSaveAsDialog)) +#define GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TYPE, GalViewInstanceSaveAsDialogClass)) +#define GAL_IS_VIEW_INSTANCE_SAVE_AS_DIALOG(obj) (GTK_CHECK_TYPE ((obj), GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TYPE)) +#define GAL_IS_VIEW_INSTANCE_SAVE_AS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TYPE)) + +typedef struct _GalViewInstanceSaveAsDialog GalViewInstanceSaveAsDialog; +typedef struct _GalViewInstanceSaveAsDialogClass GalViewInstanceSaveAsDialogClass; + +typedef enum { + GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_REPLACE, + GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_TOGGLE_CREATE +} GalViewInstanceSaveAsDialogToggle; + +struct _GalViewInstanceSaveAsDialog +{ + GnomeDialog parent; + + /* item specific fields */ + GladeXML *gui; + ETableModel *model; + + GalViewInstance *instance; + GalViewCollection *collection; + + GalViewInstanceSaveAsDialogToggle toggle; +}; + +struct _GalViewInstanceSaveAsDialogClass +{ + GnomeDialogClass parent_class; +}; + +GtkWidget *gal_view_instance_save_as_dialog_new (GalViewInstance *instance); +GtkType gal_view_instance_save_as_dialog_get_type (void); + +void gal_view_instance_save_as_dialog_save (GalViewInstanceSaveAsDialog *dialog); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GAL_VIEW_INSTANCE_SAVE_AS_DIALOG_H__ */ diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c index 0deaf91c60..26e1f5546d 100644 --- a/widgets/menus/gal-view-instance.c +++ b/widgets/menus/gal-view-instance.c @@ -30,10 +30,14 @@ #include <gnome-xml/parser.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-util.h> +#include <libgnomeui/gnome-dialog.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" +#include "gal-view-instance-save-as-dialog.h" +#include <sys/stat.h> +#include <unistd.h> #define GVI_CLASS(e) ((GalViewInstanceClass *)((GtkObject *)e)->klass) @@ -41,6 +45,8 @@ static GtkObjectClass *gal_view_instance_parent_class; +#define d(x) x + enum { DISPLAY_VIEW, CHANGED, @@ -71,23 +77,94 @@ gal_view_instance_display_view (GalViewInstance *instance, GalView *view) } 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) { + g_free (instance->current_id); + instance->current_id = NULL; + save_current_view (instance); + gal_view_instance_changed(instance); + } + + gal_view_save (view, instance->custom_filename); +} + +static void +disconnect_view (GalViewInstance *instance) +{ + if (instance->current_view) { + if (instance->view_changed_id) { + gtk_signal_disconnect (GTK_OBJECT (instance->current_view), + instance->view_changed_id); + } + + gtk_object_unref (GTK_OBJECT (instance->current_view)); + } + g_free (instance->current_type); + g_free (instance->current_title); + instance->current_title = NULL; + instance->current_type = NULL; + instance->view_changed_id = 0; + instance->current_view = NULL; +} + +static void +connect_view (GalViewInstance *instance, GalView *view) +{ + if (instance->current_view) + disconnect_view (instance); + instance->current_view = view; + + instance->current_title = g_strdup (gal_view_get_title(view)); + instance->current_type = g_strdup (gal_view_get_type_code(view)); + instance->view_changed_id = + gtk_signal_connect(GTK_OBJECT(instance->current_view), "changed", + GTK_SIGNAL_FUNC(view_changed), instance); + + gal_view_instance_display_view (instance, instance->current_view); +} + +static void gal_view_instance_destroy (GtkObject *object) { GalViewInstance *instance = GAL_VIEW_INSTANCE(object); - if (instance->collection) + if (instance->collection) { + if (instance->collection_changed_id) { + gtk_signal_disconnect (GTK_OBJECT (instance->collection), + instance->collection_changed_id); + } 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)); - + disconnect_view (instance); + + g_free (instance->default_view); + if (gal_view_instance_parent_class->destroy) (*gal_view_instance_parent_class->destroy)(object); } @@ -125,17 +202,22 @@ gal_view_instance_class_init (GtkObjectClass *object_class) static void gal_view_instance_init (GalViewInstance *instance) { - instance->collection = NULL; + instance->collection = NULL; - instance->instance_id = NULL; - instance->custom_filename = 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; + instance->current_title = NULL; + instance->current_type = NULL; + instance->current_id = NULL; + instance->current_view = NULL; + + instance->view_changed_id = 0; + instance->collection_changed_id = 0; + + instance->loaded = FALSE; + instance->default_view = NULL; } /** @@ -168,34 +250,14 @@ gal_view_instance_get_type (void) } 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) +collection_changed (GalView *view, GalViewInstance *instance) { - if (instance->current_id != NULL) { - instance->current_view = NULL; - save_current_view (instance); - gal_view_instance_changed(instance); + if (instance->current_id) { + char *view_id = instance->current_id; + instance->current_id = NULL; + gal_view_instance_set_current_view_id (instance, view_id); + g_free (view_id); } - - gal_view_save (view, instance->custom_filename); } static void @@ -203,37 +265,52 @@ load_current_view (GalViewInstance *instance) { xmlDoc *doc; xmlNode *root; + GalView *view = NULL; doc = xmlParseFile(instance->current_view_filename); - if (!doc) + if (doc == NULL) { + instance->current_id = g_strdup (gal_view_instance_get_default_view (instance)); + + if (instance->current_id) { + int index = gal_view_collection_get_view_index_by_id (instance->collection, + instance->current_id); + + if (index != -1) { + view = gal_view_collection_get_view (instance->collection, + index); + view = gal_view_clone(view); + connect_view (instance, view); + } + } 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 { + if (instance->current_id != NULL) { 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); + if (index != -1) { + view = gal_view_collection_get_view (instance->collection, + index); + view = gal_view_clone(view); + } + } + if (view == NULL) { + char *type; + type = e_xml_get_string_prop_by_name_with_default (root, "current_view_type", NULL); + view = gal_view_collection_load_view_from_file (instance->collection, + type, + instance->custom_filename); + g_free (type); } - 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); + connect_view (instance, view); - gal_view_instance_display_view (instance, instance->current_view); + xmlFreeDoc(doc); } /** @@ -268,6 +345,9 @@ gal_view_instance_construct (GalViewInstance *instance, GalViewCollection *colle instance->collection = collection; if (collection) gtk_object_ref (GTK_OBJECT (collection)); + instance->collection_changed_id = + gtk_signal_connect (GTK_OBJECT (collection), "changed", + GTK_SIGNAL_FUNC (collection_changed), instance); instance->instance_id = g_strdup (instance_id); safe_id = g_strdup (instance->instance_id); @@ -283,8 +363,6 @@ gal_view_instance_construct (GalViewInstance *instance, GalViewCollection *colle g_free (safe_id); - load_current_view (instance); - return instance; } @@ -292,11 +370,14 @@ gal_view_instance_construct (GalViewInstance *instance, GalViewCollection *colle char * gal_view_instance_get_current_view_id (GalViewInstance *instance) { - return g_strdup (instance->current_id); + if (instance->current_id && gal_view_collection_get_view_index_by_id (instance->collection, instance->current_id) != -1) + return g_strdup (instance->current_id); + else + return NULL; } void -gal_view_instance_set_current_view_id (GalViewInstance *instance, char *view_id) +gal_view_instance_set_current_view_id (GalViewInstance *instance, const char *view_id) { GalView *view; int index; @@ -304,31 +385,23 @@ gal_view_instance_set_current_view_id (GalViewInstance *instance, char *view_id) 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; + d(g_print("%s: view_id set to %s\n", __FUNCTION__, view_id)); - if (instance->current_view) { - gtk_object_unref (GTK_OBJECT (instance->current_view)); - } + if (instance->current_id && !strcmp (instance->current_id, view_id)) + return; - 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); + index = gal_view_collection_get_view_index_by_id (instance->collection, view_id); + if (index != -1) { + view = gal_view_collection_get_view (instance->collection, index); + connect_view (instance, gal_view_clone (view)); + } save_current_view (instance); gal_view_instance_changed(instance); - gal_view_instance_display_view (instance, view); + gal_view_instance_display_view (instance, instance->current_view); } GalView * @@ -336,3 +409,73 @@ gal_view_instance_get_current_view (GalViewInstance *instance) { return instance->current_view; } + +void +gal_view_instance_set_custom_view (GalViewInstance *instance, GalView *view) +{ + g_free (instance->current_id); + instance->current_id = NULL; + + view = gal_view_clone (view); + connect_view (instance, view); + gal_view_save (view, instance->custom_filename); + save_current_view (instance); + gal_view_instance_changed(instance); +} + +static void +dialog_clicked(GtkWidget *dialog, int button, GalViewInstance *instance) +{ + if (button == 0) { + gal_view_instance_save_as_dialog_save (GAL_VIEW_INSTANCE_SAVE_AS_DIALOG (dialog)); + } + gnome_dialog_close(GNOME_DIALOG(dialog)); +} + +void +gal_view_instance_save_as (GalViewInstance *instance) +{ + GtkWidget *dialog = gal_view_instance_save_as_dialog_new(instance); + gtk_signal_connect(GTK_OBJECT(dialog), "clicked", + GTK_SIGNAL_FUNC(dialog_clicked), instance); + gtk_widget_show(dialog); +} + +/* This is idempotent. Once it's been called once, the rest of the calls are ignored. */ +void +gal_view_instance_load (GalViewInstance *instance) +{ + if (!instance->loaded) { + load_current_view (instance); + instance->loaded = TRUE; + } +} + +/* These only mean anything before gal_view_instance_load is called the first time. */ +const char * +gal_view_instance_get_default_view (GalViewInstance *instance) +{ + if (instance->default_view) + return instance->default_view; + else + return gal_view_collection_get_default_view (instance->collection); +} + +void +gal_view_instance_set_default_view (GalViewInstance *instance, const char *id) +{ + g_free (instance->default_view); + instance->default_view = g_strdup (id); +} + +gboolean +gal_view_instance_exists (GalViewInstance *instance) +{ + struct stat st; + + if (instance->current_view_filename && stat (instance->current_view_filename, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) + return TRUE; + else + return FALSE; + +} diff --git a/widgets/menus/gal-view-instance.h b/widgets/menus/gal-view-instance.h index 9243448768..9d0febf0f0 100644 --- a/widgets/menus/gal-view-instance.h +++ b/widgets/menus/gal-view-instance.h @@ -51,6 +51,12 @@ typedef struct { char *current_id; GalView *current_view; + + guint view_changed_id; + guint collection_changed_id; + + guint loaded : 1; + char *default_view; } GalViewInstance; typedef struct { @@ -79,12 +85,28 @@ GalViewInstance *gal_view_instance_construct (GalViewInstance *inst /* 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); + const char *view_id); GalView *gal_view_instance_get_current_view (GalViewInstance *instance); +/* Sets the current view to the given custom view. */ +void gal_view_instance_set_custom_view (GalViewInstance *instance, + GalView *view); + + +/* Returns true if this instance has ever been used before. */ +gboolean gal_view_instance_exists (GalViewInstance *instance); + /* Manipulate the view collection */ -void gal_view_instance_save_current_view (GalViewInstance *instance); -void gal_view_instance_set_default (GalViewInstance *instance); +/* void gal_view_instance_set_as_default (GalViewInstance *instance); */ +void gal_view_instance_save_as (GalViewInstance *instance); + +/* This is idempotent. Once it's been called once, the rest of the calls are ignored. */ +void gal_view_instance_load (GalViewInstance *instance); + +/* These only mean anything before gal_view_instance_load is called the first time. */ +const char *gal_view_instance_get_default_view (GalViewInstance *instance); +void gal_view_instance_set_default_view (GalViewInstance *instance, + const char *id); END_GNOME_DECLS diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index 4439a3e9bf..2dc03d9a25 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -3299,6 +3299,31 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) /* fixme: */ static int +next_word (EText *text, int start) +{ + char *p; + int length; + + length = strlen (text->text); + + if (start >= length) { + return length; + } else { + p = g_utf8_next_char (text->text + start); + + while (p && *p && g_unichar_validate (g_utf8_get_char (p))) { + gunichar unival = g_utf8_get_char (p); + if (g_unichar_isspace (unival)) { + return p - text->text; + } else + p = g_utf8_next_char (p); + } + } + + return p - text->text; +} + +static int _get_position(EText *text, ETextEventProcessorCommand *command) { int length, obj_num; @@ -3393,28 +3418,7 @@ _get_position(EText *text, ETextEventProcessorCommand *command) break; case E_TEP_FORWARD_WORD: - new_pos = -1; - length = strlen (text->text); - - if (text->selection_end >= length) { - new_pos = length; - } else { - - p = g_utf8_next_char (text->text + text->selection_end); - - while (p && *p && g_unichar_validate (g_utf8_get_char (p))) { - unival = g_utf8_get_char (p); - if (g_unichar_isspace (unival)) { - new_pos = p - text->text; - p = NULL; - } else - p = g_utf8_next_char (p); - } - } - - if (new_pos == -1) - new_pos = p - text->text; - + new_pos = next_word (text, text->selection_end); break; case E_TEP_BACKWARD_WORD: @@ -3586,6 +3590,50 @@ _insert(EText *text, char *string, int value) } static void +capitalize (EText *text, int start, int end, ETextEventProcessorCaps type) +{ + gboolean first = TRUE; + const char *p = text->text + start; + const char *text_end = text->text + end; + char *new_text = g_new0 (char, g_utf8_strlen (text->text + start, start - end) * 6); + char *output = new_text; + + while (p && *p && p < text_end && g_unichar_validate (g_utf8_get_char (p))) { + gunichar unival = g_utf8_get_char (p); + gunichar newval = unival; + + switch (type) { + case E_TEP_CAPS_UPPER: + newval = g_unichar_toupper (unival); + break; + case E_TEP_CAPS_LOWER: + newval = g_unichar_tolower (unival); + break; + case E_TEP_CAPS_TITLE: + if (g_unichar_isalpha (unival)) { + if (first) + newval = g_unichar_totitle (unival); + else + newval = g_unichar_tolower (unival); + first = FALSE; + } else { + first = TRUE; + } + break; + } + g_unichar_to_utf8 (newval, output); + output = g_utf8_next_char (output); + + p = g_utf8_next_char (p); + } + *output = 0; + + e_text_model_delete (text->model, start, end - start); + e_text_model_insert (text->model, start, new_text); + g_free (new_text); +} + +static void e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gpointer data) { EText *text = E_TEXT(data); @@ -3678,6 +3726,15 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM(text), command->time); scroll = FALSE; break; + case E_TEP_CAPS: + if (text->selection_start == text->selection_end) { + capitalize (text, text->selection_start, next_word (text, text->selection_start), command->value); + } else { + int selection_start = MIN (text->selection_start, text->selection_end); + int selection_end = text->selection_start + text->selection_end - selection_start; /* Slightly faster than MAX */ + capitalize (text, selection_start, selection_end, command->value); + } + break; case E_TEP_NOP: scroll = FALSE; break; |