diff --git a/archiver/ChangeLog b/archiver/ChangeLog index cf09986e8..856a1e4db 100644 --- a/archiver/ChangeLog +++ b/archiver/ChangeLog @@ -1,3 +1,20 @@ +2000-12-22 Bradford Hovinen + + * archive.c (foreach_cb): + (archive_foreach_child_location): Use auxillary structure to pass + data to traversal callback + (archive_get_location): + (archive_register_location): strdup() location ids + (free_location_cb): free() key + +2000-12-20 Bradford Hovinen + + * location.c (location_get_parent): Implement + + * archive.c (load_all_locations): Implement + (foreach_cb): + (archive_foreach_child_location): Implement + 2000-12-19 Bradford Hovinen * Makefile.am (bin_PROGRAMS): Changed name of archiver to diff --git a/archiver/Makefile.am b/archiver/Makefile.am index 1f9b55549..0bd616d7f 100644 --- a/archiver/Makefile.am +++ b/archiver/Makefile.am @@ -1,6 +1,9 @@ Locationmetadir = $(datadir)/hcm/default Locationmeta_DATA = default-user.xml default-global.xml +gladedir = $(prefix)/share/hcm/glade +glade_DATA = rollback-location-management.glade + includedir = $(prefix)/include/helix-archiver INCLUDES = \ @@ -9,9 +12,11 @@ INCLUDES = \ -DVERSION=\""$(VERSION)"\" \ -DCONFIGDIR=\""/etc"\" \ -DLOCATION_DIR=\""$(datadir)/hcm/default"\" \ - $(GNOME_XML_CFLAGS) + -DGLADE_DIR=\""$(datadir)/hcm/glade"\" \ + $(GNOME_XML_CFLAGS) \ + $(LIBGLADE_CFLAGS) -bin_PROGRAMS = helix-archiver +bin_PROGRAMS = helix-archiver helix-config-manager lib_LIBRARIES = libhelix_archiver.a libhelix_archiver_a_SOURCES = \ @@ -28,9 +33,23 @@ helix_archiver_SOURCES = \ main.c helix_archiver_LDADD = \ - $(GNOME_LIBDIR) \ - $(GNOMEUI_LIBS) \ - $(INTLLIBS) \ - $(GNOME_XML_LIB) \ + $(GNOME_LIBDIR) \ + $(GNOMEUI_LIBS) \ + $(INTLLIBS) \ + $(GNOME_XML_LIB) \ libhelix_archiver.a +helix_config_manager_SOURCES = \ + config-manager.c \ + config-manager-dialog.c config-manager-dialog.h \ + create-location-dialog.c create-location-dialog.h \ + rollback-widget.c rollback-widget.h \ + location-list.c location-list.h + +helix_config_manager_LDADD = \ + $(GNOME_LIBDIR) \ + $(GNOMEUI_LIBS) \ + $(INTLLIBS) \ + $(GNOME_XML_LIB) \ + $(LIBGLADE_LIBS) \ + libhelix_archiver.a diff --git a/archiver/TODO b/archiver/TODO index 5bef1b999..4f73e4076 100644 --- a/archiver/TODO +++ b/archiver/TODO @@ -2,6 +2,11 @@ * Archiving changes in location metadata * Fix race in lock handling and add timeout support (look in gnome-mime) * Support multiple backends from CLI + * Add translateable backend description support + +GUI + * Try to factor out populate_locations_list to be common between the + different dialogs Long-term * Add clustering support: diff --git a/archiver/archive.c b/archiver/archive.c index aab4166e5..e4529c36b 100644 --- a/archiver/archive.c +++ b/archiver/archive.c @@ -29,30 +29,49 @@ #include #include #include +#include +#include #include "archive.h" +typedef struct _GRealTree GRealTree; +typedef struct _GTreeNode GTreeNode; + +typedef struct _foreach_t foreach_t; + +struct _foreach_t +{ + Archive *archive; + LocationCB callback; + Location *parent; + gpointer user_data; +}; + static GtkObjectClass *parent_class; +static Archive *user_archive; +static Archive *global_archive; + enum { ARG_0, ARG_PREFIX }; -static void archive_init (Archive *archive); -static void archive_class_init (ArchiveClass *klass); +static void archive_init (Archive *archive); +static void archive_class_init (ArchiveClass *klass); -static void archive_destroy (GtkObject *object); +static void archive_destroy (GtkObject *object); -static void archive_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); +static void archive_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); -static void archive_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); +static void archive_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); -static gboolean do_load (Archive *archive); +static gboolean do_load (Archive *archive); +static void load_all_locations (Archive *archive); guint archive_get_type (void) @@ -162,6 +181,11 @@ archive_load (gboolean is_global) GtkObject *object; gchar *prefix; + if (is_global && global_archive != NULL) + return GTK_OBJECT (global_archive); + else if (user_archive != NULL) + return GTK_OBJECT (user_archive); + if (is_global) prefix = CONFIGDIR "/helix-config"; else @@ -184,6 +208,11 @@ archive_load (gboolean is_global) ARCHIVE (object)->backend_list = BACKEND_LIST (backend_list_new (is_global)); + if (is_global) + global_archive = ARCHIVE (object); + else + user_archive = ARCHIVE (object); + return object; } @@ -191,6 +220,7 @@ static gint free_location_cb (gchar *locid, Location *location) { location_close (location); + g_free (locid); return FALSE; } @@ -262,7 +292,8 @@ archive_get_location (Archive *archive, const gchar *locid) if (!loc_obj) return NULL; if (loc_obj) - g_tree_insert (archive->locations, locid, loc_obj); + g_tree_insert (archive->locations, + g_strdup (locid), loc_obj); } if (loc_obj) { @@ -290,7 +321,7 @@ archive_register_location (Archive *archive, Location *location) g_return_if_fail (IS_LOCATION (location)); g_tree_insert (archive->locations, - location_get_id (location), + g_strdup (location_get_id (location)), location); } @@ -501,6 +532,51 @@ archive_get_backend_list (Archive *archive) return archive->backend_list; } +static gint +foreach_cb (gchar *key, Location *value, foreach_t *data) +{ + if (location_get_parent (value) == data->parent) + return data->callback (data->archive, value, + data->user_data); + else + return 0; +} + +/** + * archive_foreach_child_location: + * @archive: + * @callback: Callback to invoke + * @parent: Iterate through the children of this location; iterate through + * toplevel locations if this is NULL + * @data: Arbitrary data to pass to the callback + * + * Invoke the given callback for each location that inherits the given + * location, or for each toplevel location if the parent given is + * NULL. Terminate the iteration if any child returns a nonzero value + **/ + +void +archive_foreach_child_location (Archive *archive, LocationCB callback, + Location *parent, gpointer data) +{ + foreach_t f_data; + + g_return_if_fail (archive != NULL); + g_return_if_fail (IS_ARCHIVE (archive)); + + load_all_locations (archive); + + f_data.archive = archive; + f_data.callback = callback; + f_data.parent = parent; + f_data.user_data = data; + + g_tree_traverse (archive->locations, + (GTraverseFunc) foreach_cb, + G_IN_ORDER, + &f_data); +} + /* Load the archive information from disk; return TRUE on success and FALSE on * failure */ @@ -521,3 +597,39 @@ do_load (Archive *archive) return TRUE; } + +/* Load and register all the locations for this archive */ + +static void +load_all_locations (Archive *archive) +{ + DIR *archive_dir; + struct dirent entry, *entryp; + gchar *filename; + + archive_dir = opendir (archive->prefix); + + if (archive_dir == NULL) { + g_warning ("load_all_locations: %s", g_strerror (errno)); + return; + } + + while (1) { + if (readdir_r (archive_dir, &entry, &entryp)) { + g_warning ("load_all_locations: %s", + g_strerror (errno)); + break; + } + + if (entryp == NULL) break; + + if (strcmp (entry.d_name, ".") && + strcmp (entry.d_name, "..")) + { + filename = g_concat_dir_and_file (archive->prefix, + entry.d_name); + if (g_file_test (filename, G_FILE_TEST_ISDIR)) + archive_get_location (archive, entry.d_name); + } + } +} diff --git a/archiver/archive.h b/archiver/archive.h index 36710a169..2d5405604 100644 --- a/archiver/archive.h +++ b/archiver/archive.h @@ -34,16 +34,17 @@ #define IS_ARCHIVE(obj) GTK_CHECK_TYPE (obj, archive_get_type ()) typedef struct _ArchiveClass ArchiveClass; +typedef gint (*LocationCB) (Archive *, Location *, gpointer); struct _Archive { - GtkObject object; + GtkObject object; - gchar *prefix; - GTree *locations; - gboolean is_global; + gchar *prefix; + GTree *locations; + gboolean is_global; - gchar *current_location_id; + gchar *current_location_id; BackendList *backend_list; }; @@ -53,25 +54,35 @@ struct _ArchiveClass GtkObjectClass parent; }; -guint archive_get_type (void); +guint archive_get_type (void); -GtkObject *archive_load (gboolean is_global); +GtkObject *archive_load (gboolean is_global); -void archive_close (Archive *archive); +void archive_close (Archive *archive); -Location *archive_get_location (Archive *archive, const gchar *location); -void archive_register_location (Archive *archive, Location *location); -void archive_unregister_location (Archive *archive, Location *location); +Location *archive_get_location (Archive *archive, + const gchar *location); +void archive_register_location (Archive *archive, + Location *location); +void archive_unregister_location (Archive *archive, + Location *location); -Location *archive_get_current_location (Archive *archive); -void archive_set_current_location (Archive *archive, Location *location); +Location *archive_get_current_location (Archive *archive); +void archive_set_current_location (Archive *archive, + Location *location); const gchar *archive_get_current_location_id (Archive *archive); -void archive_set_current_location_id (Archive *archive, const gchar *locid); +void archive_set_current_location_id (Archive *archive, + const gchar *locid); -const gchar *archive_get_prefix (Archive *archive); -gboolean archive_is_global (Archive *archive); +const gchar *archive_get_prefix (Archive *archive); +gboolean archive_is_global (Archive *archive); -BackendList *archive_get_backend_list (Archive *archive); +BackendList *archive_get_backend_list (Archive *archive); + +void archive_foreach_child_location (Archive *archive, + LocationCB callback, + Location *parent, + gpointer data); #endif /* __ARCHIVE */ diff --git a/archiver/config-manager-dialog.c b/archiver/config-manager-dialog.c new file mode 100644 index 000000000..bf0c8de15 --- /dev/null +++ b/archiver/config-manager-dialog.c @@ -0,0 +1,625 @@ +/* -*- mode: c; style: linux -*- */ + +/* config-manager-dialog.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#include "config-manager-dialog.h" +#include "create-location-dialog.h" +#include "archive.h" +#include "location.h" +#include "backend-list.h" +#include "location-list.h" + +#define WID(str) (glade_xml_get_widget (dialog->p->config_dialog_data, str)) + +enum { + ARG_0, + ARG_TYPE +}; + +struct _ConfigManagerDialogPrivate +{ + GladeXML *config_dialog_data; + + CMDialogType type; + + struct tm *date; + gboolean rollback_all; + gchar *backend_id; + gchar *selected_location_id; + + Archive *global_archive; + Archive *user_archive; + + BackendList *global_list; + BackendList *user_list; + + Location *current_global; + Location *current_user; + + LocationList *location_list; +}; + +static GnomeDialogClass *parent_class; + +static void config_manager_dialog_init (ConfigManagerDialog *dialog); +static void config_manager_dialog_class_init (ConfigManagerDialogClass *class); + +static void config_manager_dialog_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void config_manager_dialog_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); + +static void config_manager_dialog_finalize (GtkObject *object); + +static void ok_cb (GtkWidget *widget, + ConfigManagerDialog *dialog); +static void apply_cb (GtkWidget *widget, + ConfigManagerDialog *dialog); +static void cancel_cb (GtkWidget *widget, + ConfigManagerDialog *dialog); +static void time_count_changed_cb (GtkSpinButton *button, + ConfigManagerDialog *dialog); +static void rollback_all_toggled_cb (GtkToggleButton *button, + ConfigManagerDialog *dialog); +static void rollback_one_toggled_cb (GtkToggleButton *button, + ConfigManagerDialog *dialog); +static void backend_select_cb (GtkMenuItem *menu_item, + ConfigManagerDialog *dialog); + +static void create_cb (GtkWidget *button, + ConfigManagerDialog *dialog); +static void rename_cb (GtkWidget *button, + ConfigManagerDialog *dialog); +static void destroy_cb (GtkWidget *button, + ConfigManagerDialog *dialog); +static void change_location_cb (GtkWidget *button, + ConfigManagerDialog *dialog); +static void edit_location_cb (GtkWidget *button, + ConfigManagerDialog *dialog); +static void real_create_cb (CreateLocationDialog + *create_dialog, + gchar *name, + Location *parent, + ConfigManagerDialog *dialog); + +static void do_rollback (ConfigManagerDialog *dialog); +static void reset_time (ConfigManagerDialog *dialog, + guint sub_days); +static gint populate_backends_cb (BackendList *list, + gchar *backend_id, + ConfigManagerDialog *dialog); +static void populate_backends_list (ConfigManagerDialog *dialog, + BackendList *list); + +static void set_backend_controls_sensitive (ConfigManagerDialog *dialog, + gboolean s); + +guint +config_manager_dialog_get_type (void) +{ + static guint config_manager_dialog_type = 0; + + if (!config_manager_dialog_type) { + GtkTypeInfo config_manager_dialog_info = { + "ConfigManagerDialog", + sizeof (ConfigManagerDialog), + sizeof (ConfigManagerDialogClass), + (GtkClassInitFunc) config_manager_dialog_class_init, + (GtkObjectInitFunc) config_manager_dialog_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + config_manager_dialog_type = + gtk_type_unique (gnome_dialog_get_type (), + &config_manager_dialog_info); + } + + return config_manager_dialog_type; +} + +static void +config_manager_dialog_init (ConfigManagerDialog *dialog) +{ + static char *buttons[] = { + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_APPLY, + GNOME_STOCK_BUTTON_CANCEL, + NULL + }; + + gnome_dialog_constructv (GNOME_DIALOG (dialog), + _("Rollback and Location Management"), + buttons); + + dialog->p = g_new0 (ConfigManagerDialogPrivate, 1); + dialog->p->config_dialog_data = + glade_xml_new (GLADE_DIR "/rollback-location-management.glade", + "config_dialog_data"); + + gtk_box_pack_start (GTK_BOX + (GNOME_DIALOG (dialog)->vbox), + WID ("config_dialog_data"), 0, TRUE, TRUE); + + gtk_window_set_policy (GTK_WINDOW (dialog), + TRUE, FALSE, TRUE); + + gnome_dialog_button_connect (GNOME_DIALOG (dialog), + 0, GTK_SIGNAL_FUNC (ok_cb), + dialog); + gnome_dialog_button_connect (GNOME_DIALOG (dialog), + 1, GTK_SIGNAL_FUNC (apply_cb), + dialog); + gnome_dialog_button_connect (GNOME_DIALOG (dialog), + 2, GTK_SIGNAL_FUNC (cancel_cb), + dialog); + + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "time_count_changed_cb", + time_count_changed_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "rollback_all_toggled_cb", + rollback_all_toggled_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "rollback_one_toggled_cb", + rollback_one_toggled_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "create_cb", + create_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "rename_cb", + rename_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "destroy_cb", + destroy_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "change_location_cb", + change_location_cb, + dialog); + glade_xml_signal_connect_data (dialog->p->config_dialog_data, + "edit_location_cb", + edit_location_cb, + dialog); + + dialog->p->rollback_all = TRUE; + dialog->p->date = g_new (struct tm, 1); + dialog->p->location_list = + LOCATION_LIST (location_list_new (FALSE, NULL, NULL)); + + gtk_widget_show (GTK_WIDGET (dialog->p->location_list)); + gtk_container_add (GTK_CONTAINER (WID ("location_tree_location")), + GTK_WIDGET (dialog->p->location_list)); + + set_backend_controls_sensitive (dialog, FALSE); + reset_time (dialog, 0); +} + +static void +config_manager_dialog_class_init (ConfigManagerDialogClass *class) +{ + GtkObjectClass *object_class; + + gtk_object_add_arg_type ("ConfigManagerDialog::type", + GTK_TYPE_INT, + GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE, + ARG_TYPE); + + object_class = GTK_OBJECT_CLASS (class); + object_class->finalize = config_manager_dialog_finalize; + object_class->set_arg = config_manager_dialog_set_arg; + object_class->get_arg = config_manager_dialog_get_arg; + + parent_class = GNOME_DIALOG_CLASS + (gtk_type_class (gnome_dialog_get_type ())); +} + +static void +config_manager_dialog_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + ConfigManagerDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object)); + + dialog = CONFIG_MANAGER_DIALOG (object); + + switch (arg_id) { + case ARG_TYPE: + dialog->p->type = GTK_VALUE_INT (*arg); + + switch (dialog->p->type) { + case CM_DIALOG_USER_ONLY: + dialog->p->user_archive = + ARCHIVE (archive_load (FALSE)); + dialog->p->global_archive = NULL; + break; + + case CM_DIALOG_GLOBAL_ONLY: + dialog->p->global_archive = + ARCHIVE (archive_load (TRUE)); + dialog->p->user_archive = NULL; + break; + + case CM_DIALOG_BOTH: + dialog->p->user_archive = + ARCHIVE (archive_load (FALSE)); + dialog->p->global_archive = + ARCHIVE (archive_load (TRUE)); + break; + } + + if (dialog->p->user_archive != NULL) { + dialog->p->user_list = + archive_get_backend_list + (dialog->p->user_archive); + dialog->p->current_user = + archive_get_current_location + (dialog->p->user_archive); + populate_backends_list + (dialog, dialog->p->user_list); + } + + if (dialog->p->global_archive != NULL) { + dialog->p->global_list = + archive_get_backend_list + (dialog->p->global_archive); + dialog->p->current_global = + archive_get_current_location + (dialog->p->global_archive); + populate_backends_list + (dialog, dialog->p->global_list); + } + + gtk_object_set (GTK_OBJECT (dialog->p->location_list), + "user-archive", dialog->p->user_archive, + "global-archive", dialog->p->global_archive, + NULL); + + break; + + default: + g_warning ("Bad argument set"); + break; + } +} + +static void +config_manager_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + ConfigManagerDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object)); + + dialog = CONFIG_MANAGER_DIALOG (object); + + switch (arg_id) { + case ARG_TYPE: + GTK_VALUE_INT (*arg) = dialog->p->type; + break; + + default: + g_warning ("Bad argument get"); + break; + } +} + +static void +config_manager_dialog_finalize (GtkObject *object) +{ + ConfigManagerDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (object)); + + dialog = CONFIG_MANAGER_DIALOG (object); + + if (dialog->p->date != NULL) + g_free (dialog->p->date); + + if (dialog->p->type == CM_DIALOG_USER_ONLY || + dialog->p->type == CM_DIALOG_BOTH) + { + gtk_object_unref (GTK_OBJECT (dialog->p->current_user)); + gtk_object_unref (GTK_OBJECT (dialog->p->user_list)); + gtk_object_unref (GTK_OBJECT (dialog->p->user_archive)); + } + + if (dialog->p->type == CM_DIALOG_GLOBAL_ONLY || + dialog->p->type == CM_DIALOG_BOTH) + { + gtk_object_unref (GTK_OBJECT (dialog->p->current_global)); + gtk_object_unref (GTK_OBJECT (dialog->p->global_list)); + gtk_object_unref (GTK_OBJECT (dialog->p->global_archive)); + } + + g_free (dialog->p); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); +} + +GtkWidget * +config_manager_dialog_new (CMDialogType type) +{ + return gtk_widget_new (config_manager_dialog_get_type (), + "type", type, + NULL); +} + +static void +ok_cb (GtkWidget *widget, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + do_rollback (dialog); + + gnome_dialog_close (GNOME_DIALOG (dialog)); +} + +static void +apply_cb (GtkWidget *widget, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + do_rollback (dialog); +} + +static void +cancel_cb (GtkWidget *widget, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + /* This little hack will trick the location manager into rolling back + * to the last known configuration + */ + g_free (dialog->p->date); + dialog->p->date = NULL; + do_rollback (dialog); + + gnome_dialog_close (GNOME_DIALOG (dialog)); +} + +static void +time_count_changed_cb (GtkSpinButton *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + reset_time (dialog, gtk_spin_button_get_value_as_int (button)); +} + +static void +rollback_all_toggled_cb (GtkToggleButton *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + if (gtk_toggle_button_get_active (button)) { + dialog->p->rollback_all = TRUE; + set_backend_controls_sensitive (dialog, FALSE); + } +} + +static void +rollback_one_toggled_cb (GtkToggleButton *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + if (gtk_toggle_button_get_active (button)) { + dialog->p->rollback_all = FALSE; + set_backend_controls_sensitive (dialog, TRUE); + } +} + +static void +backend_select_cb (GtkMenuItem *menu_item, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + dialog->p->backend_id = gtk_object_get_data (GTK_OBJECT (menu_item), + "backend-id"); +} + +static void +create_cb (GtkWidget *button, ConfigManagerDialog *dialog) +{ + CreateLocationDialog *create_dialog; + + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + create_dialog = CREATE_LOCATION_DIALOG + (create_location_dialog_new (dialog->p->type)); + + gtk_signal_connect (GTK_OBJECT (create_dialog), + "create-location", + GTK_SIGNAL_FUNC (real_create_cb), + dialog); + + gtk_widget_show (GTK_WIDGET (create_dialog)); +} + +static void +rename_cb (GtkWidget *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); +} + +static void +destroy_cb (GtkWidget *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); +} + +static void +change_location_cb (GtkWidget *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + /* FIXME */ + archive_set_current_location (dialog->p->user_archive, + location_list_get_selected_location + (dialog->p->location_list)); +} + +static void +edit_location_cb (GtkWidget *button, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); +} + +static void +real_create_cb (CreateLocationDialog *create_dialog, gchar *name, + Location *parent, ConfigManagerDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CONFIG_MANAGER_DIALOG (dialog)); + + /* FIXME */ + location_new (dialog->p->user_archive, name, parent); + location_list_reread (dialog->p->location_list); +} + +static void +do_rollback (ConfigManagerDialog *dialog) +{ + switch (dialog->p->type) { + case CM_DIALOG_USER_ONLY: + if (dialog->p->rollback_all) + location_rollback_all_to + (dialog->p->current_user, + dialog->p->date, TRUE); + else + location_rollback_backend_to + (dialog->p->current_user, + dialog->p->date, + dialog->p->backend_id, TRUE); + break; + + case CM_DIALOG_GLOBAL_ONLY: + if (dialog->p->rollback_all) + location_rollback_all_to + (dialog->p->current_global, + dialog->p->date, TRUE); + else + location_rollback_backend_to + (dialog->p->current_global, + dialog->p->date, + dialog->p->backend_id, TRUE); + break; + + case CM_DIALOG_BOTH: + if (dialog->p->rollback_all) { + location_rollback_all_to + (dialog->p->current_global, + dialog->p->date, TRUE); + location_rollback_all_to + (dialog->p->current_user, + dialog->p->date, TRUE); + } + else if (backend_list_contains + (dialog->p->global_list, dialog->p->backend_id)) + { + location_rollback_backend_to + (dialog->p->current_global, + dialog->p->date, + dialog->p->backend_id, TRUE); + } else { + location_rollback_backend_to + (dialog->p->current_user, + dialog->p->date, + dialog->p->backend_id, TRUE); + } + + break; + } +} + +static void +reset_time (ConfigManagerDialog *dialog, guint sub_days) +{ + time_t current_time; + + time (¤t_time); + current_time -= sub_days * 24 * 60 * 60; + localtime_r (¤t_time, dialog->p->date); +} + +static gint +populate_backends_cb (BackendList *list, gchar *backend_id, + ConfigManagerDialog *dialog) +{ + GtkWidget *menu_item; + GtkWidget *menu; + + menu_item = gtk_menu_item_new_with_label (backend_id); + gtk_widget_show (menu_item); + gtk_object_set_data (GTK_OBJECT (menu_item), + "backend-id", backend_id); + gtk_signal_connect (GTK_OBJECT (menu_item), "activate", + GTK_SIGNAL_FUNC (backend_select_cb), dialog); + + menu = gtk_option_menu_get_menu + (GTK_OPTION_MENU (WID ("backend_select"))); + gtk_menu_append (GTK_MENU (menu), menu_item); + return 0; +} + +static void +populate_backends_list (ConfigManagerDialog *dialog, BackendList *list) +{ + backend_list_foreach (list, (BackendCB) populate_backends_cb, dialog); + + gtk_option_menu_set_history + (GTK_OPTION_MENU (WID ("backend_select")), 0); +} + +static void +set_backend_controls_sensitive (ConfigManagerDialog *dialog, gboolean s) +{ + gtk_widget_set_sensitive (WID ("backend_select"), s); +} diff --git a/archiver/config-manager-dialog.h b/archiver/config-manager-dialog.h new file mode 100644 index 000000000..7e82ebe2a --- /dev/null +++ b/archiver/config-manager-dialog.h @@ -0,0 +1,63 @@ +/* -*- mode: c; style: linux -*- */ + +/* config-manager-dialog.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifndef __CONFIG_MANAGER_DIALOG_H +#define __CONFIG_MANAGER_DIALOG_H + +#include + +BEGIN_GNOME_DECLS + +#define CONFIG_MANAGER_DIALOG(obj) GTK_CHECK_CAST (obj, config_manager_dialog_get_type (), ConfigManagerDialog) +#define CONFIG_MANAGER_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, config_manager_dialog_get_type (), ConfigManagerDialogClass) +#define IS_CONFIG_MANAGER_DIALOG(obj) GTK_CHECK_TYPE (obj, config_manager_dialog_get_type ()) + +typedef struct _ConfigManagerDialog ConfigManagerDialog; +typedef struct _ConfigManagerDialogClass ConfigManagerDialogClass; +typedef struct _ConfigManagerDialogPrivate ConfigManagerDialogPrivate; + +typedef enum _CMDialogType CMDialogType; + +struct _ConfigManagerDialog +{ + GnomeDialog parent; + + ConfigManagerDialogPrivate *p; +}; + +struct _ConfigManagerDialogClass +{ + GnomeDialogClass gnome_dialog_class; +}; + +enum _CMDialogType { + CM_DIALOG_USER_ONLY, CM_DIALOG_GLOBAL_ONLY, CM_DIALOG_BOTH +}; + +guint config_manager_dialog_get_type (void); + +GtkWidget *config_manager_dialog_new (CMDialogType type); + +END_GNOME_DECLS + +#endif /* __CONFIG_MANAGER_DIALOG_H */ diff --git a/archiver/config-manager.c b/archiver/config-manager.c new file mode 100644 index 000000000..fa49d860e --- /dev/null +++ b/archiver/config-manager.c @@ -0,0 +1,53 @@ +/* -*- mode: c; style: linux -*- */ + +/* config-manager.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "config-manager-dialog.h" + +int +main (int argc, char **argv) +{ + GtkWidget *dialog; + + bindtextdomain (PACKAGE, GNOMELOCALEDIR); + textdomain (PACKAGE); + + gnome_init ("config-manager", VERSION, argc, argv); + glade_gnome_init (); + + dialog = config_manager_dialog_new (CM_DIALOG_USER_ONLY); + gtk_widget_show (dialog); + + gtk_signal_connect (GTK_OBJECT (dialog), "destroy", + gtk_main_quit, NULL); + + gtk_main (); + + return 0; +} diff --git a/archiver/create-location-dialog.c b/archiver/create-location-dialog.c new file mode 100644 index 000000000..441bdcdaa --- /dev/null +++ b/archiver/create-location-dialog.c @@ -0,0 +1,291 @@ +/* -*- mode: c; style: linux -*- */ + +/* create-location-dialog.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "create-location-dialog.h" +#include "location-list.h" + +#define WID(str) (glade_xml_get_widget (dialog->p->create_dialog_data, str)) + +enum { + ARG_0, + ARG_TYPE +}; + +enum { + CREATE_LOCATION_SIGNAL, + LAST_SIGNAL +}; + +struct _CreateLocationDialogPrivate +{ + GladeXML *create_dialog_data; + + CMDialogType type; + + gchar *selected_location_id; + + Archive *global_archive; + Archive *user_archive; + + LocationList *location_list; +}; + +static GnomeDialogClass *parent_class; + +static guint create_location_dialog_signals[LAST_SIGNAL] = { 0 }; + +static void create_location_dialog_init (CreateLocationDialog *dialog); +static void create_location_dialog_class_init (CreateLocationDialogClass *class); + +static void create_location_dialog_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void create_location_dialog_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); + +static void ok_cb (GtkWidget *widget, + CreateLocationDialog *dialog); +static void cancel_cb (GtkWidget *widget, + CreateLocationDialog *dialog); + +static void create_location_dialog_finalize (GtkObject *object); + +guint +create_location_dialog_get_type (void) +{ + static guint create_location_dialog_type = 0; + + if (!create_location_dialog_type) { + GtkTypeInfo create_location_dialog_info = { + "CreateLocationDialog", + sizeof (CreateLocationDialog), + sizeof (CreateLocationDialogClass), + (GtkClassInitFunc) create_location_dialog_class_init, + (GtkObjectInitFunc) create_location_dialog_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + create_location_dialog_type = + gtk_type_unique (gnome_dialog_get_type (), + &create_location_dialog_info); + } + + return create_location_dialog_type; +} + +static void +create_location_dialog_init (CreateLocationDialog *dialog) +{ + static char *buttons[] = { + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, + NULL + }; + + gnome_dialog_constructv (GNOME_DIALOG (dialog), + _("Rollback and Location Management"), + buttons); + + dialog->p = g_new0 (CreateLocationDialogPrivate, 1); + dialog->p->create_dialog_data = + glade_xml_new (GLADE_DIR "/rollback-location-management.glade", + "create_dialog_data"); + + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), + WID ("create_dialog_data"), 0, TRUE, TRUE); + + gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, FALSE, TRUE); + + gnome_dialog_button_connect (GNOME_DIALOG (dialog), + 0, GTK_SIGNAL_FUNC (ok_cb), + dialog); + gnome_dialog_button_connect (GNOME_DIALOG (dialog), + 1, GTK_SIGNAL_FUNC (cancel_cb), + dialog); + + dialog->p->location_list = + LOCATION_LIST (location_list_new (FALSE, NULL, NULL)); + + gtk_widget_show (GTK_WIDGET (dialog->p->location_list)); + gtk_container_add (GTK_CONTAINER (WID ("location_list_location")), + GTK_WIDGET (dialog->p->location_list)); +} + +static void +create_location_dialog_class_init (CreateLocationDialogClass *class) +{ + GtkObjectClass *object_class; + + gtk_object_add_arg_type ("CreateLocationDialog::type", + GTK_TYPE_INT, + GTK_ARG_CONSTRUCT_ONLY | GTK_ARG_READWRITE, + ARG_TYPE); + + object_class = GTK_OBJECT_CLASS (class); + object_class->finalize = create_location_dialog_finalize; + object_class->set_arg = create_location_dialog_set_arg; + object_class->get_arg = create_location_dialog_get_arg; + + create_location_dialog_signals[CREATE_LOCATION_SIGNAL] = + gtk_signal_new ("create-location", GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CreateLocationDialogClass, + create_location), + gtk_marshal_NONE__POINTER_POINTER, + GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, + GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, + create_location_dialog_signals, + LAST_SIGNAL); + + parent_class = GNOME_DIALOG_CLASS + (gtk_type_class (gnome_dialog_get_type ())); +} + +static void +create_location_dialog_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + CreateLocationDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object)); + + dialog = CREATE_LOCATION_DIALOG (object); + + switch (arg_id) { + case ARG_TYPE: + dialog->p->type = GTK_VALUE_INT (*arg); + + switch (dialog->p->type) { + case CM_DIALOG_USER_ONLY: + dialog->p->user_archive = + ARCHIVE (archive_load (FALSE)); + dialog->p->global_archive = NULL; + break; + + case CM_DIALOG_GLOBAL_ONLY: + dialog->p->global_archive = + ARCHIVE (archive_load (TRUE)); + dialog->p->user_archive = NULL; + break; + + case CM_DIALOG_BOTH: + dialog->p->user_archive = + ARCHIVE (archive_load (FALSE)); + dialog->p->global_archive = + ARCHIVE (archive_load (TRUE)); + break; + } + + gtk_object_set (GTK_OBJECT (dialog->p->location_list), + "user-archive", dialog->p->user_archive, + "global-archive", dialog->p->global_archive, + NULL); + + break; + + default: + g_warning ("Bad argument set"); + break; + } +} + +static void +create_location_dialog_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + CreateLocationDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object)); + + dialog = CREATE_LOCATION_DIALOG (object); + + switch (arg_id) { + case ARG_TYPE: + GTK_VALUE_INT (*arg) = dialog->p->type; + break; + + default: + g_warning ("Bad argument get"); + break; + } +} + +static void +create_location_dialog_finalize (GtkObject *object) +{ + CreateLocationDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_CREATE_LOCATION_DIALOG (object)); + + dialog = CREATE_LOCATION_DIALOG (object); + + g_free (dialog->p); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); +} + +GtkObject * +create_location_dialog_new (CMDialogType type) +{ + return gtk_object_new (create_location_dialog_get_type (), + "type", type, + NULL); +} + +static void +ok_cb (GtkWidget *widget, CreateLocationDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CREATE_LOCATION_DIALOG (dialog)); + + gtk_signal_emit (GTK_OBJECT (dialog), + create_location_dialog_signals + [CREATE_LOCATION_SIGNAL], + gtk_entry_get_text + (GTK_ENTRY (WID ("location_name_entry"))), + location_list_get_selected_location + (dialog->p->location_list)); + + gnome_dialog_close (GNOME_DIALOG (dialog)); +} + +static void +cancel_cb (GtkWidget *widget, CreateLocationDialog *dialog) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (IS_CREATE_LOCATION_DIALOG (dialog)); + + gnome_dialog_close (GNOME_DIALOG (dialog)); +} + diff --git a/archiver/create-location-dialog.h b/archiver/create-location-dialog.h new file mode 100644 index 000000000..7c5abf74e --- /dev/null +++ b/archiver/create-location-dialog.h @@ -0,0 +1,62 @@ +/* -*- mode: c; style: linux -*- */ + +/* create-location-dialog.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifndef __CREATE_LOCATION_DIALOG_H +#define __CREATE_LOCATION_DIALOG_H + +#include + +#include "config-manager-dialog.h" +#include "location.h" + +BEGIN_GNOME_DECLS + +#define CREATE_LOCATION_DIALOG(obj) GTK_CHECK_CAST (obj, create_location_dialog_get_type (), CreateLocationDialog) +#define CREATE_LOCATION_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, create_location_dialog_get_type (), CreateLocationDialogClass) +#define IS_CREATE_LOCATION_DIALOG(obj) GTK_CHECK_TYPE (obj, create_location_dialog_get_type ()) + +typedef struct _CreateLocationDialog CreateLocationDialog; +typedef struct _CreateLocationDialogClass CreateLocationDialogClass; +typedef struct _CreateLocationDialogPrivate CreateLocationDialogPrivate; + +struct _CreateLocationDialog +{ + GnomeDialog parent; + + CreateLocationDialogPrivate *p; +}; + +struct _CreateLocationDialogClass +{ + GnomeDialogClass gnome_dialog_class; + + void (*create_location) (CreateLocationDialog *, gchar *, Location *); +}; + +guint create_location_dialog_get_type (void); + +GtkObject *create_location_dialog_new (CMDialogType type); + +END_GNOME_DECLS + +#endif /* __CREATE_LOCATION_DIALOG_H */ diff --git a/archiver/location-list.c b/archiver/location-list.c new file mode 100644 index 000000000..46fc7c5d5 --- /dev/null +++ b/archiver/location-list.c @@ -0,0 +1,364 @@ +/* -*- mode: c; style: linux -*- */ + +/* location-list.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "location-list.h" + +typedef struct _pair_t pair_t; + +struct _pair_t +{ + gpointer a, b; +}; + +enum { + ARG_0, + ARG_USER_ARCHIVE, + ARG_GLOBAL_ARCHIVE, + ARG_SEPARATE_LOCATIONS +}; + +struct _LocationListPrivate +{ + gchar *selected_location_id; + Location *selected_location; + + gboolean separate_locations; + Archive *user_archive; + Archive *global_archive; +}; + +static GtkCTreeClass *parent_class; + +static void location_list_init (LocationList *location_list); +static void location_list_class_init (LocationListClass *class); + +static void location_list_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void location_list_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); + +static void select_row_cb (LocationList *list, + GList *node, gint column); + +static void location_list_finalize (GtkObject *object); + +static gint populate_locations_cb (Archive *archive, + Location *location, + pair_t *data); +static void populate_locations_list (LocationList *list, + gboolean do_global); + +guint +location_list_get_type (void) +{ + static guint location_list_type = 0; + + if (!location_list_type) { + GtkTypeInfo location_list_info = { + "LocationList", + sizeof (LocationList), + sizeof (LocationListClass), + (GtkClassInitFunc) location_list_class_init, + (GtkObjectInitFunc) location_list_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + location_list_type = + gtk_type_unique (gtk_ctree_get_type (), + &location_list_info); + } + + return location_list_type; +} + +static void +location_list_init (LocationList *location_list) +{ + static char *titles = { "Location" }; + + gtk_ctree_construct (GTK_CTREE (location_list), + 1, 0, &titles); + + gtk_clist_column_titles_hide (GTK_CLIST (location_list)); + + location_list->p = g_new0 (LocationListPrivate, 1); + + gtk_signal_connect (GTK_OBJECT (location_list), + "tree-select-row", GTK_SIGNAL_FUNC (select_row_cb), + NULL); +} + +static void +location_list_class_init (LocationListClass *class) +{ + GtkObjectClass *object_class; + + gtk_object_add_arg_type ("LocationList::user-archive", + GTK_TYPE_POINTER, + GTK_ARG_READWRITE, + ARG_USER_ARCHIVE); + + gtk_object_add_arg_type ("LocationList::global-archive", + GTK_TYPE_POINTER, + GTK_ARG_READWRITE, + ARG_GLOBAL_ARCHIVE); + + gtk_object_add_arg_type ("LocationList::separate-locations", + GTK_TYPE_POINTER, + GTK_ARG_READWRITE, + ARG_SEPARATE_LOCATIONS); + + object_class = GTK_OBJECT_CLASS (class); + object_class->finalize = location_list_finalize; + object_class->set_arg = location_list_set_arg; + object_class->get_arg = location_list_get_arg; + + parent_class = GTK_CTREE_CLASS + (gtk_type_class (gtk_ctree_get_type ())); +} + +static void +location_list_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + LocationList *location_list; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_LOCATION_LIST (object)); + + location_list = LOCATION_LIST (object); + + switch (arg_id) { + case ARG_USER_ARCHIVE: + g_return_if_fail (GTK_VALUE_POINTER (*arg) == NULL || + IS_ARCHIVE (GTK_VALUE_POINTER (*arg))); + + if (GTK_VALUE_POINTER (*arg) == NULL) return; + + location_list->p->user_archive = + ARCHIVE (GTK_VALUE_POINTER (*arg)); + + gtk_object_ref (GTK_OBJECT (location_list->p->user_archive)); + populate_locations_list (location_list, FALSE); + + break; + + case ARG_GLOBAL_ARCHIVE: + g_return_if_fail (GTK_VALUE_POINTER (*arg) == NULL || + IS_ARCHIVE (GTK_VALUE_POINTER (*arg))); + + if (GTK_VALUE_POINTER (*arg) == NULL) return; + + location_list->p->global_archive = + ARCHIVE (GTK_VALUE_POINTER (*arg)); + + gtk_object_ref (GTK_OBJECT (location_list->p->global_archive)); + populate_locations_list (location_list, TRUE); + + break; + + case ARG_SEPARATE_LOCATIONS: + location_list->p->separate_locations = + GTK_VALUE_INT (*arg); + break; + + default: + g_warning ("Bad argument set"); + break; + } +} + +static void +location_list_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + LocationList *location_list; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_LOCATION_LIST (object)); + + location_list = LOCATION_LIST (object); + + switch (arg_id) { + case ARG_USER_ARCHIVE: + GTK_VALUE_POINTER (*arg) = location_list->p->user_archive; + break; + + case ARG_GLOBAL_ARCHIVE: + GTK_VALUE_POINTER (*arg) = location_list->p->global_archive; + break; + + case ARG_SEPARATE_LOCATIONS: + GTK_VALUE_INT (*arg) = location_list->p->separate_locations; + break; + + default: + g_warning ("Bad argument get"); + break; + } +} + +static void +location_list_finalize (GtkObject *object) +{ + LocationList *location_list; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_LOCATION_LIST (object)); + + location_list = LOCATION_LIST (object); + + if (location_list->p->user_archive != NULL) + gtk_object_unref + (GTK_OBJECT (location_list->p->user_archive)); + + if (location_list->p->global_archive != NULL) + gtk_object_unref + (GTK_OBJECT (location_list->p->global_archive)); + + g_free (location_list->p); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); +} + +GtkWidget * +location_list_new (gboolean sep_locations, Archive *user_archive, + Archive *global_archive) +{ + return gtk_widget_new (location_list_get_type (), + "separate-locations", sep_locations, + "user-archive", user_archive, + "global-archive", global_archive, + NULL); +} + +gchar * +location_list_get_selected_location_id (LocationList *list) +{ + g_return_val_if_fail (list != NULL, NULL); + g_return_val_if_fail (IS_LOCATION_LIST (list), NULL); + + return list->p->selected_location_id; +} + +Location * +location_list_get_selected_location (LocationList *list) +{ + g_return_val_if_fail (list != NULL, NULL); + g_return_val_if_fail (IS_LOCATION_LIST (list), NULL); + + return list->p->selected_location; +} + +void +location_list_reread (LocationList *list) +{ + g_return_if_fail (list != NULL); + g_return_if_fail (IS_LOCATION_LIST (list)); + + gtk_clist_freeze (GTK_CLIST (list)); + gtk_clist_clear (GTK_CLIST (list)); + + if (list->p->global_archive) + populate_locations_list (list, TRUE); + + if (list->p->user_archive) + populate_locations_list (list, FALSE); + + gtk_clist_thaw (GTK_CLIST (list)); +} + +static void +select_row_cb (LocationList *list, GList *node, gint column) +{ + GtkCTreeRow *row; + + g_return_if_fail (list != NULL); + g_return_if_fail (IS_LOCATION_LIST (list)); + + row = GTK_CTREE_ROW (node); + list->p->selected_location = row->row.data; + list->p->selected_location_id = + GTK_CELL_PIXTEXT (row->row.cell[0])->text; +} + +static gint +populate_locations_cb (Archive *archive, Location *location, pair_t *data) +{ + pair_t new_pair; + char *label; + + label = g_strdup (location_get_label (location)); + + new_pair.b = gtk_ctree_insert_node (GTK_CTREE (data->a), + (GtkCTreeNode *) data->b, NULL, + &label, GNOME_PAD_SMALL, NULL, + NULL, NULL, NULL, FALSE, TRUE); + gtk_ctree_node_set_row_data (GTK_CTREE (data->a), + (GtkCTreeNode *) new_pair.b, + location); + + new_pair.a = data->a; + + archive_foreach_child_location (archive, + (LocationCB) populate_locations_cb, + location, &new_pair); + + return 0; +} + +static void +populate_locations_list (LocationList *list, gboolean do_global) +{ + pair_t pair; + Archive *archive; + char *label; + + if (do_global) { + archive = list->p->global_archive; + label = _("Global locations"); + } else { + archive = list->p->user_archive; + label = _("User locations"); + } + + pair.a = list; + + if (list->p->separate_locations) + pair.b = gtk_ctree_insert_node (GTK_CTREE (list), + NULL, NULL, &label, + GNOME_PAD_SMALL, NULL, + NULL, NULL, NULL, FALSE, + TRUE); + else + pair.b = NULL; + + archive_foreach_child_location (archive, + (LocationCB) populate_locations_cb, + NULL, &pair); +} diff --git a/archiver/location-list.h b/archiver/location-list.h new file mode 100644 index 000000000..e2937475f --- /dev/null +++ b/archiver/location-list.h @@ -0,0 +1,68 @@ +/* -*- mode: c; style: linux -*- */ + +/* location-list.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifndef __LOCATION_LIST_H +#define __LOCATION_LIST_H + +#include + +#include "archive.h" +#include "location.h" +#include "config-manager-dialog.h" + +BEGIN_GNOME_DECLS + +#define LOCATION_LIST(obj) GTK_CHECK_CAST (obj, location_list_get_type (), LocationList) +#define LOCATION_LIST_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, location_list_get_type (), LocationListClass) +#define IS_LOCATION_LIST(obj) GTK_CHECK_TYPE (obj, location_list_get_type ()) + +typedef struct _LocationList LocationList; +typedef struct _LocationListClass LocationListClass; +typedef struct _LocationListPrivate LocationListPrivate; + +struct _LocationList +{ + GtkCTree parent; + + LocationListPrivate *p; +}; + +struct _LocationListClass +{ + GtkCTreeClass gtk_ctree_class; +}; + +guint location_list_get_type (void); + +GtkWidget *location_list_new (gboolean sep_locations, + Archive *user_archive, + Archive *global_archive); + +gchar *location_list_get_selected_location_id (LocationList *list); +Location *location_list_get_selected_location (LocationList *list); + +void location_list_reread (LocationList *list); + +END_GNOME_DECLS + +#endif /* __LOCATION_LIST_H */ diff --git a/archiver/location.c b/archiver/location.c index d73e40954..a91442422 100644 --- a/archiver/location.c +++ b/archiver/location.c @@ -798,6 +798,24 @@ location_find_path_from_common_parent (Location *location, return list_node; } +/** + * location_get_parent + * @location: + * + * Returns a reference to the location that this location inherits + * + * Return value: Reference to parent location + **/ + +Location * +location_get_parent (Location *location) +{ + g_return_val_if_fail (location != NULL, NULL); + g_return_val_if_fail (IS_LOCATION (location), NULL); + + return location->p->inherits_location; +} + /** * location_get_path: * @location: diff --git a/archiver/location.h b/archiver/location.h index 2fa2ef718..4e41065a0 100644 --- a/archiver/location.h +++ b/archiver/location.h @@ -103,6 +103,7 @@ void location_foreach_backend (Location *location, GList *location_find_path_from_common_parent (Location *location, Location *location2); +Location *location_get_parent (Location *location); const gchar *location_get_path (Location *location); const gchar *location_get_label (Location *location); const gchar *location_get_id (Location *location); diff --git a/archiver/rollback-location-management.glade b/archiver/rollback-location-management.glade new file mode 100644 index 000000000..cc1289329 --- /dev/null +++ b/archiver/rollback-location-management.glade @@ -0,0 +1,647 @@ + + + + + Rollback-location-management + rollback-location-management + + src + pixmaps + C + True + True + + + + GnomeDialog + rollback_location_dialog + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button1 + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button2 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button3 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkNotebook + config_dialog_data + True + True + True + GTK_POS_TOP + False + 2 + 2 + False + + 0 + True + True + + + + GtkTable + table1 + 5 + 4 + 2 + False + 5 + 5 + + + GtkRadioButton + rollback_all_toggle + True + + toggled + rollback_all_toggled_cb + Tue, 19 Dec 2000 20:58:48 GMT + + + False + True + restore_type + + 0 + 2 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + GtkButton + button4 + True + + GTK_RELIEF_NORMAL + + 0 + 1 + 3 + 4 + 0 + 0 + False + False + False + False + True + False + + + + + GtkButton + button5 + True + + GTK_RELIEF_NORMAL + + 1 + 2 + 3 + 4 + 0 + 0 + False + False + False + False + True + False + + + + + GtkHBox + hbox2 + False + 0 + + 0 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + True + + + + GtkRadioButton + rollback_one_toggle + True + + toggled + rollback_one_toggled_cb + Tue, 19 Dec 2000 20:58:59 GMT + + + False + True + restore_type + + 0 + False + False + + + + + GtkOptionMenu + backend_select + True + + 0 + + 0 + True + True + + + + + + GtkHBox + hbox1 + False + 5 + + 0 + 2 + 0 + 1 + 0 + 0 + True + False + False + False + True + True + + + + GtkLabel + label3 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkSpinButton + time_count + True + + changed + time_count_changed_cb + Tue, 19 Dec 2000 20:15:27 GMT + + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 + 0 + 1000 + 1 + 10 + 10 + + 0 + False + True + + + + + GtkLabel + label4 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + + GtkLabel + Notebook:tab + label1 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkHBox + location_tree_box + 5 + False + 5 + + + GtkVBox + vbox1 + False + 5 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + create_button + True + + clicked + create_cb + Wed, 20 Dec 2000 23:51:41 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + destroy_button + True + + clicked + destroy_cb + Wed, 20 Dec 2000 23:51:56 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + rename_button + True + + clicked + rename_cb + Wed, 20 Dec 2000 23:52:13 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkHSeparator + hseparator1 + + 0 + False + True + + + + + GtkButton + change_location_button + True + + clicked + change_location_cb + Wed, 20 Dec 2000 23:52:33 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + edit_button + True + + clicked + edit_location_cb + Wed, 20 Dec 2000 23:52:51 GMT + + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + + GtkScrolledWindow + location_tree_location + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + GTK_PACK_END + + + + Placeholder + + + + + + GtkLabel + Notebook:tab + label2 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + + GnomeDialog + create_location_dialog + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox2 + False + 8 + + 4 + True + True + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area2 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button11 + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button12 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button13 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + GtkVBox + create_dialog_data + False + 5 + + 0 + True + True + + + + GtkHBox + hbox4 + False + 5 + + 0 + True + True + + + + GtkLabel + label7 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + location_name_entry + True + True + True + 0 + + + 0 + True + True + + + + + + GtkLabel + label8 + + GTK_JUSTIFY_LEFT + False + 0 + 0.5 + 0 + 0 + + 0 + False + True + + + + + GtkScrolledWindow + location_list_location + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + Placeholder + + + + + + + diff --git a/archiver/rollback-widget.c b/archiver/rollback-widget.c new file mode 100644 index 000000000..8bba63c1f --- /dev/null +++ b/archiver/rollback-widget.c @@ -0,0 +1,163 @@ +/* -*- mode: c; style: linux -*- */ + +/* rollback-widget.c + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rollback-widget.h" + +enum { + ARG_0, + ARG_SAMPLE +}; + +struct _RollbackWidgetPrivate +{ + /* Private data members */ +}; + +static GtkWidgetClass *parent_class; + +static void rollback_widget_init (RollbackWidget *rollback_widget); +static void rollback_widget_class_init (RollbackWidgetClass *class); + +static void rollback_widget_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); +static void rollback_widget_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); + +static void rollback_widget_finalize (GtkObject *object); + +guint +rollback_widget_get_type (void) +{ + static guint rollback_widget_type = 0; + + if (!rollback_widget_type) { + GtkTypeInfo rollback_widget_info = { + "RollbackWidget", + sizeof (RollbackWidget), + sizeof (RollbackWidgetClass), + (GtkClassInitFunc) rollback_widget_class_init, + (GtkObjectInitFunc) rollback_widget_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + rollback_widget_type = + gtk_type_unique (gtk_widget_get_type (), + &rollback_widget_info); + } + + return rollback_widget_type; +} + +static void +rollback_widget_init (RollbackWidget *rollback_widget) +{ + rollback_widget->p = g_new0 (RollbackWidgetPrivate, 1); +} + +static void +rollback_widget_class_init (RollbackWidgetClass *class) +{ + GtkObjectClass *object_class; + + gtk_object_add_arg_type ("RollbackWidget::sample", + GTK_TYPE_POINTER, + GTK_ARG_READWRITE, + ARG_SAMPLE); + + object_class = GTK_OBJECT_CLASS (class); + object_class->finalize = rollback_widget_finalize; + object_class->set_arg = rollback_widget_set_arg; + object_class->get_arg = rollback_widget_get_arg; + + parent_class = GTK_WIDGET_CLASS + (gtk_type_class (gtk_widget_get_type ())); +} + +static void +rollback_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + RollbackWidget *rollback_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_ROLLBACK_WIDGET (object)); + + rollback_widget = ROLLBACK_WIDGET (object); + + switch (arg_id) { + case ARG_SAMPLE: + break; + + default: + g_warning ("Bad argument set"); + break; + } +} + +static void +rollback_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + RollbackWidget *rollback_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_ROLLBACK_WIDGET (object)); + + rollback_widget = ROLLBACK_WIDGET (object); + + switch (arg_id) { + case ARG_SAMPLE: + break; + + default: + g_warning ("Bad argument get"); + break; + } +} + +static void +rollback_widget_finalize (GtkObject *object) +{ + RollbackWidget *rollback_widget; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_ROLLBACK_WIDGET (object)); + + rollback_widget = ROLLBACK_WIDGET (object); + + g_free (rollback_widget->p); + + GTK_OBJECT_CLASS (parent_class)->finalize (object); +} + +GtkObject * +rollback_widget_new (void) +{ + return gtk_object_new (rollback_widget_get_type (), + NULL); +} diff --git a/archiver/rollback-widget.h b/archiver/rollback-widget.h new file mode 100644 index 000000000..768b50226 --- /dev/null +++ b/archiver/rollback-widget.h @@ -0,0 +1,57 @@ +/* -*- mode: c; style: linux -*- */ + +/* rollback-widget.h + * Copyright (C) 2000 Helix Code, Inc. + * + * Written by Bradford Hovinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * 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. + */ + +#ifndef __ROLLBACK_WIDGET_H +#define __ROLLBACK_WIDGET_H + +#include + +BEGIN_GNOME_DECLS + +#define ROLLBACK_WIDGET(obj) GTK_CHECK_CAST (obj, rollback_widget_get_type (), RollbackWidget) +#define ROLLBACK_WIDGET_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, rollback_widget_get_type (), RollbackWidgetClass) +#define IS_ROLLBACK_WIDGET(obj) GTK_CHECK_TYPE (obj, rollback_widget_get_type ()) + +typedef struct _RollbackWidget RollbackWidget; +typedef struct _RollbackWidgetClass RollbackWidgetClass; +typedef struct _RollbackWidgetPrivate RollbackWidgetPrivate; + +struct _RollbackWidget +{ + GtkWidget parent; + + RollbackWidgetPrivate *p; +}; + +struct _RollbackWidgetClass +{ + GtkWidgetClass gtk_widget_class; +}; + +guint rollback_widget_get_type (void); + +GtkObject *rollback_widget_new (void); + +END_GNOME_DECLS + +#endif /* __ROLLBACK_WIDGET_H */