/* To-do widget for gncal * * Copyright (C) 1998 The Free Software Foundation * * Author: Federico Mena */ #include #include #include #include "gncal-todo.h" #include "main.h" #include "popup-menu.h" static void gncal_todo_init (GncalTodo *todo); guint gncal_todo_get_type (void) { static guint todo_type = 0; if (!todo_type) { GtkTypeInfo todo_info = { "GncalTodo", sizeof (GncalTodo), sizeof (GncalTodoClass), (GtkClassInitFunc) NULL, (GtkObjectInitFunc) gncal_todo_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL }; todo_type = gtk_type_unique (gtk_vbox_get_type (), &todo_info); } return todo_type; } static void ok_button (GtkWidget *widget, GnomeDialog *dialog) { iCalObject *ico; GncalTodo *todo; GtkEntry *entry; 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")); if (ico->summary) g_free (ico->summary); ico->summary = g_strdup (gtk_entry_get_text (entry)); ico->user_data = NULL; if (ico->new) { gnome_calendar_add_object (todo->calendar, ico); ico->new = FALSE; } else gnome_calendar_object_changed (todo->calendar, ico, CHANGE_ALL); /* ok, summary only... */ gtk_widget_destroy (GTK_WIDGET (dialog)); } static void cancel_button (GtkWidget *widget, GnomeDialog *dialog) { iCalObject *ico; ico = gtk_object_get_user_data (GTK_OBJECT (dialog)); ico->user_data = NULL; if (ico->new) ical_object_destroy (ico); gtk_widget_destroy (GTK_WIDGET (dialog)); } static gint delete_event (GtkWidget *widget, GdkEvent *event, GnomeDialog *dialog) { cancel_button (NULL, dialog); return TRUE; } static void simple_todo_editor (GncalTodo *todo, iCalObject *ico) { GtkWidget *dialog; GtkWidget *hbox; GtkWidget *w; GtkWidget *entry; dialog = gnome_dialog_new (ico->new ? _("Create to-do item") : _("Edit to-do item"), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL); gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (todo->calendar)); hbox = gtk_hbox_new (FALSE, 4); gtk_container_border_width (GTK_CONTAINER (hbox), 4); gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); w = gtk_label_new (_("Summary:")); gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0); gtk_widget_show (w); entry = gtk_entry_new (); gtk_entry_set_text (GTK_ENTRY (entry), ico->summary); gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); gtk_widget_show (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); 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); gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); gnome_dialog_editable_enters (GNOME_DIALOG (dialog), GTK_EDITABLE(entry)); gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); gtk_widget_show (dialog); gtk_widget_grab_focus (entry); } static iCalObject * get_clist_selected_ico (GtkCList *clist) { gint sel; if (!clist->selection) return NULL; sel = GPOINTER_TO_INT(clist->selection->data); return gtk_clist_get_row_data (clist, sel); } static void add_todo (GncalTodo *todo) { iCalObject *ico; ico = ical_new ("", user_name, ""); ico->type = ICAL_TODO; ico->new = TRUE; simple_todo_editor (todo, ico); } static void edit_todo (GncalTodo *todo) { simple_todo_editor (todo, get_clist_selected_ico (todo->clist)); } static void delete_todo (GncalTodo *todo) { gnome_calendar_remove_object (todo->calendar, get_clist_selected_ico (todo->clist)); } static void add_activated (GtkWidget *widget, GncalTodo *todo) { add_todo (todo); } static void edit_activated (GtkWidget *widget, GncalTodo *todo) { edit_todo (todo); } static void delete_activated (GtkWidget *widget, GncalTodo *todo) { delete_todo (todo); } static void clist_row_selected (GtkCList *clist, gint row, gint column, GdkEventButton *event, GncalTodo *todo) { static struct menu_item items[] = { { N_("Add to-do item..."), (GtkSignalFunc) add_activated, NULL, TRUE }, { N_("Edit this item..."), (GtkSignalFunc) edit_activated, NULL, TRUE }, { N_("Delete this item"), (GtkSignalFunc) delete_activated, NULL, TRUE } }; int i; gtk_widget_set_sensitive (todo->edit_button, (todo->clist->selection != NULL)); gtk_widget_set_sensitive (todo->delete_button, (todo->clist->selection != NULL)); if (!event) return; switch (event->button) { case 1: if (event->type == GDK_2BUTTON_PRESS) edit_todo (todo); break; case 3: for (i = 0; i < (sizeof (items) / sizeof (items[0])); i++) items[i].data = todo; popup_menu (items, sizeof (items) / sizeof (items[0]), event); break; default: break; } } static void gncal_todo_init (GncalTodo *todo) { GtkWidget *w; GtkWidget *sw; GtkWidget *hbox; gtk_box_set_spacing (GTK_BOX (todo), 4); /* Label */ w = gtk_label_new (_("To-do list")); gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (todo), w, FALSE, FALSE, 0); gtk_widget_show (w); /* Clist */ sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (todo), sw, TRUE, TRUE, 0); gtk_widget_show (sw); w = gtk_clist_new (1); 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_container_add (GTK_CONTAINER (sw), w); gtk_widget_show (w); /* Box for buttons */ hbox = gtk_hbox_new (TRUE, 4); gtk_box_pack_start (GTK_BOX (todo), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); /* Add */ w = gtk_button_new_with_label (_("Add...")); gtk_signal_connect (GTK_OBJECT (w), "clicked", (GtkSignalFunc) add_activated, todo); gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); gtk_widget_show (w); /* Edit */ w = gtk_button_new_with_label (_("Edit...")); todo->edit_button = w; gtk_widget_set_sensitive (w, FALSE); gtk_signal_connect (GTK_OBJECT (w), "clicked", (GtkSignalFunc) edit_activated, todo); gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); gtk_widget_show (w); /* Delete */ w = gtk_button_new_with_label (_("Delete")); todo->delete_button = w; gtk_widget_set_sensitive (w, FALSE); gtk_signal_connect (GTK_OBJECT (w), "clicked", (GtkSignalFunc) delete_activated, todo); gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); gtk_widget_show (w); } GtkWidget * gncal_todo_new (GnomeCalendar *calendar) { GncalTodo *todo; g_return_val_if_fail (calendar != NULL, NULL); todo = gtk_type_new (gncal_todo_get_type ()); todo->calendar = calendar; gncal_todo_update (todo, NULL, 0); return GTK_WIDGET (todo); } static void insert_in_clist (GncalTodo *todo, iCalObject *ico) { int i; char *text[1] = { ico->summary }; iCalObject *row_ico; 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. */ for (i = 0; i < todo->clist->rows; i++) { row_ico = gtk_clist_get_row_data (todo->clist, i); if (ico->priority >= row_ico->priority) break; } gtk_clist_insert (todo->clist, i, text); } /* Set the appropriate "done" icon and hook the object to the row */ gtk_clist_set_row_data (todo->clist, i, ico); } void gncal_todo_update (GncalTodo *todo, iCalObject *ico, int flags) { GList *list; g_return_if_fail (todo != NULL); g_return_if_fail (GNCAL_IS_TODO (todo)); gtk_clist_freeze (todo->clist); 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); gtk_widget_set_sensitive (todo->edit_button, (todo->clist->selection != NULL)); gtk_widget_set_sensitive (todo->delete_button, (todo->clist->selection != NULL)); }