diff options
-rw-r--r-- | art/ChangeLog | 4 | ||||
-rw-r--r-- | art/Makefile.am | 1 | ||||
-rw-r--r-- | art/listview.xpm | 34 | ||||
-rw-r--r-- | calendar/ChangeLog | 40 | ||||
-rw-r--r-- | calendar/gui/Makefile.am | 7 | ||||
-rw-r--r-- | calendar/gui/calendar-commands.c | 23 | ||||
-rw-r--r-- | calendar/gui/calendar-view-factory.c | 6 | ||||
-rw-r--r-- | calendar/gui/control-factory.c | 3 | ||||
-rw-r--r-- | calendar/gui/e-cal-list-view.c | 526 | ||||
-rw-r--r-- | calendar/gui/e-cal-list-view.etspec | 17 | ||||
-rw-r--r-- | calendar/gui/e-cal-list-view.h | 98 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.c | 28 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 65 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 3 | ||||
-rw-r--r-- | ui/ChangeLog | 4 | ||||
-rw-r--r-- | ui/evolution-calendar.xml | 2 |
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> |