← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~karl-qdh/indicator-datetime/calendarmenuitemsignals into lp:indicator-datetime

 

Karl Lattimer has proposed merging lp:~karl-qdh/indicator-datetime/calendarmenuitemsignals into lp:indicator-datetime.

Requested reviews:
  Ted Gould (ted)
Related bugs:
  Bug #726531 in Indicator Date and Time: "Browsing calendar widget should update appointments"
  https://bugs.launchpad.net/indicator-datetime/+bug/726531

For more details, see:
https://code.launchpad.net/~karl-qdh/indicator-datetime/calendarmenuitemsignals/+merge/53467

Updated code in this branch to fulfil ted's comments

Partially fixes bug #726531
-- 
https://code.launchpad.net/~karl-qdh/indicator-datetime/calendarmenuitemsignals/+merge/53467
Your team ayatana-commits is subscribed to branch lp:indicator-datetime.
=== modified file 'src/datetime-service.c'
--- src/datetime-service.c	2011-03-15 02:43:27 +0000
+++ src/datetime-service.c	2011-03-15 15:51:12 +0000
@@ -280,9 +280,6 @@
 static gboolean
 month_changed_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, guint timestamp)
 {
-	// BLOCKED: get type, then get type as string from the variant causes segfault in glib
-	// TODO: * Set some globals so when we-re-run update appointment menu items it gets the right start date
-	//		 * update appointment menu items
 	start_time_appointments = (time_t)g_variant_get_uint32(variant);
 	
 	g_debug("Received month changed with timestamp: %d -> %s",(int)start_time_appointments, ctime(&start_time_appointments));	
@@ -290,6 +287,37 @@
 	return TRUE;
 }
 
+static gboolean
+day_selected_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, guint timestamp)
+{
+	start_time_appointments = (time_t)g_variant_get_uint32(variant);
+	
+	g_debug("Received day-selected with timestamp: %d -> %s",(int)start_time_appointments, ctime(&start_time_appointments));	
+	update_appointment_menu_items(NULL);
+	return TRUE;
+}
+
+static gboolean
+day_selected_double_click_cb (DbusmenuMenuitem * menuitem, gchar *name, GVariant *variant, guint timestamp)
+{
+	time_t evotime = (time_t)g_variant_get_uint32(variant);
+	
+	g_debug("Received day-selected-double-click with timestamp: %d -> %s",(int)evotime, ctime(&evotime));	
+	
+	gchar *ad = isodate_from_time_t(evotime);
+	gchar *cmd = g_strconcat("evolution calendar:///?startdate=", ad, NULL);
+	
+	GError * error = NULL;
+
+	g_debug("Issuing command '%s'", cmd);
+	if (!g_spawn_command_line_async(cmd, &error)) {
+		g_warning("Unable to start %s: %s", (char *)cmd, error->message);
+		g_error_free(error);
+	}
+	
+	return TRUE;
+}
+
 static guint ecaltimer = 0;
 
 static void
@@ -365,8 +393,10 @@
 			stop_ecal_timer();
 		}
 		
-		// Connect to event::month-changed 
+		// Connect to calendar events
 		g_signal_connect(calendar, "event::month-changed", G_CALLBACK(month_changed_cb), NULL);
+		g_signal_connect(calendar, "event::day-selected", G_CALLBACK(day_selected_cb), NULL);
+		g_signal_connect(calendar, "event::day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), NULL);
 		g_free(evo);
 	} else {
 		g_debug("Unable to find calendar app.");
@@ -543,27 +573,51 @@
 	if (updating_appointments) return TRUE;
 	updating_appointments = TRUE;
 	
-	time_t t1, t2;
+	time_t curtime = 0, t1 = 0, t2 = 0;
 	gchar *ad;
 	GList *l;
 	GSList *g;
 	GError *gerror = NULL;
 	gint i;
-	gint width, height;
+	gint width = 0, height = 0;
 	ESourceList * sources = NULL;
-	
-	if (start_time_appointments > 0)
-		t1 = start_time_appointments;
-	else
-		time(&t1);
-
-	/* TODO: 7 days ahead of now, we actually need number_of_days_in_this_month 
-	 *       so we call "mark-day" for all remaining days in this month
-	 * N.B. Ideally we want any/all dates which are later than today to be marked.
-	 */
-	t2 = t1 + (time_t) (7 * 24 * 60 * 60); 
-	
-	// TODO Remove all highlights from the calendar widget
+
+	// Get today & work out query times
+	time(&curtime);
+  	struct tm *today = localtime(&curtime);
+	const int mday = today->tm_mday;
+	const int mon = today->tm_mon;
+	const int year = today->tm_year;
+	
+  	struct tm *start_tm = NULL;
+	int this_year = today->tm_year + 1900;
+	int days[12]={31,28,31,30,31,30,31,31,30,31,30,31};
+	if ((this_year % 400 == 0) || (this_year % 100 > 0 && this_year % 4 == 0)) days[1] = 29;
+	
+	int highlightdays = days[mon] - mday + 1;
+	t1 = curtime; // By default the current time is the appointment start time. 
+	
+	if (start_time_appointments > 0) {
+  		start_tm = localtime(&start_time_appointments);
+		int start_month = start_tm->tm_mon;
+		int start_year = start_tm->tm_year + 1900;
+		if ((start_month != mon) || (start_year != this_year)) {
+			// Set t1 to the start of that month.
+			struct tm month_start = {0};
+			month_start.tm_year = start_tm->tm_year;
+			month_start.tm_mon = start_tm->tm_mon;
+			month_start.tm_mday = 1;
+			t1 = mktime(&month_start);
+			highlightdays = days[mon];
+		}
+	}
+	
+	g_debug("Will highlight %d days from %s", highlightdays, ctime(&t1));
+
+	t2 = t1 + (time_t) (highlightdays * 24 * 60 * 60); 
+	
+	// Remove all highlights from the calendar widget
+	dbusmenu_menuitem_property_set (calendar, CALENDAR_MENUITEM_PROP_CLEAR_MARKS, NULL);
 	
 	if (!e_cal_get_sources(&sources, E_CAL_SOURCE_TYPE_EVENT, &gerror)) {
 		g_debug("Failed to get ecal sources\n");
@@ -588,7 +642,7 @@
 		
 		for (s = e_source_group_peek_sources (group); s; s = s->next) {
 			ESource *source = E_SOURCE (s->data);
-			//g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
+			g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
 			ECal *ecal = e_cal_new(source, E_CAL_SOURCE_TYPE_EVENT);
 			e_cal_set_auth_func (ecal, (ECalAuthFunc) auth_func, NULL);
 			
@@ -605,7 +659,8 @@
 	g_debug("Number of ECalComponents returned: %d", g_list_length(comp_instances));
 	GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances);
 	comp_instances = NULL;
-
+	g_debug("Components sorted");
+	
 	/* Remove all of the previous appointments */
 	if (appointments != NULL) {
 		g_debug("Freeing old appointments");
@@ -619,9 +674,7 @@
 		}
 	}
 
-	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); 
-	// Sometimes these give negative numbers, sometimes large numbers which look like timestamps
-	// is there a buffer overwrite causing it?
+	gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
 	if (width <= 0) width = 12;
 	if (height <= 0) height = 12;
 	if (width > 30) width = 12;
@@ -646,13 +699,34 @@
 		char right[20];
 		//const gchar *uri;
 		DbusmenuMenuitem * item;
-
-		g_debug("Start Object %p", ecalcomp);
-		
-		// TODO Mark days
+		
+		ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp);
+		struct tm *due = NULL;
+		if (vtype == E_CAL_COMPONENT_EVENT) due = localtime(&ci->start);
+		else if (vtype == E_CAL_COMPONENT_TODO) due = localtime(&ci->end);
+		else continue;
+		
+		const int dmday = due->tm_mday;
+		const int dmon = due->tm_mon;
+		const int dyear = due->tm_year;
+		
+		// Mark day
+		g_debug("Marking date %s", ctime(&ci->start));
+		dbusmenu_menuitem_property_set_int (calendar, CALENDAR_MENUITEM_PROP_MARK, due->tm_mday);
+
+
+		// If the appointment time is less than the selected date, 
+		// don't create an appointment item for it.
+		if (vtype == E_CAL_COMPONENT_EVENT) {
+			if (ci->start < start_time_appointments) continue;
+		} else if (vtype == E_CAL_COMPONENT_TODO) {
+			if (ci->end < start_time_appointments) continue;
+		}
 		
 		if (i >= 5) continue;
 		i++;
+
+		g_debug("Create menu item");
 		
 		item = dbusmenu_menuitem_new();
 		dbusmenu_menuitem_property_set       (item, DBUSMENU_MENUITEM_PROP_TYPE, APPOINTMENT_MENUITEM_TYPE);
@@ -668,25 +742,6 @@
 		g_free (summary);
 
 		// Due text
-		ECalComponentVType vtype = e_cal_component_get_vtype (ecalcomp);
-		
-		// Get today
-		time_t curtime = time(NULL);
-  		struct tm *today = localtime(&curtime);
-		
-		int mday = today->tm_mday;
-		int mon = today->tm_mon;
-		int year = today->tm_year;
-		
-		struct tm *due;
-		if (vtype == E_CAL_COMPONENT_EVENT) due = localtime(&ci->start);
-		else if (vtype == E_CAL_COMPONENT_TODO) due = localtime(&ci->end);
-		else continue;
-
-		int dmday = due->tm_mday;
-		int dmon = due->tm_mon;
-		int dyear = due->tm_year;
-		
 		if (apt_output == SETTINGS_TIME_12_HOUR) {
 			if ((mday == dmday) && (mon == dmon) && (year == dyear))
 				strftime(right, 20, _(DEFAULT_TIME_12_FORMAT), due);
@@ -703,7 +758,6 @@
 			else
 				strftime(right, 20, _(DEFAULT_TIME_FORMAT_WITH_DAY), due);
 		}
-		
 		g_debug("Appointment time: %s, for date %s", right, asctime(due));
 		dbusmenu_menuitem_property_set (item, APPOINTMENT_MENUITEM_PROP_RIGHT, right);
 		
@@ -723,10 +777,9 @@
 		// Draw the correct icon for the appointment type and then tint it using mask fill.
 		// For now we'll create a circle
         if (color_spec != NULL) {
-        	// Fixme causes segfault, but we have colours now yay!
         	GdkColor color;
         	gdk_color_parse (color_spec, &color);	
-        	g_debug("Creating a cairo surface\n    size, %d by %d", width, height);         
+        	g_debug("Creating a cairo surface: size, %d by %d", width, height);         
         	cairo_surface_t *surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, width, height ); 
 
     		cairo_t *cr = cairo_create(surface);
@@ -771,13 +824,13 @@
 	  			
 				dbusmenu_menuitem_property_set_image (item, APPOINTMENT_MENUITEM_PROP_ICON, pixbuf);
 			} else {
-				g_debug("Creating pixbuf from surface failed\n    Couldn't create new pixbuf for size, %d by %d", width, height);
+				g_debug("Creating pixbuf from surface failed");
 			}
 			cairo_surface_destroy (surface);
 			cairo_destroy(cr);
 		}
 		dbusmenu_menuitem_child_add_position (root, item, 2+i);
-		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them east to remove
+		appointments = g_list_append         (appointments, item); // Keep track of the items here to make them easy to remove
 		g_debug("Adding appointment: %p", item);
 	}
 	
@@ -785,8 +838,8 @@
 	for (l = sorted_comp_instances; l; l = l->next) { 
 		const struct comp_instance *ci = l->data;
 		g_object_unref(ci->comp);
-		g_list_free(sorted_comp_instances);
 	}
+	g_list_free(sorted_comp_instances);
 	
 	updating_appointments = FALSE;
 	g_debug("End of objects");
@@ -820,6 +873,12 @@
 	check_timezone_sync();
 }
 
+static void
+time_format_changed (void)
+{
+	update_appointment_menu_items(NULL);
+}
+
 /* Does the work to build the default menu, really calls out
    to other functions but this is the core to clean up the
    main function. */
@@ -872,6 +931,7 @@
 	g_signal_connect (conf, "changed::" SETTINGS_SHOW_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
 	g_signal_connect (conf, "changed::" SETTINGS_LOCATIONS_S, G_CALLBACK (show_locations_changed), NULL);
 	g_signal_connect (conf, "changed::" SETTINGS_SHOW_EVENTS_S, G_CALLBACK (show_events_changed), NULL);
+	g_signal_connect (conf, "changed::" SETTINGS_TIME_FORMAT_S, G_CALLBACK (time_format_changed), NULL);
 
 	DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
 	dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);

=== modified file 'src/indicator-datetime.c'
--- src/indicator-datetime.c	2011-03-15 02:40:24 +0000
+++ src/indicator-datetime.c	2011-03-15 15:51:12 +0000
@@ -813,7 +813,7 @@
 	
 	if (self->priv->show_seconds ||
 		(self->priv->time_mode == SETTINGS_TIME_CUSTOM && self->priv->custom_show_seconds)) {
-		self->priv->timer = g_timeout_add_seconds(1, timer_func, self);
+		self->priv->timer = g_timeout_add_full(G_PRIORITY_HIGH, 865, timer_func, self, NULL);
 	} else {
 		if (datetime == NULL) {
 			datetime = g_date_time_new_now_local();
@@ -1154,9 +1154,9 @@
 	} else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_CLEAR_MARKS)) {
 		ido_calendar_menu_item_clear_marks (IDO_CALENDAR_MENU_ITEM (mi_data));
 	} else if (!g_strcmp0(prop, CALENDAR_MENUITEM_PROP_SET_DATE)) {
-		// const gint * array = g_variant_get_fixed_array(value, NULL, sizeof(gint));
-		// TODO: Needs ido branch merged - lp:~karl-qdh/ido/select-activate-set-date
-		// ido_calendar_menu_item_set_date (IDO_CALENDAR_MENU_ITEM (mi_data), array[0], array[1], array[2]);
+		gsize size = 3;
+		const gint * array = g_variant_get_fixed_array(value, &size, sizeof(gint));
+		ido_calendar_menu_item_set_date (IDO_CALENDAR_MENU_ITEM (mi_data), array[0], array[1], array[2]);
 	} else {
 		g_warning("Indicator Item property '%s' unknown", prop);
 	}
@@ -1257,13 +1257,10 @@
 	guint timestamp = (guint)time(NULL);
 	dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "month-changed", variant, timestamp);
 }
-
-// TODO: Needs ido branch merged - lp:~karl-qdh/ido/select-activate-set-date
-/*	
+	
 static void
 day_selected_cb (IdoCalendarMenuItem *ido,
-				  guint           day,
-                  gpointer        user_data) 
+                 gpointer        user_data) 
 {
 	guint d,m,y;
 	DbusmenuMenuitem * item = DBUSMENU_MENUITEM (user_data);
@@ -1281,7 +1278,6 @@
 
 static void
 day_selected_double_click_cb (IdoCalendarMenuItem *ido,
-				              guint           day,
                               gpointer        user_data) 
 {
 	guint d,m,y;
@@ -1297,8 +1293,6 @@
 	guint timestamp = (guint)time(NULL);
 	dbusmenu_menuitem_handle_event(DBUSMENU_MENUITEM(item), "day-selected-double-click", variant, timestamp);
 }
-*/
-
 
 static gboolean
 new_calendar_item (DbusmenuMenuitem * newitem,
@@ -1333,10 +1327,8 @@
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, GTK_MENU_ITEM(ido), parent);
 	g_signal_connect_after(ido, "month-changed", G_CALLBACK(month_changed_cb), (gpointer)newitem);
-	
-	// TODO: Needs ido branch merged - lp:~karl-qdh/ido/select-activate-set-date
-	/*g_signal_connect_after(ido, "day-selected", G_CALLBACK(day_selected_cb), (gpointer)newitem);
-	g_signal_connect_after(ido, "day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), (gpointer)newitem);*/
+	g_signal_connect_after(ido, "day-selected", G_CALLBACK(day_selected_cb), (gpointer)newitem);
+	g_signal_connect_after(ido, "day-selected-double-click", G_CALLBACK(day_selected_double_click_cb), (gpointer)newitem);
 
 	return TRUE;
 }


Follow ups