From 9adbbaf76fe141c5a5051999f37a9ee9a005153e Mon Sep 17 00:00:00 2001 From: "Clifford R. Conover" Date: Thu, 11 Mar 1999 02:58:18 +0000 Subject: Add support for Due Date when adding a TODO item here. (column_resized): 1999-03-10 Clifford R. Conover * gncal-todo.c (simple_todo_editor): Add support for Due Date when adding a TODO item here. (column_resized): New function (init_column_sorting): New function. (todo_click_column): New function. (convert_time_t_to_char, make_overdue_todo_style): New functions. * gnome-cal.c (gnome_calendar_todo_properties_changed): New function used to update the TODO when the properties have been chagned for it. * prop.c (prop_apply_todo): Apply TODO properties. * gncal-day-panel.c (todo_list_properties_changed): Update the TODO display here. * eventedit.c (date_edit_new): Made public svn path=/trunk/; revision=757 --- calendar/gncal-todo.c | 245 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 221 insertions(+), 24 deletions(-) (limited to 'calendar/gncal-todo.c') diff --git a/calendar/gncal-todo.c b/calendar/gncal-todo.c index a78bd9432b..4c48fe1807 100644 --- a/calendar/gncal-todo.c +++ b/calendar/gncal-todo.c @@ -11,8 +11,17 @@ #include "gncal-todo.h" #include "main.h" #include "popup-menu.h" +#include "eventedit.h" +int todo_show_due_date = 0; +int todo_due_date_overdue_highlight = 0; +char *todo_overdue_font_text; +gint todo_current_sort_column = 0; +gint todo_current_sort_type = GTK_SORT_ASCENDING; +gboolean todo_style_changed =0; +gboolean todo_list_autoresize = 1; +gboolean todo_list_redraw_in_progess = 0; static void gncal_todo_init (GncalTodo *todo); @@ -44,15 +53,15 @@ ok_button (GtkWidget *widget, GnomeDialog *dialog) iCalObject *ico; GncalTodo *todo; GtkEntry *entry; - + GnomeDateEdit *due_date; ico = gtk_object_get_user_data (GTK_OBJECT (dialog)); todo = GNCAL_TODO (gtk_object_get_data (GTK_OBJECT (dialog), "gncal_todo")); entry = GTK_ENTRY (gtk_object_get_data (GTK_OBJECT (dialog), "summary_entry")); - + due_date = GNOME_DATE_EDIT (gtk_object_get_data(GTK_OBJECT(dialog), "due_date")); if (ico->summary) g_free (ico->summary); - + ico->dtend = gnome_date_edit_get_date (due_date); ico->summary = g_strdup (gtk_entry_get_text (entry)); ico->user_data = NULL; @@ -79,6 +88,8 @@ cancel_button (GtkWidget *widget, GnomeDialog *dialog) ical_object_destroy (ico); gtk_widget_destroy (GTK_WIDGET (dialog)); + + } static gint @@ -93,7 +104,11 @@ simple_todo_editor (GncalTodo *todo, iCalObject *ico) { GtkWidget *dialog; GtkWidget *hbox; + GtkWidget *due_box; + GtkWidget *due_label; + GtkWidget *due_entry; GtkWidget *w; + GtkWidget *entry; dialog = gnome_dialog_new (ico->new ? _("Create to-do item") : _("Edit to-do item"), @@ -106,6 +121,12 @@ simple_todo_editor (GncalTodo *todo, iCalObject *ico) gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); + + due_box = gtk_hbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (due_box), 4); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), due_box, FALSE, FALSE, 0); + gtk_widget_show (due_box); + w = gtk_label_new (_("Summary:")); gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0); gtk_widget_show (w); @@ -115,15 +136,28 @@ simple_todo_editor (GncalTodo *todo, iCalObject *ico) gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); gtk_widget_show (entry); + + due_label = gtk_label_new (_("Due Date:")); + gtk_box_pack_start (GTK_BOX (due_box), due_label, FALSE, FALSE, 0); + gtk_widget_show (due_label); + + due_entry = gtk_entry_new (); + due_entry = date_edit_new (ico->dtend, FALSE); + gtk_box_pack_start (GTK_BOX (due_box), due_entry, TRUE, TRUE, 0); + gtk_widget_show (due_entry); + + ico->user_data = dialog; gtk_object_set_user_data (GTK_OBJECT (dialog), ico); gtk_object_set_data (GTK_OBJECT (dialog), "gncal_todo", todo); gtk_object_set_data (GTK_OBJECT (dialog), "summary_entry", entry); + gtk_object_set_data (GTK_OBJECT (dialog), "due_date", due_entry); gnome_dialog_button_connect (GNOME_DIALOG (dialog), 0, (GtkSignalFunc) ok_button, dialog); gnome_dialog_button_connect (GNOME_DIALOG (dialog), 1, (GtkSignalFunc) cancel_button, dialog); + gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", (GtkSignalFunc) delete_event, dialog); @@ -172,6 +206,7 @@ delete_todo (GncalTodo *todo) { gnome_calendar_remove_object (todo->calendar, get_clist_selected_ico (todo->clist)); save_default_calendar (todo->calendar); + } static void @@ -192,6 +227,7 @@ delete_activated (GtkWidget *widget, GncalTodo *todo) delete_todo (todo); } + static void clist_row_selected (GtkCList *clist, gint row, gint column, GdkEventButton *event, GncalTodo *todo) { @@ -227,13 +263,75 @@ clist_row_selected (GtkCList *clist, gint row, gint column, GdkEventButton *even } } +/* + * once we get a call back stating that a column + * has been resized never ever automatically resize again + */ +void +column_resized (GtkWidget *widget, GncalTodo *todo) +{ + /* disabling autoresize of columns */ + if (todo_list_autoresize && !todo_list_redraw_in_progess){ + todo_list_autoresize = 0; + } +} + +/* + * restore the previously set settings for sorting the + * todo list + */ +static void +init_column_sorting (GtkCList *clist) +{ + + /* due date isn't shown so we can't sort by it */ + if (todo_current_sort_column == 1 && ! todo_show_due_date) + todo_current_sort_column = 0; + + clist->sort_type = todo_current_sort_type; + clist->sort_column = todo_current_sort_column; + + gtk_clist_set_sort_column (clist, todo_current_sort_column); + gtk_clist_sort (clist); +} + +static void +todo_click_column (GtkCList *clist, gint column, gpointer data) +{ + if (column == clist->sort_column) + { + if (clist->sort_type == GTK_SORT_ASCENDING) { + clist->sort_type = GTK_SORT_DESCENDING; + todo_current_sort_type = GTK_SORT_DESCENDING; + } else { + clist->sort_type = GTK_SORT_ASCENDING; + todo_current_sort_type = GTK_SORT_ASCENDING; + } + } + else { + gtk_clist_set_sort_column (clist, column); + todo_current_sort_column = column; + } + + gtk_clist_sort (clist); + + /* + * save the sorting preferences cause I hate to have the user + * click twice + */ + + gnome_config_set_int("/calendar/Todo/sort_column", todo_current_sort_column); + gnome_config_set_int("/calendar/Todo/sort_type", todo_current_sort_type); + gnome_config_sync(); +} + static void gncal_todo_init (GncalTodo *todo) { GtkWidget *w; GtkWidget *sw; GtkWidget *hbox; - + gchar *titles[2] = {"Summary","Due Date"}; gtk_box_set_spacing (GTK_BOX (todo), 4); /* Label */ @@ -250,13 +348,20 @@ gncal_todo_init (GncalTodo *todo) gtk_box_pack_start (GTK_BOX (todo), sw, TRUE, TRUE, 0); gtk_widget_show (sw); - w = gtk_clist_new (1); + + w = gtk_clist_new_with_titles(2, titles); + todo->clist = GTK_CLIST (w); gtk_clist_set_selection_mode (todo->clist, GTK_SELECTION_BROWSE); gtk_signal_connect (GTK_OBJECT (todo->clist), "select_row", (GtkSignalFunc) clist_row_selected, todo); + gtk_signal_connect (GTK_OBJECT (todo->clist), "resize_column", + (GtkSignalFunc) column_resized, + todo); + gtk_signal_connect (GTK_OBJECT (todo->clist), "click_column", + (GtkSignalFunc) todo_click_column, NULL); gtk_container_add (GTK_CONTAINER (sw), w); gtk_widget_show (w); @@ -315,51 +420,143 @@ gncal_todo_new (GnomeCalendar *calendar) return GTK_WIDGET (todo); } + + +char * +convert_time_t_to_char (time_t t) +{ + char *buffer; + struct tm *tm; + + buffer = g_malloc(15); + tm = localtime (&t); + strftime(buffer, 15, "%m/%d/%y", tm); + + return buffer; +} + +GtkStyle * +make_overdue_todo_style(GncalTodo *todo) +{ + GtkStyle *overdue_style = NULL; + GdkColor overdue_color; + + /*make the overdue color configurable */ + overdue_color.red = color_props[COLOR_PROP_OVERDUE_TODO].r; + overdue_color.green = color_props[COLOR_PROP_OVERDUE_TODO].g; + overdue_color.blue = color_props[COLOR_PROP_OVERDUE_TODO].b; + + overdue_style = gtk_style_copy (GTK_WIDGET (todo->clist)->style); + overdue_style->base[GTK_STATE_NORMAL] = overdue_color; + + return overdue_style; +} + static void insert_in_clist (GncalTodo *todo, iCalObject *ico) { int i; - char *text[1] = { ico->summary }; - iCalObject *row_ico; + char *text[2]; + static GtkStyle *overdue_style = NULL; + + + /* setup the over due style if we haven't already, or it changed.*/ + if (todo_style_changed || !overdue_style) { + /* free the old style cause its not needed anymore */ + if(!overdue_style) g_free(overdue_style); + overdue_style = make_overdue_todo_style(todo); + todo_style_changed = 0; + } - if (ico->priority == 0) - i = gtk_clist_append (todo->clist, text); /* items with undefined priority go to the end of the list */ - else { - /* Find proper place in clist to insert object. Objects are sorted by priority. */ + text[0] = ico->summary; - for (i = 0; i < todo->clist->rows; i++) { - row_ico = gtk_clist_get_row_data (todo->clist, i); + /* + * right now column 0 will be the summary + * and column 1 will be the due date. + * WISH: this should be able to be changed on the fly + */ - if (ico->priority >= row_ico->priority) - break; - } - - gtk_clist_insert (todo->clist, i, text); + if(ico->dtend && todo_show_due_date) { + text[1] = convert_time_t_to_char(ico->dtend); + /* Append the data's pointer so later it can be properly freed */ + todo->data_ptrs = g_slist_append (todo->data_ptrs, text[1]); } - - /* Set the appropriate "done" icon and hook the object to the row */ - + else + text[1] = NULL; + + + i = gtk_clist_append (todo->clist, text); + gtk_clist_set_row_data (todo->clist, i, ico); + + /* + * determine if the task is overdue.. + * if so mark with the apropriate style + */ + if(todo_due_date_overdue_highlight) { + if(ico->dtend < time(NULL)) + gtk_clist_set_row_style(todo->clist, i, overdue_style); + } + + /* keep the list in order */ + gtk_clist_sort (todo->clist); } void gncal_todo_update (GncalTodo *todo, iCalObject *ico, int flags) { - GList *list; + GList *list; + GSList *current_list; g_return_if_fail (todo != NULL); g_return_if_fail (GNCAL_IS_TODO (todo)); - + + /* + * shut down the resize handler cause we are playing with the list. + * In otherwords turn off the event handler + */ + todo_list_redraw_in_progess =1; + + /* freeze the list */ gtk_clist_freeze (todo->clist); + init_column_sorting (todo->clist); + + /* + * before here we have to free some of the memory that + * stores the due date, or else we have a memory leak. + * luckily all of the pointers are stored in todo->data_ptrs; + */ + + /* check on the columns that we should display */ + /* check for due date */ + + if(todo_show_due_date) + gtk_clist_set_column_visibility (todo->clist, 1, 1); + else + gtk_clist_set_column_visibility (todo->clist, 1, 0); + + /* free the memory locations that were used in the previous display */ + for (current_list = todo->data_ptrs; current_list != NULL; current_list = g_slist_next(current_list)){ + g_free(current_list->data); + } + + /* free the list and clear out the pointer */ + g_slist_free(todo->data_ptrs); + todo->data_ptrs = NULL; gtk_clist_clear (todo->clist); for (list = todo->calendar->cal->todo; list; list = list->next) insert_in_clist (todo, list->data); - gtk_clist_thaw (todo->clist); + /* if we are autoresizing then do it now */ + if(todo_list_autoresize && todo->clist->rows != 0) + gtk_clist_columns_autosize (todo->clist); + gtk_clist_thaw (todo->clist); + gtk_widget_set_sensitive (todo->edit_button, (todo->clist->selection != NULL)); gtk_widget_set_sensitive (todo->delete_button, (todo->clist->selection != NULL)); + todo_list_redraw_in_progess = 0; } -- cgit