diff options
-rw-r--r-- | calendar/ChangeLog | 40 | ||||
-rw-r--r-- | calendar/gui/GNOME_Evolution_Calendar.oaf.in | 25 | ||||
-rw-r--r-- | calendar/gui/Makefile.am | 2 | ||||
-rw-r--r-- | calendar/gui/calendar-component.c | 14 | ||||
-rw-r--r-- | calendar/gui/comp-editor-factory.c | 112 | ||||
-rw-r--r-- | calendar/gui/component-factory.c | 14 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.c | 38 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.h | 1 | ||||
-rw-r--r-- | calendar/gui/e-calendar-table.c | 28 | ||||
-rw-r--r-- | calendar/gui/e-comp-editor-registry.c | 219 | ||||
-rw-r--r-- | calendar/gui/e-comp-editor-registry.h | 79 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 78 | ||||
-rw-r--r-- | calendar/gui/main.c | 6 |
13 files changed, 451 insertions, 205 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index c724d7f35d..c682b7a0c1 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,43 @@ +2002-05-26 JP Rosevear <jpr@ximian.com> + + * gui/e-comp-editor-registry.[hc]: a registry of comp editors so + we can close them all centrally + + * gui/gnome-cal.c (gnome_calendar_init): there is no editor hash + now + (gnome_calendar_destroy): ditto + (gnome_calendar_edit_object): look for the event editor in the + registry, if it isn't there, create it and add it to the registry + + * gui/e-calendar-table.c (open_task): look for the task editor in + the registry, if it isn't there, create it and add it to the + registry + + * gui/component-factory.c (request_quit): close all open editors + (create_object): add a request_quit function to the shell + component + + * gui/comp-editor-factory.c (free_client): there is no + uid_comp_hash to free any more + (editor_destroy_cb): we get an OpenClient as callback data now, + reduce the editor count and destroy it if it is 0 + (edit_existing): don't create the Component, add the new editor to + the registry, increase the editor count + (edit_new): ditto + (open_client): set the editor count to 0 + (impl_editExisting): look in the registry for the editor + + * gui/Makefile.am: Build new sources + + * gui/main.c (main): create the registry + + * gui/dialogs/comp-editor.c (comp_editor_close): prompt to save + and then close dialog + + * gui/dialogs/comp-editor.h: new proto + + * gui/GNOME_Evolution_Calendar.oaf.in: remove dead summary stuff + 2002-05-24 Rodrigo Moya <rodrigo@ximian.com> * pcs/cal-backend-file.c (save): check the value returned by diff --git a/calendar/gui/GNOME_Evolution_Calendar.oaf.in b/calendar/gui/GNOME_Evolution_Calendar.oaf.in index ce53fba7e6..dece5a0993 100644 --- a/calendar/gui/GNOME_Evolution_Calendar.oaf.in +++ b/calendar/gui/GNOME_Evolution_Calendar.oaf.in @@ -49,30 +49,6 @@ value="evolution-calendar.png"/> </oaf_server> -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory for the Calendar Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_Component" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution:Summary:ComponentFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Evolution calendar executive summary component."/> -</oaf_server> - <oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ControlFactory" type="exe" location="evolution-calendar"> @@ -198,3 +174,4 @@ </oaf_server> </oaf_info> + diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index 20e2207907..9c842635f7 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -97,6 +97,8 @@ evolution_calendar_SOURCES = \ e-calendar-table.c \ e-cell-date-edit-text.h \ e-cell-date-edit-text.c \ + e-comp-editor-registry.c \ + e-comp-editor-registry.h \ e-day-view-layout.c \ e-day-view-layout.h \ e-day-view-main-item.c \ diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index 355da4c387..f1d09b90ed 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -42,7 +42,8 @@ #include "calendar-config.h" #include "tasks-control.h" #include "tasks-migrate.h" - +#include "e-comp-editor-registry.h" +#include "dialogs/comp-editor.h" /* OAFIID for the component. */ @@ -60,6 +61,7 @@ char *evolution_dir; EvolutionShellClient *global_shell_client = NULL; +extern ECompEditorRegistry *comp_editor_registry; static const EvolutionShellComponentFolderType folder_types[] = { { FOLDER_CALENDAR, @@ -467,6 +469,14 @@ xfer_folder (EvolutionShellComponent *shell_component, CORBA_exception_free (&ev); } +static gboolean +request_quit (EvolutionShellComponent *shell_component, void *closure) +{ + e_comp_editor_registry_close_all (comp_editor_registry); + + return TRUE; +} + static GList *shells = NULL; static void @@ -677,7 +687,7 @@ create_object (void) xfer_folder, NULL, /* populate_folder_context_menu_fn */ NULL, /* get_dnd_selection_fn */ - NULL, /* request_quit */ + request_quit, NULL /* closure */); /* Offline handler */ diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c index 805e0a5c0b..b5e19575f1 100644 --- a/calendar/gui/comp-editor-factory.c +++ b/calendar/gui/comp-editor-factory.c @@ -27,11 +27,14 @@ #include <e-util/e-url.h> #include <cal-client/cal-client.h> #include "calendar-config.h" +#include "e-comp-editor-registry.h" #include "comp-editor-factory.h" #include "comp-util.h" #include "dialogs/event-editor.h" #include "dialogs/task-editor.h" +extern ECompEditorRegistry *comp_editor_registry; + /* A pending request */ @@ -65,9 +68,9 @@ typedef struct { /* Client of the calendar */ CalClient *client; - - /* Hash table of Component structures that belong to this client */ - GHashTable *uid_comp_hash; + + /* Count editors using this client */ + int editor_count; /* Pending requests; they are pending if the client is still being opened */ GSList *pending; @@ -76,21 +79,6 @@ typedef struct { guint open : 1; } OpenClient; -/* A component that is being edited */ -typedef struct { - /* Our parent client */ - OpenClient *parent; - - /* UID of the component we are editing, used as the key in the hash table */ - const char *uid; - - /* Component we are editing */ - CalComponent *comp; - - /* Component editor that is open */ - CompEditor *editor; -} Component; - /* Private part of the CompEditorFactory structure */ struct CompEditorFactoryPrivate { /* Hash table of URI->OpenClient */ @@ -149,23 +137,6 @@ comp_editor_factory_init (CompEditorFactory *factory) priv->uri_client_hash = g_hash_table_new (g_str_hash, g_str_equal); } -/* Used from g_hash_table_foreach(); frees a component structure */ -static void -free_component_cb (gpointer key, gpointer value, gpointer data) -{ - Component *c; - - c = value; - - c->parent = NULL; - c->uid = NULL; - - gtk_object_unref (GTK_OBJECT (c->comp)); - c->comp = NULL; - - g_free (c); -} - /* Frees a Request structure */ static void free_request (Request *r) @@ -190,10 +161,6 @@ free_client (OpenClient *oc) gtk_object_unref (GTK_OBJECT (oc->client)); oc->client = NULL; - g_hash_table_foreach (oc->uid_comp_hash, free_component_cb, NULL); - g_hash_table_destroy (oc->uid_comp_hash); - oc->uid_comp_hash = NULL; - for (l = oc->pending; l; l = l->next) { Request *r; @@ -246,27 +213,20 @@ comp_editor_factory_destroy (GtkObject *object) static void editor_destroy_cb (GtkObject *object, gpointer data) { - Component *c; OpenClient *oc; CompEditorFactory *factory; CompEditorFactoryPrivate *priv; - c = data; - oc = c->parent; + oc = data; factory = oc->factory; priv = factory->priv; - /* Free the Component */ - - g_hash_table_remove (oc->uid_comp_hash, c->uid); - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); + oc->editor_count--; /* See if we need to free the client */ - g_assert (oc->pending == NULL); - if (g_hash_table_size (oc->uid_comp_hash) != 0) + if (oc->editor_count != 0) return; g_hash_table_remove (priv->uri_client_hash, oc->uri); @@ -280,7 +240,6 @@ edit_existing (OpenClient *oc, const char *uid) CalComponent *comp; CalClientGetStatus status; CompEditor *editor; - Component *c; CalComponentVType vtype; g_assert (oc->open); @@ -308,7 +267,7 @@ edit_existing (OpenClient *oc, const char *uid) } /* Create the appropriate type of editor */ - + vtype = cal_component_get_vtype (comp); switch (vtype) { @@ -327,21 +286,15 @@ edit_existing (OpenClient *oc, const char *uid) } /* Set the client/object on the editor */ - - c = g_new (Component, 1); - c->parent = oc; - cal_component_get_uid (comp, &c->uid); - c->comp = comp; - c->editor = editor; - - g_hash_table_insert (oc->uid_comp_hash, (char *) c->uid, c); - - gtk_signal_connect (GTK_OBJECT (editor), "destroy", - GTK_SIGNAL_FUNC (editor_destroy_cb), c); - comp_editor_set_cal_client (editor, oc->client); comp_editor_edit_comp (editor, comp); comp_editor_focus (editor); + + oc->editor_count++; + gtk_signal_connect (GTK_OBJECT (editor), "destroy", + GTK_SIGNAL_FUNC (editor_destroy_cb), oc); + + e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); } /* Creates a component with the appropriate defaults for the specified component @@ -404,7 +357,6 @@ static void edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) { CalComponent *comp; - Component *c; CompEditor *editor; switch (type) { @@ -426,23 +378,17 @@ edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompE return; } - c = g_new (Component, 1); - c->parent = oc; - cal_component_get_uid (comp, &c->uid); - c->comp = comp; - - c->editor = editor; - - g_hash_table_insert (oc->uid_comp_hash, (char *) c->uid, c); - - gtk_signal_connect (GTK_OBJECT (editor), "destroy", - GTK_SIGNAL_FUNC (editor_destroy_cb), c); - comp_editor_set_cal_client (editor, oc->client); comp_editor_edit_comp (editor, comp); if (type == GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING) event_editor_show_meeting (EVENT_EDITOR (editor)); comp_editor_focus (editor); + + oc->editor_count++; + gtk_signal_connect (GTK_OBJECT (editor), "destroy", + GTK_SIGNAL_FUNC (editor_destroy_cb), oc); + + e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); } /* Resolves all the pending requests for a client */ @@ -553,7 +499,7 @@ open_client (CompEditorFactory *factory, const char *uristr) oc->uri = g_strdup (uristr); oc->client = client; - oc->uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal); + oc->editor_count = 0; oc->pending = NULL; oc->open = FALSE; @@ -563,7 +509,6 @@ open_client (CompEditorFactory *factory, const char *uristr) if (!cal_client_open_calendar (oc->client, uristr, FALSE)) { g_free (oc->uri); gtk_object_unref (GTK_OBJECT (oc->client)); - g_hash_table_destroy (oc->uid_comp_hash); g_free (oc); return NULL; @@ -632,7 +577,7 @@ impl_editExisting (PortableServer_Servant servant, CompEditorFactory *factory; CompEditorFactoryPrivate *priv; OpenClient *oc; - Component *c; + CompEditor *editor; factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant)); priv = factory->priv; @@ -648,12 +593,11 @@ impl_editExisting (PortableServer_Servant servant, /* Look up the component */ - c = g_hash_table_lookup (oc->uid_comp_hash, uid); - if (!c) + editor = e_comp_editor_registry_find (comp_editor_registry, uid); + if (editor != NULL) { edit_existing (oc, uid); - else { - g_assert (c->editor != NULL); - comp_editor_focus (c->editor); + } else { + comp_editor_focus (editor); } } diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c index 355da4c387..f1d09b90ed 100644 --- a/calendar/gui/component-factory.c +++ b/calendar/gui/component-factory.c @@ -42,7 +42,8 @@ #include "calendar-config.h" #include "tasks-control.h" #include "tasks-migrate.h" - +#include "e-comp-editor-registry.h" +#include "dialogs/comp-editor.h" /* OAFIID for the component. */ @@ -60,6 +61,7 @@ char *evolution_dir; EvolutionShellClient *global_shell_client = NULL; +extern ECompEditorRegistry *comp_editor_registry; static const EvolutionShellComponentFolderType folder_types[] = { { FOLDER_CALENDAR, @@ -467,6 +469,14 @@ xfer_folder (EvolutionShellComponent *shell_component, CORBA_exception_free (&ev); } +static gboolean +request_quit (EvolutionShellComponent *shell_component, void *closure) +{ + e_comp_editor_registry_close_all (comp_editor_registry); + + return TRUE; +} + static GList *shells = NULL; static void @@ -677,7 +687,7 @@ create_object (void) xfer_folder, NULL, /* populate_folder_context_menu_fn */ NULL, /* get_dnd_selection_fn */ - NULL, /* request_quit */ + request_quit, NULL /* closure */); /* Offline handler */ diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index f2a028a4ee..21f5e1c9f3 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -411,6 +411,19 @@ prompt_to_save_changes (CompEditor *editor, gboolean send) } } +/* This sets the focus to the toplevel, so any field being edited is committed. + FIXME: In future we may also want to check some of the fields are valid, + e.g. the EDateEdit fields. */ +static void +commit_all_fields (CompEditor *editor) +{ + CompEditorPrivate *priv; + + priv = editor->priv; + + gtk_window_set_focus (GTK_WINDOW (editor), NULL); +} + /* Closes the dialog box and emits the appropriate signals */ static void close_dialog (CompEditor *editor) @@ -965,6 +978,18 @@ comp_editor_send_comp (CompEditor *editor, CalComponentItipMethod method) klass->send_comp (editor, method); } +void +comp_editor_close (CompEditor *editor) +{ + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + + commit_all_fields (editor); + + if (prompt_to_save_changes (editor, TRUE)) + close_dialog (editor); +} + /** * comp_editor_merge_ui: * @editor: @@ -1048,19 +1073,6 @@ comp_editor_focus (CompEditor *editor) raise_and_focus (GTK_WIDGET (editor)); } -/* This sets the focus to the toplevel, so any field being edited is committed. - FIXME: In future we may also want to check some of the fields are valid, - e.g. the EDateEdit fields. */ -static void -commit_all_fields (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - gtk_window_set_focus (GTK_WINDOW (editor), NULL); -} - /* Menu Commands */ static void save_cmd (GtkWidget *widget, gpointer data) diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index cc5679d1cd..9297526e48 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -83,6 +83,7 @@ gboolean comp_editor_save_comp (CompEditor *editor, void comp_editor_delete_comp (CompEditor *editor); void comp_editor_send_comp (CompEditor *editor, CalComponentItipMethod method); +void comp_editor_close (CompEditor *editor); void comp_editor_merge_ui (CompEditor *editor, const char *filename, BonoboUIVerb *verbs, diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index 8a7d3dd631..f8f5e1568b 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -42,6 +42,7 @@ #include <e-util/e-dialog-utils.h> #include <widgets/misc/e-cell-date-edit.h> #include <widgets/misc/e-cell-percent.h> +#include "e-comp-editor-registry.h" #include "e-calendar-table.h" #include "e-cell-date-edit-text.h" #include "calendar-config.h" @@ -58,6 +59,7 @@ #include "art/check-filled.xpm" +extern ECompEditorRegistry *comp_editor_registry; static void e_calendar_table_class_init (ECalendarTableClass *class); static void e_calendar_table_init (ECalendarTable *cal_table); @@ -898,14 +900,24 @@ e_calendar_table_paste_clipboard (ECalendarTable *cal_table) static void open_task (ECalendarTable *cal_table, CalComponent *comp, gboolean assign) { - TaskEditor *tedit; - - tedit = task_editor_new (); - comp_editor_set_cal_client (COMP_EDITOR (tedit), calendar_model_get_cal_client (cal_table->model)); - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - if (assign) - task_editor_show_assignment (TASK_EDITOR (tedit)); - comp_editor_focus (COMP_EDITOR (tedit)); + CompEditor *tedit; + const char *uid; + + cal_component_get_uid (comp, &uid); + + tedit = e_comp_editor_registry_find (comp_editor_registry, uid); + if (tedit == NULL) { + tedit = COMP_EDITOR (task_editor_new ()); + + comp_editor_set_cal_client (tedit, calendar_model_get_cal_client (cal_table->model)); + comp_editor_edit_comp (tedit, comp); + if (assign) + task_editor_show_assignment (TASK_EDITOR (tedit)); + + e_comp_editor_registry_add (comp_editor_registry, tedit, FALSE); + } + + comp_editor_focus (tedit); } /* Opens the task in the specified row */ diff --git a/calendar/gui/e-comp-editor-registry.c b/calendar/gui/e-comp-editor-registry.c new file mode 100644 index 0000000000..4385cb1a84 --- /dev/null +++ b/calendar/gui/e-comp-editor-registry.c @@ -0,0 +1,219 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-comp-editor-registry.c + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: JP Rosevear + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gnome.h> +#include "e-comp-editor-registry.h" + +struct _ECompEditorRegistryPrivate { + GHashTable *editors; +}; + +struct _ECompEditorRegistryData +{ + CompEditor *editor; + char *uid; +}; + +typedef struct _ECompEditorRegistryData ECompEditorRegistryData; +typedef struct _ECompEditorRegistryForeachData ECompEditorRegistryForeachData; + +static GtkObjectClass *parent_class = NULL; + +static void editor_destroy_cb (GtkWidget *widget, gpointer data); + +static void +destroy (GtkObject *obj) +{ + ECompEditorRegistry *reg; + ECompEditorRegistryPrivate *priv; + + reg = E_COMP_EDITOR_REGISTRY (obj); + priv = reg->priv; + + g_hash_table_destroy (priv->editors); + + g_free (priv); +} + +static void +class_init (ECompEditorRegistryClass *klass) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (klass); + + parent_class = gtk_type_class (gtk_object_get_type ()); + + object_class->destroy = destroy; +} + +static void +init (ECompEditorRegistry *reg) +{ + ECompEditorRegistryPrivate *priv; + + priv = g_new0 (ECompEditorRegistryPrivate, 1); + + reg->priv = priv; + + priv->editors = g_hash_table_new (g_str_hash, g_str_equal); +} + + + +GtkType +e_comp_editor_registry_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "ECompEditorRegistry", + sizeof (ECompEditorRegistry), + sizeof (ECompEditorRegistryClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gtk_object_get_type (), &info); + } + + return type; +} + +GtkObject * +e_comp_editor_registry_new (void) +{ + return gtk_type_new (E_TYPE_COMP_EDITOR_REGISTRY); +} + +void +e_comp_editor_registry_add (ECompEditorRegistry *reg, CompEditor *editor, gboolean remote) +{ + ECompEditorRegistryPrivate *priv; + ECompEditorRegistryData *rdata; + CalComponent *comp; + const char *uid; + + g_return_if_fail (reg != NULL); + g_return_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg)); + g_return_if_fail (editor != NULL); + g_return_if_fail (IS_COMP_EDITOR (editor)); + + priv = reg->priv; + + comp = comp_editor_get_current_comp (editor); + cal_component_get_uid (comp, &uid); + + rdata = g_new0 (ECompEditorRegistryData, 1); + + rdata->editor = editor; + rdata->uid = g_strdup (uid); + g_hash_table_insert (priv->editors, rdata->uid, rdata); + + gtk_signal_connect (GTK_OBJECT (editor), "destroy", editor_destroy_cb, reg); + + gtk_object_unref (GTK_OBJECT (comp)); +} + +CompEditor * +e_comp_editor_registry_find (ECompEditorRegistry *reg, const char *uid) +{ + ECompEditorRegistryPrivate *priv; + ECompEditorRegistryData *rdata; + + g_return_val_if_fail (reg != NULL, NULL); + g_return_val_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg), NULL); + g_return_val_if_fail (uid != NULL, NULL); + + priv = reg->priv; + + rdata = g_hash_table_lookup (priv->editors, uid); + if (rdata != NULL) + return rdata->editor; + + return NULL; +} + +static gboolean +foreach_close_cb (gpointer key, gpointer value, gpointer data) +{ + ECompEditorRegistryData *rdata; + + rdata = value; + + gtk_signal_disconnect_by_data (GTK_OBJECT (rdata->editor), data); + + comp_editor_focus (rdata->editor); + comp_editor_close (rdata->editor); + + g_free (rdata->uid); + g_free (rdata); + + return TRUE; +} + +void +e_comp_editor_registry_close_all (ECompEditorRegistry *reg) +{ + ECompEditorRegistryPrivate *priv; + + g_return_if_fail (reg != NULL); + g_return_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg)); + + priv = reg->priv; + + g_hash_table_foreach_remove (priv->editors, foreach_close_cb, reg); +} + +static void +editor_destroy_cb (GtkWidget *widget, gpointer data) +{ + ECompEditorRegistry *reg; + ECompEditorRegistryPrivate *priv; + ECompEditorRegistryData *rdata; + CalComponent *comp; + const char *uid; + + reg = E_COMP_EDITOR_REGISTRY (data); + priv = reg->priv; + + comp = comp_editor_get_current_comp (COMP_EDITOR (widget)); + cal_component_get_uid (comp, &uid); + + rdata = g_hash_table_lookup (priv->editors, uid); + g_assert (rdata != NULL); + + g_hash_table_remove (priv->editors, rdata->uid); + g_free (rdata->uid); + g_free (rdata); + + gtk_object_unref (GTK_OBJECT (comp)); +} + diff --git a/calendar/gui/e-comp-editor-registry.h b/calendar/gui/e-comp-editor-registry.h new file mode 100644 index 0000000000..13833e2357 --- /dev/null +++ b/calendar/gui/e-comp-editor-registry.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-comp-editor-registry.h + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: JP Rosevear + */ + +#ifndef _E_COMP_EDITOR_REGISTRY_H_ +#define _E_COMP_EDITOR_REGISTRY_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtk/gtk.h> +#include <dialogs/comp-editor.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_COMP_EDITOR_REGISTRY (e_comp_editor_registry_get_type ()) +#define E_COMP_EDITOR_REGISTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_COMP_EDITOR_REGISTRY, ECompEditorRegistry)) +#define E_COMP_EDITOR_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_COMP_EDITOR_REGISTRY, ECompEditorRegistryClass)) +#define E_IS_COMP_EDITOR_REGISTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_COMP_EDITOR_REGISTRY)) +#define E_IS_COMP_EDITOR_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_COMP_EDITOR_REGISTRY)) + + +typedef struct _ECompEditorRegistry ECompEditorRegistry; +typedef struct _ECompEditorRegistryPrivate ECompEditorRegistryPrivate; +typedef struct _ECompEditorRegistryClass ECompEditorRegistryClass; + +struct _ECompEditorRegistry { + GtkObject parent; + + ECompEditorRegistryPrivate *priv; +}; + +struct _ECompEditorRegistryClass { + GtkObjectClass parent_class; +}; + +typedef void (* ECompEditorRegistryForeachFn) (CompEditor *editor, gpointer data); + + + + +GtkType e_comp_editor_registry_get_type (void); +GtkObject *e_comp_editor_registry_new (void); +void e_comp_editor_registry_add (ECompEditorRegistry *reg, + CompEditor *editor, + gboolean remote); +CompEditor *e_comp_editor_registry_find (ECompEditorRegistry *reg, + const char *uid); +void e_comp_editor_registry_close_all (ECompEditorRegistry *reg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _E_COMP_EDITOR_REGISTRY_H_ */ + + diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 848902fa04..67b84575c0 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -41,6 +41,7 @@ #include "e-util/e-url.h" #include <cal-util/timeutil.h> #include "widgets/menus/gal-view-menus.h" +#include "e-comp-editor-registry.h" #include "dialogs/event-editor.h" #include "dialogs/task-editor.h" #include "comp-util.h" @@ -56,6 +57,8 @@ #include "calendar-view-factory.h" #include "tag-calendar.h" +extern ECompEditorRegistry *comp_editor_registry; + /* Private part of the GnomeCalendar structure */ @@ -84,9 +87,6 @@ struct _GnomeCalendarPrivate { * Fields for the calendar view */ - /* Mapping of component UIDs to event editors */ - GHashTable *object_editor_hash; - /* This is the last selection explicitly selected by the user. We try to keep it the same when we switch views, but we may have to alter it depending on the view (e.g. the week views only select days, so @@ -134,11 +134,6 @@ struct _GnomeCalendarPrivate { GalViewInstance *view_instance; GalViewMenus *view_menus; - /* Whether we are being destroyed and should not mess with the object - * editor hash table. - */ - guint in_destroy : 1; - /* Our current timezone. */ icaltimezone *zone; @@ -905,8 +900,6 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->cal_categories = NULL; priv->tasks_categories = NULL; - priv->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal); - priv->current_view_type = GNOME_CAL_DAY_VIEW; priv->range_selected = FALSE; @@ -940,16 +933,6 @@ free_categories (GPtrArray *categories) g_ptr_array_free (categories, TRUE); } -/* Used from g_hash_table_foreach(); frees an UID string */ -static void -destroy_editor_cb (gpointer key, gpointer value, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (value); - gtk_object_unref (GTK_OBJECT (ee)); -} - static void gnome_calendar_destroy (GtkObject *object) { @@ -995,11 +978,6 @@ gnome_calendar_destroy (GtkObject *object) priv->task_pad_client = NULL; } - priv->in_destroy = TRUE; - g_hash_table_foreach (priv->object_editor_hash, destroy_editor_cb, NULL); - g_hash_table_destroy (priv->object_editor_hash); - priv->object_editor_hash = NULL; - if (priv->view_instance) { gtk_object_unref (GTK_OBJECT (priv->view_instance)); priv->view_instance = NULL; @@ -2139,48 +2117,12 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal, *end_time = priv->selection_end_time; } - -/* Callback used when an event editor dialog is closed */ -struct editor_closure -{ - GnomeCalendar *gcal; - char *uid; -}; - -static void -editor_closed_cb (GtkWidget *widget, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - struct editor_closure *ec; - gboolean result; - gpointer orig_key; - char *orig_uid; - - ec = (struct editor_closure *) data; - gcal = ec->gcal; - priv = gcal->priv; - - result = g_hash_table_lookup_extended (priv->object_editor_hash, ec->uid, &orig_key, NULL); - g_assert (result != FALSE); - - orig_uid = orig_key; - - if (!priv->in_destroy) - g_hash_table_remove (priv->object_editor_hash, orig_uid); - - g_free (orig_uid); - - g_free (ec); -} - void gnome_calendar_edit_object (GnomeCalendar *gcal, CalComponent *comp, gboolean meeting) { GnomeCalendarPrivate *priv; EventEditor *ee; - struct editor_closure *ec; const char *uid; g_return_if_fail (gcal != NULL); @@ -2191,28 +2133,20 @@ gnome_calendar_edit_object (GnomeCalendar *gcal, CalComponent *comp, cal_component_get_uid (comp, &uid); - ee = g_hash_table_lookup (priv->object_editor_hash, uid); + ee = EVENT_EDITOR (e_comp_editor_registry_find (comp_editor_registry, uid)); if (!ee) { - ec = g_new0 (struct editor_closure, 1); - ee = event_editor_new (); if (!ee) { g_message ("gnome_calendar_edit_object(): Could not create the event editor"); return; } - ec->gcal = gcal; - ec->uid = g_strdup (uid); - - g_hash_table_insert (priv->object_editor_hash, ec->uid, ee); - - gtk_signal_connect (GTK_OBJECT (ee), "destroy", - GTK_SIGNAL_FUNC (editor_closed_cb), - ec); comp_editor_set_cal_client (COMP_EDITOR (ee), priv->client); comp_editor_edit_comp (COMP_EDITOR (ee), comp); if (meeting) event_editor_show_meeting (ee); + + e_comp_editor_registry_add (comp_editor_registry, COMP_EDITOR (ee), FALSE); } comp_editor_focus (COMP_EDITOR (ee)); diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 5c7a2bc08f..b9b504826b 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -42,14 +42,18 @@ #include "calendar-commands.h" #include "calendar-config.h" #include "component-factory.h" +#include "e-comp-editor-registry.h" #include "comp-editor-factory.h" #include "control-factory.h" #include "itip-control-factory.h" #include "tasks-control-factory.h" +ECompEditorRegistry *comp_editor_registry = NULL; + /* The component editor factory */ static CompEditorFactory *comp_editor_factory = NULL; + static void init_bonobo (int argc, char **argv) { @@ -144,6 +148,8 @@ main (int argc, char **argv) G_LOG_LEVEL_WARNING); #endif + comp_editor_registry = E_COMP_EDITOR_REGISTRY (e_comp_editor_registry_new ()); + calendar_config_init (); control_factory_init (); |