aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--art/ChangeLog4
-rw-r--r--art/Makefile.am1
-rw-r--r--art/listview.xpm34
-rw-r--r--calendar/ChangeLog40
-rw-r--r--calendar/gui/Makefile.am7
-rw-r--r--calendar/gui/calendar-commands.c23
-rw-r--r--calendar/gui/calendar-view-factory.c6
-rw-r--r--calendar/gui/control-factory.c3
-rw-r--r--calendar/gui/e-cal-list-view.c526
-rw-r--r--calendar/gui/e-cal-list-view.etspec17
-rw-r--r--calendar/gui/e-cal-list-view.h98
-rw-r--r--calendar/gui/e-cal-model.c28
-rw-r--r--calendar/gui/gnome-cal.c65
-rw-r--r--calendar/gui/gnome-cal.h3
-rw-r--r--ui/ChangeLog4
-rw-r--r--ui/evolution-calendar.xml2
16 files changed, 850 insertions, 11 deletions
diff --git a/art/ChangeLog b/art/ChangeLog
index 5c12dae5f5..9ea16ee481 100644
--- a/art/ChangeLog
+++ b/art/ChangeLog
@@ -1,3 +1,7 @@
+2003-10-10 Hans Petter Jansson <hpj@ximian.com>
+
+ * listview.xpm: Add calendar list view icon.
+
2003-09-24 Ettore Perazzoli <ettore@ximian.com>
* about-box.png: More artwork from Jakub.
diff --git a/art/Makefile.am b/art/Makefile.am
index 88f9a25442..bd96fd0759 100644
--- a/art/Makefile.am
+++ b/art/Makefile.am
@@ -183,6 +183,7 @@ buttons_DATA = \
fetch-mail.png \
forward.png \
goto-24.png \
+ listview.xpm \
monthview.xpm \
move-message.png \
next-message.png \
diff --git a/art/listview.xpm b/art/listview.xpm
new file mode 100644
index 0000000000..56d4a7fd64
--- /dev/null
+++ b/art/listview.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char * listview_xpm[] = {
+"24 24 7 1",
+" c None",
+". c #000000",
+"+ c #D8D8D4",
+"@ c #919191",
+"# c #666666",
+"$ c #FFFFFF",
+"% c #F2F1ED",
+"....................... ",
+".++++++++++++++++++++@. ",
+".+@@@@@@@@@@@@@@@@@@@#. ",
+".+@@@@@@@@@@@@@@@@@@@#. ",
+".+@@@@@@@@@@@@@@@@@@@#. ",
+".@####################. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".@@@@@@@@@@@@@@@@@@@@#. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".@@@@@@@@@@@@@@@@@@@@#. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".@@@@@@@@@@@@@@@@@@@@#. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".$%%%%%%%%%%%%%%%%%%%@. ",
+".+@@@@@@@@@@@@@@@@@@@#. ",
+"....................... ",
+" "};
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 90d0de176d..ed6b121560 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,43 @@
+2003-10-10 Hans Petter Jansson <hpj@ximian.com>
+
+ * gui/Makefile.am (etspec_DATA): Add e-cal-list-view.etspec.
+ (libevolution_calendar_la_SOURCES): Add e-cal-list-view.[ch].
+
+ * gui/calendar-commands.c (show_list_view_clicked): Implement.
+ (calendar_get_text_for_folder_bar_label): Add case for list view.
+ Use month case and tweak it so it doesn't show "%d - %d" if the
+ time span contains only one day.
+ (verbs): Add list view.
+ (pixmaps): Add list view.
+
+ * gui/calendar-view-factory.c (calendar_view_factory_get_title):
+ Add list view case.
+ (calendar_view_factory_get_type_code): Add list view case.
+
+ * gui/control-factory.c (get_prop): Add list view case.
+
+ * gui/e-cal-model.c (get_classification): Fix to conform to updated
+ libical.
+ (ecm_set_value_at): Add missing break statements.
+ (ecm_get_color_for_component): Add braces for clarity.
+
+ * gui/gnome-cal.c (gnome_calendar_get_current_view_widget): Add
+ list view case.
+ (get_focus_location): Add list view case.
+ (connect_list_view_focus): Implement.
+ (setup_widgets): Set up list view.
+ (gnome_calendar_direction): Add list view case.
+ (set_view): Add list view case.
+ (gnome_calendar_setup_view_menus): Add list view factory.
+ (gnome_calendar_construct): Account for list view.
+ (gnome_calendar_update_config_settings): Account for list view.
+ (get_days_shown): Implement list view case.
+
+ * gui/gnome-cal.h (GnomeCalendarViewType): Add list view.
+
+ * gui/e-cal-list-view.[ch]: Implement ECalListView, subclassing
+ ECalView.
+
2003-10-09 Jeffrey Stedfast <fejj@ximian.com>
* cal-client/Makefile.am: INCLUDE path fixes for changes made to
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index f5e80f3de7..3ee9362b65 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -70,7 +70,10 @@ glade_DATA = \
e-itip-control.glade \
goto-dialog.glade
-etspec_DATA = e-calendar-table.etspec e-meeting-time-sel.etspec
+etspec_DATA = \
+ e-calendar-table.etspec \
+ e-meeting-time-sel.etspec \
+ e-cal-list-view.etspec
libevolution_calendar_la_SOURCES = \
$(IDL_GENERATED) \
@@ -104,6 +107,8 @@ libevolution_calendar_la_SOURCES = \
e-cal-model.h \
e-cal-view.c \
e-cal-view.h \
+ e-cal-list-view.c \
+ e-cal-list-view.h \
e-calendar-table.h \
e-calendar-table.c \
e-cell-date-edit-text.h \
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index 38206a66b9..c0d1b3c589 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -250,6 +250,16 @@ show_month_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path
}
+static void
+show_list_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ gnome_calendar_set_view (gcal, GNOME_CAL_LIST_VIEW, FALSE, TRUE);
+}
+
static void
cut_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
@@ -490,13 +500,18 @@ calendar_get_text_for_folder_bar_label (GnomeCalendar *gcal)
}
break;
case GNOME_CAL_MONTH_VIEW:
+ case GNOME_CAL_LIST_VIEW:
if (start_tm.tm_year == end_tm.tm_year) {
if (start_tm.tm_mon == end_tm.tm_mon) {
- e_utf8_strftime (buffer, sizeof (buffer),
- "%d", &start_tm);
+ if (start_tm.tm_mday == end_tm.tm_mday) {
+ buffer [0] = '\0';
+ } else {
+ e_utf8_strftime (buffer, sizeof (buffer),
+ "%d", &start_tm);
+ strcat (buffer, " - ");
+ }
e_utf8_strftime (end_buffer, sizeof (end_buffer),
_("%d %B %Y"), &end_tm);
- strcat (buffer, " - ");
strcat (buffer, end_buffer);
} else {
e_utf8_strftime (buffer, sizeof (buffer),
@@ -783,6 +798,7 @@ static BonoboUIVerb verbs [] = {
BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked),
BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked),
BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked),
+ BONOBO_UI_VERB ("ShowListView", show_list_view_clicked),
BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd),
BONOBO_UI_VERB ("CalendarPurge", purge_cmd),
@@ -796,6 +812,7 @@ static EPixmap pixmaps [] =
E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"),
E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"),
E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"),
+ E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"),
E_PIXMAP_END
};
diff --git a/calendar/gui/calendar-view-factory.c b/calendar/gui/calendar-view-factory.c
index f8d2d92ce3..a90e8a46d4 100644
--- a/calendar/gui/calendar-view-factory.c
+++ b/calendar/gui/calendar-view-factory.c
@@ -126,6 +126,9 @@ calendar_view_factory_get_title (GalViewFactory *factory)
case GNOME_CAL_MONTH_VIEW:
return _("Month View");
+ case GNOME_CAL_LIST_VIEW:
+ return _("List View");
+
default:
g_assert_not_reached ();
return NULL;
@@ -155,6 +158,9 @@ calendar_view_factory_get_type_code (GalViewFactory *factory)
case GNOME_CAL_MONTH_VIEW:
return "month_view";
+ case GNOME_CAL_LIST_VIEW:
+ return "list_view";
+
default:
g_assert_not_reached ();
return NULL;
diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c
index c245c983b9..191a8d85ea 100644
--- a/calendar/gui/control-factory.c
+++ b/calendar/gui/control-factory.c
@@ -93,6 +93,9 @@ get_prop (BonoboPropertyBag *bag,
case GNOME_CAL_MONTH_VIEW:
BONOBO_ARG_SET_STRING (arg, "month");
break;
+ case GNOME_CAL_LIST_VIEW:
+ BONOBO_ARG_SET_STRING (arg, "list");
+ break;
}
break;
diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c
new file mode 100644
index 0000000000..9fce533917
--- /dev/null
+++ b/calendar/gui/e-cal-list-view.c
@@ -0,0 +1,526 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * Authors:
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/*
+ * ECalListView - display calendar events in an ETable.
+ */
+
+#include <config.h>
+
+#include "e-cal-list-view.h"
+#include "ea-calendar.h"
+
+#include <math.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtkdnd.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkvscrollbar.h>
+#include <gtk/gtkwindow.h>
+#include <gal/widgets/e-gui-utils.h>
+#include <gal/widgets/e-unicode.h>
+#include <gal/util/e-util.h>
+#include <gal/e-table/e-table-memory-store.h>
+#include <gal/e-table/e-cell-checkbox.h>
+#include <gal/e-table/e-cell-toggle.h>
+#include <gal/e-table/e-cell-text.h>
+#include <gal/e-table/e-cell-combo.h>
+#include <gal/widgets/e-popup-menu.h>
+#include <widgets/misc/e-cell-date-edit.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-exec.h>
+#include <libgnome/gnome-util.h>
+#include <e-util/e-categories-config.h>
+#include <e-util/e-dialog-utils.h>
+
+#include "cal-util/timeutil.h"
+#include "e-cal-model-calendar.h"
+#include "e-cell-date-edit-text.h"
+#include "dialogs/delete-comp.h"
+#include "dialogs/delete-error.h"
+#include "dialogs/send-comp.h"
+#include "dialogs/cancel-comp.h"
+#include "dialogs/recur-comp.h"
+#include "comp-util.h"
+#include "itip-utils.h"
+#include "calendar-commands.h"
+#include "calendar-config.h"
+#include "goto.h"
+#include "misc.h"
+
+static void e_cal_list_view_class_init (ECalListViewClass *class);
+static void e_cal_list_view_init (ECalListView *cal_list_view);
+static void e_cal_list_view_destroy (GtkObject *object);
+static void e_cal_list_view_update_query (ECalView *cal_view);
+
+static GList *e_cal_list_view_get_selected_events (ECalView *cal_view);
+static gboolean e_cal_list_view_get_visible_time_range (ECalView *cal_view, time_t *start_time,
+ time_t *end_time);
+
+static gboolean e_cal_list_view_popup_menu (GtkWidget *widget);
+
+static void e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row,
+ GdkEvent *gdk_event);
+static gboolean e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col,
+ GdkEvent *event, gpointer data);
+
+static GtkTableClass *parent_class; /* Should be ECalViewClass? */
+
+E_MAKE_TYPE (e_cal_list_view, "ECalListView", ECalListView, e_cal_list_view_class_init,
+ e_cal_list_view_init, e_cal_view_get_type ());
+
+static void
+e_cal_list_view_class_init (ECalListViewClass *class)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ ECalViewClass *view_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ object_class = (GtkObjectClass *) class;
+ widget_class = (GtkWidgetClass *) class;
+ view_class = (ECalViewClass *) class;
+
+ /* Method override */
+ object_class->destroy = e_cal_list_view_destroy;
+
+ widget_class->popup_menu = e_cal_list_view_popup_menu;
+
+ view_class->get_selected_events = e_cal_list_view_get_selected_events;
+ view_class->get_visible_time_range = e_cal_list_view_get_visible_time_range;
+
+ view_class->update_query = e_cal_list_view_update_query;
+}
+
+static gint
+date_compare_cb (gconstpointer a, gconstpointer b)
+{
+ ECellDateEditValue *dv1 = (ECellDateEditValue *) a;
+ ECellDateEditValue *dv2 = (ECellDateEditValue *) b;
+ struct icaltimetype tt;
+
+ /* First check if either is NULL. NULL dates sort last. */
+ if (!dv1 || !dv2) {
+ if (dv1 == dv2)
+ return 0;
+ else if (dv1)
+ return -1;
+ else
+ return 1;
+ }
+
+ /* Copy the 2nd value and convert it to the same timezone as the
+ first. */
+ tt = dv2->tt;
+
+ icaltimezone_convert_time (&tt, dv2->zone, dv1->zone);
+
+ /* Now we can compare them. */
+
+ return icaltime_compare (dv1->tt, tt);
+}
+
+static void
+e_cal_list_view_init (ECalListView *cal_list_view)
+{
+ cal_list_view->query = NULL;
+ cal_list_view->table_scrolled = NULL;
+ cal_list_view->cursor_event = NULL;
+ cal_list_view->set_table_id = 0;
+}
+
+/* Returns the current time, for the ECellDateEdit items.
+ FIXME: Should probably use the timezone of the item rather than the
+ current timezone, though that may be difficult to get from here. */
+static struct tm
+get_current_time_cb (ECellDateEdit *ecde, gpointer data)
+{
+ char *location;
+ icaltimezone *zone;
+ struct tm tmp_tm = { 0 };
+ struct icaltimetype tt;
+
+ /* Get the current timezone. */
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ tmp_tm.tm_year = tt.year - 1900;
+ tmp_tm.tm_mon = tt.month - 1;
+ tmp_tm.tm_mday = tt.day;
+ tmp_tm.tm_hour = tt.hour;
+ tmp_tm.tm_min = tt.minute;
+ tmp_tm.tm_sec = tt.second;
+ tmp_tm.tm_isdst = -1;
+
+ return tmp_tm;
+}
+
+static void
+load_table_state (ECalListView *cal_list_view)
+{
+ struct stat st;
+
+ if (!cal_list_view->table_state_path)
+ return;
+
+ if (stat (cal_list_view->table_state_path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) {
+ e_table_load_state (e_table_scrolled_get_table (cal_list_view->table_scrolled),
+ cal_list_view->table_state_path);
+ }
+}
+
+static void
+save_table_state (ECalListView *cal_list_view)
+{
+ if (!cal_list_view->table_state_path)
+ return;
+
+ e_table_save_state (e_table_scrolled_get_table (cal_list_view->table_scrolled),
+ cal_list_view->table_state_path);
+}
+
+static void
+setup_e_table (ECalListView *cal_list_view)
+{
+ ECalModelCalendar *model;
+ ETableExtras *extras;
+ GList *strings;
+ ECell *cell, *popup_cell;
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ model = E_CAL_MODEL_CALENDAR (e_cal_view_get_model (E_CAL_VIEW (cal_list_view)));
+
+ if (cal_list_view->table_scrolled) {
+ save_table_state (cal_list_view);
+ gtk_widget_destroy (GTK_WIDGET (cal_list_view->table_scrolled));
+ }
+
+ /* Create the header columns */
+
+ extras = e_table_extras_new();
+
+ /* Normal string fields */
+
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ g_object_set (G_OBJECT (cell),
+ "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+ NULL);
+
+ e_table_extras_add_cell (extras, "calstring", cell);
+
+ /* Date fields */
+
+ cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT);
+ g_object_set (G_OBJECT (cell),
+ "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+ NULL);
+
+ popup_cell = e_cell_date_edit_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+ e_table_extras_add_cell (extras, "dateedit", popup_cell);
+ cal_list_view->dates_cell = E_CELL_DATE_EDIT (popup_cell);
+
+ e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell),
+ get_current_time_cb,
+ cal_list_view, NULL);
+
+ /* Combo fields */
+
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ g_object_set (G_OBJECT (cell),
+ "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+ "editable", FALSE,
+ NULL);
+
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Public"));
+ strings = g_list_append (strings, (char*) _("Private"));
+ strings = g_list_append (strings, (char*) _("Confidential"));
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell),
+ strings);
+
+ e_table_extras_add_cell (extras, "classification", popup_cell);
+
+ /* Sorting */
+
+ e_table_extras_add_compare (extras, "date-compare",
+ date_compare_cb);
+
+ /* Create table view */
+
+ cal_list_view->table_scrolled = E_TABLE_SCROLLED (
+ e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (model),
+ extras,
+ EVOLUTION_ETSPECDIR "/e-cal-list-view.etspec",
+ NULL));
+
+ /* Make sure text is readable on top of our color coding */
+
+ canvas = GNOME_CANVAS (e_table_scrolled_get_table (cal_list_view->table_scrolled)->table_canvas);
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
+ style->fg [GTK_STATE_SELECTED] = style->text [GTK_STATE_NORMAL];
+ style->fg [GTK_STATE_ACTIVE] = style->text [GTK_STATE_NORMAL];
+ gtk_widget_set_style (GTK_WIDGET (canvas), style);
+
+ /* Load state, if possible */
+
+ load_table_state (cal_list_view);
+
+ /* Connect signals */
+
+ g_signal_connect (e_table_scrolled_get_table (cal_list_view->table_scrolled),
+ "right-click", G_CALLBACK (e_cal_list_view_on_table_right_click), cal_list_view);
+
+ /* Attach and show widget */
+
+ gtk_table_attach (GTK_TABLE (cal_list_view), GTK_WIDGET (cal_list_view->table_scrolled),
+ 0, 2, 0, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1);
+ gtk_widget_show (GTK_WIDGET (cal_list_view->table_scrolled));
+}
+
+GtkWidget *
+e_cal_list_view_construct (ECalListView *cal_list_view, const gchar *table_state_path)
+{
+ if (table_state_path)
+ cal_list_view->table_state_path = g_strdup (table_state_path);
+ else
+ cal_list_view->table_state_path = NULL;
+
+ setup_e_table (cal_list_view);
+
+ return GTK_WIDGET (cal_list_view);
+}
+
+/**
+ * e_cal_list_view_new:
+ * @Returns: a new #ECalListView.
+ *
+ * Creates a new #ECalListView.
+ **/
+GtkWidget *
+e_cal_list_view_new (const gchar *table_state_path)
+{
+ ECalListView *cal_list_view;
+
+ cal_list_view = g_object_new (e_cal_list_view_get_type (), NULL);
+ if (!e_cal_list_view_construct (cal_list_view, table_state_path)) {
+ g_message ("e_cal_list_view(): Could not construct the calendar list GUI");
+ g_object_unref (cal_list_view);
+ return NULL;
+ }
+
+ return GTK_WIDGET (cal_list_view);
+}
+
+static void
+e_cal_list_view_destroy (GtkObject *object)
+{
+ ECalListView *cal_list_view;
+
+ cal_list_view = E_CAL_LIST_VIEW (object);
+
+ if (cal_list_view->query) {
+ g_signal_handlers_disconnect_matched (cal_list_view->query, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, cal_list_view);
+ g_object_unref (cal_list_view->query);
+ cal_list_view->query = NULL;
+ }
+
+ if (cal_list_view->set_table_id) {
+ g_source_remove (cal_list_view->set_table_id);
+ cal_list_view->set_table_id = 0;
+ }
+
+ if (cal_list_view->table_state_path) {
+ save_table_state (cal_list_view);
+ g_free (cal_list_view->table_state_path);
+ cal_list_view->table_state_path = NULL;
+ }
+
+ if (cal_list_view->cursor_event) {
+ g_free (cal_list_view->cursor_event);
+ cal_list_view->cursor_event = NULL;
+ }
+
+ if (cal_list_view->table_scrolled) {
+ gtk_widget_destroy (GTK_WIDGET (cal_list_view->table_scrolled));
+ cal_list_view->table_scrolled = NULL;
+ }
+
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
+}
+
+static gboolean
+setup_e_table_cb (gpointer data)
+{
+ setup_e_table (E_CAL_LIST_VIEW (data));
+ E_CAL_LIST_VIEW (data)->set_table_id = 0;
+ return FALSE;
+}
+
+static void
+e_cal_list_view_update_query (ECalView *cal_list_view)
+{
+ e_cal_view_set_status_message (E_CAL_VIEW (cal_list_view), _("Searching"));
+
+ if (!E_CAL_LIST_VIEW (cal_list_view)->set_table_id)
+ E_CAL_LIST_VIEW (cal_list_view)->set_table_id =
+ g_idle_add (setup_e_table_cb, cal_list_view);
+
+ e_cal_view_set_status_message (E_CAL_VIEW (cal_list_view), NULL);
+}
+
+static void
+e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row, GdkEvent *gdk_event)
+{
+ GtkMenu *popup;
+
+ popup = e_cal_view_create_popup_menu (E_CAL_VIEW (cal_list_view));
+ e_popup_menu (popup, gdk_event);
+}
+
+static gboolean
+e_cal_list_view_popup_menu (GtkWidget *widget)
+{
+ ECalListView *cal_list_view = E_CAL_LIST_VIEW (widget);
+
+ e_cal_list_view_show_popup_menu (cal_list_view, -1, NULL);
+ return TRUE;
+}
+
+static gboolean
+e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col, GdkEvent *event,
+ gpointer data)
+{
+ ECalListView *cal_list_view = E_CAL_LIST_VIEW (data);
+
+ e_cal_list_view_show_popup_menu (cal_list_view, row, event);
+ return TRUE;
+}
+
+static GList *
+e_cal_list_view_get_selected_events (ECalView *cal_view)
+{
+ GList *event_list = NULL;
+ gint cursor_row;
+
+ if (E_CAL_LIST_VIEW (cal_view)->cursor_event) {
+ g_free (E_CAL_LIST_VIEW (cal_view)->cursor_event);
+ E_CAL_LIST_VIEW (cal_view)->cursor_event = NULL;
+ }
+
+ cursor_row = e_table_get_cursor_row (e_table_scrolled_get_table (E_CAL_LIST_VIEW (cal_view)->table_scrolled));
+
+ if (cursor_row >= 0) {
+ ECalViewEvent *event;
+
+ event = E_CAL_LIST_VIEW (cal_view)->cursor_event = g_new0 (ECalViewEvent, 1);
+ event->comp_data =
+ e_cal_model_get_component_at (e_cal_view_get_model (cal_view),
+ cursor_row);
+ event_list = g_list_prepend (event_list, event);
+ }
+
+ return event_list;
+}
+
+static void
+adjust_range (icaltimetype icaltime, time_t *earliest, time_t *latest, gboolean *set)
+{
+ time_t t;
+
+ if (!icaltime_is_valid_time (icaltime))
+ return;
+
+ t = icaltime_as_timet (icaltime);
+ *earliest = MIN (*earliest, t);
+ *latest = MAX (*latest, t);
+
+ *set = TRUE;
+}
+
+/* NOTE: Time use for this function increases linearly with number of events. This is not
+ * ideal, since it's used in a couple of places. We could probably be smarter about it,
+ * and use do it less frequently... */
+static gboolean
+e_cal_list_view_get_visible_time_range (ECalView *cal_view, time_t *start_time, time_t *end_time)
+{
+ time_t earliest = G_MAXINT, latest = 0;
+ gboolean set = FALSE;
+ gint n_rows, i;
+
+ n_rows = e_table_model_row_count (E_TABLE_MODEL (e_cal_view_get_model (cal_view)));
+
+ for (i = 0; i < n_rows; i++) {
+ ECalModelComponent *comp;
+ icalcomponent *icalcomp;
+
+ comp = e_cal_model_get_component_at (e_cal_view_get_model (cal_view), i);
+ if (!comp)
+ continue;
+
+ icalcomp = comp->icalcomp;
+ if (!icalcomp)
+ continue;
+
+ adjust_range (icalcomponent_get_dtstart (icalcomp), &earliest, &latest, &set);
+ adjust_range (icalcomponent_get_dtend (icalcomp), &earliest, &latest, &set);
+ }
+
+ if (set) {
+ *start_time = earliest;
+ *end_time = latest;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+e_cal_list_view_get_range_shown (ECalListView *cal_list_view, GDate *start_date, gint *days_shown)
+{
+ time_t first, last;
+ GDate end_date;
+
+ if (!e_cal_list_view_get_visible_time_range (E_CAL_VIEW (cal_list_view), &first, &last))
+ return FALSE;
+
+ time_to_gdate_with_zone (start_date, first, e_cal_view_get_timezone (E_CAL_VIEW (cal_list_view)));
+ time_to_gdate_with_zone (&end_date, last, e_cal_view_get_timezone (E_CAL_VIEW (cal_list_view)));
+
+ *days_shown = g_date_days_between (start_date, &end_date);
+ return TRUE;
+}
diff --git a/calendar/gui/e-cal-list-view.etspec b/calendar/gui/e-cal-list-view.etspec
new file mode 100644
index 0000000000..e5a2cc0b6d
--- /dev/null
+++ b/calendar/gui/e-cal-list-view.etspec
@@ -0,0 +1,17 @@
+<ETableSpecification draw-grid="false" alternating-row-colors="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="classification" compare="string" priority="-1"/>
+ <ETableColumn model_col="2" _title="color" cell="calcolor" priority="-4"/>
+ <ETableColumn model_col="3" _title="component" cell="calcomp" priority="-4"/>
+ <ETableColumn model_col="4" _title="Description" expansion="2.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="-1"/>
+ <ETableColumn model_col="5" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/>
+ <ETableColumn model_col="8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="10"/>
+
+ <ETableState>
+ <column source="4"/>
+ <column source="3"/>
+ <column source="1"/>
+ <column source="0"/>
+ <grouping></grouping>
+ </ETableState>
+</ETableSpecification>
diff --git a/calendar/gui/e-cal-list-view.h b/calendar/gui/e-cal-list-view.h
new file mode 100644
index 0000000000..edf2e843e2
--- /dev/null
+++ b/calendar/gui/e-cal-list-view.h
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * Authors:
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright 2003, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#ifndef _E_CAL_LIST_VIEW_H_
+#define _E_CAL_LIST_VIEW_H_
+
+#include <time.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gal/widgets/e-popup-menu.h>
+
+#include "e-cal-view.h"
+#include "gnome-cal.h"
+#include "evolution-activity-client.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * ECalListView - displays calendar events in an ETable.
+ */
+
+#define E_CAL_LIST_VIEW(obj) GTK_CHECK_CAST (obj, e_cal_list_view_get_type (), ECalListView)
+#define E_CAL_LIST_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_cal_list_view_get_type (), ECalListViewClass)
+#define E_IS_CAL_LIST_VIEW(obj) GTK_CHECK_TYPE (obj, e_cal_list_view_get_type ())
+
+
+typedef struct _ECalListView ECalListView;
+typedef struct _ECalListViewClass ECalListViewClass;
+
+struct _ECalListView
+{
+ ECalView cal_view;
+
+ /* The main display table */
+ ETableScrolled *table_scrolled;
+
+ /* The path to the table's state file */
+ gchar *table_state_path;
+
+ /* S-expression for query and the query object */
+ CalQuery *query;
+
+ /* The default category for new events */
+ gchar *default_category;
+
+ /* Date editing cell */
+ ECellDateEdit *dates_cell;
+
+ /* The last ECalViewEvent we returned from e_cal_list_view_get_selected_events(), to be freed */
+ ECalViewEvent *cursor_event;
+
+ /* Idle handler ID for setting a new ETableModel */
+ gint set_table_id;
+};
+
+struct _ECalListViewClass
+{
+ ECalViewClass parent_class;
+};
+
+
+GtkType e_cal_list_view_get_type (void);
+GtkWidget *e_cal_list_view_construct (ECalListView *cal_list_view, const gchar *table_state_path);
+
+GtkWidget *e_cal_list_view_new (const gchar *table_state_path);
+
+void e_cal_list_view_set_query (ECalListView *cal_list_view, const gchar *sexp);
+void e_cal_list_view_set_default_category (ECalListView *cal_list_view, const gchar *category);
+gboolean e_cal_list_view_get_range_shown (ECalListView *cal_list_view, GDate *start_date,
+ gint *days_shown);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _E_CAL_LIST_VIEW_H_ */
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 8a68cd07e5..1c231f9c72 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -272,13 +272,28 @@ static char *
get_classification (ECalModelComponent *comp_data)
{
icalproperty *prop;
+ icalproperty_class class;
prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_CLASS_PROPERTY);
- if (prop)
- return (char *) icalproperty_get_class (prop);
+ if (!prop)
+ return _("Public");
+
+ class = icalproperty_get_class (prop);
+
+ switch (class)
+ {
+ case ICAL_CLASS_PUBLIC:
+ return _("Public");
+ case ICAL_CLASS_PRIVATE:
+ return _("Private");
+ case ICAL_CLASS_CONFIDENTIAL:
+ return _("Confidential");
+ default:
+ return _("Unknown");
+ }
- return _("Public");
+ return _("Unknown");
}
static const char *
@@ -579,14 +594,19 @@ ecm_set_value_at (ETableModel *etm, int col, int row, const void *value)
switch (col) {
case E_CAL_MODEL_FIELD_CATEGORIES :
set_categories (comp_data, value);
+ break;
case E_CAL_MODEL_FIELD_CLASSIFICATION :
set_classification (comp_data, value);
+ break;
case E_CAL_MODEL_FIELD_DESCRIPTION :
set_description (comp_data, value);
+ break;
case E_CAL_MODEL_FIELD_DTSTART :
set_dtstart (model, comp_data, value);
+ break;
case E_CAL_MODEL_FIELD_SUMMARY :
set_summary (comp_data, value);
+ break;
}
if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
@@ -858,7 +878,9 @@ ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data)
for (l = assigned_colors[i].uris; l != NULL; l = l->next) {
if (!strcmp ((const char *) l->data,
cal_client_get_uri (comp_data->client)))
+ {
return assigned_colors[i].color;
+ }
}
}
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 3ae8f4bde8..c2a0c2c61e 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -48,6 +48,7 @@
#include "e-day-view.h"
#include "e-day-view-time-item.h"
#include "e-week-view.h"
+#include "e-cal-list-view.h"
#include "evolution-calendar.h"
#include "gnome-cal.h"
#include "calendar-component.h"
@@ -108,6 +109,7 @@ struct _GnomeCalendarPrivate {
GtkWidget *work_week_view;
GtkWidget *week_view;
GtkWidget *month_view;
+ GtkWidget *list_view;
/* Calendar query for the date navigator */
GList *dn_queries; /* list of CalQueries */
@@ -452,7 +454,7 @@ dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
fprintf (stderr, "eval error: %s\n", error_str);
}
-/* Returns the current view widget, a EDayView or EWeekView. */
+/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */
GtkWidget*
gnome_calendar_get_current_view_widget (GnomeCalendar *gcal)
{
@@ -474,6 +476,9 @@ gnome_calendar_get_current_view_widget (GnomeCalendar *gcal)
case GNOME_CAL_MONTH_VIEW:
retval = priv->month_view;
break;
+ case GNOME_CAL_LIST_VIEW:
+ retval = priv->list_view;
+ break;
default:
g_assert_not_reached ();
}
@@ -500,6 +505,7 @@ get_focus_location (GnomeCalendar *gcal)
GtkWidget *widget;
EDayView *dv;
EWeekView *wv;
+ ECalListView *lv;
widget = gnome_calendar_get_current_view_widget (gcal);
@@ -523,6 +529,14 @@ get_focus_location (GnomeCalendar *gcal)
else
return FOCUS_OTHER;
+ case GNOME_CAL_LIST_VIEW:
+ lv = E_CAL_LIST_VIEW (widget);
+
+ if (GTK_WIDGET_HAS_FOCUS (e_table_scrolled_get_table (lv->table_scrolled)))
+ return FOCUS_CALENDAR;
+ else
+ return FOCUS_OTHER;
+
default:
g_assert_not_reached ();
return FOCUS_OTHER;
@@ -808,6 +822,15 @@ connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv)
G_CALLBACK (calendar_focus_change_cb), gcal);
}
+static void
+connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv)
+{
+ g_signal_connect (lv, "focus_in_event",
+ G_CALLBACK (calendar_focus_change_cb), gcal);
+ g_signal_connect (lv, "focus_out_event",
+ G_CALLBACK (calendar_focus_change_cb), gcal);
+}
+
/* Callback used when the selection in the taskpad table changes. We just proxy
* the signal with our own one.
*/
@@ -953,14 +976,26 @@ setup_widgets (GnomeCalendar *gcal)
connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view));
+ /* The List View. */
+ filename = g_strdup_printf ("%s/config/CalListView", evolution_dir);
+ priv->list_view = e_cal_list_view_new (filename);
+ g_free (filename);
+
+ e_cal_view_set_calendar (E_CAL_VIEW (priv->list_view), gcal);
+ gtk_widget_show (priv->list_view);
+ gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
+ priv->list_view, gtk_label_new (""));
+
+ connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view));
+
model = (ECalModel *) e_cal_model_calendar_new ();
e_cal_view_set_model (E_CAL_VIEW (priv->day_view), model);
e_cal_view_set_model (E_CAL_VIEW (priv->work_week_view), model);
e_cal_view_set_model (E_CAL_VIEW (priv->week_view), model);
e_cal_view_set_model (E_CAL_VIEW (priv->month_view), model);
+ e_cal_view_set_model (E_CAL_VIEW (priv->list_view), model);
g_object_unref (model);
-
gnome_calendar_update_config_settings (gcal, TRUE);
}
@@ -1265,6 +1300,8 @@ gnome_calendar_direction (GnomeCalendar *gcal, int direction)
priv->zone);
break;
+ case GNOME_CAL_LIST_VIEW:
+ g_warning ("Using month view time interval for list view.");
case GNOME_CAL_MONTH_VIEW:
start_time = time_add_month_with_zone (start_time, direction,
priv->zone);
@@ -1415,6 +1452,11 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type,
round_selection = TRUE;
break;
+ case GNOME_CAL_LIST_VIEW:
+ view_id = "List_View";
+ focus_widget = priv->list_view;
+ break;
+
default:
g_warning ("A penguin is loose!");
g_assert_not_reached ();
@@ -1550,6 +1592,10 @@ gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic)
gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
g_object_unref (factory);
+ factory = calendar_view_factory_new (GNOME_CAL_LIST_VIEW);
+ gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
+ g_object_unref (factory);
+
/* Load the collection and create the menus */
gal_view_collection_load (collection);
@@ -1965,7 +2011,7 @@ gnome_calendar_construct (GnomeCalendar *gcal)
/* Get the default view to show. */
view_type = calendar_config_get_default_view ();
- if (view_type < GNOME_CAL_DAY_VIEW || view_type > GNOME_CAL_MONTH_VIEW)
+ if (view_type < GNOME_CAL_DAY_VIEW || view_type > GNOME_CAL_LIST_VIEW)
view_type = GNOME_CAL_DAY_VIEW;
gnome_calendar_set_view (gcal, view_type, FALSE, FALSE);
@@ -2278,6 +2324,7 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
e_cal_view_set_timezone (E_CAL_VIEW (priv->work_week_view), priv->zone);
e_cal_view_set_timezone (E_CAL_VIEW (priv->week_view), priv->zone);
e_cal_view_set_timezone (E_CAL_VIEW (priv->month_view), priv->zone);
+ e_cal_view_set_timezone (E_CAL_VIEW (priv->list_view), priv->zone);
if (initializing) {
priv->hpane_pos = calendar_config_get_hpane_pos ();
@@ -2594,6 +2641,18 @@ get_days_shown (GnomeCalendar *gcal, GDate *start_date, gint *days_shown)
break;
+ case GNOME_CAL_LIST_VIEW:
+ if (!e_cal_list_view_get_range_shown (E_CAL_LIST_VIEW (priv->list_view),
+ start_date, days_shown)) {
+ /* No valid items in list */
+ time_to_gdate_with_zone (start_date, time (NULL), priv->zone);
+ *days_shown = 1;
+ }
+ else if (*days_shown < 1) {
+ *days_shown = 1;
+ }
+ break;
+
default:
g_assert_not_reached ();
}
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index ff5b1a6bd0..c9bbcbaff4 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -54,7 +54,8 @@ typedef enum {
GNOME_CAL_DAY_VIEW,
GNOME_CAL_WORK_WEEK_VIEW,
GNOME_CAL_WEEK_VIEW,
- GNOME_CAL_MONTH_VIEW
+ GNOME_CAL_MONTH_VIEW,
+ GNOME_CAL_LIST_VIEW
} GnomeCalendarViewType;
typedef enum
diff --git a/ui/ChangeLog b/ui/ChangeLog
index 159a03a8c1..212861251c 100644
--- a/ui/ChangeLog
+++ b/ui/ChangeLog
@@ -1,3 +1,7 @@
+2003-10-10 Hans Petter Jansson <hpj@ximian.com>
+
+ * evolution-calendar.xml: Add calendar list view task button.
+
2003-10-02 Rodney Dawes <dobey@ximian.com>
* evolution-mail-message.xml: Patch to use Control-L for "Reply
diff --git a/ui/evolution-calendar.xml b/ui/evolution-calendar.xml
index fb605baeb3..2c6ac8d53a 100644
--- a/ui/evolution-calendar.xml
+++ b/ui/evolution-calendar.xml
@@ -13,6 +13,7 @@
<cmd name="ShowWorkWeekView" _tip="Show the working week" pixtype="pixbuf"/>
<cmd name="ShowWeekView" _tip="Show one week" pixtype="pixbuf"/>
<cmd name="ShowMonthView" _tip="Show one month" pixtype="pixbuf"/>
+ <cmd name="ShowListView" _tip="Show as list" pixtype="pixbuf"/>
<cmd name="Cut" _tip="Cut the selection" accel="*Control*x" pixtype="stock" pixname="gtk-cut"/>
<cmd name="Copy" _tip="Copy the selection" accel="*Control*c" pixtype="stock" pixname="gtk-copy"/>
@@ -93,6 +94,7 @@
<toolitem name="WorkWeekView" verb="ShowWorkWeekView" _label="Work Week" priority="1" pixtype="pixbuf"/>
<toolitem name="WeekView" verb="ShowWeekView" _label="Week" priority="1" pixtype="pixbuf"/>
<toolitem name="MonthView" verb="ShowMonthView" _label="Month" priority="1" pixtype="pixbuf"/>
+ <toolitem name="ListView" verb="ShowListView" _label="List" priority="1" pixtype="pixbuf"/>
</dockitem>