aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--widgets/menus/gal-view-collection.c160
-rw-r--r--widgets/menus/gal-view-collection.h17
-rw-r--r--widgets/menus/gal-view-etable.c145
-rw-r--r--widgets/menus/gal-view-etable.h36
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.c309
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.glade269
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.h89
-rw-r--r--widgets/menus/gal-view-instance.c299
-rw-r--r--widgets/menus/gal-view-instance.h28
-rw-r--r--widgets/text/e-text.c101
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;