aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/GNOME_Evolution_Calendar.oaf.in13
-rw-r--r--calendar/gui/Makefile.am2
-rw-r--r--calendar/gui/cal-search-bar.c260
-rw-r--r--calendar/gui/cal-search-bar.h62
-rw-r--r--calendar/gui/calendar-commands.c120
-rw-r--r--calendar/gui/calendar-model.c379
-rw-r--r--calendar/gui/calendar-model.h3
-rw-r--r--calendar/gui/comp-editor-factory.c228
-rw-r--r--calendar/gui/comp-editor-factory.h59
-rw-r--r--calendar/gui/e-calendar-table.c191
-rw-r--r--calendar/gui/e-calendar-table.h36
-rw-r--r--calendar/gui/e-tasks.c93
-rw-r--r--calendar/gui/gnome-cal.c132
-rw-r--r--calendar/gui/itip-utils.c1
14 files changed, 944 insertions, 635 deletions
diff --git a/calendar/gui/GNOME_Evolution_Calendar.oaf.in b/calendar/gui/GNOME_Evolution_Calendar.oaf.in
index 70924677f7..0e07c3bfa2 100644
--- a/calendar/gui/GNOME_Evolution_Calendar.oaf.in
+++ b/calendar/gui/GNOME_Evolution_Calendar.oaf.in
@@ -117,4 +117,17 @@
_value="A sample Bonobo control which displays an calendar."/>
</oaf_server>
+<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory"
+ type="exe"
+ location="evolution-calendar">
+
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:1.0"/>
+ <item value="IDL:Bonobo/Unknown:1.0"/>
+ </oaf_attribute>
+
+ <oaf_attribute name="description" type="string"
+ _value="Factory to centralize calendar component editor dialogs"/>
+</oaf_server>
+
</oaf_info>
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 0aa57aeda8..a694e1b21a 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -59,6 +59,8 @@ etspec_DATA = e-calendar-table.etspec
evolution_calendar_SOURCES = \
$(IDL_GENERATED) \
+ cal-search-bar.c \
+ cal-search-bar.h \
calendar-config.c \
calendar-config.h \
calendar-commands.c \
diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c
new file mode 100644
index 0000000000..351f65c5e6
--- /dev/null
+++ b/calendar/gui/cal-search-bar.c
@@ -0,0 +1,260 @@
+/* Evolution calendar - Search bar widget for calendar views
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * 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 of the License, 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 <glib.h>
+#include <gtk/gtksignal.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include "cal-search-bar.h"
+
+
+
+/* Menu items for the ESearchBar */
+static ESearchBarItem search_menu_items[] = {
+ E_FILTERBAR_RESET,
+ { NULL, -1 }
+};
+
+/* IDs and option items for the ESearchBar */
+enum {
+ SEARCH_ANY_FIELD_CONTAINS,
+ SEARCH_SUMMARY_CONTAINS,
+ SEARCH_DESCRIPTION_CONTAINS,
+ SEARCH_COMMENT_CONTAINS,
+ SEARCH_HAS_CATEGORY
+};
+
+static ESearchBarItem search_option_items[] = {
+ { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS },
+ { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS },
+ { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS },
+ { N_("Comment contains"), SEARCH_COMMENT_CONTAINS },
+ { N_("Has category"), SEARCH_HAS_CATEGORY },
+ { NULL, -1 }
+};
+
+
+
+static void cal_search_bar_class_init (CalSearchBarClass *class);
+
+static void cal_search_bar_query_changed (ESearchBar *search);
+static void cal_search_bar_menu_activated (ESearchBar *search, int item);
+
+/* Signal IDs */
+enum {
+ SEXP_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint cal_search_bar_signals[LAST_SIGNAL] = { 0 };
+
+
+
+/**
+ * cal_search_bar_get_type:
+ *
+ * Registers the #CalSearchBar class if necessary and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #CalSearchBar class.
+ **/
+GtkType
+cal_search_bar_get_type (void)
+{
+ static GtkType cal_search_bar_type = 0;
+
+ if (!cal_search_bar_type) {
+ static const GtkTypeInfo cal_search_bar_info = {
+ "CalSearchBar",
+ sizeof (CalSearchBar),
+ sizeof (CalSearchBarClass),
+ (GtkClassInitFunc) cal_search_bar_class_init,
+ (GtkObjectInitFunc) NULL,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ cal_search_bar_type = gtk_type_unique (E_SEARCH_BAR_TYPE, &cal_search_bar_info);
+ }
+
+ return cal_search_bar_type;
+}
+
+/* Class initialization function for the calendar search bar */
+static void
+cal_search_bar_class_init (CalSearchBarClass *class)
+{
+ ESearchBarClass *e_search_bar_class;
+ GtkObjectClass *object_class;
+
+ e_search_bar_class = (ESearchBarClass *) class;
+ object_class = (GtkObjectClass *) class;
+
+ cal_search_bar_signals[SEXP_CHANGED] =
+ gtk_signal_new ("sexp_changed",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (CalSearchBarClass, sexp_changed),
+ gtk_marshal_NONE__STRING,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_STRING);
+
+ gtk_object_class_add_signals (object_class, cal_search_bar_signals, LAST_SIGNAL);
+
+ class->sexp_changed = NULL;
+
+ e_search_bar_class->query_changed = cal_search_bar_query_changed;
+ e_search_bar_class->menu_activated = cal_search_bar_menu_activated;
+}
+
+
+
+/* Emits the "sexp_changed" signal for the calendar search bar */
+static void
+notify_sexp_changed (CalSearchBar *cal_search, const char *sexp)
+{
+ gtk_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[SEXP_CHANGED],
+ sexp);
+}
+
+/* Sets the query string to be (contains? "field" "text") */
+static void
+notify_query_contains (CalSearchBar *cal_search, const char *field, const char *text)
+{
+ char *sexp;
+
+ sexp = g_strdup_printf ("(contains? \"%s\" \"%s\")", field, text);
+ notify_sexp_changed (cal_search, sexp);
+ g_free (sexp);
+}
+
+/* query_changed handler for the calendar search bar */
+static void
+cal_search_bar_query_changed (ESearchBar *search)
+{
+ CalSearchBar *cal_search;
+ int item;
+ char *text;
+
+ cal_search = CAL_SEARCH_BAR (search);
+
+ item = e_search_bar_get_option_choice (search);
+ text = e_search_bar_get_text (search);
+
+ if (!text)
+ return; /* This is an error in the UTF8 conversion, not an empty string! */
+
+ switch (item) {
+ case SEARCH_ANY_FIELD_CONTAINS:
+ notify_query_contains (cal_search, "any", text);
+ break;
+
+ case SEARCH_SUMMARY_CONTAINS:
+ notify_query_contains (cal_search, "summary", text);
+ break;
+
+ case SEARCH_DESCRIPTION_CONTAINS:
+ notify_query_contains (cal_search, "description", text);
+ break;
+
+ case SEARCH_COMMENT_CONTAINS:
+ notify_query_contains (cal_search, "comment", text);
+ break;
+
+ case SEARCH_HAS_CATEGORY: {
+ char *sexp;
+
+ sexp = g_strdup_printf ("(has-categories? \"%s\")", text);
+ notify_sexp_changed (cal_search, sexp);
+ g_free (sexp);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_free (text);
+}
+
+/* menu_activated handler for the calendar search bar */
+static void
+cal_search_bar_menu_activated (ESearchBar *search, int item)
+{
+ CalSearchBar *cal_search;
+
+ cal_search = CAL_SEARCH_BAR (search);
+
+ switch (item) {
+ case E_FILTERBAR_RESET_ID:
+ notify_sexp_changed (cal_search, "#t"); /* match all */
+ /* FIXME: should we change the rest of the search bar so that
+ * the user sees that he selected "show all" instead of some
+ * type/text search combination?
+ */
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+
+
+/**
+ * cal_search_bar_construct:
+ * @cal_search: A calendar search bar.
+ *
+ * Constructs a calendar search bar by binding its menu and option items.
+ *
+ * Return value: The same value as @cal_search.
+ **/
+CalSearchBar *
+cal_search_bar_construct (CalSearchBar *cal_search)
+{
+ g_return_val_if_fail (cal_search != NULL, NULL);
+ g_return_val_if_fail (IS_CAL_SEARCH_BAR (cal_search), NULL);
+
+ e_search_bar_construct (E_SEARCH_BAR (cal_search), search_menu_items, search_option_items);
+ return cal_search;
+}
+
+/**
+ * cal_search_bar_new:
+ *
+ * Creates a new calendar search bar.
+ *
+ * Return value: A newly-created calendar search bar. You should connect to the
+ * "sexp_changed" signal to monitor changes in the generated sexps.
+ **/
+GtkWidget *
+cal_search_bar_new (void)
+{
+ CalSearchBar *cal_search;
+
+ cal_search = gtk_type_new (TYPE_CAL_SEARCH_BAR);
+ return GTK_WIDGET (cal_search_bar_construct (cal_search));
+}
diff --git a/calendar/gui/cal-search-bar.h b/calendar/gui/cal-search-bar.h
new file mode 100644
index 0000000000..1317369371
--- /dev/null
+++ b/calendar/gui/cal-search-bar.h
@@ -0,0 +1,62 @@
+/* Evolution calendar - Search bar widget for calendar views
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * 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 of the License, 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 CAL_SEARCH_BAR_H
+#define CAL_SEARCH_BAR_H
+
+#include <libgnome/gnome-defs.h>
+#include "widgets/misc/e-search-bar.h"
+#include "widgets/misc/e-filter-bar.h"
+
+BEGIN_GNOME_DECLS
+
+
+
+#define TYPE_CAL_SEARCH_BAR (cal_search_bar_get_type ())
+#define CAL_SEARCH_BAR(obj) (GTK_CHECK_CAST ((obj), TYPE_CAL_SEARCH_BAR, CalSearchBar))
+#define CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CAL_SEARCH_BAR, \
+ CalSearchBarClass))
+#define IS_CAL_SEARCH_BAR(obj) (GTK_CHECK_TYPE ((obj), TYPE_CAL_SEARCH_BAR))
+#define IS_CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CAL_SEARCH_BAR))
+
+typedef struct {
+ ESearchBar search_bar;
+} CalSearchBar;
+
+typedef struct {
+ ESearchBarClass parent_class;
+
+ /* Notification signals */
+
+ void (* sexp_changed) (CalSearchBar *cal_search, const char *sexp);
+} CalSearchBarClass;
+
+GtkType cal_search_bar_get_type (void);
+
+CalSearchBar *cal_search_bar_construct (CalSearchBar *cal_search);
+
+GtkWidget *cal_search_bar_new (void);
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index 0216c15f48..a0366685c9 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -263,104 +263,7 @@ show_month_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path
static void
-new_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- new_calendar ();
-}
-
-static void
-open_ok (GtkWidget *widget, GtkFileSelection *fs)
-{
- GtkWidget *error_dialog;
- int ret;
- if(!g_file_exists (gtk_file_selection_get_filename (fs))) {
- error_dialog = gnome_message_box_new (
- _("File not found"),
- GNOME_MESSAGE_BOX_ERROR,
- GNOME_STOCK_BUTTON_OK,
- NULL);
-
- gnome_dialog_set_parent (GNOME_DIALOG (error_dialog), GTK_WINDOW (fs));
- ret = gnome_dialog_run (GNOME_DIALOG (error_dialog));
- } else {
- /* FIXME: find out who owns this calendar and use that name */
-#ifndef NO_WARNINGS
-#warning "FIXME: find out who owns this calendar and use that name"
-#endif
- /*
- new_calendar ("Somebody", gtk_file_selection_get_filename (fs));
- */
- gtk_widget_destroy (GTK_WIDGET (fs));
- }
-}
-
-static void
-open_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GtkFileSelection *fs;
-
- fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Open calendar")));
-
- gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
- (GtkSignalFunc) open_ok,
- fs);
- gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked",
- (GtkSignalFunc) gtk_widget_destroy,
- GTK_OBJECT (fs));
-
- gtk_widget_show (GTK_WIDGET (fs));
- gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me */
-}
-
-static void
-save_ok (GtkWidget *widget, GtkFileSelection *fs)
-{
- GnomeCalendar *gcal;
- gchar *fname;
-
- gcal = GNOME_CALENDAR (gtk_object_get_user_data (GTK_OBJECT (fs)));
- gtk_window_set_wmclass (GTK_WINDOW (gcal), "gnomecal", "gnomecal");
-
- fname = g_strdup (gtk_file_selection_get_filename (fs));
- g_free(fname);
- gtk_main_quit ();
-}
-
-static gint
-close_save (GtkWidget *w)
-{
- gtk_main_quit ();
- return TRUE;
-}
-
-static void
-save_as_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
- GtkFileSelection *fs;
-
- gcal = GNOME_CALENDAR (data);
-
- fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save calendar")));
- gtk_object_set_user_data (GTK_OBJECT (fs), gcal);
-
- gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
- (GtkSignalFunc) save_ok,
- fs);
- gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked",
- (GtkSignalFunc) close_save,
- GTK_OBJECT (fs));
- gtk_signal_connect_object (GTK_OBJECT (fs), "delete_event",
- GTK_SIGNAL_FUNC (close_save),
- GTK_OBJECT (fs));
- gtk_widget_show (GTK_WIDGET (fs));
- gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me even more */
- gtk_main ();
- gtk_widget_destroy (GTK_WIDGET (fs));
-}
-
-static void
-preferences_cmd (BonoboUIComponent *uic, gpointer data, const char *path)
+settings_cmd (BonoboUIComponent *uic, gpointer data, const char *path)
{
if (!preferences_dialog)
preferences_dialog = cal_prefs_dialog_new ();
@@ -471,21 +374,16 @@ clear_folder_bar_label (BonoboControl *control)
}
static BonoboUIVerb verbs [] = {
- BONOBO_UI_VERB ("CalendarNew", new_calendar_cmd),
- BONOBO_UI_VERB ("CalendarOpen", open_calendar_cmd),
- BONOBO_UI_VERB ("CalendarSaveAs", save_as_calendar_cmd),
BONOBO_UI_VERB ("CalendarPrint", file_print_cb),
BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb),
- BONOBO_UI_VERB ("EditNewAppointment", new_appointment_cb),
- BONOBO_UI_VERB ("EditNewEvent", new_event_cb),
- BONOBO_UI_VERB ("CalendarPreferences", preferences_cmd),
+ BONOBO_UI_VERB ("CalendarNewAppointment", new_appointment_cb),
+ BONOBO_UI_VERB ("CalendarNewEvent", new_event_cb),
+ BONOBO_UI_VERB ("CalendarSettings", settings_cmd),
BONOBO_UI_VERB ("CutEvent", cut_event_cmd),
BONOBO_UI_VERB ("CopyEvent", copy_event_cmd),
BONOBO_UI_VERB ("PasteEvent", paste_event_cmd),
- BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd),
-
BONOBO_UI_VERB ("CalendarPrev", previous_clicked),
BONOBO_UI_VERB ("CalendarToday", today_clicked),
BONOBO_UI_VERB ("CalendarNext", next_clicked),
@@ -496,16 +394,18 @@ static BonoboUIVerb verbs [] = {
BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked),
BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked),
+ BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd),
+
BONOBO_UI_VERB_END
};
static EPixmap pixmaps [] =
{
- E_PIXMAP ("/menu/File/New/NewFirstItem/CalendarNew", "new_appointment.xpm"),
+ E_PIXMAP ("/menu/File/New/NewFirstItem/NewAppointment", "new_appointment.xpm"),
E_PIXMAP ("/menu/File/Print/Print", "print.xpm"),
- E_PIXMAP ("/menu/File/Print/Print Preview", "print-preview.xpm"),
- E_PIXMAP ("/menu/Actions/Component/CalendarNew", "new_appointment.xpm"),
- E_PIXMAP ("/menu/Tools/Component/CalendarPreferences", "configure_16_calendar.xpm"),
+ E_PIXMAP ("/menu/File/Print/PrintPreview", "print-preview.xpm"),
+ E_PIXMAP ("/menu/Actions/Component/NewAppointment", "new_appointment.xpm"),
+ E_PIXMAP ("/menu/Tools/Component/CalendarSettings", "configure_16_calendar.xpm"),
E_PIXMAP ("/Toolbar/New", "buttons/new_appointment.png"),
E_PIXMAP ("/Toolbar/Print", "buttons/print.png"),
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
index 2e48ecf00c..7fccf3937a 100644
--- a/calendar/gui/calendar-model.c
+++ b/calendar/gui/calendar-model.c
@@ -48,6 +48,10 @@ struct _CalendarModelPrivate {
/* Types of objects we are dealing with */
CalObjType type;
+ /* S-expression for query and the query object */
+ char *sexp;
+ CalQuery *query;
+
/* Array of pointers to calendar objects */
GArray *objects;
@@ -96,12 +100,10 @@ static void calendar_model_free_value (ETableModel *etm, int col, void *value);
static void *calendar_model_initialize_value (ETableModel *etm, int col);
static gboolean calendar_model_value_is_empty (ETableModel *etm, int col, const void *value);
static char * calendar_model_value_to_string (ETableModel *etm, int col, const void *value);
-static void load_objects (CalendarModel *model);
static int remove_object (CalendarModel *model, const char *uid);
static void ensure_task_complete (CalComponent *comp,
time_t completed_date);
static void ensure_task_not_complete (CalComponent *comp);
-static void calendar_model_collect_all_categories (CalendarModel *model);
static gboolean calendar_model_collect_categories (CalendarModel *model,
CalComponent *comp);
@@ -190,6 +192,9 @@ calendar_model_init (CalendarModel *model)
priv = g_new0 (CalendarModelPrivate, 1);
model->priv = priv;
+ priv->sexp = g_strdup ("#t"); /* match all by default */
+ priv->query = NULL;
+
priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *));
priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal);
priv->new_comp_vtype = CAL_COMPONENT_EVENT;
@@ -257,6 +262,17 @@ calendar_model_destroy (GtkObject *object)
priv->client = NULL;
}
+ if (priv->sexp) {
+ g_free (priv->sexp);
+ priv->sexp = NULL;
+ }
+
+ if (priv->query) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), model);
+ gtk_object_unref (GTK_OBJECT (priv->query));
+ priv->query = NULL;
+ }
+
/* Free the uid->index hash data and the array of UIDs */
free_objects (model);
@@ -1729,105 +1745,20 @@ calendar_model_new (void)
}
-/* Callback used when a calendar is opened into the server */
+/* Callback used when a component is updated in the live query */
static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- CalendarModel *model;
-
- model = CALENDAR_MODEL (data);
-
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- load_objects (model);
- calendar_model_collect_all_categories (model);
- }
-
- e_table_model_changed (E_TABLE_MODEL (model));
-}
-
-
-/* Removes an object from the model and updates all the indices that follow.
- * Returns the index of the object that was removed, or -1 if no object with
- * such UID was found.
- */
-static int
-remove_object (CalendarModel *model, const char *uid)
-{
- CalendarModelPrivate *priv;
- int *idx;
- CalComponent *orig_comp;
- int i;
- int n;
-
- priv = model->priv;
-
- /* Find the index of the object to be removed */
-
- idx = g_hash_table_lookup (priv->uid_index_hash, uid);
- if (!idx)
- return -1;
-
- orig_comp = g_array_index (priv->objects, CalComponent *, *idx);
- g_assert (orig_comp != NULL);
-
- /* Decrease the indices of all the objects that follow in the array */
-
- for (i = *idx + 1; i < priv->objects->len; i++) {
- CalComponent *comp;
- int *comp_idx;
- const char *comp_uid;
-
- comp = g_array_index (priv->objects, CalComponent *, i);
- g_assert (comp != NULL);
-
- cal_component_get_uid (comp, &comp_uid);
-
- comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid);
- g_assert (comp_idx != NULL);
-
- (*comp_idx)--;
- g_assert (*comp_idx >= 0);
- }
-
- /* Remove this object from the array and hash */
-
- g_hash_table_remove (priv->uid_index_hash, uid);
- g_array_remove_index (priv->objects, *idx);
-
- gtk_object_unref (GTK_OBJECT (orig_comp));
-
- n = *idx;
- g_free (idx);
-
- return n;
-}
-
-/* Returns whether a component's type matches the types we support */
-static gboolean
-matches_type (CalObjType type, CalComponentVType vtype)
-{
- return ((vtype == CAL_COMPONENT_EVENT && (type & CALOBJ_TYPE_EVENT))
- || (vtype == CAL_COMPONENT_TODO && (type & CALOBJ_TYPE_TODO))
- || (vtype == CAL_COMPONENT_JOURNAL && (type & CALOBJ_TYPE_JOURNAL)));
-}
-
-/* Callback used when an object is updated in the server */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
+query_obj_updated_cb (CalQuery *query, const char *uid,
+ gboolean query_in_progress, int n_scanned, int total,
+ gpointer data)
{
CalendarModel *model;
CalendarModelPrivate *priv;
int orig_idx;
CalComponent *new_comp;
- CalComponentVType new_comp_vtype;
const char *new_comp_uid;
int *new_idx;
CalClientGetStatus status;
- g_print ("In calendar model obj_updated_cb\n");
-
model = CALENDAR_MODEL (data);
priv = model->priv;
@@ -1837,14 +1768,6 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
switch (status) {
case CAL_CLIENT_GET_SUCCESS:
- /* Check if we are interested in this type of object */
-
- new_comp_vtype = cal_component_get_vtype (new_comp);
- if (!matches_type (priv->type, new_comp_vtype)) {
- gtk_object_unref (GTK_OBJECT (new_comp));
- break;
- }
-
/* Insert the object into the model */
cal_component_get_uid (new_comp, &new_comp_uid);
@@ -1922,13 +1845,11 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
default:
g_assert_not_reached ();
}
-
- g_print ("Out calendar model obj_updated_cb\n");
}
-/* Callback used when an object is removed in the server */
+/* Callback used when a component is removed from the live query */
static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
+query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data)
{
CalendarModel *model;
int idx;
@@ -1941,67 +1862,175 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
e_table_model_row_deleted (E_TABLE_MODEL (model), idx);
}
-/* Loads the required objects from the calendar client */
+/* Callback used when a query ends */
static void
-load_objects (CalendarModel *model)
+query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
+{
+ CalendarModel *model;
+
+ model = CALENDAR_MODEL (data);
+
+ /* FIXME */
+
+ if (status != CAL_QUERY_DONE_SUCCESS)
+ fprintf (stderr, "query done: %s\n", error_str);
+}
+
+/* Callback used when an evaluation error occurs when running a query */
+static void
+query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
+{
+ CalendarModel *model;
+
+ model = CALENDAR_MODEL (data);
+
+ /* FIXME */
+
+ fprintf (stderr, "eval error: %s\n", error_str);
+}
+
+/* Builds a complete query sexp for the calendar model by adding the predicates
+ * to filter only for the type of objects that the model supports.
+ */
+static char *
+adjust_query_sexp (CalendarModel *model, const char *sexp)
{
CalendarModelPrivate *priv;
- GList *uids;
- GList *l;
+ CalObjType type;
+ char *type_sexp;
+ char *new_sexp;
priv = model->priv;
- g_assert (cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED);
+ type = priv->type;
- uids = cal_client_get_uids (priv->client, priv->type);
+ if (!(type & CALOBJ_TYPE_ANY))
+ type_sexp = g_strdup ("#t");
+ else
+ type_sexp = g_strdup_printf (
+ "(or %s %s %s)",
+ (type & CALOBJ_TYPE_EVENT) ? "(= (get-vtype) \"VEVENT\")" : "",
+ (type & CALOBJ_TYPE_TODO) ? "(= (get-vtype) \"VTODO\")" : "",
+ (type & CALOBJ_TYPE_JOURNAL) ? "(= (get-vtype) \"VJOURNAL\")" : "");
- for (l = uids; l; l = l->next) {
- char *uid;
- CalComponent *comp;
- const char *comp_uid;
- CalClientGetStatus status;
- CalComponentVType comp_vtype;
- int *idx;
+ new_sexp = g_strdup_printf ("(and %s %s)", type_sexp, sexp);
+ g_free (type_sexp);
+
+ return new_sexp;
+}
+
+/* Restarts a query */
+static void
+update_query (CalendarModel *model)
+{
+ CalendarModelPrivate *priv;
+ char *real_sexp;
- uid = l->data;
- status = cal_client_get_object (priv->client, uid, &comp);
+ priv = model->priv;
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- break;
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+ free_objects (model);
+ e_table_model_changed (E_TABLE_MODEL (model));
- case CAL_CLIENT_GET_NOT_FOUND:
- /* Nothing; the object may have been removed from the server */
- continue;
+ if (!(priv->client
+ && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED))
+ return;
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("load_objects(): Syntax error when getting object `%s'", uid);
- continue;
+ if (priv->query) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), model);
+ gtk_object_unref (GTK_OBJECT (priv->query));
+ }
- default:
- g_assert_not_reached ();
- }
+ g_assert (priv->sexp != NULL);
+ real_sexp = adjust_query_sexp (model, priv->sexp);
- /* Check if we are interested in this type of object */
+ priv->query = cal_client_get_query (priv->client, real_sexp);
+ g_free (real_sexp);
- comp_vtype = cal_component_get_vtype (comp);
- if (!matches_type (priv->type, comp_vtype)) {
- gtk_object_unref (GTK_OBJECT (comp));
- continue;
- }
+ if (!priv->query) {
+ g_message ("update_query(): Could not create the query");
+ return;
+ }
- /* Insert the object into the model */
+ gtk_signal_connect (GTK_OBJECT (priv->query), "obj_updated",
+ GTK_SIGNAL_FUNC (query_obj_updated_cb), model);
+ gtk_signal_connect (GTK_OBJECT (priv->query), "obj_removed",
+ GTK_SIGNAL_FUNC (query_obj_removed_cb), model);
+ gtk_signal_connect (GTK_OBJECT (priv->query), "query_done",
+ GTK_SIGNAL_FUNC (query_query_done_cb), model);
+ gtk_signal_connect (GTK_OBJECT (priv->query), "eval_error",
+ GTK_SIGNAL_FUNC (query_eval_error_cb), model);
+}
+
+/* Callback used when a calendar is opened into the server */
+static void
+cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
+{
+ CalendarModel *model;
- idx = g_new (int, 1);
+ model = CALENDAR_MODEL (data);
+
+ if (status != CAL_CLIENT_OPEN_SUCCESS)
+ return;
- g_array_append_val (priv->objects, comp);
- *idx = priv->objects->len - 1;
+ update_query (model);
+}
+
+
+/* Removes an object from the model and updates all the indices that follow.
+ * Returns the index of the object that was removed, or -1 if no object with
+ * such UID was found.
+ */
+static int
+remove_object (CalendarModel *model, const char *uid)
+{
+ CalendarModelPrivate *priv;
+ int *idx;
+ CalComponent *orig_comp;
+ int i;
+ int n;
+
+ priv = model->priv;
+
+ /* Find the index of the object to be removed */
+
+ idx = g_hash_table_lookup (priv->uid_index_hash, uid);
+ if (!idx)
+ return -1;
+
+ orig_comp = g_array_index (priv->objects, CalComponent *, *idx);
+ g_assert (orig_comp != NULL);
+
+ /* Decrease the indices of all the objects that follow in the array */
+
+ for (i = *idx + 1; i < priv->objects->len; i++) {
+ CalComponent *comp;
+ int *comp_idx;
+ const char *comp_uid;
+
+ comp = g_array_index (priv->objects, CalComponent *, i);
+ g_assert (comp != NULL);
cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (priv->uid_index_hash, (char *) comp_uid, idx);
+
+ comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid);
+ g_assert (comp_idx != NULL);
+
+ (*comp_idx)--;
+ g_assert (*comp_idx >= 0);
}
- cal_obj_uid_list_free (uids);
+ /* Remove this object from the array and hash */
+
+ g_hash_table_remove (priv->uid_index_hash, uid);
+ g_array_remove_index (priv->objects, *idx);
+
+ gtk_object_unref (GTK_OBJECT (orig_comp));
+
+ n = *idx;
+ g_free (idx);
+
+ return n;
}
/**
@@ -2051,8 +2080,6 @@ calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjTy
if (priv->client == client && priv->type == type)
return;
- e_table_model_pre_change (E_TABLE_MODEL(model));
-
if (client)
gtk_object_ref (GTK_OBJECT (client));
@@ -2061,25 +2088,42 @@ calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjTy
gtk_object_unref (GTK_OBJECT (priv->client));
}
- free_objects (model);
-
priv->client = client;
priv->type = type;
if (priv->client) {
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), model);
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), model);
-
- if (cal_client_get_load_state (priv->client) != CAL_CLIENT_LOAD_LOADED)
+ if (cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED)
+ update_query (model);
+ else
gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened",
GTK_SIGNAL_FUNC (cal_opened_cb), model);
- else
- load_objects (model);
}
+}
- e_table_model_changed (E_TABLE_MODEL (model));
+/**
+ * calendar_model_set_query:
+ * @model: A calendar model.
+ * @sexp: Sexp that defines the query.
+ *
+ * Sets the query sexp that a calendar model will use to filter its contents.
+ **/
+void
+calendar_model_set_query (CalendarModel *model, const char *sexp)
+{
+ CalendarModelPrivate *priv;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (IS_CALENDAR_MODEL (model));
+ g_return_if_fail (sexp != NULL);
+
+ priv = model->priv;
+
+ if (priv->sexp)
+ g_free (priv->sexp);
+
+ priv->sexp = g_strdup (sexp);
+
+ update_query (model);
}
@@ -2294,31 +2338,6 @@ calendar_model_set_default_category (CalendarModel *model,
}
-static void
-calendar_model_collect_all_categories (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
- CalComponent *comp;
- int i;
-
- priv = model->priv;
-
- /* Destroy the current tree and start from scratch. */
- g_tree_traverse (priv->categories, (GTraverseFunc) g_free,
- G_PRE_ORDER, NULL);
- g_tree_destroy (priv->categories);
-
- priv->categories = g_tree_new ((GCompareFunc)strcmp);
-
- for (i = 0; i < priv->objects->len; i++) {
- comp = g_array_index (priv->objects, CalComponent *, i);
- calendar_model_collect_categories (model, comp);
- }
-
- gtk_signal_emit (GTK_OBJECT (model),
- calendar_model_signals [CATEGORIES_CHANGED]);
-}
-
static gboolean
calendar_model_collect_categories (CalendarModel *model,
diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h
index 5a47d3752e..c06b1f3f48 100644
--- a/calendar/gui/calendar-model.h
+++ b/calendar/gui/calendar-model.h
@@ -65,6 +65,9 @@ void calendar_model_set_cal_client (CalendarModel *model,
CalClient *client,
CalObjType type);
+void calendar_model_set_query (CalendarModel *model,
+ const char *sexp);
+
void calendar_model_set_new_comp_vtype (CalendarModel *model,
CalComponentVType vtype);
CalComponentVType calendar_model_get_new_comp_vtype (CalendarModel *model);
diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c
new file mode 100644
index 0000000000..8c32bb3059
--- /dev/null
+++ b/calendar/gui/comp-editor-factory.c
@@ -0,0 +1,228 @@
+/* Evolution calendar - Component editor factory object
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * 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 of the License, 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 <cal-client/cal-client.h>
+#include "comp-editor-factory.h"
+
+
+
+/* An client we have open */
+typedef struct {
+ /* Uri of the calendar, used as key in the clients hash table */
+ GnomeVFSURI *uri;
+
+ /* Client of the calendar */
+ CalClient *client;
+
+ /* Hash table of components that belong to this client */
+ GHashTable *uid_comp_hash;
+
+ /* Number of times this client has been opened */
+ int refcount;
+} 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;
+
+/* Private part of the CompEditorFactory structure */
+struct CompEditorFactoryPrivate {
+ /* Hash table of URI->OpenClient */
+ GHashTable *uri_client_hash;
+};
+
+
+
+static void comp_editor_factory_class_init (CompEditorFactoryClass *class);
+static void comp_editor_factory_init (CompEditorFactory *factory);
+static void comp_editor_factory_destroy (GtkObject *object);
+
+static void impl_editExisting (PortableServer_Servant servant,
+ const CORBA_char *uri,
+ const GNOME_Evolution_Calendar_CalObjUID uid,
+ CORBA_Environment *ev);
+static void impl_editNew (PortableServer_Servant servant,
+ const CORBA_char *uri,
+ const GNOME_Evolution_Calendar_CalObjType type,
+ CORBA_Environment *ev);
+
+static BonoboXObjectClass *parent_class = NULL;
+
+
+
+BONOBO_X_TYPE_FUNC_FULL (CompEditorFactory,
+ GNOME_Evolution_Calendar_CompEditorFactory,
+ BONOBO_X_OBJECT_TYPE,
+ comp_editor_factory);
+
+/* Class initialization function for the component editor factory */
+static void
+comp_editor_factory_class_init (CompEditorFactoryClass *class)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
+
+ class->epv.editExisting = impl_editExisting;
+ class->epv.editNew = impl_editNew;
+
+ object_class->destroy = comp_editor_factory_destroy;
+}
+
+/* Object initialization function for the component editor factory */
+static void
+comp_editor_factory_init (CompEditorFactory *factory)
+{
+ CompEditorFactoryPrivate *priv;
+
+ priv = g_new (CompEditorFactoryPrivate, 1);
+
+ priv->uri_client_hash = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal);
+}
+
+/* Used from g_hash_table_foreach(); frees a client structure */
+static void
+free_client_cb (gpointer key, gpointer value, gpointer data)
+{
+ OpenClient *oc;
+
+ oc = value;
+
+ gnome_vfs_uri_unref (oc->uri);
+ cal_client_unref (oc->client);
+ g_hash_table_destroy (oc->uid_comp_hash);
+
+ g_free (oc);
+}
+
+/* Destroy handler for the component editor factory */
+static void
+comp_editor_factory_destroy (GtkObject *object)
+{
+ CompEditorFactory *factory;
+ CompEditorFactoryPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_FACTORY (object));
+
+ factory = COMP_EDITOR_FACTORY (object);
+ priv = factory->priv;
+
+ g_hash_table_foreach (priv->uri_client_hash, free_client_cb, NULL);
+ g_hash_table_destroy (priv->uri_client_hash);
+ priv->uri_client_hash = NULL;
+
+ g_free (priv);
+ factory->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* Creates a new OpenClient structure by synchronously (!) opening a calendar
+ * client. Returns NULL if it could not open it.
+ */
+static OpenClient *
+open_client (GnomeVFSURI *uri)
+{
+ CalClient *client;
+
+ client = cal_client_new ();
+ if (!client)
+ return NULL;
+
+ gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
+ GTK_SIGNAL_FUNC (cal_opened_cb), NULL);
+
+ oc = g_new (OpenClient, 1);
+ oc->uri = uri;
+ oc->client = client;
+ oc->uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ oc->refcount = 1;
+
+}
+
+static void
+impl_editExisting (PortableServer_Servant servant,
+ const CORBA_char *str_uri,
+ const GNOME_Evolution_Calendar_CalObjUID uid,
+ CORBA_Environment *ev)
+{
+ CompEditorFactory *factory;
+ CompEditorFactoryPrivate *priv;
+ GnomeVFSURI *uri;
+ OpenClient *oc;
+ CalClient *client;
+ Component *c;
+
+ factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant));
+ priv = factory->priv;
+
+ /* Look up the client */
+
+ uri = gnome_vfs_uri_new (str_uri);
+ if (!uri) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_CompEditorFactory_InvalidURI,
+ NULL);
+ return;
+ }
+
+ oc = g_hash_table_lookup (priv->uri_client_hash, uri);
+ if (oc)
+ client = oc->client;
+ else {
+ oc = open_client (uri);
+ if (!oc) {
+ gnome_vfs_uri_unref (uri);
+
+ CORBA_exception_set (
+ ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_CompEditorFactory_BackendContactError,
+ NULL);
+ return;
+ }
+
+ client = oc->client;
+ }
+
+ gnome_vfs_uri_unref (uri);
+
+ /* Look up the component */
+
+ c = g_hash_table_lookup (oc->uid_comp_hash,
+}
diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h
new file mode 100644
index 0000000000..3e8387d6a7
--- /dev/null
+++ b/calendar/gui/comp-editor-factory.h
@@ -0,0 +1,59 @@
+/* Evolution calendar - Component editor factory object
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@ximian.com>
+ *
+ * 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 of the License, 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 COMP_EDITOR_FACTORY_H
+#define COMP_EDITOR_FACTORY_H
+
+#include <bonobo/bonobo-xobject.h>
+#include "evolution-calendar.h"
+
+
+
+#define TYPE_COMP_EDITOR_FACTORY (comp_editor_factory_get_type ())
+#define COMP_EDITOR_FACTORY(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_FACTORY, \
+ CompEditorFactory))
+#define COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
+ TYPE_COMP_EDITOR_FACTORY, CompEditorFactoryClass))
+#define IS_COMP_EDITOR_FACTORY(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_FACTORY))
+#define IS_COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR_FACTORY))
+
+typedef struct CompEditorFactoryPrivate CompEditorFactoryPrivate;
+
+typedef struct {
+ BonoboXObject xobject;
+
+ /* Private data */
+ CompEditorFactoryPrivate *priv;
+} CompEditorFactory;
+
+typedef struct {
+ BonoboXObjectClass parent_class;
+
+ POA_GNOME_Evolution_Calendar_CompEditorFactory__epv epv;
+} CompEditorFactoryClass;
+
+GtkType comp_editor_factory_get_type (void);
+
+CompEditorFactory *comp_editor_factory_new (void);
+
+
+
+#endif
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 999b64d99f..fc86f5e4f9 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -82,18 +82,6 @@ static gint e_calendar_table_on_key_press (ETable *table,
GdkEventKey *event,
ECalendarTable *cal_table);
-static void e_calendar_table_apply_filter (ECalendarTable *cal_table);
-static void e_calendar_table_on_model_changed (ETableModel *model,
- ECalendarTable *cal_table);
-static void e_calendar_table_on_rows_inserted (ETableModel *model,
- int row,
- int count,
- ECalendarTable *cal_table);
-static void e_calendar_table_on_rows_deleted (ETableModel *model,
- int row,
- int count,
- ECalendarTable *cal_table);
-
static void selection_clear_event (GtkWidget *invisible,
GdkEventSelection *event,
ECalendarTable *cal_table);
@@ -252,39 +240,11 @@ e_calendar_table_init (ECalendarTable *cal_table)
ETableExtras *extras;
gint i;
GdkPixbuf *pixbuf;
- GdkColormap *colormap;
- gboolean success[E_CALENDAR_TABLE_COLOR_LAST];
- gint nfailed;
GList *strings;
- /* Allocate the colors we need. */
-
- colormap = gtk_widget_get_colormap (GTK_WIDGET (cal_table));
-
- cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].red = 65535;
- cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].green = 0;
- cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].blue = 0;
-
- nfailed = gdk_colormap_alloc_colors (colormap, cal_table->colors,
- E_CALENDAR_TABLE_COLOR_LAST,
- FALSE, TRUE, success);
- if (nfailed)
- g_warning ("Failed to allocate all colors");
-
/* Create the model */
cal_table->model = calendar_model_new ();
- cal_table->subset_model = e_table_subset_variable_new (E_TABLE_MODEL (cal_table->model));
-
- gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_changed",
- GTK_SIGNAL_FUNC (e_calendar_table_on_model_changed),
- cal_table);
- gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_rows_inserted",
- GTK_SIGNAL_FUNC (e_calendar_table_on_rows_inserted),
- cal_table);
- gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_rows_deleted",
- GTK_SIGNAL_FUNC (e_calendar_table_on_rows_deleted),
- cal_table);
/* Create the header columns */
@@ -472,7 +432,7 @@ e_calendar_table_init (ECalendarTable *cal_table)
/* Create the table */
- table = e_table_scrolled_new_from_spec_file (cal_table->subset_model,
+ table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (cal_table->model),
extras,
EVOLUTION_ETSPECDIR "/e-calendar-table.etspec",
NULL);
@@ -566,9 +526,6 @@ e_calendar_table_destroy (GtkObject *object)
gtk_object_unref (GTK_OBJECT (cal_table->model));
cal_table->model = NULL;
- gtk_object_unref (GTK_OBJECT (cal_table->subset_model));
- cal_table->subset_model = NULL;
-
if (cal_table->invisible)
gtk_widget_destroy (cal_table->invisible);
if (cal_table->clipboard_selection)
@@ -577,15 +534,6 @@ e_calendar_table_destroy (GtkObject *object)
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
-
-void
-e_calendar_table_set_cal_client (ECalendarTable *cal_table,
- CalClient *client)
-{
- calendar_model_set_cal_client (cal_table->model, client,
- CALOBJ_TYPE_TODO);
-}
-
/**
* e_calendar_table_get_table:
* @cal_table: A calendar table.
@@ -724,6 +672,8 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table)
else
comp = NULL;
+ /* FIXME: this may be something other than a TODO component */
+
if (delete_component_dialog (comp, n_selected, CAL_COMPONENT_TODO, GTK_WIDGET (cal_table)))
delete_selected_components (cal_table);
}
@@ -1011,141 +961,6 @@ e_calendar_table_save_state (ECalendarTable *cal_table,
}
-void
-e_calendar_table_set_filter_func (ECalendarTable *cal_table,
- ECalendarTableFilterFunc filter_func,
- gpointer filter_data,
- GDestroyNotify filter_data_destroy)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- if (cal_table->filter_func == filter_func
- && cal_table->filter_data == filter_data
- && cal_table->filter_data_destroy == filter_data_destroy)
- return;
-
- if (cal_table->filter_data_destroy)
- (*cal_table->filter_data_destroy) (cal_table->filter_data);
-
- cal_table->filter_func = filter_func;
- cal_table->filter_data = filter_data;
- cal_table->filter_data_destroy = filter_data_destroy;
-
- e_calendar_table_apply_filter (cal_table);
-}
-
-
-static void
-e_calendar_table_apply_filter (ECalendarTable *cal_table)
-{
- ETableSubsetVariable *etssv;
- CalComponent *comp;
- gint rows, row;
-
- etssv = E_TABLE_SUBSET_VARIABLE (cal_table->subset_model);
-
- /* Make sure that any edits get saved first. */
- e_table_model_pre_change (cal_table->subset_model);
-
- /* FIXME: A hack to remove all the existing rows quickly. */
- E_TABLE_SUBSET (cal_table->subset_model)->n_map = 0;
-
- if (cal_table->filter_func == NULL) {
- e_table_subset_variable_add_all (etssv);
- } else {
- rows = e_table_model_row_count (E_TABLE_MODEL (cal_table->model));
- for (row = 0; row < rows; row++) {
- comp = calendar_model_get_component (cal_table->model,
- row);
-
- if ((*cal_table->filter_func) (cal_table, comp,
- cal_table->filter_data))
- e_table_subset_variable_add (etssv, row);
- }
- }
-
- e_table_model_changed (cal_table->subset_model);
-}
-
-
-gboolean
-e_calendar_table_filter_by_category (ECalendarTable *cal_table,
- CalComponent *comp,
- gpointer filter_data)
-{
- GSList *categories_list, *elem;
- gboolean retval = FALSE;
-
- cal_component_get_categories_list (comp, &categories_list);
-
- for (elem = categories_list; elem; elem = elem->next) {
- if (retval == FALSE
- && !strcmp ((char*) elem->data, (char*) filter_data))
- retval = TRUE;
- g_free (elem->data);
- }
-
- g_slist_free (categories_list);
-
- return retval;
-}
-
-
-static void
-e_calendar_table_on_model_changed (ETableModel *model,
- ECalendarTable *cal_table)
-{
- e_calendar_table_apply_filter (cal_table);
-}
-
-
-static void
-e_calendar_table_on_rows_inserted (ETableModel *model,
- int row,
- int count,
- ECalendarTable *cal_table)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- gboolean add_row;
-
- add_row = FALSE;
-
- if (cal_table->filter_func) {
- CalComponent *comp;
-
- comp = calendar_model_get_component (cal_table->model, row + i);
- g_assert (comp != NULL);
-
- add_row = (* cal_table->filter_func) (cal_table, comp,
- cal_table->filter_data);
- } else
- add_row = TRUE;
-
- if (add_row) {
- ETableSubsetVariable *etssv;
-
- etssv = E_TABLE_SUBSET_VARIABLE (cal_table->subset_model);
-
- e_table_subset_variable_increment (etssv, row, 1);
- e_table_subset_variable_add (etssv, row);
- }
- }
-}
-
-
-static void
-e_calendar_table_on_rows_deleted (ETableModel *model,
- int row,
- int count,
- ECalendarTable *cal_table)
-{
- /* We just reapply the filter since we aren't too bothered about
- being efficient. It doesn't happen often. */
- e_calendar_table_apply_filter (cal_table);
-}
-
static void
invisible_destroyed (GtkWidget *invisible, ECalendarTable *cal_table)
{
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index 5ab32f3c18..c7e83e5d80 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -39,14 +39,6 @@ extern "C" {
* Used for calendar events and tasks.
*/
-/* These index our colors array. */
-typedef enum
-{
- E_CALENDAR_TABLE_COLOR_OVERDUE,
-
- E_CALENDAR_TABLE_COLOR_LAST
-} ECalendarTableColors;
-
#define E_CALENDAR_TABLE(obj) GTK_CHECK_CAST (obj, e_calendar_table_get_type (), ECalendarTable)
#define E_CALENDAR_TABLE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_table_get_type (), ECalendarTableClass)
@@ -57,29 +49,14 @@ typedef struct _ECalendarTable ECalendarTable;
typedef struct _ECalendarTableClass ECalendarTableClass;
-typedef gboolean (*ECalendarTableFilterFunc) (ECalendarTable *cal_table,
- CalComponent *comp,
- gpointer data);
-
struct _ECalendarTable
{
GtkTable table;
- /* This is the underlying model which contains all the tasks/events. */
+ /* The model that we use */
CalendarModel *model;
- /* This is the model that we use when filtering the tasks/events. */
- ETableModel *subset_model;
-
GtkWidget *etable;
-
- /* Colors for drawing. */
- GdkColor colors[E_CALENDAR_TABLE_COLOR_LAST];
-
- /* Data for filtering the Tasks. */
- ECalendarTableFilterFunc filter_func;
- gpointer filter_data;
- GDestroyNotify filter_data_destroy;
/* The ECell used to view & edit dates. */
ECellDateEdit *dates_cell;
@@ -101,9 +78,6 @@ GtkWidget* e_calendar_table_new (void);
CalendarModel *e_calendar_table_get_model (ECalendarTable *cal_table);
-void e_calendar_table_set_cal_client (ECalendarTable *cal_table,
- CalClient *client);
-
ETable *e_calendar_table_get_table (ECalendarTable *cal_table);
void e_calendar_table_delete_selected (ECalendarTable *cal_table);
@@ -120,14 +94,6 @@ void e_calendar_table_load_state (ECalendarTable *cal_table,
void e_calendar_table_save_state (ECalendarTable *cal_table,
gchar *filename);
-void e_calendar_table_set_filter_func (ECalendarTable *cal_table,
- ECalendarTableFilterFunc filter_func,
- gpointer filter_data,
- GDestroyNotify filter_data_destroy);
-gboolean e_calendar_table_filter_by_category (ECalendarTable *cal_table,
- CalComponent *comp,
- gpointer filter_data);
-
#ifdef __cplusplus
}
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index dbf7a7d779..e0a0b8ef8f 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -32,6 +32,7 @@
#include <gal/menus/gal-view-etable.h>
#include "widgets/menus/gal-view-menus.h"
#include "dialogs/task-editor.h"
+#include "cal-search-bar.h"
#include "calendar-config.h"
#include "component-factory.h"
@@ -50,10 +51,17 @@ struct _ETasksPrivate {
/* The ECalendarTable showing the tasks. */
GtkWidget *tasks_view;
+ /* Search bar for tasks and the current sexp */
+ GtkWidget *search_bar;
+ char *sexp;
+
/* The option menu showing the categories, and the popup menu. */
GtkWidget *categories_option_menu;
GtkWidget *categories_menu;
+ /* The category that is currently selected, used to filter out items */
+ char *category;
+
/* View collection and the view menus handler */
GalViewCollection *view_collection;
GalViewMenus *view_menus;
@@ -131,6 +139,9 @@ e_tasks_init (ETasks *tasks)
priv = g_new0 (ETasksPrivate, 1);
tasks->priv = priv;
+ priv->sexp = g_strdup ("#t"); /* Match all */
+ priv->category = NULL;
+
setup_widgets (tasks);
}
@@ -148,6 +159,51 @@ table_selection_change_cb (ETable *etable, gpointer data)
n_selected);
}
+/* Updates the query in the table model by composing the currently selected
+ * category with the current sexp.
+ */
+static void
+update_query (ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ char *new_sexp;
+ gboolean free_new_sexp;
+ CalendarModel *model;
+
+ priv = tasks->priv;
+
+ g_assert (priv->sexp != NULL);
+
+ if (priv->category) {
+ new_sexp = g_strdup_printf ("(and %s (has-categories? \"%s\"))",
+ priv->sexp, priv->category);
+ free_new_sexp = TRUE;
+ } else {
+ new_sexp = priv->sexp;
+ free_new_sexp = FALSE;
+ }
+
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+ calendar_model_set_query (model, new_sexp);
+
+ if (free_new_sexp)
+ g_free (new_sexp);
+}
+
+/* Callback used when the sexp in the search bar changes */
+static void
+search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data)
+{
+ ETasks *tasks;
+ ETasksPrivate *priv;
+
+ tasks = E_TASKS (data);
+ priv = tasks->priv;
+
+ priv->sexp = g_strdup (sexp);
+ update_query (tasks);
+}
+
#define E_TASKS_TABLE_DEFAULT_STATE \
"<?xml version=\"1.0\"?>" \
"<ETableState>" \
@@ -169,11 +225,17 @@ setup_widgets (ETasks *tasks)
priv = tasks->priv;
- hbox = gtk_hbox_new (FALSE, 0);
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
gtk_widget_show (hbox);
gtk_table_attach (GTK_TABLE (tasks), hbox, 0, 1, 0, 1,
GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ priv->search_bar = cal_search_bar_new ();
+ gtk_signal_connect (GTK_OBJECT (priv->search_bar), "sexp_changed",
+ GTK_SIGNAL_FUNC (search_bar_sexp_changed_cb), tasks);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->search_bar, TRUE, TRUE, 0);
+ gtk_widget_show (priv->search_bar);
+
priv->categories_option_menu = gtk_option_menu_new ();
gtk_widget_show (priv->categories_option_menu);
gtk_box_pack_end (GTK_BOX (hbox), priv->categories_option_menu,
@@ -215,6 +277,7 @@ GtkWidget *
e_tasks_construct (ETasks *tasks)
{
ETasksPrivate *priv;
+ CalendarModel *model;
g_return_val_if_fail (tasks != NULL, NULL);
g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
@@ -232,8 +295,10 @@ e_tasks_construct (ETasks *tasks)
gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
GTK_SIGNAL_FUNC (obj_removed_cb), tasks);
- e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->tasks_view),
- priv->client);
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+ g_assert (model != NULL);
+
+ calendar_model_set_cal_client (model, priv->client, CALOBJ_TYPE_TODO);
return GTK_WIDGET (tasks);
}
@@ -271,6 +336,15 @@ e_tasks_destroy (GtkObject *object)
tasks = E_TASKS (object);
priv = tasks->priv;
+ g_assert (priv->sexp != NULL);
+ g_free (priv->sexp);
+ priv->sexp = NULL;
+
+ if (priv->category) {
+ g_free (priv->category);
+ priv->category = NULL;
+ }
+
/* Save the ETable layout. */
config_filename = e_tasks_get_config_filename (tasks);
e_calendar_table_save_state (E_CALENDAR_TABLE (priv->tasks_view),
@@ -497,7 +571,6 @@ e_tasks_delete_selected (ETasks *tasks)
e_calendar_table_delete_selected (cal_table);
}
-
static void
e_tasks_on_filter_selected (GtkMenuShell *menu_shell,
ETasks *tasks)
@@ -518,16 +591,18 @@ e_tasks_on_filter_selected (GtkMenuShell *menu_shell,
cal_table = E_CALENDAR_TABLE (priv->tasks_view);
model = cal_table->model;
+ if (priv->category)
+ g_free (priv->category);
+
if (!strcmp (category, _("All"))) {
calendar_model_set_default_category (model, NULL);
- e_calendar_table_set_filter_func (cal_table, NULL, NULL,
- NULL);
+ priv->category = NULL;
} else {
calendar_model_set_default_category (model, category);
- e_calendar_table_set_filter_func (cal_table,
- e_calendar_table_filter_by_category,
- g_strdup (category), g_free);
+ priv->category = g_strdup (category);
}
+
+ update_query (tasks);
}
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 7068fbe1fe..9aaaefb396 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -40,8 +40,6 @@
#include <gal/e-paned/e-vpaned.h>
#include <cal-util/timeutil.h>
#include "widgets/menus/gal-view-menus.h"
-#include "widgets/misc/e-search-bar.h"
-#include "widgets/misc/e-filter-bar.h"
#include "dialogs/event-editor.h"
#include "e-calendar-table.h"
#include "e-day-view.h"
@@ -49,6 +47,7 @@
#include "evolution-calendar.h"
#include "gnome-cal.h"
#include "component-factory.h"
+#include "cal-search-bar.h"
#include "calendar-commands.h"
#include "calendar-config.h"
#include "calendar-view.h"
@@ -201,28 +200,6 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
object_class->destroy = gnome_calendar_destroy;
}
-static ESearchBarItem search_menu_items[] = {
- E_FILTERBAR_RESET,
- { NULL, -1 }
-};
-
-enum {
- SEARCH_ANY_FIELD_CONTAINS,
- SEARCH_SUMMARY_CONTAINS,
- SEARCH_DESCRIPTION_CONTAINS,
- SEARCH_COMMENT_CONTAINS,
- SEARCH_HAS_CATEGORY
-};
-
-static ESearchBarItem search_option_items[] = {
- { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS },
- { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS },
- { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS },
- { N_("Comment contains"), SEARCH_COMMENT_CONTAINS },
- { N_("Has category"), SEARCH_HAS_CATEGORY },
- { NULL, -1 }
-};
-
/**
* gnome_calendar_set_query:
* @gcal: A calendar.
@@ -264,88 +241,6 @@ gnome_calendar_set_query (GnomeCalendar *gcal, char *sexp)
}
}
-/* Sets the query string to be (contains? "field" "text") */
-static void
-set_query_contains (GnomeCalendar *gcal, const char *field, const char *text)
-{
- char *sexp;
-
- sexp = g_strdup_printf ("(contains? \"%s\" \"%s\")", field, text);
- gnome_calendar_set_query (gcal, sexp);
- g_free (sexp);
-}
-
-/* Callback used when the query string is changed in the search bar */
-static void
-search_bar_query_changed_cb (ESearchBar *search_bar, gpointer data)
-{
- GnomeCalendar *gcal;
- int item;
- char *text;
-
- gcal = GNOME_CALENDAR (data);
-
- item = e_search_bar_get_option_choice (search_bar);
- text = e_search_bar_get_text (search_bar);
-
- if (!text)
- return; /* This is an error in the UTF8 conversion, not an empty string! */
-
- switch (item) {
- case SEARCH_ANY_FIELD_CONTAINS:
- set_query_contains (gcal, "any", text);
- break;
-
- case SEARCH_SUMMARY_CONTAINS:
- set_query_contains (gcal, "summary", text);
- break;
-
- case SEARCH_DESCRIPTION_CONTAINS:
- set_query_contains (gcal, "description", text);
- break;
-
- case SEARCH_COMMENT_CONTAINS:
- set_query_contains (gcal, "comment", text);
- break;
-
- case SEARCH_HAS_CATEGORY: {
- char *sexp;
-
- sexp = g_strdup_printf ("(has-categories? \"%s\")", text);
- gnome_calendar_set_query (gcal, sexp);
- g_free (sexp);
- break;
- }
-
- default:
- g_assert_not_reached ();
- }
-
- g_free (text);
-}
-
-/* Callback used when a menu item is activated in the search bar */
-static void
-search_bar_menu_activated_cb (ESearchBar *search_bar, int item, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- switch (item) {
- case E_FILTERBAR_RESET_ID:
- gnome_calendar_set_query (gcal, "#t"); /* match all */
- /* FIXME: should we change the rest of the search bar so that
- * the user sees that he selected "show all" instead of some
- * type/text search combination?
- */
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
/* Returns the current time, for the ECalendarItem. */
static struct tm
get_current_time (ECalendarItem *calitem, gpointer data)
@@ -372,6 +267,16 @@ get_current_time (ECalendarItem *calitem, gpointer data)
return tmp_tm;
}
+/* Callback used when the sexp changes in the calendar search bar */
+static void
+search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+ gnome_calendar_set_query (gcal, sexp);
+}
+
static void
setup_widgets (GnomeCalendar *gcal)
{
@@ -382,11 +287,9 @@ setup_widgets (GnomeCalendar *gcal)
priv = gcal->priv;
- priv->search_bar = e_search_bar_new (search_menu_items, search_option_items);
- gtk_signal_connect (GTK_OBJECT (priv->search_bar), "query_changed",
- GTK_SIGNAL_FUNC (search_bar_query_changed_cb), gcal);
- gtk_signal_connect (GTK_OBJECT (priv->search_bar), "menu_activated",
- GTK_SIGNAL_FUNC (search_bar_menu_activated_cb), gcal);
+ priv->search_bar = cal_search_bar_new ();
+ gtk_signal_connect (GTK_OBJECT (priv->search_bar), "sexp_changed",
+ GTK_SIGNAL_FUNC (search_bar_sexp_changed_cb), gcal);
gtk_widget_show (priv->search_bar);
gtk_box_pack_start (GTK_BOX (gcal), priv->search_bar, FALSE, FALSE, 0);
@@ -1138,6 +1041,7 @@ gnome_calendar_construct (GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
GnomeCalendarViewType view_type;
+ CalendarModel *model;
g_return_val_if_fail (gcal != NULL, NULL);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
@@ -1177,8 +1081,10 @@ gnome_calendar_construct (GnomeCalendar *gcal)
gtk_signal_connect (GTK_OBJECT (priv->task_pad_client), "cal_opened",
GTK_SIGNAL_FUNC (cal_opened_cb), gcal);
- e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->todo),
- priv->task_pad_client);
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
+ g_assert (model != NULL);
+
+ calendar_model_set_cal_client (model, priv->task_pad_client, CALOBJ_TYPE_TODO);
/* Get the default view to show. */
view_type = calendar_config_get_default_view ();
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index 57212106c6..7c3add0dd1 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -34,6 +34,7 @@
#include <gal/util/e-util.h>
#include <ical.h>
#include <Evolution-Composer.h>
+#include "cal-util/cal-util.h"
#include "itip-utils.h"
#define GNOME_EVOLUTION_COMPOSER_OAFIID "OAFIID:GNOME_Evolution_Mail_Composer"