aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog19
-rw-r--r--calendar/Makefile.am4
-rw-r--r--calendar/gnome-cal.c23
-rw-r--r--calendar/gnome-cal.h2
-rw-r--r--calendar/gnome-month-item.c573
-rw-r--r--calendar/gnome-month-item.h68
-rw-r--r--calendar/gui/Makefile.am4
-rw-r--r--calendar/gui/gnome-cal.c23
-rw-r--r--calendar/gui/gnome-cal.h2
-rw-r--r--calendar/gui/gnome-month-item.c573
-rw-r--r--calendar/gui/gnome-month-item.h68
-rw-r--r--calendar/gui/month-view.c118
-rw-r--r--calendar/gui/month-view.h51
-rw-r--r--calendar/month-view.c118
-rw-r--r--calendar/month-view.h51
15 files changed, 1677 insertions, 20 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index ffa0f5107b..7de7dd2c19 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,22 @@
+1998-08-10 Federico Mena Quintero <federico@nuclecu.unam.mx>
+
+ * month-view.[ch]: Start of the month view widget. This will use
+ the generic month item and extend it to have the semantics desired
+ for the gnomecal month view.
+
+ * gnome-month-item.[ch]: New generic canvas item for the month
+ view and the "small calendars". This is intended to be a
+ high-level display engine for monthly calendars. This is a work
+ in progress.
+
+ * gnome-cal.h (GnomeCalendar): Added a month_view field.
+
+ * gnome-cal.c (setup_widgets): Create the month view and insert it
+ into the notebook.
+
+ * Makefile.am: Added month-view.[ch] and gnome-month-item.[ch] to
+ the sources.
+
1998-08-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
* main.c (about_calendar_cmd): Use an array of const strings to
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index f2d62adf9d..59260889c2 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -32,11 +32,15 @@ gnomecal_SOURCES = \
gncal-todo.h \
gncal-year-view.c \
gncal-year-view.h \
+ gnome-month-item.c \
+ gnome-month-item.h \
getdate.y \
gnome-cal.c \
gnome-cal.h \
main.c \
main.h \
+ month-view.c \
+ month-view.h \
popup-menu.c \
popup-menu.h \
prop.c \
diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c
index 9731bd855c..234f782fa3 100644
--- a/calendar/gnome-cal.c
+++ b/calendar/gnome-cal.c
@@ -15,6 +15,7 @@
#include "gncal-day-panel.h"
#include "gncal-week-view.h"
#include "gncal-year-view.h"
+#include "month-view.h"
#include "timeutil.h"
#include "views.h"
#include "main.h"
@@ -48,16 +49,18 @@ setup_widgets (GnomeCalendar *gcal)
now = time (NULL);
- gcal->notebook = gtk_notebook_new ();
- gcal->day_view = gncal_day_panel_new (gcal, now);
- gcal->week_view = gncal_week_view_new (gcal, now);
- gcal->year_view = gncal_year_view_new (gcal, now);
- gcal->task_view = tasks_create (gcal);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View")));
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View")));
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View")));
-/* gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); */
+ gcal->notebook = gtk_notebook_new ();
+ gcal->day_view = gncal_day_panel_new (gcal, now);
+ gcal->week_view = gncal_week_view_new (gcal, now);
+ gcal->month_view = month_view_new (gcal);
+ gcal->year_view = gncal_year_view_new (gcal, now);
+ gcal->task_view = tasks_create (gcal);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->month_view, gtk_label_new (_("Month View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View")));
+/* gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); */
gtk_widget_show_all (gcal->notebook);
diff --git a/calendar/gnome-cal.h b/calendar/gnome-cal.h
index 52ce26eaf9..ec1290a652 100644
--- a/calendar/gnome-cal.h
+++ b/calendar/gnome-cal.h
@@ -10,6 +10,7 @@
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gtkcalendar.h>
#include "calendar.h"
@@ -27,6 +28,7 @@ typedef struct {
GtkWidget *notebook;
GtkWidget *day_view;
GtkWidget *week_view;
+ GtkWidget *month_view;
GtkWidget *year_view;
GtkWidget *task_view;
void *event_editor;
diff --git a/calendar/gnome-month-item.c b/calendar/gnome-month-item.c
new file mode 100644
index 0000000000..fc30cdd85b
--- /dev/null
+++ b/calendar/gnome-month-item.c
@@ -0,0 +1,573 @@
+/* General-purpose monthly calendar canvas item for GNOME
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <time.h>
+#include <gnome.h>
+#include "gnome-month-item.h"
+
+
+/* These are indices into the items array of a GnomeMonthItem structure */
+enum {
+ ITEM_HEAD_GROUP = 0,
+ ITEM_HEAD_BOX = 7,
+ ITEM_HEAD_LABEL = 14
+};
+
+enum {
+ ARG_0,
+ ARG_YEAR,
+ ARG_MONTH,
+ ARG_X,
+ ARG_Y,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+ ARG_ANCHOR,
+ ARG_PADDING,
+ ARG_DAY_NAMES,
+ ARG_HEADING_HEIGHT,
+ ARG_HEADING_ANCHOR,
+ ARG_START_ON_MONDAY
+};
+
+
+static void gnome_month_item_class_init (GnomeMonthItemClass *class);
+static void gnome_month_item_init (GnomeMonthItem *mitem);
+static void gnome_month_item_destroy (GtkObject *object);
+static void gnome_month_item_set_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void gnome_month_item_get_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+
+
+
+static GnomeCanvasGroupClass *parent_class;
+
+
+GtkType
+gnome_month_item_get_type (void)
+{
+ static GtkType month_item_type = 0;
+
+ if (!month_item_type) {
+ GtkTypeInfo month_item_info = {
+ "GnomeMonthItem",
+ sizeof (GnomeMonthItem),
+ sizeof (GnomeMonthItemClass),
+ (GtkClassInitFunc) gnome_month_item_class_init,
+ (GtkObjectInitFunc) gnome_month_item_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ month_item_type = gtk_type_unique (gnome_canvas_group_get_type (), &month_item_info);
+ }
+
+ return month_item_type;
+}
+
+static void
+gnome_month_item_class_init (GnomeMonthItemClass *class)
+{
+ GtkObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ object_class = (GtkObjectClass *) class;
+ item_class = (GnomeCanvasItemClass *) class;
+
+ parent_class = gtk_type_class (gnome_canvas_group_get_type ());
+
+ gtk_object_add_arg_type ("GnomeMonthItem::year", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_YEAR);
+ gtk_object_add_arg_type ("GnomeMonthItem::month", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_MONTH);
+ gtk_object_add_arg_type ("GnomeMonthItem::x", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X);
+ gtk_object_add_arg_type ("GnomeMonthItem::y", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y);
+ gtk_object_add_arg_type ("GnomeMonthItem::width", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("GnomeMonthItem::height", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEIGHT);
+ gtk_object_add_arg_type ("GnomeMonthItem::anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_ANCHOR);
+ gtk_object_add_arg_type ("GnomeMonthItem::padding", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_PADDING);
+ gtk_object_add_arg_type ("GnomeMonthItem::day_names", GTK_TYPE_POINTER, GTK_ARG_READABLE, ARG_DAY_NAMES);
+ gtk_object_add_arg_type ("GnomeMonthItem::heading_height", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEADING_HEIGHT);
+ gtk_object_add_arg_type ("GnomeMonthItem::heading_anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_HEADING_ANCHOR);
+ gtk_object_add_arg_type ("GnomeMonthItem::start_on_monday", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_START_ON_MONDAY);
+
+ object_class->destroy = gnome_month_item_destroy;
+ object_class->set_arg = gnome_month_item_set_arg;
+ object_class->get_arg = gnome_month_item_get_arg;
+}
+
+/* Takes an anchor specification and the corners of a rectangle, and returns an anchored point with
+ * respect to that rectangle.
+ */
+static void
+get_label_anchor (GtkAnchorType anchor, double x1, double y1, double x2, double y2, double *x, double *y)
+{
+ switch (anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_SW:
+ *x = x1;
+ break;
+
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ *x = (x1 + x2) / 2.0;
+ break;
+
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ *x = x2;
+ break;
+ }
+
+ switch (anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_NE:
+ *y = y1;
+ break;
+
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ *y = (y1 + y2) / 2.0;
+ break;
+
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ *y = y2;
+ break;
+ }
+}
+
+/* Resets the position of the day name headings in the calendar */
+static void
+reshape_headings (GnomeMonthItem *mitem)
+{
+ double width;
+ int i;
+ double x, y;
+
+ width = mitem->width / 7;
+
+ for (i = 0; i < 7; i++) {
+ /* Group */
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_GROUP + i],
+ "x", width * i,
+ "y", 0.0,
+ NULL);
+
+ /* Box */
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_BOX + i],
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", width,
+ "y2", mitem->head_height,
+ NULL);
+
+ /* Label */
+ get_label_anchor (mitem->head_anchor,
+ mitem->padding,
+ mitem->padding,
+ width - mitem->padding,
+ mitem->head_height - mitem->padding,
+ &x, &y);
+
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_LABEL + i],
+ "x", x,
+ "y", y,
+ "anchor", mitem->head_anchor,
+ NULL);
+ }
+}
+
+/* Changes the positions and resizes the items in the calendar to match the new size of the
+ * calendar.
+ */
+static void
+reshape (GnomeMonthItem *mitem)
+{
+ reshape_headings (mitem);
+}
+
+/* Creates the items for the day name headings */
+static void
+create_headings (GnomeMonthItem *mitem)
+{
+ int i;
+
+ /* Just create the items; they will be positioned and configured by a call to reshape() */
+
+ for (i = 0; i < 7; i++) {
+ /* Group */
+ mitem->items[ITEM_HEAD_GROUP + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem),
+ gnome_canvas_group_get_type (),
+ NULL);
+
+ /* Box */
+ mitem->items[ITEM_HEAD_BOX + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem->items[ITEM_HEAD_GROUP + i]),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "black",
+ NULL);
+
+ /* Label */
+ mitem->items[ITEM_HEAD_LABEL + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem->items[ITEM_HEAD_GROUP + i]),
+ gnome_canvas_text_get_type (),
+ "fill_color", "white",
+ NULL);
+ }
+}
+
+/* Returns a normalized day index (as in sunday to saturday) based on a visible day index */
+static int
+get_day_index (GnomeMonthItem *mitem, int draw_index)
+{
+ if (mitem->start_on_monday)
+ return (draw_index + 1) % 7;
+ else
+ return draw_index;
+}
+
+/* Resets the text of the day name headings */
+static void
+set_day_names (GnomeMonthItem *mitem)
+{
+ int i;
+
+ for (i = 0; i < 7; i++)
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_LABEL + get_day_index (mitem, i)],
+ "text", mitem->day_names[get_day_index (mitem, i)],
+ NULL);
+}
+
+/* Creates all the canvas items that make up the calendar */
+static void
+create_items (GnomeMonthItem *mitem)
+{
+ /* 7 heading groups
+ * 7 heading boxes
+ * 7 heading labels
+ * ------------------
+ * 21 items total
+ */
+
+ mitem->items = g_new (GnomeCanvasItem *, 21);
+
+ create_headings (mitem);
+ /* FIXME */
+
+ /* Initialize by default to three-letter day names */
+
+ mitem->day_names[0] = _("Sun");
+ mitem->day_names[1] = _("Mon");
+ mitem->day_names[2] = _("Tue");
+ mitem->day_names[3] = _("Wed");
+ mitem->day_names[4] = _("Thu");
+ mitem->day_names[5] = _("Fri");
+ mitem->day_names[6] = _("Sat");
+
+ set_day_names (mitem);
+ reshape (mitem);
+}
+
+static void
+gnome_month_item_init (GnomeMonthItem *mitem)
+{
+ time_t t;
+ struct tm *tm;
+
+ /* Initialize to the current month by default */
+
+ t = time (NULL);
+ tm = localtime (&t);
+
+ mitem->year = tm->tm_year + 1900;
+ mitem->month = tm->tm_mon;
+
+ mitem->x = 0.0;
+ mitem->y = 0.0;
+ mitem->width = 150.0; /* not unreasonable defaults, I hope */
+ mitem->height = 100.0;
+ mitem->anchor = GTK_ANCHOR_NW;
+ mitem->padding = 0.0;
+ mitem->head_height = 14.0;
+ mitem->head_anchor = GTK_ANCHOR_CENTER;
+}
+
+GnomeCanvasItem *
+gnome_month_item_new (GnomeCanvasGroup *parent)
+{
+ GnomeMonthItem *mitem;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (GNOME_IS_CANVAS_GROUP (parent), NULL);
+
+ mitem = GNOME_MONTH_ITEM (gnome_canvas_item_new (parent,
+ gnome_month_item_get_type (),
+ NULL));
+
+ gnome_month_item_construct (mitem);
+
+ return GNOME_CANVAS_ITEM (mitem);
+}
+
+void
+gnome_month_item_construct (GnomeMonthItem *mitem)
+{
+ g_return_if_fail (mitem != NULL);
+ g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
+
+ create_items (mitem);
+}
+
+static void
+free_day_names (GnomeMonthItem *mitem)
+{
+ int i;
+
+ if (mitem->day_names[0])
+ for (i = 0; i < 7; i++)
+ g_free (mitem->day_names[i]);
+}
+
+static void
+gnome_month_item_destroy (GtkObject *object)
+{
+ GnomeMonthItem *mitem;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GNOME_IS_MONTH_ITEM (object));
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ free_day_names (mitem);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* Recalculates the position of the toplevel calendar group based on the logical position and anchor */
+static void
+reanchor (GnomeMonthItem *mitem)
+{
+ double x, y;
+
+ x = mitem->x;
+ y = mitem->y;
+
+ switch (mitem->anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_SW:
+ break;
+
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ x -= mitem->width / 2;
+ break;
+
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ x -= mitem->width;
+ break;
+ }
+
+ switch (mitem->anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_NE:
+ break;
+
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ y -= mitem->height / 2;
+ break;
+
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ y -= mitem->height;
+ break;
+ }
+
+ /* Explicitly use the canvas group class prefix since the month item class has x and y
+ * arguments as well.
+ */
+
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
+ "GnomeCanvasGroup::x", x,
+ "GnomeCanvasGroup::y", y,
+ NULL);
+}
+
+static void
+recalc_month (GnomeMonthItem *mitem)
+{
+ /* FIXME */
+}
+
+static void
+gnome_month_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ GnomeMonthItem *mitem;
+ char **day_names;
+ int i;
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ switch (arg_id) {
+ case ARG_YEAR:
+ mitem->year = GTK_VALUE_UINT (*arg);
+ recalc_month (mitem);
+ break;
+
+ case ARG_MONTH:
+ mitem->month = GTK_VALUE_UINT (*arg);
+ recalc_month (mitem);
+ break;
+
+ case ARG_X:
+ mitem->x = GTK_VALUE_DOUBLE (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_Y:
+ mitem->y = GTK_VALUE_DOUBLE (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_WIDTH:
+ mitem->width = fabs (GTK_VALUE_DOUBLE (*arg));
+ reanchor (mitem);
+ reshape (mitem);
+ break;
+
+ case ARG_HEIGHT:
+ mitem->height = fabs (GTK_VALUE_DOUBLE (*arg));
+ reanchor (mitem);
+ reshape (mitem);
+ break;
+
+ case ARG_ANCHOR:
+ mitem->anchor = GTK_VALUE_ENUM (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_PADDING:
+ mitem->padding = fabs (GTK_VALUE_DOUBLE (*arg));
+ reshape (mitem);
+ break;
+
+ case ARG_DAY_NAMES:
+ day_names = GTK_VALUE_POINTER (*arg);
+
+ /* First, check that none of the names is null */
+
+ for (i = 0; i < 7; i++)
+ if (!day_names[i]) {
+ g_warning ("Day number %d was NULL; day names cannot be NULL!", i);
+ return;
+ }
+
+ /* Set the new names */
+
+ free_day_names (mitem);
+ for (i = 0; i < 7; i++)
+ mitem->day_names[i] = g_strdup (day_names[i]);
+
+ set_day_names (mitem);
+ break;
+
+ case ARG_HEADING_HEIGHT:
+ mitem->head_height = fabs (GTK_VALUE_DOUBLE (*arg));
+ reshape (mitem);
+ break;
+
+ case ARG_HEADING_ANCHOR:
+ mitem->head_anchor = GTK_VALUE_ENUM (*arg);
+ reshape (mitem);
+ break;
+
+ case ARG_START_ON_MONDAY:
+ mitem->start_on_monday = GTK_VALUE_BOOL (*arg);
+ set_day_names (mitem);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+gnome_month_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ GnomeMonthItem *mitem;
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ switch (arg_id) {
+ case ARG_YEAR:
+ GTK_VALUE_UINT (*arg) = mitem->year;
+ break;
+
+ case ARG_MONTH:
+ GTK_VALUE_UINT (*arg) = mitem->month;
+ break;
+
+ case ARG_X:
+ GTK_VALUE_DOUBLE (*arg) = mitem->x;
+ break;
+
+ case ARG_Y:
+ GTK_VALUE_DOUBLE (*arg) = mitem->y;
+ break;
+
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = mitem->width;
+ break;
+
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = mitem->height;
+ break;
+
+ case ARG_ANCHOR:
+ GTK_VALUE_ENUM (*arg) = mitem->anchor;
+ break;
+
+ case ARG_PADDING:
+ GTK_VALUE_DOUBLE (*arg) = mitem->padding;
+ break;
+
+ case ARG_HEADING_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = mitem->head_height;
+ break;
+
+ case ARG_HEADING_ANCHOR:
+ GTK_VALUE_ENUM (*arg) = mitem->head_anchor;
+ break;
+
+ case ARG_START_ON_MONDAY:
+ GTK_VALUE_BOOL (*arg) = mitem->start_on_monday;
+ break;
+
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/calendar/gnome-month-item.h b/calendar/gnome-month-item.h
new file mode 100644
index 0000000000..2260186c6d
--- /dev/null
+++ b/calendar/gnome-month-item.h
@@ -0,0 +1,68 @@
+/* General-purpose monthly calendar canvas item for GNOME
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#ifndef GNOME_MONTH_ITEM_H
+#define GNOME_MONTH_ITEM_H
+
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkpacker.h> /* why the hell is GtkAnchorType here and not in gtkenums.h? */
+#include <libgnomeui/gnome-canvas.h>
+
+
+BEGIN_GNOME_DECLS
+
+
+#define GNOME_TYPE_MONTH_ITEM (gnome_month_item_get_type ())
+#define GNOME_MONTH_ITEM(obj) (GTK_CHECK_CAST ((obj), GNOME_TYPE_MONTH_ITEM, GnomeMonthItem))
+#define GNOME_MONTH_ITEM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_MONTH_ITEM, GnomeMonthItemClass))
+#define GNOME_IS_MONTH_ITEM(obj) (GTK_CHECK_TYPE ((obj), GNOME_TYPE_MONTH_ITEM))
+#define GNOME_IS_MONTH_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_MONTH_ITEM))
+
+
+typedef struct _GnomeMonthItem GnomeMonthItem;
+typedef struct _GnomeMonthItemClass GnomeMonthItemClass;
+
+struct _GnomeMonthItem {
+ GnomeCanvasGroup group;
+
+ int year; /* Year to show (full, no two-digit crap) */
+ int month; /* Month to show (0-11) */
+
+ double x, y; /* Position at anchor */
+ double width, height; /* Size of calendar */
+ GtkAnchorType anchor; /* Anchor side for calendar */
+
+ double padding; /* Padding to use between division lines and text */
+
+ char *day_names[7]; /* Names to use for the day labels, starting from Sunday */
+
+ double head_height; /* Height of the headings row */
+ GtkAnchorType head_anchor; /* Anchor side for the heading labels */
+
+ GnomeCanvasItem **items; /* All the items that make up the calendar */
+
+ int start_on_monday : 1; /* Start the week on Monday? If false, then start from Sunday */
+};
+
+struct _GnomeMonthItemClass {
+ GnomeCanvasGroupClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType gnome_month_item_get_type (void);
+
+/* Creates a new month item with the specified group as parent */
+GnomeCanvasItem *gnome_month_item_new (GnomeCanvasGroup *parent);
+
+/* Constructor function useful for derived classes */
+void gnome_month_item_construct (GnomeMonthItem *mitem);
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index f2d62adf9d..59260889c2 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -32,11 +32,15 @@ gnomecal_SOURCES = \
gncal-todo.h \
gncal-year-view.c \
gncal-year-view.h \
+ gnome-month-item.c \
+ gnome-month-item.h \
getdate.y \
gnome-cal.c \
gnome-cal.h \
main.c \
main.h \
+ month-view.c \
+ month-view.h \
popup-menu.c \
popup-menu.h \
prop.c \
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 9731bd855c..234f782fa3 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -15,6 +15,7 @@
#include "gncal-day-panel.h"
#include "gncal-week-view.h"
#include "gncal-year-view.h"
+#include "month-view.h"
#include "timeutil.h"
#include "views.h"
#include "main.h"
@@ -48,16 +49,18 @@ setup_widgets (GnomeCalendar *gcal)
now = time (NULL);
- gcal->notebook = gtk_notebook_new ();
- gcal->day_view = gncal_day_panel_new (gcal, now);
- gcal->week_view = gncal_week_view_new (gcal, now);
- gcal->year_view = gncal_year_view_new (gcal, now);
- gcal->task_view = tasks_create (gcal);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View")));
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View")));
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View")));
-/* gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); */
+ gcal->notebook = gtk_notebook_new ();
+ gcal->day_view = gncal_day_panel_new (gcal, now);
+ gcal->week_view = gncal_week_view_new (gcal, now);
+ gcal->month_view = month_view_new (gcal);
+ gcal->year_view = gncal_year_view_new (gcal, now);
+ gcal->task_view = tasks_create (gcal);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->month_view, gtk_label_new (_("Month View")));
+ gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View")));
+/* gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); */
gtk_widget_show_all (gcal->notebook);
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 52ce26eaf9..ec1290a652 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -10,6 +10,7 @@
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gnome-app.h>
+#include <libgnomeui/gtkcalendar.h>
#include "calendar.h"
@@ -27,6 +28,7 @@ typedef struct {
GtkWidget *notebook;
GtkWidget *day_view;
GtkWidget *week_view;
+ GtkWidget *month_view;
GtkWidget *year_view;
GtkWidget *task_view;
void *event_editor;
diff --git a/calendar/gui/gnome-month-item.c b/calendar/gui/gnome-month-item.c
new file mode 100644
index 0000000000..fc30cdd85b
--- /dev/null
+++ b/calendar/gui/gnome-month-item.c
@@ -0,0 +1,573 @@
+/* General-purpose monthly calendar canvas item for GNOME
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#include <config.h>
+#include <math.h>
+#include <time.h>
+#include <gnome.h>
+#include "gnome-month-item.h"
+
+
+/* These are indices into the items array of a GnomeMonthItem structure */
+enum {
+ ITEM_HEAD_GROUP = 0,
+ ITEM_HEAD_BOX = 7,
+ ITEM_HEAD_LABEL = 14
+};
+
+enum {
+ ARG_0,
+ ARG_YEAR,
+ ARG_MONTH,
+ ARG_X,
+ ARG_Y,
+ ARG_WIDTH,
+ ARG_HEIGHT,
+ ARG_ANCHOR,
+ ARG_PADDING,
+ ARG_DAY_NAMES,
+ ARG_HEADING_HEIGHT,
+ ARG_HEADING_ANCHOR,
+ ARG_START_ON_MONDAY
+};
+
+
+static void gnome_month_item_class_init (GnomeMonthItemClass *class);
+static void gnome_month_item_init (GnomeMonthItem *mitem);
+static void gnome_month_item_destroy (GtkObject *object);
+static void gnome_month_item_set_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void gnome_month_item_get_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+
+
+
+static GnomeCanvasGroupClass *parent_class;
+
+
+GtkType
+gnome_month_item_get_type (void)
+{
+ static GtkType month_item_type = 0;
+
+ if (!month_item_type) {
+ GtkTypeInfo month_item_info = {
+ "GnomeMonthItem",
+ sizeof (GnomeMonthItem),
+ sizeof (GnomeMonthItemClass),
+ (GtkClassInitFunc) gnome_month_item_class_init,
+ (GtkObjectInitFunc) gnome_month_item_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ month_item_type = gtk_type_unique (gnome_canvas_group_get_type (), &month_item_info);
+ }
+
+ return month_item_type;
+}
+
+static void
+gnome_month_item_class_init (GnomeMonthItemClass *class)
+{
+ GtkObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ object_class = (GtkObjectClass *) class;
+ item_class = (GnomeCanvasItemClass *) class;
+
+ parent_class = gtk_type_class (gnome_canvas_group_get_type ());
+
+ gtk_object_add_arg_type ("GnomeMonthItem::year", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_YEAR);
+ gtk_object_add_arg_type ("GnomeMonthItem::month", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_MONTH);
+ gtk_object_add_arg_type ("GnomeMonthItem::x", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X);
+ gtk_object_add_arg_type ("GnomeMonthItem::y", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y);
+ gtk_object_add_arg_type ("GnomeMonthItem::width", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH);
+ gtk_object_add_arg_type ("GnomeMonthItem::height", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEIGHT);
+ gtk_object_add_arg_type ("GnomeMonthItem::anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_ANCHOR);
+ gtk_object_add_arg_type ("GnomeMonthItem::padding", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_PADDING);
+ gtk_object_add_arg_type ("GnomeMonthItem::day_names", GTK_TYPE_POINTER, GTK_ARG_READABLE, ARG_DAY_NAMES);
+ gtk_object_add_arg_type ("GnomeMonthItem::heading_height", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEADING_HEIGHT);
+ gtk_object_add_arg_type ("GnomeMonthItem::heading_anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_HEADING_ANCHOR);
+ gtk_object_add_arg_type ("GnomeMonthItem::start_on_monday", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_START_ON_MONDAY);
+
+ object_class->destroy = gnome_month_item_destroy;
+ object_class->set_arg = gnome_month_item_set_arg;
+ object_class->get_arg = gnome_month_item_get_arg;
+}
+
+/* Takes an anchor specification and the corners of a rectangle, and returns an anchored point with
+ * respect to that rectangle.
+ */
+static void
+get_label_anchor (GtkAnchorType anchor, double x1, double y1, double x2, double y2, double *x, double *y)
+{
+ switch (anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_SW:
+ *x = x1;
+ break;
+
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ *x = (x1 + x2) / 2.0;
+ break;
+
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ *x = x2;
+ break;
+ }
+
+ switch (anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_NE:
+ *y = y1;
+ break;
+
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ *y = (y1 + y2) / 2.0;
+ break;
+
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ *y = y2;
+ break;
+ }
+}
+
+/* Resets the position of the day name headings in the calendar */
+static void
+reshape_headings (GnomeMonthItem *mitem)
+{
+ double width;
+ int i;
+ double x, y;
+
+ width = mitem->width / 7;
+
+ for (i = 0; i < 7; i++) {
+ /* Group */
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_GROUP + i],
+ "x", width * i,
+ "y", 0.0,
+ NULL);
+
+ /* Box */
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_BOX + i],
+ "x1", 0.0,
+ "y1", 0.0,
+ "x2", width,
+ "y2", mitem->head_height,
+ NULL);
+
+ /* Label */
+ get_label_anchor (mitem->head_anchor,
+ mitem->padding,
+ mitem->padding,
+ width - mitem->padding,
+ mitem->head_height - mitem->padding,
+ &x, &y);
+
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_LABEL + i],
+ "x", x,
+ "y", y,
+ "anchor", mitem->head_anchor,
+ NULL);
+ }
+}
+
+/* Changes the positions and resizes the items in the calendar to match the new size of the
+ * calendar.
+ */
+static void
+reshape (GnomeMonthItem *mitem)
+{
+ reshape_headings (mitem);
+}
+
+/* Creates the items for the day name headings */
+static void
+create_headings (GnomeMonthItem *mitem)
+{
+ int i;
+
+ /* Just create the items; they will be positioned and configured by a call to reshape() */
+
+ for (i = 0; i < 7; i++) {
+ /* Group */
+ mitem->items[ITEM_HEAD_GROUP + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem),
+ gnome_canvas_group_get_type (),
+ NULL);
+
+ /* Box */
+ mitem->items[ITEM_HEAD_BOX + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem->items[ITEM_HEAD_GROUP + i]),
+ gnome_canvas_rect_get_type (),
+ "fill_color", "black",
+ NULL);
+
+ /* Label */
+ mitem->items[ITEM_HEAD_LABEL + i] =
+ gnome_canvas_item_new (GNOME_CANVAS_GROUP (mitem->items[ITEM_HEAD_GROUP + i]),
+ gnome_canvas_text_get_type (),
+ "fill_color", "white",
+ NULL);
+ }
+}
+
+/* Returns a normalized day index (as in sunday to saturday) based on a visible day index */
+static int
+get_day_index (GnomeMonthItem *mitem, int draw_index)
+{
+ if (mitem->start_on_monday)
+ return (draw_index + 1) % 7;
+ else
+ return draw_index;
+}
+
+/* Resets the text of the day name headings */
+static void
+set_day_names (GnomeMonthItem *mitem)
+{
+ int i;
+
+ for (i = 0; i < 7; i++)
+ gnome_canvas_item_set (mitem->items[ITEM_HEAD_LABEL + get_day_index (mitem, i)],
+ "text", mitem->day_names[get_day_index (mitem, i)],
+ NULL);
+}
+
+/* Creates all the canvas items that make up the calendar */
+static void
+create_items (GnomeMonthItem *mitem)
+{
+ /* 7 heading groups
+ * 7 heading boxes
+ * 7 heading labels
+ * ------------------
+ * 21 items total
+ */
+
+ mitem->items = g_new (GnomeCanvasItem *, 21);
+
+ create_headings (mitem);
+ /* FIXME */
+
+ /* Initialize by default to three-letter day names */
+
+ mitem->day_names[0] = _("Sun");
+ mitem->day_names[1] = _("Mon");
+ mitem->day_names[2] = _("Tue");
+ mitem->day_names[3] = _("Wed");
+ mitem->day_names[4] = _("Thu");
+ mitem->day_names[5] = _("Fri");
+ mitem->day_names[6] = _("Sat");
+
+ set_day_names (mitem);
+ reshape (mitem);
+}
+
+static void
+gnome_month_item_init (GnomeMonthItem *mitem)
+{
+ time_t t;
+ struct tm *tm;
+
+ /* Initialize to the current month by default */
+
+ t = time (NULL);
+ tm = localtime (&t);
+
+ mitem->year = tm->tm_year + 1900;
+ mitem->month = tm->tm_mon;
+
+ mitem->x = 0.0;
+ mitem->y = 0.0;
+ mitem->width = 150.0; /* not unreasonable defaults, I hope */
+ mitem->height = 100.0;
+ mitem->anchor = GTK_ANCHOR_NW;
+ mitem->padding = 0.0;
+ mitem->head_height = 14.0;
+ mitem->head_anchor = GTK_ANCHOR_CENTER;
+}
+
+GnomeCanvasItem *
+gnome_month_item_new (GnomeCanvasGroup *parent)
+{
+ GnomeMonthItem *mitem;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (GNOME_IS_CANVAS_GROUP (parent), NULL);
+
+ mitem = GNOME_MONTH_ITEM (gnome_canvas_item_new (parent,
+ gnome_month_item_get_type (),
+ NULL));
+
+ gnome_month_item_construct (mitem);
+
+ return GNOME_CANVAS_ITEM (mitem);
+}
+
+void
+gnome_month_item_construct (GnomeMonthItem *mitem)
+{
+ g_return_if_fail (mitem != NULL);
+ g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
+
+ create_items (mitem);
+}
+
+static void
+free_day_names (GnomeMonthItem *mitem)
+{
+ int i;
+
+ if (mitem->day_names[0])
+ for (i = 0; i < 7; i++)
+ g_free (mitem->day_names[i]);
+}
+
+static void
+gnome_month_item_destroy (GtkObject *object)
+{
+ GnomeMonthItem *mitem;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GNOME_IS_MONTH_ITEM (object));
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ free_day_names (mitem);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* Recalculates the position of the toplevel calendar group based on the logical position and anchor */
+static void
+reanchor (GnomeMonthItem *mitem)
+{
+ double x, y;
+
+ x = mitem->x;
+ y = mitem->y;
+
+ switch (mitem->anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_SW:
+ break;
+
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ x -= mitem->width / 2;
+ break;
+
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ x -= mitem->width;
+ break;
+ }
+
+ switch (mitem->anchor) {
+ case GTK_ANCHOR_NW:
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_NE:
+ break;
+
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ y -= mitem->height / 2;
+ break;
+
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ y -= mitem->height;
+ break;
+ }
+
+ /* Explicitly use the canvas group class prefix since the month item class has x and y
+ * arguments as well.
+ */
+
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
+ "GnomeCanvasGroup::x", x,
+ "GnomeCanvasGroup::y", y,
+ NULL);
+}
+
+static void
+recalc_month (GnomeMonthItem *mitem)
+{
+ /* FIXME */
+}
+
+static void
+gnome_month_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ GnomeMonthItem *mitem;
+ char **day_names;
+ int i;
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ switch (arg_id) {
+ case ARG_YEAR:
+ mitem->year = GTK_VALUE_UINT (*arg);
+ recalc_month (mitem);
+ break;
+
+ case ARG_MONTH:
+ mitem->month = GTK_VALUE_UINT (*arg);
+ recalc_month (mitem);
+ break;
+
+ case ARG_X:
+ mitem->x = GTK_VALUE_DOUBLE (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_Y:
+ mitem->y = GTK_VALUE_DOUBLE (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_WIDTH:
+ mitem->width = fabs (GTK_VALUE_DOUBLE (*arg));
+ reanchor (mitem);
+ reshape (mitem);
+ break;
+
+ case ARG_HEIGHT:
+ mitem->height = fabs (GTK_VALUE_DOUBLE (*arg));
+ reanchor (mitem);
+ reshape (mitem);
+ break;
+
+ case ARG_ANCHOR:
+ mitem->anchor = GTK_VALUE_ENUM (*arg);
+ reanchor (mitem);
+ break;
+
+ case ARG_PADDING:
+ mitem->padding = fabs (GTK_VALUE_DOUBLE (*arg));
+ reshape (mitem);
+ break;
+
+ case ARG_DAY_NAMES:
+ day_names = GTK_VALUE_POINTER (*arg);
+
+ /* First, check that none of the names is null */
+
+ for (i = 0; i < 7; i++)
+ if (!day_names[i]) {
+ g_warning ("Day number %d was NULL; day names cannot be NULL!", i);
+ return;
+ }
+
+ /* Set the new names */
+
+ free_day_names (mitem);
+ for (i = 0; i < 7; i++)
+ mitem->day_names[i] = g_strdup (day_names[i]);
+
+ set_day_names (mitem);
+ break;
+
+ case ARG_HEADING_HEIGHT:
+ mitem->head_height = fabs (GTK_VALUE_DOUBLE (*arg));
+ reshape (mitem);
+ break;
+
+ case ARG_HEADING_ANCHOR:
+ mitem->head_anchor = GTK_VALUE_ENUM (*arg);
+ reshape (mitem);
+ break;
+
+ case ARG_START_ON_MONDAY:
+ mitem->start_on_monday = GTK_VALUE_BOOL (*arg);
+ set_day_names (mitem);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+gnome_month_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+{
+ GnomeMonthItem *mitem;
+
+ mitem = GNOME_MONTH_ITEM (object);
+
+ switch (arg_id) {
+ case ARG_YEAR:
+ GTK_VALUE_UINT (*arg) = mitem->year;
+ break;
+
+ case ARG_MONTH:
+ GTK_VALUE_UINT (*arg) = mitem->month;
+ break;
+
+ case ARG_X:
+ GTK_VALUE_DOUBLE (*arg) = mitem->x;
+ break;
+
+ case ARG_Y:
+ GTK_VALUE_DOUBLE (*arg) = mitem->y;
+ break;
+
+ case ARG_WIDTH:
+ GTK_VALUE_DOUBLE (*arg) = mitem->width;
+ break;
+
+ case ARG_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = mitem->height;
+ break;
+
+ case ARG_ANCHOR:
+ GTK_VALUE_ENUM (*arg) = mitem->anchor;
+ break;
+
+ case ARG_PADDING:
+ GTK_VALUE_DOUBLE (*arg) = mitem->padding;
+ break;
+
+ case ARG_HEADING_HEIGHT:
+ GTK_VALUE_DOUBLE (*arg) = mitem->head_height;
+ break;
+
+ case ARG_HEADING_ANCHOR:
+ GTK_VALUE_ENUM (*arg) = mitem->head_anchor;
+ break;
+
+ case ARG_START_ON_MONDAY:
+ GTK_VALUE_BOOL (*arg) = mitem->start_on_monday;
+ break;
+
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
diff --git a/calendar/gui/gnome-month-item.h b/calendar/gui/gnome-month-item.h
new file mode 100644
index 0000000000..2260186c6d
--- /dev/null
+++ b/calendar/gui/gnome-month-item.h
@@ -0,0 +1,68 @@
+/* General-purpose monthly calendar canvas item for GNOME
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#ifndef GNOME_MONTH_ITEM_H
+#define GNOME_MONTH_ITEM_H
+
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkpacker.h> /* why the hell is GtkAnchorType here and not in gtkenums.h? */
+#include <libgnomeui/gnome-canvas.h>
+
+
+BEGIN_GNOME_DECLS
+
+
+#define GNOME_TYPE_MONTH_ITEM (gnome_month_item_get_type ())
+#define GNOME_MONTH_ITEM(obj) (GTK_CHECK_CAST ((obj), GNOME_TYPE_MONTH_ITEM, GnomeMonthItem))
+#define GNOME_MONTH_ITEM_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_MONTH_ITEM, GnomeMonthItemClass))
+#define GNOME_IS_MONTH_ITEM(obj) (GTK_CHECK_TYPE ((obj), GNOME_TYPE_MONTH_ITEM))
+#define GNOME_IS_MONTH_ITEM_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_MONTH_ITEM))
+
+
+typedef struct _GnomeMonthItem GnomeMonthItem;
+typedef struct _GnomeMonthItemClass GnomeMonthItemClass;
+
+struct _GnomeMonthItem {
+ GnomeCanvasGroup group;
+
+ int year; /* Year to show (full, no two-digit crap) */
+ int month; /* Month to show (0-11) */
+
+ double x, y; /* Position at anchor */
+ double width, height; /* Size of calendar */
+ GtkAnchorType anchor; /* Anchor side for calendar */
+
+ double padding; /* Padding to use between division lines and text */
+
+ char *day_names[7]; /* Names to use for the day labels, starting from Sunday */
+
+ double head_height; /* Height of the headings row */
+ GtkAnchorType head_anchor; /* Anchor side for the heading labels */
+
+ GnomeCanvasItem **items; /* All the items that make up the calendar */
+
+ int start_on_monday : 1; /* Start the week on Monday? If false, then start from Sunday */
+};
+
+struct _GnomeMonthItemClass {
+ GnomeCanvasGroupClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType gnome_month_item_get_type (void);
+
+/* Creates a new month item with the specified group as parent */
+GnomeCanvasItem *gnome_month_item_new (GnomeCanvasGroup *parent);
+
+/* Constructor function useful for derived classes */
+void gnome_month_item_construct (GnomeMonthItem *mitem);
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/month-view.c b/calendar/gui/month-view.c
new file mode 100644
index 0000000000..78eec0c91d
--- /dev/null
+++ b/calendar/gui/month-view.c
@@ -0,0 +1,118 @@
+/* Month view display for gncal
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#include <config.h>
+#include "month-view.h"
+
+
+static void month_view_class_init (MonthViewClass *class);
+static void month_view_init (MonthView *mv);
+static void month_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void month_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+
+static GnomeCanvasClass *parent_class;
+
+
+GtkType
+month_view_get_type (void)
+{
+ static GtkType month_view_type = 0;
+
+ if (!month_view_type) {
+ GtkTypeInfo month_view_info = {
+ "MonthView",
+ sizeof (MonthView),
+ sizeof (MonthViewClass),
+ (GtkClassInitFunc) month_view_class_init,
+ (GtkObjectInitFunc) month_view_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ month_view_type = gtk_type_unique (gnome_canvas_get_type (), &month_view_info);
+ }
+
+ return month_view_type;
+}
+
+static void
+month_view_class_init (MonthViewClass *class)
+{
+ GtkWidgetClass *widget_class;
+
+ widget_class = (GtkWidgetClass *) class;
+
+ parent_class = gtk_type_class (gnome_canvas_get_type ());
+
+ widget_class->size_request = month_view_size_request;
+ widget_class->size_allocate = month_view_size_allocate;
+}
+
+static void
+month_view_init (MonthView *mv)
+{
+ mv->mitem = gnome_month_item_new (GNOME_CANVAS_GROUP (mv->canvas.root));
+ gnome_canvas_item_set (mv->mitem,
+ "x", 0.0,
+ "y", 0.0,
+ "anchor", GTK_ANCHOR_NW,
+ NULL);
+}
+
+GtkWidget *
+month_view_new (GnomeCalendar *calendar)
+{
+ MonthView *mv;
+
+ g_return_val_if_fail (calendar != NULL, NULL);
+
+ mv = gtk_type_new (month_view_get_type ());
+
+ mv->calendar = calendar;
+
+ return GTK_WIDGET (mv);
+}
+
+static void
+month_view_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (requisition != NULL);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_request)
+ (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
+
+ requisition->width = 200;
+ requisition->height = 150;
+}
+
+static void
+month_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ MonthView *mv;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (allocation != NULL);
+
+ mv = MONTH_VIEW (widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+ (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+ gnome_canvas_set_scroll_region (GNOME_CANVAS (mv), 0, 0, allocation->width, allocation->height);
+
+ gnome_canvas_item_set (mv->mitem,
+ "width", (double) allocation->width,
+ "height", (double) allocation->height,
+ NULL);
+}
diff --git a/calendar/gui/month-view.h b/calendar/gui/month-view.h
new file mode 100644
index 0000000000..0f35817d78
--- /dev/null
+++ b/calendar/gui/month-view.h
@@ -0,0 +1,51 @@
+/* Month view display for gncal
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#ifndef MONTH_VIEW_H
+#define MONTH_VIEW_H
+
+#include <libgnome/gnome-defs.h>
+#include "gnome-cal.h"
+#include "gnome-month-item.h"
+
+
+BEGIN_GNOME_DECLS
+
+
+#define TYPE_MONTH_VIEW (month_view_get_type ())
+#define MONTH_VIEW(obj) (GTK_CHECK_CAST ((obj), TYPE_MONTH_VIEW, MonthView))
+#define MONTH_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_MONTH_VIEW, MonthViewClass))
+#define IS_MONTH_VIEW(obj) (GTK_CHECK_TYPE ((obj), TYPE_MONTH_VIEW))
+#define IS_MONTH_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_MONTH_VIEW))
+
+
+typedef struct _MonthView MonthView;
+typedef struct _MonthViewClass MonthViewClass;
+
+struct _MonthView {
+ GnomeCanvas canvas;
+
+ GnomeCalendar *calendar; /* The calendar we are associated to */
+
+ GnomeCanvasItem *mitem; /* The canvas month item used by this month view */
+};
+
+struct _MonthViewClass {
+ GnomeCanvasClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType month_view_get_type (void);
+
+/* Creates a new month view widget associated to the specified calendar */
+GtkWidget *month_view_new (GnomeCalendar *calendar);
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/month-view.c b/calendar/month-view.c
new file mode 100644
index 0000000000..78eec0c91d
--- /dev/null
+++ b/calendar/month-view.c
@@ -0,0 +1,118 @@
+/* Month view display for gncal
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#include <config.h>
+#include "month-view.h"
+
+
+static void month_view_class_init (MonthViewClass *class);
+static void month_view_init (MonthView *mv);
+static void month_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void month_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+
+static GnomeCanvasClass *parent_class;
+
+
+GtkType
+month_view_get_type (void)
+{
+ static GtkType month_view_type = 0;
+
+ if (!month_view_type) {
+ GtkTypeInfo month_view_info = {
+ "MonthView",
+ sizeof (MonthView),
+ sizeof (MonthViewClass),
+ (GtkClassInitFunc) month_view_class_init,
+ (GtkObjectInitFunc) month_view_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ month_view_type = gtk_type_unique (gnome_canvas_get_type (), &month_view_info);
+ }
+
+ return month_view_type;
+}
+
+static void
+month_view_class_init (MonthViewClass *class)
+{
+ GtkWidgetClass *widget_class;
+
+ widget_class = (GtkWidgetClass *) class;
+
+ parent_class = gtk_type_class (gnome_canvas_get_type ());
+
+ widget_class->size_request = month_view_size_request;
+ widget_class->size_allocate = month_view_size_allocate;
+}
+
+static void
+month_view_init (MonthView *mv)
+{
+ mv->mitem = gnome_month_item_new (GNOME_CANVAS_GROUP (mv->canvas.root));
+ gnome_canvas_item_set (mv->mitem,
+ "x", 0.0,
+ "y", 0.0,
+ "anchor", GTK_ANCHOR_NW,
+ NULL);
+}
+
+GtkWidget *
+month_view_new (GnomeCalendar *calendar)
+{
+ MonthView *mv;
+
+ g_return_val_if_fail (calendar != NULL, NULL);
+
+ mv = gtk_type_new (month_view_get_type ());
+
+ mv->calendar = calendar;
+
+ return GTK_WIDGET (mv);
+}
+
+static void
+month_view_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (requisition != NULL);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_request)
+ (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
+
+ requisition->width = 200;
+ requisition->height = 150;
+}
+
+static void
+month_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ MonthView *mv;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (allocation != NULL);
+
+ mv = MONTH_VIEW (widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+ (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+ gnome_canvas_set_scroll_region (GNOME_CANVAS (mv), 0, 0, allocation->width, allocation->height);
+
+ gnome_canvas_item_set (mv->mitem,
+ "width", (double) allocation->width,
+ "height", (double) allocation->height,
+ NULL);
+}
diff --git a/calendar/month-view.h b/calendar/month-view.h
new file mode 100644
index 0000000000..0f35817d78
--- /dev/null
+++ b/calendar/month-view.h
@@ -0,0 +1,51 @@
+/* Month view display for gncal
+ *
+ * Copyright (C) 1998 Red Hat Software, Inc.
+ *
+ * Author: Federico Mena <federico@nuclecu.unam.mx>
+ */
+
+#ifndef MONTH_VIEW_H
+#define MONTH_VIEW_H
+
+#include <libgnome/gnome-defs.h>
+#include "gnome-cal.h"
+#include "gnome-month-item.h"
+
+
+BEGIN_GNOME_DECLS
+
+
+#define TYPE_MONTH_VIEW (month_view_get_type ())
+#define MONTH_VIEW(obj) (GTK_CHECK_CAST ((obj), TYPE_MONTH_VIEW, MonthView))
+#define MONTH_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_MONTH_VIEW, MonthViewClass))
+#define IS_MONTH_VIEW(obj) (GTK_CHECK_TYPE ((obj), TYPE_MONTH_VIEW))
+#define IS_MONTH_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_MONTH_VIEW))
+
+
+typedef struct _MonthView MonthView;
+typedef struct _MonthViewClass MonthViewClass;
+
+struct _MonthView {
+ GnomeCanvas canvas;
+
+ GnomeCalendar *calendar; /* The calendar we are associated to */
+
+ GnomeCanvasItem *mitem; /* The canvas month item used by this month view */
+};
+
+struct _MonthViewClass {
+ GnomeCanvasClass parent_class;
+};
+
+
+/* Standard Gtk function */
+GtkType month_view_get_type (void);
+
+/* Creates a new month view widget associated to the specified calendar */
+GtkWidget *month_view_new (GnomeCalendar *calendar);
+
+
+END_GNOME_DECLS
+
+#endif