aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog37
-rw-r--r--calendar/gui/calendar-model.c164
-rw-r--r--calendar/gui/calendar-model.h8
-rw-r--r--calendar/gui/dialogs/task-editor-dialog.glade3
-rw-r--r--calendar/gui/dialogs/task-editor-dialog.glade.h26
-rw-r--r--calendar/gui/dialogs/task-editor.c1
-rw-r--r--calendar/gui/dialogs/task-editor.h1
-rw-r--r--calendar/gui/dialogs/task-page.glade3
-rw-r--r--calendar/gui/e-calendar-table.c326
-rw-r--r--calendar/gui/e-calendar-table.h23
-rw-r--r--calendar/gui/e-day-view.c4
-rw-r--r--calendar/gui/e-tasks.c268
-rw-r--r--calendar/gui/e-tasks.h4
-rw-r--r--calendar/gui/e-week-view.c1
-rw-r--r--calendar/gui/gnome-cal.c167
-rw-r--r--calendar/gui/tasks-control.c3
-rw-r--r--calendar/gui/widget-util.c7
17 files changed, 836 insertions, 210 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 779e6aa30b..95ed315159 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,40 @@
+2001-01-14 Damon Chaplin <damon@helixcode.com>
+
+ * gui/dialogs/task-editor.[hc]: moved #include
+ <cal-client/cal-client.h> to the .h file.
+
+ * gui/e-tasks.c: load & save the Tasks folders' ETable layout.
+ Added an option menu to filter tasks by category.
+
+ * gui/gnome-cal.c: use the "Tasks" folder for the TaskPad.
+ (We may make the actual tasks folder shown a per-calendar option.)
+
+ * gui/tasks-control.c (tasks_control_new_task_cmd): added support for
+ the New Task icon on the toolbar.
+
+ * gui/e-calendar-table.[hc]: we now use an ETableSubsetVariable model
+ to filter the tasks by a category. And tidied up a little.
+
+ * gui/calendar-model.[hc]: added way to get all the categories used by
+ the tasks, so we can show an option menu of them. Also a signal which
+ is emitted when they are changed.
+ Also allows a default category to be set, which is used to initialize
+ the 'click-to-add' row.
+ Also made sure the initialize_value()/get_value() functions don't
+ return NULL since that can cause a SEGV.
+
+ * gui/e-week-view.c:
+ * gui/e-day-view.c: set the "fill_color_rgba" arg of the EText items
+ to black since it doesn't seem to set up a default color properly.
+ Hopefully this fixes the bug on Solaris where the items appear with
+ strange colors.
+
+ * gui/widget-util.c (date_edit_new): use the calendar_config function
+ to set most of the options. It wasn't setting the 12/24 hour option
+ before.
+
+ * gui/dialogs/task-editor-dialog.glade: added "Undefined" priority.
+
2001-01-12 Ettore Perazzoli <ettore@helixcode.com>
* gui/component-factory.c (factory_fn): Pass NULL as the
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
index 7168f2714b..2fb4f89bf0 100644
--- a/calendar/gui/calendar-model.c
+++ b/calendar/gui/calendar-model.c
@@ -23,12 +23,6 @@
#include <config.h>
-#include <math.h>
-#include <ctype.h>
-#include <gnome.h>
-#include <cal-util/timeutil.h>
-#include "calendar-model.h"
-#include "calendar-commands.h"
/* We need this for strptime. */
#define _XOPEN_SOURCE 500
@@ -38,6 +32,14 @@
#undef _XOPEN_SOURCE
#undef __USE_XOPEN
+#include <math.h>
+#include <ctype.h>
+#include <gnome.h>
+#include <cal-util/timeutil.h>
+#include "calendar-model.h"
+#include "calendar-commands.h"
+
+
/* Private part of the ECalendarModel structure */
@@ -59,8 +61,24 @@ struct _CalendarModelPrivate {
/* HACK: so that ETable can do its stupid append_row() thing */
guint appending_row : 1;
+
+ /* The default category to use when creating new tasks, e.g. when the
+ filter is set to a certain category we use that category when
+ creating a new task. */
+ gchar *default_category;
+
+ /* A balanced tree of the categories used by all the tasks/events. */
+ GTree *categories;
+};
+
+enum {
+ CATEGORIES_CHANGED,
+
+ LAST_SIGNAL
};
+static gint calendar_model_signals [LAST_SIGNAL] = { 0 };
+
static void calendar_model_class_init (CalendarModelClass *class);
@@ -85,6 +103,9 @@ 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);
static ETableModelClass *parent_class;
@@ -134,6 +155,17 @@ calendar_model_class_init (CalendarModelClass *class)
parent_class = gtk_type_class (E_TABLE_MODEL_TYPE);
+ calendar_model_signals [CATEGORIES_CHANGED] =
+ gtk_signal_new ("categories-changed",
+ GTK_RUN_LAST, object_class->type,
+ GTK_SIGNAL_OFFSET (CalendarModelClass,
+ categories_changed),
+ gtk_signal_default_marshaller,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, calendar_model_signals,
+ LAST_SIGNAL);
+
object_class->destroy = calendar_model_destroy;
etm_class->column_count = calendar_model_column_count;
@@ -149,6 +181,8 @@ calendar_model_class_init (CalendarModelClass *class)
#if 0
etm_class->value_to_string = calendar_model_value_to_string;
#endif
+
+ class->categories_changed = NULL;
}
/* Object initialization function for the calendar table model */
@@ -163,6 +197,8 @@ calendar_model_init (CalendarModel *model)
priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *));
priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal);
priv->use_24_hour_format = TRUE;
+
+ priv->categories = g_tree_new ((GCompareFunc)strcmp);
}
/* Called from g_hash_table_foreach_remove(), frees a stored UID->index
@@ -232,6 +268,14 @@ calendar_model_destroy (GtkObject *object)
g_array_free (priv->objects, TRUE);
priv->objects = NULL;
+ g_free (priv->default_category);
+
+ /* We only need to free the first argument, the key, so g_free will do.
+ */
+ g_tree_traverse (priv->categories, (GTraverseFunc) g_free,
+ G_PRE_ORDER, NULL);
+ g_tree_destroy (priv->categories);
+
/* Free the private structure */
g_free (priv);
@@ -307,7 +351,7 @@ get_categories (CalComponent *comp)
cal_component_get_categories (comp, &categories);
- return g_strdup (categories);
+ return categories ? (char*) categories : "";
}
/* Returns a string based on the CLASSIFICATION property of a calendar component */
@@ -336,7 +380,7 @@ get_classification (CalComponent *comp)
default:
g_assert_not_reached ();
- return NULL;
+ return "";
}
}
@@ -1142,6 +1186,10 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val
switch (col) {
case CAL_COMPONENT_FIELD_CATEGORIES:
set_categories (comp, value);
+ if (calendar_model_collect_categories (model, comp)) {
+ gtk_signal_emit (GTK_OBJECT (model),
+ calendar_model_signals [CATEGORIES_CHANGED]);
+ }
break;
/* FIXME: CLASSIFICATION requires an option menu cell renderer */
@@ -1313,11 +1361,7 @@ calendar_model_duplicate_value (ETableModel *etm, int col, const void *value)
switch (col) {
case CAL_COMPONENT_FIELD_CATEGORIES:
- return dup_string (value);
-
case CAL_COMPONENT_FIELD_CLASSIFICATION:
- return (void *) value;
-
case CAL_COMPONENT_FIELD_COMPLETED:
case CAL_COMPONENT_FIELD_DTEND:
case CAL_COMPONENT_FIELD_DTSTART:
@@ -1326,11 +1370,7 @@ calendar_model_duplicate_value (ETableModel *etm, int col, const void *value)
case CAL_COMPONENT_FIELD_PERCENT:
case CAL_COMPONENT_FIELD_PRIORITY:
case CAL_COMPONENT_FIELD_SUMMARY:
- return dup_string (value);
-
case CAL_COMPONENT_FIELD_TRANSPARENCY:
- return (void *) value;
-
case CAL_COMPONENT_FIELD_URL:
return dup_string (value);
@@ -1402,15 +1442,17 @@ init_string (void)
static void *
calendar_model_initialize_value (ETableModel *etm, int col)
{
+ CalendarModel *model;
+
g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL);
+ model = CALENDAR_MODEL (etm);
+
switch (col) {
case CAL_COMPONENT_FIELD_CATEGORIES:
- return init_string ();
+ return g_strdup (model->priv->default_category ? model->priv->default_category : "");
case CAL_COMPONENT_FIELD_CLASSIFICATION:
- return NULL;
-
case CAL_COMPONENT_FIELD_COMPLETED:
case CAL_COMPONENT_FIELD_DTEND:
case CAL_COMPONENT_FIELD_DTSTART:
@@ -1419,11 +1461,7 @@ calendar_model_initialize_value (ETableModel *etm, int col)
case CAL_COMPONENT_FIELD_PERCENT:
case CAL_COMPONENT_FIELD_PRIORITY:
case CAL_COMPONENT_FIELD_SUMMARY:
- return init_string ();
-
case CAL_COMPONENT_FIELD_TRANSPARENCY:
- return NULL;
-
case CAL_COMPONENT_FIELD_URL:
return init_string ();
@@ -1506,8 +1544,10 @@ cal_loaded_cb (CalClient *client,
e_table_model_pre_change (E_TABLE_MODEL (model));
- if (status == CAL_CLIENT_LOAD_SUCCESS)
+ if (status == CAL_CLIENT_LOAD_SUCCESS) {
load_objects (model);
+ calendar_model_collect_all_categories (model);
+ }
e_table_model_changed (E_TABLE_MODEL (model));
}
@@ -1980,3 +2020,79 @@ calendar_model_set_use_24_hour_format (CalendarModel *model,
}
}
+
+void
+calendar_model_set_default_category (CalendarModel *model,
+ gchar *default_category)
+{
+ g_return_if_fail (IS_CALENDAR_MODEL (model));
+
+ g_free (model->priv->default_category);
+ model->priv->default_category = g_strdup (default_category);
+}
+
+
+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,
+ CalComponent *comp)
+{
+ CalendarModelPrivate *priv;
+ GSList *categories_list, *elem;
+ gboolean changed = FALSE;
+
+ priv = model->priv;
+
+ cal_component_get_categories_list (comp, &categories_list);
+
+ for (elem = categories_list; elem; elem = elem->next) {
+ if (!g_tree_lookup (priv->categories, elem->data)) {
+ /* We store a '1' as the data, just so we can use
+ g_tree_lookup() on it. Note that we don't free
+ the string since it is now part of the tree. */
+ g_tree_insert (priv->categories, elem->data,
+ GINT_TO_POINTER (1));
+ changed = TRUE;
+ } else {
+ g_free (elem->data);
+ }
+ }
+
+ g_slist_free (categories_list);
+
+ return changed;
+}
+
+
+GTree*
+calendar_model_get_categories (CalendarModel *model)
+{
+ g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL);
+
+ return model->priv->categories;
+}
diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h
index b8c08a5dbc..e4946393b6 100644
--- a/calendar/gui/calendar-model.h
+++ b/calendar/gui/calendar-model.h
@@ -51,6 +51,8 @@ struct _CalendarModel {
struct _CalendarModelClass {
ETableModelClass parent_class;
+
+ void (* categories_changed) (CalendarModel *model);
};
GtkType calendar_model_get_type (void);
@@ -73,6 +75,12 @@ gboolean calendar_model_get_use_24_hour_format (CalendarModel *model);
void calendar_model_set_use_24_hour_format (CalendarModel *model,
gboolean use_24_hour_format);
+GTree* calendar_model_get_categories (CalendarModel *model);
+
+void calendar_model_set_default_category (CalendarModel *model,
+ gchar *default_category);
+
+
END_GNOME_DECLS
diff --git a/calendar/gui/dialogs/task-editor-dialog.glade b/calendar/gui/dialogs/task-editor-dialog.glade
index 272fa48e55..ea4adcc5e2 100644
--- a/calendar/gui/dialogs/task-editor-dialog.glade
+++ b/calendar/gui/dialogs/task-editor-dialog.glade
@@ -401,6 +401,7 @@ Cancelled
<items>High
Normal
Low
+Undefined
</items>
<initial_choice>0</initial_choice>
<child>
@@ -484,6 +485,7 @@ Confidential
<class>GtkButton</class>
<name>contacts-button</name>
<can_focus>True</can_focus>
+ <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -522,6 +524,7 @@ Confidential
<class>GtkButton</class>
<name>categories-button</name>
<can_focus>True</can_focus>
+ <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
diff --git a/calendar/gui/dialogs/task-editor-dialog.glade.h b/calendar/gui/dialogs/task-editor-dialog.glade.h
index 20f7db3014..052fe951dd 100644
--- a/calendar/gui/dialogs/task-editor-dialog.glade.h
+++ b/calendar/gui/dialogs/task-editor-dialog.glade.h
@@ -10,22 +10,20 @@ gchar *s = N_("Sta_rt Date:");
gchar *s = N_("_Due Date:");
gchar *s = N_("% Comp_lete:");
gchar *s = N_("_Status:");
-gchar *s = N_("Not Started\n"
- "In Progress\n"
- "Completed\n"
- "Cancelled\n"
- "");
+gchar *s = N_("Not Started");
+gchar *s = N_("In Progress");
+gchar *s = N_("Completed");
+gchar *s = N_("Cancelled");
gchar *s = N_("_Priority:");
-gchar *s = N_("High\n"
- "Normal\n"
- "Low\n"
- "");
+gchar *s = N_("High");
+gchar *s = N_("Normal");
+gchar *s = N_("Low");
+gchar *s = N_("Undefined");
gchar *s = N_("C_lassification:");
-gchar *s = N_("None\n"
- "Public\n"
- "Private\n"
- "Confidential\n"
- "");
+gchar *s = N_("None");
+gchar *s = N_("Public");
+gchar *s = N_("Private");
+gchar *s = N_("Confidential");
gchar *s = N_("_Contacts...");
gchar *s = N_("Ca_tegories...");
gchar *s = N_("Task");
diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c
index 288244802e..cca8298713 100644
--- a/calendar/gui/dialogs/task-editor.c
+++ b/calendar/gui/dialogs/task-editor.c
@@ -36,7 +36,6 @@
#include <e-util/e-dialog-widgets.h>
#include <widgets/misc/e-dateedit.h>
#include <cal-util/timeutil.h>
-#include <cal-client/cal-client.h>
#include "task-editor.h"
#include "../calendar-config.h"
#include "../widget-util.h"
diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h
index a53d29c2a2..c74e979dff 100644
--- a/calendar/gui/dialogs/task-editor.h
+++ b/calendar/gui/dialogs/task-editor.h
@@ -27,6 +27,7 @@
#include <gtk/gtkobject.h>
#include <libgnome/gnome-defs.h>
#include <bonobo.h>
+#include <cal-client/cal-client.h>
BEGIN_GNOME_DECLS
diff --git a/calendar/gui/dialogs/task-page.glade b/calendar/gui/dialogs/task-page.glade
index 272fa48e55..ea4adcc5e2 100644
--- a/calendar/gui/dialogs/task-page.glade
+++ b/calendar/gui/dialogs/task-page.glade
@@ -401,6 +401,7 @@ Cancelled
<items>High
Normal
Low
+Undefined
</items>
<initial_choice>0</initial_choice>
<child>
@@ -484,6 +485,7 @@ Confidential
<class>GtkButton</class>
<name>contacts-button</name>
<can_focus>True</can_focus>
+ <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -522,6 +524,7 @@ Confidential
<class>GtkButton</class>
<name>categories-button</name>
<can_focus>True</can_focus>
+ <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index cd3aacc058..6ee22b9759 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -49,34 +49,45 @@
#include "check-filled.xpm"
-static void e_calendar_table_class_init (ECalendarTableClass *class);
-static void e_calendar_table_init (ECalendarTable *cal_table);
-static void e_calendar_table_destroy (GtkObject *object);
-
-static void e_calendar_table_on_double_click (ETable *table,
- gint row,
- gint col,
- GdkEvent *event,
- ECalendarTable *cal_table);
-static gint e_calendar_table_on_right_click (ETable *table,
- gint row,
- gint col,
- GdkEventButton *event,
- ECalendarTable *cal_table);
-static void e_calendar_table_on_open_task (GtkWidget *menuitem,
- gpointer data);
-static void e_calendar_table_on_mark_task_complete (GtkWidget *menuitem,
- gpointer data);
-static void e_calendar_table_on_delete_task (GtkWidget *menuitem,
- gpointer data);
-static gint e_calendar_table_on_key_press (ETable *table,
- gint row,
- gint col,
- GdkEventKey *event,
- ECalendarTable *cal_table);
-
-static void e_calendar_table_open_task (ECalendarTable *cal_table,
- gint row);
+static void e_calendar_table_class_init (ECalendarTableClass *class);
+static void e_calendar_table_init (ECalendarTable *cal_table);
+static void e_calendar_table_destroy (GtkObject *object);
+
+static void e_calendar_table_on_double_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ ECalendarTable *cal_table);
+static gint e_calendar_table_on_right_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEventButton *event,
+ ECalendarTable *cal_table);
+static void e_calendar_table_on_open_task (GtkWidget *menuitem,
+ gpointer data);
+static void e_calendar_table_on_mark_task_complete (GtkWidget *menuitem,
+ gpointer data);
+static void e_calendar_table_on_delete_task (GtkWidget *menuitem,
+ gpointer data);
+static gint e_calendar_table_on_key_press (ETable *table,
+ gint row,
+ gint col,
+ GdkEventKey *event,
+ ECalendarTable *cal_table);
+
+static void e_calendar_table_open_task (ECalendarTable *cal_table,
+ gint row);
+
+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_row_inserted (ETableModel *model,
+ gint row,
+ ECalendarTable *cal_table);
+static void e_calendar_table_on_row_deleted (ETableModel *model,
+ gint row,
+ ECalendarTable *cal_table);
+
/* The icons to represent the task. */
#define E_CALENDAR_MODEL_NUM_ICONS 4
@@ -155,61 +166,61 @@ static char *list [] = {
};
#endif
-#define E_CALENDAR_TABLE_SPEC \
- "<ETableSpecification click-to-add=\"true\" " \
- " _click-to-add-message=\"Click to add a task\" " \
- " draw-grid=\"true\">" \
- " <ETableColumn model_col= \"0\" _title=\"Categories\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"1\" _title=\"Classification\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"2\" _title=\"Completion Date\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"3\" _title=\"End Date\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"4\" _title=\"Start Date\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"5\" _title=\"Due Date\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"6\" _title=\"Geographical Position\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"7\" _title=\"Percent complete\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"8\" _title=\"Priority\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col= \"9\" _title=\"Summary\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"summary\" compare=\"string\"/>" \
- " <ETableColumn model_col=\"10\" _title=\"Transparency\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col=\"11\" _title=\"URL\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col=\"12\" _title=\"Alarms\" " \
- " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
- " cell=\"string\" compare=\"string\"/>" \
- " <ETableColumn model_col=\"13\" pixbuf=\"icon\" " \
- " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" " \
- " cell=\"icon\" compare=\"integer\"/>" \
- " <ETableColumn model_col=\"14\" pixbuf=\"complete\" " \
- " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" " \
- " cell=\"checkbox\" compare=\"integer\"/>" \
- " <ETableState>" \
- " <column source=\"13\"/>" \
- " <column source=\"14\"/>" \
- " <column source= \"9\"/>" \
- " <grouping></grouping>" \
- " </ETableState>" \
+#define E_CALENDAR_TABLE_SPEC \
+ "<ETableSpecification click-to-add=\"true\" " \
+ " _click-to-add-message=\"Click here to add a task\" " \
+ " draw-grid=\"true\">" \
+ " <ETableColumn model_col= \"0\" _title=\"Categories\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"1\" _title=\"Classification\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"2\" _title=\"Completion Date\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"3\" _title=\"End Date\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"4\" _title=\"Start Date\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"5\" _title=\"Due Date\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"6\" _title=\"Geographical Position\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"7\" _title=\"% Complete\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"8\" _title=\"Priority\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col= \"9\" _title=\"Summary\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col=\"10\" _title=\"Transparency\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col=\"11\" _title=\"URL\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col=\"12\" _title=\"Alarms\" " \
+ " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \
+ " cell=\"calstring\" compare=\"string\"/>" \
+ " <ETableColumn model_col=\"13\" pixbuf=\"icon\" " \
+ " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" "\
+ " cell=\"icon\" compare=\"integer\"/>" \
+ " <ETableColumn model_col=\"14\" pixbuf=\"complete\" " \
+ " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" "\
+ " cell=\"checkbox\" compare=\"integer\"/>" \
+ " <ETableState>" \
+ " <column source=\"13\"/>" \
+ " <column source=\"14\"/>" \
+ " <column source= \"9\"/>" \
+ " <grouping></grouping>" \
+ " </ETableState>" \
"</ETableSpecification>"
static void
@@ -217,7 +228,6 @@ e_calendar_table_init (ECalendarTable *cal_table)
{
GtkWidget *table;
ETable *e_table;
- ETableModel *model;
ECell *cell;
ETableExtras *extras;
gint i;
@@ -243,7 +253,17 @@ e_calendar_table_init (ECalendarTable *cal_table)
/* Create the model */
cal_table->model = calendar_model_new ();
- model = E_TABLE_MODEL (cal_table->model);
+ 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_row_inserted",
+ GTK_SIGNAL_FUNC (e_calendar_table_on_row_inserted),
+ cal_table);
+ gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_row_deleted",
+ GTK_SIGNAL_FUNC (e_calendar_table_on_row_deleted),
+ cal_table);
/* Create the header columns */
@@ -255,7 +275,7 @@ e_calendar_table_init (ECalendarTable *cal_table)
"bold_column", CAL_COMPONENT_FIELD_OVERDUE,
"color_column", CAL_COMPONENT_FIELD_COLOR,
NULL);
- e_table_extras_add_cell(extras, "summary", cell);
+ e_table_extras_add_cell (extras, "calstring", cell);
/* Create pixmaps */
@@ -275,8 +295,8 @@ e_calendar_table_init (ECalendarTable *cal_table)
/* Create the table */
- table = e_table_scrolled_new (model, extras, E_CALENDAR_TABLE_SPEC,
- NULL);
+ table = e_table_scrolled_new (cal_table->subset_model, extras,
+ E_CALENDAR_TABLE_SPEC, NULL);
gtk_object_unref (GTK_OBJECT (extras));
cal_table->etable = table;
@@ -345,6 +365,8 @@ e_calendar_table_on_double_click (ETable *table,
GdkEvent *event,
ECalendarTable *cal_table)
{
+ g_print ("In e_calendar_table_on_double_click\n");
+
e_calendar_table_open_task (cal_table, row);
}
@@ -500,9 +522,135 @@ void
e_calendar_table_save_state (ECalendarTable *cal_table,
gchar *filename)
{
-
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
e_table_save_state (e_table_scrolled_get_table(E_TABLE_SCROLLED (cal_table->etable)),
filename);
}
+
+
+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_row_inserted (ETableModel *model,
+ gint row,
+ ECalendarTable *cal_table)
+{
+ ETableSubsetVariable *etssv;
+ CalComponent *comp;
+ gboolean add_row = FALSE;
+
+ etssv = E_TABLE_SUBSET_VARIABLE (cal_table->subset_model);
+
+ if (cal_table->filter_func == NULL) {
+ add_row = TRUE;
+ } else {
+ comp = calendar_model_get_component (cal_table->model, row);
+
+ if ((*cal_table->filter_func) (cal_table, comp,
+ cal_table->filter_data))
+ add_row = TRUE;
+ }
+
+ if (add_row) {
+ e_table_subset_variable_increment (etssv, row, 1);
+ e_table_subset_variable_add (etssv, row);
+ }
+}
+
+
+static void
+e_calendar_table_on_row_deleted (ETableModel *model,
+ gint row,
+ 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);
+}
diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h
index 1265a80a72..6ca8a32515 100644
--- a/calendar/gui/e-calendar-table.h
+++ b/calendar/gui/e-calendar-table.h
@@ -53,16 +53,30 @@ typedef enum
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. */
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;
};
struct _ECalendarTableClass
@@ -85,6 +99,15 @@ 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
}
#endif /* __cplusplus */
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 1f10194cb0..1cb4b182ec 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -625,6 +625,7 @@ e_day_view_init (EDayView *day_view)
"max_lines", 1,
"editable", TRUE,
"draw_background", FALSE,
+ "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
NULL);
gnome_canvas_item_hide (day_view->drag_long_event_item);
@@ -733,6 +734,7 @@ e_day_view_init (EDayView *day_view)
"clip", TRUE,
"editable", TRUE,
"draw_background", FALSE,
+ "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
NULL);
gnome_canvas_item_hide (day_view->drag_item);
@@ -4194,6 +4196,7 @@ e_day_view_reshape_long_event (EDayView *day_view,
"editable", TRUE,
"use_ellipsis", TRUE,
"draw_background", FALSE,
+ "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
NULL);
gtk_signal_connect (GTK_OBJECT (event->canvas_item), "event",
GTK_SIGNAL_FUNC (e_day_view_on_text_item_event),
@@ -4552,6 +4555,7 @@ e_day_view_reshape_day_event (EDayView *day_view,
"clip", TRUE,
"use_ellipsis", TRUE,
"draw_background", FALSE,
+ "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
NULL);
gtk_signal_connect (GTK_OBJECT (event->canvas_item),
"event",
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index 552b1f54fc..29c067783a 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -26,8 +26,10 @@
#include <gnome.h>
#include <gal/util/e-util.h>
#include <gal/e-table/e-table-scrolled.h>
+#include "dialogs/task-editor.h"
#include "e-calendar-table.h"
#include "alarm-notify.h"
+#include "component-factory.h"
#include "e-tasks.h"
@@ -49,11 +51,15 @@ struct _ETasksPrivate {
/* Loading state; we can be loading or creating a calendar */
LoadState load_state;
- /* URI being loaded, NULL if we are not being loaded */
- char *loading_uri;
+ /* URI of the folder being shown. */
+ char *folder_uri;
/* The ECalendarTable showing the tasks. */
GtkWidget *tasks_view;
+
+ /* The option menu showing the categories, and the popup menu. */
+ GtkWidget *categories_option_menu;
+ GtkWidget *categories_menu;
};
@@ -66,8 +72,21 @@ static void cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpoint
static void obj_updated_cb (CalClient *client, const char *uid, gpointer data);
static void obj_removed_cb (CalClient *client, const char *uid, gpointer data);
+static char* e_tasks_get_config_filename (ETasks *tasks);
+
+static void e_tasks_on_filter_selected (GtkMenuShell *menu_shell,
+ ETasks *tasks);
+static void e_tasks_on_categories_changed (CalendarModel *model,
+ ETasks *tasks);
+static void e_tasks_rebuild_categories_menu (ETasks *tasks);
+static gint e_tasks_add_menu_item (gpointer key,
+ gpointer value,
+ gpointer data);
+
+
static GtkTableClass *parent_class;
+
E_MAKE_TYPE (e_tasks, "ETasks", ETasks,
e_tasks_class_init, e_tasks_init,
GTK_TYPE_TABLE)
@@ -112,21 +131,47 @@ e_tasks_init (ETasks *tasks)
"<grouping/>" \
"</ETableState>"
+
static void
setup_widgets (ETasks *tasks)
{
ETasksPrivate *priv;
ETable *etable;
+ GtkWidget *hbox, *menuitem, *categories_label;
priv = tasks->priv;
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox);
+ gtk_table_attach (GTK_TABLE (tasks), hbox, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ 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,
+ FALSE, FALSE, 0);
+
+ priv->categories_menu = gtk_menu_new ();
+
+ menuitem = gtk_menu_item_new_with_label (_("All"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (priv->categories_menu), menuitem);
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->categories_option_menu), priv->categories_menu);
+
+ categories_label = gtk_label_new (_("Category:"));
+ gtk_widget_show (categories_label);
+ gtk_box_pack_end (GTK_BOX (hbox), categories_label, FALSE, FALSE, 4);
+
+
priv->tasks_view = e_calendar_table_new ();
etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable));
e_table_set_state (etable, E_TASKS_TABLE_DEFAULT_STATE);
- gtk_table_attach (GTK_TABLE (tasks), priv->tasks_view, 0, 1, 0, 1,
+ gtk_table_attach (GTK_TABLE (tasks), priv->tasks_view, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (priv->tasks_view);
+ gtk_signal_connect (GTK_OBJECT (E_CALENDAR_TABLE (priv->tasks_view)->model), "categories-changed", GTK_SIGNAL_FUNC (e_tasks_on_categories_changed), tasks);
}
@@ -182,6 +227,7 @@ e_tasks_destroy (GtkObject *object)
{
ETasks *tasks;
ETasksPrivate *priv;
+ char *config_filename;
g_return_if_fail (object != NULL);
g_return_if_fail (E_IS_TASKS (object));
@@ -189,19 +235,17 @@ e_tasks_destroy (GtkObject *object)
tasks = E_TASKS (object);
priv = tasks->priv;
- /* Save the ETable layout. FIXME: Need to save in a per-folder config
- file like the mail folders use. */
-#if 0
- filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir);
- e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename);
- g_free (filename);
-#endif
+ /* Save the ETable layout. */
+ config_filename = e_tasks_get_config_filename (tasks);
+ e_calendar_table_save_state (E_CALENDAR_TABLE (priv->tasks_view),
+ config_filename);
+ g_free (config_filename);
priv->load_state = LOAD_STATE_NOT_LOADED;
- if (priv->loading_uri) {
- g_free (priv->loading_uri);
- priv->loading_uri = NULL;
+ if (priv->folder_uri) {
+ g_free (priv->folder_uri);
+ priv->folder_uri = NULL;
}
if (priv->client) {
@@ -224,6 +268,7 @@ e_tasks_open (ETasks *tasks,
ETasksOpenMode gcom)
{
ETasksPrivate *priv;
+ char *config_filename;
g_return_val_if_fail (tasks != NULL, FALSE);
g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
@@ -233,9 +278,9 @@ e_tasks_open (ETasks *tasks,
g_return_val_if_fail (priv->load_state == LOAD_STATE_NOT_LOADED,
FALSE);
- g_assert (priv->loading_uri == NULL);
+ g_assert (priv->folder_uri == NULL);
- priv->loading_uri = g_strdup (file);
+ priv->folder_uri = g_strdup (file);
if (gcom == E_TASKS_OPEN)
priv->load_state = LOAD_STATE_WAIT_LOAD;
@@ -246,10 +291,16 @@ e_tasks_open (ETasks *tasks,
return FALSE;
}
+ config_filename = e_tasks_get_config_filename (tasks);
+ e_calendar_table_load_state (E_CALENDAR_TABLE (priv->tasks_view),
+ config_filename);
+ g_free (config_filename);
+
+
if (!cal_client_load_calendar (priv->client, file)) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- g_free (priv->loading_uri);
- priv->loading_uri = NULL;
+ g_free (priv->folder_uri);
+ priv->folder_uri = NULL;
g_message ("e_tasks_open(): Could not issue the request");
return FALSE;
@@ -263,7 +314,7 @@ e_tasks_open (ETasks *tasks,
* the cal_loaded signal from the client is invoked.
*/
static void
-initial_load (ETasks *tasks)
+initial_load (ETasks *tasks)
{
ETasksPrivate *priv;
@@ -274,7 +325,8 @@ initial_load (ETasks *tasks)
/* Displays an error to indicate that loading a calendar failed */
static void
-load_error (ETasks *tasks, const char *uri)
+load_error (ETasks *tasks,
+ const char *uri)
{
char *msg;
@@ -285,7 +337,8 @@ load_error (ETasks *tasks, const char *uri)
/* Displays an error to indicate that creating a calendar failed */
static void
-create_error (ETasks *tasks, const char *uri)
+create_error (ETasks *tasks,
+ const char *uri)
{
char *msg;
@@ -297,7 +350,8 @@ create_error (ETasks *tasks, const char *uri)
/* Displays an error to indicate that the specified URI method is not supported */
static void
-method_error (ETasks *tasks, const char *uri)
+method_error (ETasks *tasks,
+ const char *uri)
{
char *msg;
@@ -308,7 +362,9 @@ method_error (ETasks *tasks, const char *uri)
/* Callback from the calendar client when a calendar is loaded */
static void
-cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
+cal_loaded_cb (CalClient *client,
+ CalClientLoadStatus status,
+ gpointer data)
{
ETasks *tasks;
ETasksPrivate *priv;
@@ -319,7 +375,7 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
g_assert (priv->load_state != LOAD_STATE_NOT_LOADED
&& priv->load_state != LOAD_STATE_LOADED);
- g_assert (priv->loading_uri != NULL);
+ g_assert (priv->folder_uri != NULL);
free_uri = TRUE;
@@ -330,10 +386,10 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
initial_load (tasks);
} else if (status == CAL_CLIENT_LOAD_ERROR) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- load_error (tasks, priv->loading_uri);
+ load_error (tasks, priv->folder_uri);
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (tasks, priv->loading_uri);
+ method_error (tasks, priv->folder_uri);
} else
g_assert_not_reached ();
@@ -348,14 +404,14 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
free_uri = FALSE;
if (!cal_client_create_calendar (priv->client,
- priv->loading_uri)) {
+ priv->folder_uri)) {
priv->load_state = LOAD_STATE_NOT_LOADED;
free_uri = TRUE;
g_message ("cal_loaded_cb(): Could not issue the create request");
}
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (tasks, priv->loading_uri);
+ method_error (tasks, priv->folder_uri);
} else
g_assert_not_reached ();
@@ -367,7 +423,7 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
initial_load (tasks);
} else if (status == CAL_CLIENT_LOAD_ERROR) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- create_error (tasks, priv->loading_uri);
+ create_error (tasks, priv->folder_uri);
} else if (status == CAL_CLIENT_LOAD_IN_USE) {
/* Someone created the URI while we were issuing the
* create request, so we just try to reload.
@@ -376,14 +432,14 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
free_uri = FALSE;
if (!cal_client_load_calendar (priv->client,
- priv->loading_uri)) {
+ priv->folder_uri)) {
priv->load_state = LOAD_STATE_NOT_LOADED;
free_uri = TRUE;
g_message ("cal_loaded_cb(): Could not issue the load request");
}
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (tasks, priv->loading_uri);
+ method_error (tasks, priv->folder_uri);
} else
g_assert_not_reached ();
@@ -392,17 +448,14 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
default:
g_assert_not_reached ();
}
-
- if (free_uri) {
- g_free (priv->loading_uri);
- priv->loading_uri = NULL;
- }
}
/* Callback from the calendar client when an object is updated */
static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
+obj_updated_cb (CalClient *client,
+ const char *uid,
+ gpointer data)
{
ETasks *tasks;
ETasksPrivate *priv;
@@ -416,7 +469,9 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
/* Callback from the calendar client when an object is removed */
static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
+obj_removed_cb (CalClient *client,
+ const char *uid,
+ gpointer data)
{
ETasks *tasks;
ETasksPrivate *priv;
@@ -428,6 +483,27 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
}
+static char*
+e_tasks_get_config_filename (ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ char *url, *filename;
+
+ priv = tasks->priv;
+
+ url = g_strdup (priv->folder_uri);
+
+ /* This turns all funny characters into '_', in the string itself. */
+ e_filename_make_safe (url);
+
+ filename = g_strdup_printf ("%s/config/et-header-%s", evolution_dir,
+ url);
+ g_free (url);
+
+ return filename;
+}
+
+
/**
* e_tasks_get_cal_client:
* @tasks: An #ETasks.
@@ -437,14 +513,128 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
* Return value: A calendar client interface object.
**/
CalClient *
-e_tasks_get_cal_client (ETasks *tasks)
+e_tasks_get_cal_client (ETasks *tasks)
{
ETasksPrivate *priv;
- g_return_val_if_fail (tasks != NULL, NULL);
g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
priv = tasks->priv;
return priv->client;
}
+
+
+void
+e_tasks_new_task (ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ TaskEditor *tedit;
+ CalComponent *comp;
+
+ g_return_if_fail (E_IS_TASKS (tasks));
+
+ priv = tasks->priv;
+
+ tedit = task_editor_new ();
+ task_editor_set_cal_client (tedit, priv->client);
+
+ comp = cal_component_new ();
+ cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
+
+ task_editor_set_todo_object (tedit, comp);
+
+ gtk_object_unref (GTK_OBJECT (comp));
+}
+
+
+static void
+e_tasks_on_filter_selected (GtkMenuShell *menu_shell,
+ ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ ECalendarTable *cal_table;
+ CalendarModel *model;
+ GtkWidget *label;
+ char *category;
+
+ g_return_if_fail (E_IS_TASKS (tasks));
+
+ priv = tasks->priv;
+
+ label = GTK_BIN (priv->categories_option_menu)->child;
+ gtk_label_get (GTK_LABEL (label), &category);
+
+ cal_table = E_CALENDAR_TABLE (priv->tasks_view);
+ model = cal_table->model;
+
+ g_print ("!#!#!#!#!# filter selected: %s\n", category);
+
+ if (!strcmp (category, _("All"))) {
+ calendar_model_set_default_category (model, NULL);
+ e_calendar_table_set_filter_func (cal_table, NULL, NULL,
+ 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);
+ }
+}
+
+
+static void
+e_tasks_on_categories_changed (CalendarModel *model,
+ ETasks *tasks)
+{
+ g_print ("In e_tasks_on_categories_changed\n");
+
+ e_tasks_rebuild_categories_menu (tasks);
+}
+
+
+static void
+e_tasks_rebuild_categories_menu (ETasks *tasks)
+{
+ ETasksPrivate *priv;
+ CalendarModel *model;
+ GTree *categories;
+ GtkWidget *menuitem;
+
+ priv = tasks->priv;
+
+ priv->categories_menu = gtk_menu_new ();
+
+ menuitem = gtk_menu_item_new_with_label (_("All"));
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (priv->categories_menu), menuitem);
+
+ model = E_CALENDAR_TABLE (priv->tasks_view)->model;
+ categories = calendar_model_get_categories (model);
+ g_return_if_fail (categories != NULL);
+
+ g_tree_traverse (categories, e_tasks_add_menu_item, G_IN_ORDER,
+ priv->categories_menu);
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->categories_option_menu), priv->categories_menu);
+
+ gtk_signal_connect (GTK_OBJECT (priv->categories_menu), "deactivate",
+ GTK_SIGNAL_FUNC (e_tasks_on_filter_selected),
+ tasks);
+}
+
+
+static gint
+e_tasks_add_menu_item (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label ((char*) key);
+ gtk_widget_show (menuitem);
+ gtk_menu_append (GTK_MENU (data), menuitem);
+
+ return FALSE;
+}
+
diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h
index 86dbb1ff56..a777c32375 100644
--- a/calendar/gui/e-tasks.h
+++ b/calendar/gui/e-tasks.h
@@ -65,7 +65,9 @@ gboolean e_tasks_open (ETasks *tasks,
char *file,
ETasksOpenMode gcom);
-CalClient *e_tasks_get_cal_client (ETasks *tasks);
+CalClient *e_tasks_get_cal_client (ETasks *tasks);
+
+void e_tasks_new_task (ETasks *tasks);
#endif /* _E_TASKS_H_ */
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index c9344c88f4..0b7743e970 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -2478,6 +2478,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
"editable", TRUE,
"text", text.value ? text.value : "",
"use_ellipsis", TRUE,
+ "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0),
NULL);
gtk_signal_connect (GTK_OBJECT (span->text_item), "event",
GTK_SIGNAL_FUNC (e_week_view_on_text_item_event),
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 5daf6c9b55..fafd31d583 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -51,6 +51,11 @@ typedef enum {
/* Private part of the GnomeCalendar structure */
struct _GnomeCalendarPrivate {
+
+ /*
+ * The Calendar Folder.
+ */
+
/* The calendar client object we monitor */
CalClient *client;
@@ -60,6 +65,21 @@ struct _GnomeCalendarPrivate {
/* URI being loaded, NULL if we are not being loaded */
char *loading_uri;
+ /*
+ * The TaskPad Folder.
+ */
+
+ /* The calendar client object we monitor */
+ CalClient *task_pad_client;
+
+ /* Loading state; we can be loading or creating a calendar */
+ LoadState task_pad_load_state;
+
+ /* URI being loaded, NULL if we are not being loaded */
+ char *task_pad_loading_uri;
+
+
+
/* Mapping of component UIDs to event editors */
GHashTable *object_editor_hash;
@@ -289,6 +309,7 @@ gnome_calendar_init (GnomeCalendar *gcal)
gcal->priv = priv;
priv->load_state = LOAD_STATE_NOT_LOADED;
+ priv->task_pad_load_state = LOAD_STATE_NOT_LOADED;
priv->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal);
@@ -330,18 +351,30 @@ gnome_calendar_destroy (GtkObject *object)
g_free (filename);
priv->load_state = LOAD_STATE_NOT_LOADED;
+ priv->task_pad_load_state = LOAD_STATE_NOT_LOADED;
if (priv->loading_uri) {
g_free (priv->loading_uri);
priv->loading_uri = NULL;
}
+ if (priv->task_pad_loading_uri) {
+ g_free (priv->task_pad_loading_uri);
+ priv->task_pad_loading_uri = NULL;
+ }
+
if (priv->client) {
alarm_notify_remove_client (priv->client);
gtk_object_unref (GTK_OBJECT (priv->client));
priv->client = NULL;
}
+ if (priv->task_pad_client) {
+ alarm_notify_remove_client (priv->task_pad_client);
+ gtk_object_unref (GTK_OBJECT (priv->task_pad_client));
+ priv->task_pad_client = NULL;
+ }
+
priv->in_destroy = TRUE;
g_hash_table_foreach (priv->object_editor_hash, destroy_editor_cb, NULL);
g_hash_table_destroy (priv->object_editor_hash);
@@ -673,7 +706,7 @@ load_error (GnomeCalendar *gcal, const char *uri)
{
char *msg;
- msg = g_strdup_printf (_("Could not load the calendar in `%s'"), uri);
+ msg = g_strdup_printf (_("Could not load the folder in `%s'"), uri);
gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
g_free (msg);
}
@@ -684,7 +717,7 @@ create_error (GnomeCalendar *gcal, const char *uri)
{
char *msg;
- msg = g_strdup_printf (_("Could not create a calendar in `%s'"), uri);
+ msg = g_strdup_printf (_("Could not create a folder in `%s'"), uri);
gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
g_free (msg);
}
@@ -706,27 +739,43 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
{
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
- gboolean free_uri;
+ gboolean free_uri, is_calendar = FALSE;
+ LoadState *load_state;
+ char **loading_uri;
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
- g_assert (priv->load_state != LOAD_STATE_NOT_LOADED && priv->load_state != LOAD_STATE_LOADED);
- g_assert (priv->loading_uri != NULL);
+ if (client == priv->client) {
+ is_calendar = TRUE;
+ load_state = &priv->load_state;
+ loading_uri = &priv->loading_uri;
+ } else if (client == priv->task_pad_client) {
+ load_state = &priv->task_pad_load_state;
+ loading_uri = &priv->task_pad_loading_uri;
+ } else {
+ g_assert_not_reached ();
+ return;
+ }
+
+ g_assert (*load_state != LOAD_STATE_NOT_LOADED
+ && *load_state != LOAD_STATE_LOADED);
+ g_assert (*loading_uri != NULL);
free_uri = TRUE;
- switch (priv->load_state) {
+ switch (*load_state) {
case LOAD_STATE_WAIT_LOAD:
if (status == CAL_CLIENT_LOAD_SUCCESS) {
- priv->load_state = LOAD_STATE_LOADED;
- initial_load (gcal);
+ *load_state = LOAD_STATE_LOADED;
+ if (is_calendar)
+ initial_load (gcal);
} else if (status == CAL_CLIENT_LOAD_ERROR) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
- load_error (gcal, priv->loading_uri);
+ *load_state = LOAD_STATE_NOT_LOADED;
+ load_error (gcal, *loading_uri);
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (gcal, priv->loading_uri);
+ *load_state = LOAD_STATE_NOT_LOADED;
+ method_error (gcal, *loading_uri);
} else
g_assert_not_reached ();
@@ -734,20 +783,22 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
case LOAD_STATE_WAIT_LOAD_BEFORE_CREATE:
if (status == CAL_CLIENT_LOAD_SUCCESS) {
- priv->load_state = LOAD_STATE_LOADED;
- initial_load (gcal);
+ *load_state = LOAD_STATE_LOADED;
+ if (is_calendar)
+ initial_load (gcal);
} else if (status == CAL_CLIENT_LOAD_ERROR) {
- priv->load_state = LOAD_STATE_WAIT_CREATE;
+ *load_state = LOAD_STATE_WAIT_CREATE;
free_uri = FALSE;
- if (!cal_client_create_calendar (priv->client, priv->loading_uri)) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
+ if (!cal_client_create_calendar (client,
+ *loading_uri)) {
+ *load_state = LOAD_STATE_NOT_LOADED;
free_uri = TRUE;
g_message ("cal_loaded_cb(): Could not issue the create request");
}
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (gcal, priv->loading_uri);
+ *load_state = LOAD_STATE_NOT_LOADED;
+ method_error (gcal, *loading_uri);
} else
g_assert_not_reached ();
@@ -755,26 +806,28 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
case LOAD_STATE_WAIT_CREATE:
if (status == CAL_CLIENT_LOAD_SUCCESS) {
- priv->load_state = LOAD_STATE_LOADED;
- initial_load (gcal);
+ *load_state = LOAD_STATE_LOADED;
+ if (is_calendar)
+ initial_load (gcal);
} else if (status == CAL_CLIENT_LOAD_ERROR) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
- create_error (gcal, priv->loading_uri);
+ *load_state = LOAD_STATE_NOT_LOADED;
+ create_error (gcal, *loading_uri);
} else if (status == CAL_CLIENT_LOAD_IN_USE) {
/* Someone created the URI while we were issuing the
* create request, so we just try to reload.
*/
- priv->load_state = LOAD_STATE_WAIT_LOAD;
+ *load_state = LOAD_STATE_WAIT_LOAD;
free_uri = FALSE;
- if (!cal_client_load_calendar (priv->client, priv->loading_uri)) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
+ if (!cal_client_load_calendar (client,
+ *loading_uri)) {
+ *load_state = LOAD_STATE_NOT_LOADED;
free_uri = TRUE;
g_message ("cal_loaded_cb(): Could not issue the load request");
}
} else if (status == CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED) {
- priv->load_state = LOAD_STATE_NOT_LOADED;
- method_error (gcal, priv->loading_uri);
+ *load_state = LOAD_STATE_NOT_LOADED;
+ method_error (gcal, *loading_uri);
} else
g_assert_not_reached ();
@@ -785,8 +838,8 @@ cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data)
}
if (free_uri) {
- g_free (priv->loading_uri);
- priv->loading_uri = NULL;
+ g_free (*loading_uri);
+ *loading_uri = NULL;
}
}
@@ -816,7 +869,6 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
tag_calendar_by_client (priv->date_navigator, priv->client);
}
-
GtkWidget *
gnome_calendar_construct (GnomeCalendar *gcal)
{
@@ -829,6 +881,9 @@ gnome_calendar_construct (GnomeCalendar *gcal)
priv = gcal->priv;
+ /*
+ * Calendar Folder Client.
+ */
priv->client = cal_client_new ();
if (!priv->client)
return NULL;
@@ -842,13 +897,32 @@ gnome_calendar_construct (GnomeCalendar *gcal)
alarm_notify_add_client (priv->client);
- e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->todo), priv->client);
+ e_day_view_set_cal_client (E_DAY_VIEW (priv->day_view),
+ priv->client);
+ e_day_view_set_cal_client (E_DAY_VIEW (priv->work_week_view),
+ priv->client);
+ e_week_view_set_cal_client (E_WEEK_VIEW (priv->week_view),
+ priv->client);
+ e_week_view_set_cal_client (E_WEEK_VIEW (priv->month_view),
+ priv->client);
+
+ /*
+ * TaskPad Folder Client.
+ */
+ priv->task_pad_client = cal_client_new ();
+ if (!priv->task_pad_client)
+ return NULL;
- e_day_view_set_cal_client (E_DAY_VIEW (priv->day_view), priv->client);
- e_day_view_set_cal_client (E_DAY_VIEW (priv->work_week_view), priv->client);
- e_week_view_set_cal_client (E_WEEK_VIEW (priv->week_view), priv->client);
- e_week_view_set_cal_client (E_WEEK_VIEW (priv->month_view), priv->client);
+ gtk_signal_connect (GTK_OBJECT (priv->task_pad_client), "cal_loaded",
+ GTK_SIGNAL_FUNC (cal_loaded_cb), gcal);
+ alarm_notify_add_client (priv->task_pad_client);
+
+ e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->todo),
+ priv->task_pad_client);
+
+
+ /* Get the default view to show. */
view = calendar_config_get_default_view ();
switch (view) {
case 1:
@@ -911,6 +985,7 @@ gboolean
gnome_calendar_open (GnomeCalendar *gcal, char *file, GnomeCalendarOpenMode gcom)
{
GnomeCalendarPrivate *priv;
+ LoadState initial_load_state;
g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
@@ -918,8 +993,10 @@ gnome_calendar_open (GnomeCalendar *gcal, char *file, GnomeCalendarOpenMode gcom
priv = gcal->priv;
g_return_val_if_fail (priv->load_state == LOAD_STATE_NOT_LOADED, FALSE);
+ g_return_val_if_fail (priv->task_pad_load_state == LOAD_STATE_NOT_LOADED, FALSE);
g_assert (priv->loading_uri == NULL);
+ g_assert (priv->task_pad_loading_uri == NULL);
priv->loading_uri = g_strdup (file);
@@ -932,6 +1009,8 @@ gnome_calendar_open (GnomeCalendar *gcal, char *file, GnomeCalendarOpenMode gcom
return FALSE;
}
+ initial_load_state = priv->load_state;
+
if (!cal_client_load_calendar (priv->client, file)) {
priv->load_state = LOAD_STATE_NOT_LOADED;
g_free (priv->loading_uri);
@@ -941,6 +1020,22 @@ gnome_calendar_open (GnomeCalendar *gcal, char *file, GnomeCalendarOpenMode gcom
return FALSE;
}
+ /* Open the appropriate Tasks folder to show in the TaskPad.
+ Currently we just show the folder named "Tasks", but it will be
+ a per-calendar option in future. */
+ priv->task_pad_loading_uri = g_strdup_printf ("%s/local/Tasks/tasks.ics", evolution_dir);
+ priv->task_pad_load_state = initial_load_state;
+
+ if (!cal_client_load_calendar (priv->task_pad_client,
+ priv->task_pad_loading_uri)) {
+ priv->task_pad_load_state = LOAD_STATE_NOT_LOADED;
+ g_free (priv->task_pad_loading_uri);
+ priv->task_pad_loading_uri = NULL;
+
+ g_message ("gnome_calendar_open(): Could not issue the request");
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c
index ba2b699dd2..7721b0d08a 100644
--- a/calendar/gui/tasks-control.c
+++ b/calendar/gui/tasks-control.c
@@ -219,7 +219,8 @@ tasks_control_new_task_cmd (BonoboUIComponent *uic,
gpointer data,
const char *path)
{
- g_print ("Create new task\n");
+ ETasks *tasks = data;
+ e_tasks_new_task (tasks);
}
diff --git a/calendar/gui/widget-util.c b/calendar/gui/widget-util.c
index 9d271d29f3..d6034ce8b0 100644
--- a/calendar/gui/widget-util.c
+++ b/calendar/gui/widget-util.c
@@ -47,11 +47,8 @@ date_edit_new (gboolean show_date, gboolean show_time)
e_date_edit_set_show_date (dedit, show_date);
e_date_edit_set_show_time (dedit, show_time);
- e_date_edit_set_time_popup_range (dedit,
- calendar_config_get_day_start_hour (),
- calendar_config_get_day_end_hour ());
- e_date_edit_set_week_start_day (dedit, (calendar_config_get_week_start_day () + 6) % 7);
- e_date_edit_set_show_week_numbers (dedit, calendar_config_get_dnav_show_week_no ());
+
+ calendar_config_configure_e_date_edit (dedit);
return GTK_WIDGET (dedit);
}