(fwd) Re: gnomecal categories (was: Re: contributing to gncal)



[ If you get this message more than once, please blame in on my malfunctioning mail setup. Sorry. ]

Hello gnome-pim friends,

As promised (though a bit later than expected, sorry) here's my
categories patch for gnome-pim. It should work against the latest (as
in '5 minutes ago') cvs version.

There are some known issues and limitations: 
(however as the feature-freeze deadline is today, I posting this patch now)

* So far it only works for the todo list

* No user definable categories yet, just a number of stock
categories. If categories not in stock are in your .vcf file, they
should work, no pixmaps yet.

* I think there's a bug in the loading of categories - while the
categories are saved correctly, only one of them is loaded. When
stepping through 'ical_object_from_vobject' I can see already there
the other categories are missing. So probably with experience in that
area should take a look.

* I have to debug more for memleaks. Couldn't find anything with
memprof so far, but that may be my inexperience with the tool ;-)

There are a lot of niceties to add - such as pixmaps, user-definable
categories and so on. However, modulo the bug i mentioned it should be
useful right now... 

Note that my girlfriend stated that people who need categorization
in their todo-list have too much to do. ;-)

Cheers,
	Dirk-Jan.

------------------------------------ 
      -  Dirk-Jan C. Binnema -
------------------------------------
 E-Mail  : djcb@dds.nl
 ICQ     : 50685597
 WWW     : www.casema.net/~devnull
 PGP/GPG : 5A48 377F 7EF5 8397 DD70  
   	   6F41 07CD BE51 4AEB 4286
------------------------------------





































































----- End forwarded message -----
------------------------------------ 
      -  Dirk-Jan C. Binnema -
------------------------------------
 E-Mail  : djcb@dds.nl
 ICQ     : 50685597
 WWW     : www.casema.net/~devnull
 PGP/GPG : 5A48 377F 7EF5 8397 DD70  
   	   6F41 07CD BE51 4AEB 4286
------------------------------------








diff -u -r -P gnome-pim/gncal/ChangeLog gnome-pim-categories/gncal/ChangeLog
--- gnome-pim/gncal/ChangeLog	Tue Feb  1 05:40:20 2000
+++ gnome-pim-categories/gncal/ChangeLog	Sun Feb  6 00:57:09 2000
@@ -1,12 +1,14 @@
-2000-02-02  Eskil Heyn Olsen  <deity@eskil.dk>
+2000-02-06 Dirk-Jan C. Binnema <djcb@dds.nl>
 
-	* calendar-conduit-control-applet.c: Uses the new libgpilotd
-
-2000-01-24  Eskil Heyn Olsen  <deity@eskil.dk>
-
-	* calendar-conduit.c: oops, forgot to commit a working
-	version. This now starts the calendar object up properly.
-	Plus a paranoia check reg. occurrence rules.
+	Added category support for TODO items
+	* gncal-todo.c: added category support button
+	* modify-cats.[ch]: modify cats dialog
+	* calobj.c: categories initialization
+	            fixed small bug (VCResourcesProp)
+	* main.[ch]: read categories visibility property
+	* prop.c: add categories to show/don't show dialog
+	TODO: bug in loading of multiple categories (?)
+	TODO: hunt for memleaks	
 
 2000-01-09  Eskil Heyn Olsen  <deity@eskil.dk>
 


diff -u -r -P gnome-pim/gncal/Makefile.am gnome-pim-categories/gncal/Makefile.am
--- gnome-pim/gncal/Makefile.am	Sun Jan  9 16:59:43 2000
+++ gnome-pim-categories/gncal/Makefile.am	Thu Jan 27 22:57:05 2000
@@ -80,6 +80,8 @@
 	main.h			\
 	mark.c			\
 	mark.h			\
+	modify-cats.c           \
+	modify-cats.h           \
 	month-view.c		\
 	month-view.h		\
 	popup-menu.c		\


diff -u -r -P gnome-pim/gncal/calobj.c gnome-pim-categories/gncal/calobj.c
--- gnome-pim/gncal/calobj.c	Wed Nov  3 03:36:31 1999
+++ gnome-pim-categories/gncal/calobj.c	Wed Feb  2 19:05:27 2000
@@ -86,6 +86,7 @@
 	ico->summary   = g_strdup (summary);
 	ico->class     = g_strdup ("PUBLIC");
 	ico->status    = g_strdup ("NEEDS ACTION");
+	ico->categories= NULL;
 
 	default_alarm  (ico, &ico->dalarm, organizer, ALARM_DISPLAY);
 	default_alarm  (ico, &ico->palarm, organizer, ALARM_PROGRAM);
@@ -987,7 +988,7 @@
 
 	/* resources */
 	if (ical->resources)
-		store_list (o, VCCategoriesProp, ical->resources);
+		store_list (o, VCResourcesProp, ical->resources);
 
 	/* priority */
 	addPropValue (o, VCPriorityProp, to_str (ical->priority));


diff -u -r -P gnome-pim/gncal/gncal-todo.c gnome-pim-categories/gncal/gncal-todo.c
--- gnome-pim/gncal/gncal-todo.c	Mon Nov 22 09:04:06 1999
+++ gnome-pim-categories/gncal/gncal-todo.c	Wed Feb  2 18:14:11 2000
@@ -16,12 +16,12 @@
 int todo_show_due_date = 0;
 int todo_show_priority = 0;
 int todo_show_time_remaining = 0;
+int todo_show_categories = 0;
 
 int todo_item_dstatus_highlight_overdue = 0;
 int todo_item_dstatus_highlight_due_today = 0;
 int todo_item_dstatus_highlight_not_due_yet = 0;
 
-
 char *todo_overdue_font_text;
 gint todo_current_sort_column = 0;
 gint todo_current_sort_type = GTK_SORT_ASCENDING;
@@ -30,6 +30,8 @@
 gboolean todo_list_autoresize = 1;
 gboolean todo_list_redraw_in_progess = 0;
 static void gncal_todo_init (GncalTodo *todo);
+static void modify_categories ( GtkWidget *widget, GnomeDialog *dialog );
+
 
 
 guint
@@ -63,6 +65,7 @@
 	GnomeDateEdit *due_date;
 	GtkText *comment;
 	GtkSpinButton *priority;
+	GList* categories;
 
 	ico = gtk_object_get_user_data (GTK_OBJECT (dialog));
 
@@ -71,6 +74,8 @@
 	due_date = GNOME_DATE_EDIT (gtk_object_get_data(GTK_OBJECT(dialog), "due_date"));
 	priority = GTK_SPIN_BUTTON (gtk_object_get_data(GTK_OBJECT(dialog), "priority"));
 	comment = GTK_TEXT(gtk_object_get_data (GTK_OBJECT(dialog), "comment"));
+	categories = (GList*) gtk_object_get_data (GTK_OBJECT(dialog), "categories");
+
 	if (ico->summary)
 	  g_free (ico->summary);
 	if (ico->comment)
@@ -81,6 +86,13 @@
 	ico->comment = gtk_editable_get_chars( GTK_EDITABLE(comment), 0, -1);
 	ico->user_data = NULL;
 
+	/* free old category list */
+	if ( ico->categories ) 
+		g_list_free ( ico->categories );
+
+	ico->categories = categories_as_ico_categories ( categories );
+	
+
 	if (ico->new) {
 		gnome_calendar_add_object (todo->calendar, ico);
 		ico->new = FALSE;
@@ -91,6 +103,7 @@
 	gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
+
 static void
 cancel_button (GtkWidget *widget, GnomeDialog *dialog)
 {
@@ -108,6 +121,7 @@
 
 }
 
+
 static gint
 delete_event (GtkWidget *widget, GdkEvent *event, GnomeDialog *dialog)
 {
@@ -115,6 +129,7 @@
 	return TRUE;
 }
 
+
 static void
 simple_todo_editor (GncalTodo *todo, iCalObject *ico)
 {
@@ -129,13 +144,18 @@
 	GtkWidget *comment_internal_box;
 	GtkWidget *comment_sep;
 	GtkWidget *w;
+	GtkWidget *pri_cat_box;
 	GtkWidget *pri_box;
 	GtkWidget *pri_label;
 	GtkWidget *pri_spin;
 	GtkObject *pri_adj;
+	GtkWidget *cat_box;
+	GtkWidget *cat_label;
+	GtkWidget *cat_entry;
+	GtkWidget *cat_button;
 
 	GtkWidget *entry;
-
+	
 	dialog = gnome_dialog_new (ico->new ? _("Create to-do item") : _("Edit to-do item"),
 				   GNOME_STOCK_BUTTON_OK,
 				   GNOME_STOCK_BUTTON_CANCEL,
@@ -146,18 +166,17 @@
 	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);
 
-	pri_box = gtk_hbox_new (FALSE, 4);
-	gtk_container_border_width (GTK_CONTAINER (pri_box), 4);
-	gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox), pri_box, FALSE, FALSE, 0);
-	gtk_widget_show (pri_box);
+	pri_cat_box = gtk_hbox_new (FALSE, 4);
+	gtk_container_border_width (GTK_CONTAINER (pri_cat_box), 4);
+	gtk_box_pack_start(GTK_BOX (GNOME_DIALOG (dialog)->vbox), pri_cat_box, FALSE, FALSE, 0);
+	gtk_widget_show (pri_cat_box);
 	
-	comment_box = gtk_hbox_new (FALSE, 4);
+        comment_box = gtk_hbox_new (FALSE, 4);
 	gtk_container_border_width (GTK_CONTAINER (comment_box), 4);
 	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), comment_box, FALSE, FALSE, 0);
 	gtk_widget_show (comment_box);
@@ -177,7 +196,6 @@
 	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);
@@ -187,9 +205,30 @@
 	gtk_box_pack_start (GTK_BOX (due_box), due_entry, TRUE, TRUE, 0);
 	gtk_widget_show (due_entry);
 
+	pri_box   = gtk_hbox_new (FALSE, 4);
 	pri_label = gtk_label_new (_("Priority:"));
 	gtk_box_pack_start (GTK_BOX (pri_box), pri_label, FALSE, FALSE, 0);
 	gtk_widget_show (pri_label);
+	gtk_widget_show (pri_box);
+
+	cat_box    = gtk_hbox_new (FALSE, 4);
+	cat_label  = gtk_label_new (_("Categories:"));
+	cat_entry  = gtk_entry_new ();
+	gtk_entry_set_editable (GTK_ENTRY(cat_entry), FALSE );
+	gtk_entry_set_text (GTK_ENTRY(cat_entry), ico_categories_as_string(ico->categories));
+	cat_button = gtk_button_new_with_label (_("Modify"));
+	gtk_signal_connect (GTK_OBJECT(cat_button), "clicked", modify_categories, dialog );
+	gtk_box_pack_start (GTK_BOX (cat_box), cat_label, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (cat_box), cat_entry, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (cat_box), cat_button, FALSE, FALSE, 0);
+	gtk_widget_show ( cat_box );
+	gtk_widget_show ( cat_label );
+	gtk_widget_show ( cat_entry );
+	gtk_widget_show ( cat_button );
+
+
+	gtk_box_pack_start ( GTK_BOX (pri_cat_box), pri_box, FALSE, FALSE, 0);
+	gtk_box_pack_start ( GTK_BOX (pri_cat_box), cat_box, FALSE, FALSE, 0);
 
 	pri_adj = gtk_adjustment_new (5.0, 1.0, 9.0, 1.0, 3.0, 0.0);
 	pri_spin = gtk_spin_button_new (GTK_ADJUSTMENT(pri_adj), 0.0, 0);
@@ -208,9 +247,6 @@
 	gtk_box_pack_start (GTK_BOX (comment_internal_box), comment_label, TRUE, TRUE, 0);
 	gtk_widget_show (comment_label);
 
-
-
-
 	comment_text = gtk_text_new (NULL, NULL);
 	gtk_text_set_editable (GTK_TEXT (comment_text), TRUE);
 	gtk_text_set_word_wrap( GTK_TEXT(comment_text), TRUE);
@@ -231,7 +267,9 @@
 	gtk_object_set_data (GTK_OBJECT (dialog), "due_date", due_entry);
 	gtk_object_set_data (GTK_OBJECT (dialog), "priority", pri_spin);
 	gtk_object_set_data (GTK_OBJECT (dialog), "comment", comment_text);
-	
+	gtk_object_set_data (GTK_OBJECT (dialog), "cat_entry", cat_entry);
+	gtk_object_set_data (GTK_OBJECT (dialog), "categories", ico_categories_as_categories (ico->categories));
+
 	gnome_dialog_button_connect (GNOME_DIALOG (dialog), 0, (GtkSignalFunc) ok_button, dialog);
 	gnome_dialog_button_connect (GNOME_DIALOG (dialog), 1, (GtkSignalFunc) cancel_button, dialog);
 
@@ -315,6 +353,29 @@
 }
 
 
+/*
+ * modify the categories for this item
+ *
+ */
+static void
+modify_categories ( GtkWidget *widget, GnomeDialog *dialog)
+{
+	GList *categories;
+	GtkEntry *cat_entry;
+	iCalObject *ico = gtk_object_get_user_data (GTK_OBJECT(dialog));
+       
+	categories = ico_categories_as_categories ( ico->categories ); 
+ 
+	modify_cats_dialog ( GTK_WIDGET(dialog), &categories );
+	gtk_object_set_data ( GTK_OBJECT(dialog), "categories", categories );
+	
+	cat_entry = gtk_object_get_data (GTK_OBJECT(dialog), "cat_entry" );
+	gtk_entry_set_text ( cat_entry, categories_as_string ( categories ));
+}
+
+
+
+
 static void
 clist_row_selected (GtkCList *clist, gint row, gint column, GdkEventButton *event, GncalTodo *todo)
 {
@@ -418,19 +479,21 @@
 	GtkWidget *w;
 	GtkWidget *sw;
 	GtkWidget *hbox;
-	gchar *titles[4] = {
+	gchar *titles[5] = {
 	    N_("Summary"),
 	    N_("Due Date"),
 	    N_("Priority"),
-	    N_("Time Left")
+	    N_("Time Left"),
+	    N_("Categories")
 	};
-	char *tmp[4];
+	char *tmp[5];
 	tmp[0] = _(titles[0]);
 	tmp[1] = _(titles[1]);
 	tmp[2] = _(titles[2]);
 	tmp[3] = _(titles[3]);
+	tmp[4] = _(titles[4]);
 
-	gtk_box_set_spacing (GTK_BOX (todo), 4);
+	gtk_box_set_spacing (GTK_BOX (todo), 5);
 
 	/* Label */
 
@@ -447,7 +510,7 @@
 	gtk_widget_show (sw);
 
 
-	w = gtk_clist_new_with_titles(4, tmp);
+	w = gtk_clist_new_with_titles(5, tmp);
 
 	todo->clist = GTK_CLIST (w);
 	gtk_clist_set_selection_mode (todo->clist, GTK_SELECTION_BROWSE);
@@ -618,7 +681,7 @@
 insert_in_clist (GncalTodo *todo, iCalObject *ico)
 {
 	int i;
-	char *text[4];
+	char *text[5];
 	char time_remaining_buffer[100];
 	time_t time_remain;
 	todo_remaining_time_form time_remaining_form;
@@ -630,8 +693,7 @@
 	int days = 0;
 	int hours = 0;
 	int minutes = 0;
-	int seconds = 0; 
-	
+	int seconds = 0;
 	
 	/* an array for the styles of items */
 	static GtkStyle *dstatus_styles[TODO_ITEM_DSTATUS_LAST_DUE_STATUS];
@@ -651,8 +713,6 @@
 	}
 
 	  
-       
-
 
 	text[0] =  ico->summary;
 
@@ -760,6 +820,18 @@
 	else
 	  text[2] = NULL;
 
+	/*
+	 * categories, comma-separated 
+	 */
+	if ( ico->categories && todo_show_categories ) {
+		
+	        text[4] = ico_categories_as_string ( ico->categories ); /* FIXME: leaking here ?! */ 
+	} else
+
+		text[4] = NULL;
+
+
+
 	i = gtk_clist_append (todo->clist, text);
 	
 	gtk_clist_set_row_data (todo->clist, i, ico);
@@ -842,6 +914,14 @@
 	  gtk_clist_set_column_visibility (todo->clist, 2, 1);
 	else
 	  gtk_clist_set_column_visibility (todo->clist, 2, 0);
+
+	
+	if ( todo_show_categories ) 
+
+		gtk_clist_set_column_visibility ( todo->clist, 4, 1);
+	else
+		gtk_clist_set_column_visibility ( todo->clist, 4, 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)){
@@ -867,6 +947,13 @@
 	gtk_widget_set_sensitive (todo->delete_button, (todo->clist->selection != NULL));
 	todo_list_redraw_in_progess = 0;
 }
+
+
+
+
+
+
+
 
 
 
diff -u -r -P gnome-pim/gncal/gncal-todo.h gnome-pim-categories/gncal/gncal-todo.h
--- gnome-pim/gncal/gncal-todo.h	Thu Mar 11 03:58:11 1999
+++ gnome-pim-categories/gncal/gncal-todo.h	Thu Jan 27 22:57:06 2000
@@ -12,7 +12,7 @@
 #include <gtk/gtkvbox.h>
 #include <libgnome/gnome-defs.h>
 #include "gnome-cal.h"
-
+#include "modify-cats.h"
 
 BEGIN_GNOME_DECLS
 
@@ -34,7 +34,7 @@
 
 	GtkWidget *edit_button;
 	GtkWidget *delete_button;
-              GSList *data_ptrs;
+	GSList *data_ptrs;
   
  
 };
diff -u -r -P gnome-pim/gncal/main.c gnome-pim-categories/gncal/main.c
--- gnome-pim/gncal/main.c	Fri Dec 31 16:58:08 1999
+++ gnome-pim-categories/gncal/main.c	Thu Jan 27 22:57:06 2000
@@ -226,6 +226,9 @@
 	
 	todo_show_priority = gnome_config_get_bool("/calendar/Todo/show_priority");
 
+	todo_show_categories = gnome_config_get_bool("/calendar/Todo/show_categories");
+
+
 	/* read alarm settings */
 	beep_on_display = gnome_config_get_bool ("/calendar/alarms/beep_on_display=FALSE");
 	enable_aalarm_timeout = gnome_config_get_bool ("/calendar/alarms/enable_audio_timeout=FALSE");
diff -u -r -P gnome-pim/gncal/main.h gnome-pim-categories/gncal/main.h
--- gnome-pim/gncal/main.h	Fri Dec  3 01:55:01 1999
+++ gnome-pim-categories/gncal/main.h	Thu Jan 27 22:57:06 2000
@@ -49,6 +49,7 @@
 extern gboolean todo_style_changed;
 extern gint todo_current_sort_column;
 extern gint todo_current_sort_type;
+extern int todo_show_categories;
 
 /* alarm stuff */
 extern CalendarAlarm alarm_defaults[4];
diff -u -r -P gnome-pim/gncal/modify-cats.c gnome-pim-categories/gncal/modify-cats.c
--- gnome-pim/gncal/modify-cats.c	Thu Jan  1 01:00:00 1970
+++ gnome-pim-categories/gncal/modify-cats.c	Sat Feb  5 23:42:41 2000
@@ -0,0 +1,495 @@
+/* 
+ * modify-cats.c
+ * dialog for modifying categories for an item
+ * part of gnome-cal 
+ */
+
+
+/*
+** Copyright (C) 2000 Dirk-Jan C. Binnema <djcb@dds.nl>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**  
+** 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.
+**  
+*/
+
+#include "modify-cats.h"
+
+
+static GtkWidget *list_selected, *list_available;
+
+static void fill_stock_categories (GList **categories );
+static void populate_list_boxes ( GList **category_list );
+static gboolean already_in_categories ( GList *categories, gchar* cat );
+
+
+
+static void cb_add_button_pressed (GtkWidget *button, gpointer data);
+static void cb_remove_button_pressed (GtkWidget *button, gpointer data);
+static void cb_select_list_selected ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data);
+static void cb_unselect_list_selected ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data);
+static void cb_select_list_available ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data);
+static void cb_unselect_list_available ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data);
+
+/*
+ * contruct & show the 'modify categories' dialog
+ */
+gint
+modify_cats_dialog ( GtkWidget *parent, GList **categories )
+{
+	GtkWidget *dialog;
+	GtkWidget *commlist_box;
+	GtkWidget *main_label;
+	GtkWidget *list_label_box;
+	GtkWidget *label_selected, *label_available;
+	GtkWidget *button_box;
+	GtkWidget *add_button, *remove_button;
+	GtkWidget *add_icon, *remove_icon;
+	GtkWidget *scrollwin_left, *scrollwin_right;
+	GtkTooltips *tooltips;
+
+	gchar* buttons[2];
+	buttons[0] = _("Done") ;
+	buttons[1] = NULL;
+	
+	dialog = gnome_dialog_newv ( _("Category selection"), (const gchar**)buttons);
+	main_label = gtk_label_new ( _("Please select categories for the current item") );
+	gtk_widget_show (main_label);
+ 
+	list_label_box  = gtk_hbox_new ( FALSE, 0 );
+	label_selected  = gtk_label_new ( _("Selected"));
+	label_available = gtk_label_new ( _("Available"));
+	gtk_box_pack_start_defaults ( GTK_BOX (list_label_box), label_selected  );
+	gtk_box_pack_start_defaults ( GTK_BOX (list_label_box), label_available );
+	gtk_widget_show (list_label_box );
+	gtk_widget_show ( label_selected );
+	gtk_widget_show ( label_available );
+	
+	commlist_box    = gtk_hbox_new ( FALSE, 5);
+	scrollwin_left  = gtk_scrolled_window_new ( NULL, NULL );
+	scrollwin_right = gtk_scrolled_window_new ( NULL, NULL );
+       	list_selected   = gtk_clist_new (3);
+	list_available  = gtk_clist_new (3);
+	gtk_clist_set_selection_mode ( GTK_CLIST(list_selected), GTK_SELECTION_MULTIPLE);
+	gtk_clist_set_selection_mode ( GTK_CLIST(list_available), GTK_SELECTION_MULTIPLE);
+
+	button_box      = gtk_vbox_new ( FALSE, 0);
+	add_icon        = gnome_stock_pixmap_widget ( NULL, GNOME_STOCK_BUTTON_PREV );
+	add_button      = gtk_button_new();
+	gtk_container_add (GTK_CONTAINER(add_button), add_icon);
+	remove_icon     = gnome_stock_pixmap_widget ( NULL, GNOME_STOCK_BUTTON_NEXT );
+	remove_button   = gtk_button_new();
+	gtk_container_add (GTK_CONTAINER(remove_button), remove_icon);
+       
+	/* tooltips */
+	tooltips = gtk_tooltips_new();
+	gtk_tooltips_set_tip (GTK_TOOLTIPS(tooltips), add_button, 
+			      _("Add a category"),
+			      _("Add a category to the list of selected categories"));
+
+	gtk_tooltips_set_tip (GTK_TOOLTIPS(tooltips), remove_button, 
+			      _("Remove a category"),
+			      _("Remove a category from  the list of selected categories"));
+
+	gtk_signal_connect ( GTK_OBJECT (list_selected),  "select-row",     cb_select_list_selected,  NULL );
+	gtk_signal_connect ( GTK_OBJECT (list_selected),  "unselect-row",   cb_unselect_list_selected, NULL );
+	gtk_signal_connect ( GTK_OBJECT (list_available),  "select-row",    cb_select_list_available,  NULL );
+	gtk_signal_connect ( GTK_OBJECT (list_available),  "unselect-row",  cb_unselect_list_available, NULL );
+	
+	gtk_signal_connect ( GTK_OBJECT (add_button), "pressed",    cb_add_button_pressed,    categories );
+	gtk_signal_connect ( GTK_OBJECT (remove_button), "pressed", cb_remove_button_pressed, categories );
+
+	gtk_box_pack_start (GTK_BOX(button_box), add_button, FALSE, FALSE, 0 );
+	gtk_box_pack_start (GTK_BOX(button_box), remove_button, FALSE, FALSE, 0 );
+	gtk_container_add  (GTK_CONTAINER(scrollwin_left), list_selected );
+	gtk_container_add  (GTK_CONTAINER(scrollwin_right), list_available );
+	gtk_widget_set_usize (GTK_WIDGET(scrollwin_left), 50, 100 );
+	gtk_widget_set_usize (GTK_WIDGET(scrollwin_right), 50, 100 );
+	
+	gtk_box_pack_start_defaults (GTK_BOX(commlist_box), scrollwin_left);
+	gtk_box_pack_start_defaults (GTK_BOX(commlist_box), button_box);
+	gtk_box_pack_start_defaults (GTK_BOX(commlist_box), scrollwin_right);
+	gtk_widget_show ( add_icon );
+	gtk_widget_show ( remove_icon);
+	gtk_widget_show ( add_button );
+	gtk_widget_show ( remove_button );
+	gtk_widget_show ( scrollwin_left );
+	gtk_widget_show ( scrollwin_right );
+	gtk_widget_show ( list_selected );
+	gtk_widget_show ( list_available );
+	gtk_widget_show ( button_box );
+	gtk_widget_show ( commlist_box );
+	
+	gtk_box_pack_start_defaults ( GTK_BOX (GNOME_DIALOG(dialog)->vbox), main_label);
+	gtk_box_pack_start_defaults ( GTK_BOX (GNOME_DIALOG(dialog)->vbox), list_label_box);
+	gtk_box_pack_start_defaults ( GTK_BOX (GNOME_DIALOG(dialog)->vbox), commlist_box);
+	
+	fill_stock_categories ( categories );
+	populate_list_boxes ( categories );
+
+	gnome_dialog_set_parent ( GNOME_DIALOG(dialog), GTK_WINDOW(parent) );
+	
+	gtk_widget_set_usize ( GTK_WIDGET(dialog), 300, 250 );
+	return gnome_dialog_run_and_close (GNOME_DIALOG(dialog));
+}
+
+
+void 
+populate_list_boxes ( GList **categories )
+{
+	gint row_id = 0;
+	
+	Category* cursor_item;
+	gchar*  dummy[] = { NULL, NULL, NULL}; 
+	GList *cursor = g_list_first(*categories);
+
+	gtk_clist_clear (GTK_CLIST(list_available));
+	gtk_clist_clear (GTK_CLIST(list_selected));
+	
+	while ( cursor ) {
+		
+		cursor_item = (Category*) cursor->data;
+	
+		if ( cursor_item->is_available ) {
+			
+			row_id = gtk_clist_append ( GTK_CLIST(list_available), dummy );
+			gtk_clist_set_text ( GTK_CLIST(list_available), row_id, 2, cursor_item->name);
+			gtk_clist_set_row_data ( GTK_CLIST(list_available), row_id, (gpointer) cursor_item );
+	
+		} else {
+
+			row_id = gtk_clist_append ( GTK_CLIST(list_selected), dummy );
+			gtk_clist_set_text ( GTK_CLIST(list_selected), row_id, 2, cursor_item->name);
+			gtk_clist_set_row_data ( GTK_CLIST(list_selected), row_id, (gpointer) cursor_item );
+		}
+
+		cursor = g_list_next ( cursor );
+	}
+}
+
+
+void
+cb_add_button_pressed ( GtkWidget* button, gpointer category_list )
+{
+        GList  *list  = *((GList**) category_list); 
+	Category* cursor_item;
+
+	while ( list ) {
+		
+		cursor_item = (Category*) list->data;
+		
+		if ( (TRUE == cursor_item -> is_available ) 
+		    && ( TRUE == cursor_item -> selected )) {
+	
+			cursor_item -> is_available = FALSE;
+			cursor_item -> selected     = FALSE;
+	
+		}
+		list = g_list_next ( list );
+	}
+	
+	populate_list_boxes ( category_list );
+}
+
+
+void
+cb_remove_button_pressed ( GtkWidget* button, gpointer category_list )
+{
+	GList  *list = *((GList**) category_list);  
+	Category* cursor_item;
+
+	while ( list ) {
+		
+		cursor_item = (Category*) list->data;
+		
+		if ( (FALSE == cursor_item -> is_available ) 
+		    && ( TRUE == cursor_item -> selected )) {
+	
+			cursor_item -> is_available = TRUE;
+			cursor_item -> selected     = FALSE;
+		}
+
+		list = g_list_next (list);
+	}
+
+	populate_list_boxes ( category_list );
+}
+
+
+
+void 
+cb_select_list_selected ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data)
+{
+	Category* cat = (Category*) gtk_clist_get_row_data (GTK_CLIST(list_selected), row);
+	cat -> selected = TRUE;
+}
+
+
+
+void 
+cb_unselect_list_selected ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data)
+{
+	Category* cat = (Category*) gtk_clist_get_row_data (GTK_CLIST(list_selected), row);
+	cat -> selected = FALSE;
+}
+
+
+void 
+cb_select_list_available ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data)
+{
+	Category* cat = (Category*) gtk_clist_get_row_data (GTK_CLIST(list_available), row);
+	cat -> selected = TRUE;
+}
+
+
+
+void 
+cb_unselect_list_available ( GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer data)
+{
+	Category* cat = (Category*) gtk_clist_get_row_data (GTK_CLIST(list_available), row);
+	cat -> selected = FALSE;
+}
+
+
+
+GList*
+ico_categories_as_categories ( GList *ico_categories )
+{
+	GList *ico_cursor = g_list_first(ico_categories);
+	GList *categories  = NULL;
+	Category* new_cat;
+
+	while ( ico_cursor ) {
+
+		new_cat = g_new (Category, 1);
+		new_cat -> name = (gchar*)ico_cursor->data;
+		new_cat -> name_end = NULL;
+		new_cat -> is_available = FALSE;
+		new_cat -> selected     = FALSE;
+
+		categories = g_list_append (categories, new_cat);
+
+		ico_cursor = g_list_next (ico_cursor);
+	}
+
+
+	return g_list_first (categories);
+}
+
+
+GList*
+categories_as_ico_categories ( GList *categories )
+{
+	GList *cursor = g_list_first(categories);
+        GList* ico_categories = NULL;
+	Category * this_cat;
+	
+	while ( cursor ) {
+		
+		this_cat = (Category*) cursor->data;
+
+		if ( FALSE == this_cat -> is_available ) 
+			ico_categories = g_list_append ( ico_categories, this_cat->name ); 
+	       
+				
+		cursor = g_list_next ( cursor );
+	}
+
+	return g_list_first (ico_categories);
+}
+
+
+
+/*
+ * print non-available (ie. selected) categories
+ * must be freed by caller
+ */
+gchar*
+categories_as_string ( GList *categories )
+{
+	GList *cursor;
+	Category* cursor_item;
+	gchar *sep = ", ", *cat_string;
+	gboolean first_cat = TRUE;
+	gint size = 1;
+
+	if ( NULL == categories ) {
+		
+	        cat_string = g_new0 ( gchar, 1 );
+		sprintf ( cat_string, "%s", "" );
+		
+		return cat_string;
+	}
+
+	/* determine length */
+	cursor = categories;
+	while ( cursor ) {
+	
+		cursor_item = (Category*) cursor->data;
+
+		if ( FALSE == cursor_item -> is_available ) 
+			size += strlen (cursor_item->name) + strlen(sep);
+
+		cursor = g_list_next (cursor);
+	}
+
+	cat_string = g_new0 ( gchar, size );
+
+	/* fill string */
+	cursor = categories;
+	while ( cursor ) {
+		
+		cursor_item = (Category*) cursor->data;
+
+		if ( FALSE == cursor_item -> is_available ) {
+			sprintf ( cat_string, "%s%s%s", cat_string, ((first_cat)?"":sep), cursor_item->name);
+			first_cat = FALSE;
+		}
+		
+		cursor = cursor = g_list_next (cursor);
+	}
+		
+	return cat_string;
+}
+
+
+/*
+ *  must be freed by caller
+ */
+gchar*
+ico_categories_as_string ( GList *ico_categories )
+{
+	GList *cursor;
+	gchar *sep = ", ", *cat_string;
+	gboolean first_cat = TRUE;
+	gint size = 1;
+
+	if ( NULL == ico_categories ) {
+		
+	        cat_string = g_new0 ( gchar, 1 );
+		sprintf ( cat_string, "%s", "" );
+		
+		return cat_string;
+	}
+
+	/* determine length */
+	for ( cursor = ico_categories; cursor; cursor=g_list_next(cursor) )
+	
+		size += strlen ( (gchar*) cursor->data ) + strlen(sep);
+	       
+	
+	cat_string = g_new0 ( gchar, size );
+
+	/* fill string */
+	for ( cursor = ico_categories; cursor; cursor=g_list_next(cursor) ) {
+		
+		sprintf ( cat_string, "%s%s%s", cat_string, (first_cat)?"":sep, (gchar*) cursor->data );
+		first_cat = FALSE;
+	}		
+	return cat_string;
+}
+
+
+	
+void
+fill_stock_categories ( GList **categories )
+{
+	/*  stock categories to attach to todo items */
+	static Category stock_category[] = {
+		{ N_("Church"),		NULL, TRUE,  FALSE },
+		{ N_("Friends"),	NULL, TRUE,  FALSE },
+		{ N_("Guadec"),		NULL, TRUE,  FALSE },
+		{ N_("Hacking"),	NULL, TRUE,  FALSE },
+		{ N_("Hobby"),		NULL, TRUE,  FALSE },
+		{ N_("Housekeeping"),	NULL, TRUE,  FALSE },
+		{ N_("Love"),		NULL, TRUE,  FALSE },
+		{ N_("Meeting"),	NULL, TRUE,  FALSE },
+		{ N_("Money"),		NULL, TRUE,  FALSE },
+		{ N_("Music"),		NULL, TRUE,  FALSE },
+		{ N_("Paperwork"),      NULL, TRUE,  FALSE },
+		{ N_("Relatives"),      NULL, TRUE,  FALSE },
+		{ N_("School"),		NULL, TRUE,  FALSE },
+		{ N_("Shopping"),	NULL, TRUE,  FALSE },
+		{ N_("Travel"),		NULL, TRUE,  FALSE },
+		{ N_("Work"),		NULL, TRUE,  FALSE },
+		{ NULL }
+	};
+
+	Category* new_cat;
+	gint index = 0;
+
+	GList *cursor = *categories;
+
+	while ( stock_category[index].name ) {
+
+		if ( ! already_in_categories ( cursor, stock_category[index].name )) {
+			
+			new_cat = g_new ( Category, 1 );
+			new_cat->name = stock_category[index].name;
+			new_cat->name_end = NULL;
+			new_cat->is_available = TRUE;
+			new_cat->selected = FALSE;
+			
+			*categories = g_list_append (*categories, new_cat );
+		}
+
+		index++;
+	}
+}
+
+		     
+
+
+
+gboolean
+already_in_categories ( GList *categories, gchar* cat ) 
+{
+
+	GList *cursor = categories;
+	gboolean found = FALSE;
+	Category *cursor_item;
+	
+	if ( NULL == cursor )
+		return FALSE;
+
+	while ( cursor ) {
+
+		cursor_item = (Category*) cursor->data;
+
+		if ( 0 == strcmp ( cat, cursor_item->name  )) {
+			found = TRUE;
+			break;
+		}
+
+		cursor = g_list_next ( cursor );
+	}
+
+	return found;
+}
+
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
diff -u -r -P gnome-pim/gncal/modify-cats.h gnome-pim-categories/gncal/modify-cats.h
--- gnome-pim/gncal/modify-cats.h	Thu Jan  1 01:00:00 1970
+++ gnome-pim-categories/gncal/modify-cats.h	Mon Jan 31 18:55:26 2000
@@ -0,0 +1,66 @@
+/* 
+ * modify-cats.h
+ * dialog for modifying categories for an item
+ * part of gnome-cal 
+ */
+
+
+/*
+** Copyright (C) 2000 Dirk-Jan C. Binnema <djcb@dds.nl>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**  
+** 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 _MODIFY_CATS_H_
+#define _MODIFY_CATS_H_
+
+#include <config.h>
+#include <gnome.h>
+#include "gncal-todo.h"
+
+
+/*
+ *  this structures stores the data for category visual representation
+ */
+typedef struct _Category {
+	gchar *name;                 /* name of the category */ 
+	gchar *name_end;             /* NULL */
+	/*gchar *icon; */                /* the pixmap */
+	gboolean is_available;       /* is this category not yet chosen? */
+	gboolean selected;           /* is thi category selected in the clist? */
+} Category;
+
+
+gint modify_cats_dialog ( GtkWidget *parent, GList **list );
+gchar *ico_categories_as_string ( GList *ico_categories );
+gchar *categories_as_string     ( GList *categories );
+GList *categories_as_ico_categories ( GList *categories );
+GList *ico_categories_as_categories ( GList *ico_categories );
+
+
+#endif /* _MODIFY_CATS_H_ */
+
+
+
+
+
+
+
+
+
+
+
diff -u -r -P gnome-pim/gncal/prop.c gnome-pim-categories/gncal/prop.c
--- gnome-pim/gncal/prop.c	Fri Dec  3 01:55:01 1999
+++ gnome-pim-categories/gncal/prop.c	Thu Jan 27 22:57:06 2000
@@ -53,6 +53,7 @@
 static GtkWidget *todo_item_highlight_due_today;
 
 static GtkWidget *priority_show_button;
+static GtkWidget *categories_show_button;
 
 /* Widgets for the alarm page */
 static GtkWidget *enable_display_beep;
@@ -148,8 +149,8 @@
 	todo_item_dstatus_highlight_due_today = GTK_TOGGLE_BUTTON(todo_item_highlight_due_today)->active;
 
 	todo_show_priority = GTK_TOGGLE_BUTTON (priority_show_button)->active;
-
 	todo_show_time_remaining = GTK_TOGGLE_BUTTON (todo_item_time_remaining_show_button)->active;
+	todo_show_categories = GTK_TOGGLE_BUTTON (categories_show_button)->active;
 
 	/* storing the values */
 
@@ -161,6 +162,8 @@
         gnome_config_set_bool("/calendar/Todo/highlight_not_due_yet", todo_item_dstatus_highlight_not_due_yet);
 	gnome_config_set_bool("/calendar/Todo/show_due_date", todo_show_due_date);
 	gnome_config_set_bool("/calendar/Todo/show_priority", todo_show_priority);
+	gnome_config_set_bool("/calendar/Todo/show_categories", todo_show_categories);
+
 	/* need to sync our config changes. */
 	gnome_config_sync ();
 
@@ -604,6 +607,7 @@
 	due_date_show_button = gtk_check_button_new_with_label (_("Due Date"));
 	priority_show_button = gtk_check_button_new_with_label (_("Priority"));
 	todo_item_time_remaining_show_button = gtk_check_button_new_with_label (_("Time Until Due"));
+	categories_show_button = gtk_check_button_new_with_label (_("Categories"));
 
 	gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(due_date_show_button), todo_show_due_date);
 	gtk_signal_connect (GTK_OBJECT(due_date_show_button),
@@ -626,6 +630,14 @@
 			    (GtkSignalFunc) todo_option_set,
 			    NULL);
 	gtk_box_pack_start (GTK_BOX (vbox), priority_show_button, FALSE, FALSE, 0);
+
+	gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(categories_show_button), todo_show_categories);
+	gtk_signal_connect (GTK_OBJECT(categories_show_button), 
+			    "clicked",
+			    (GtkSignalFunc) todo_option_set,
+			    NULL);
+	gtk_box_pack_start (GTK_BOX (vbox), categories_show_button, FALSE, FALSE, 0);
+
 	return frame;
 }
 static GtkWidget *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]