25 #include "gnc-dense-cal.h"
26 #include "gnc-dense-cal-model.h"
29 #include <glib/gi18n.h>
66 static const int DENSE_CAL_DEFAULT_WIDTH = 15;
67 static const int DENSE_CAL_DEFAULT_HEIGHT = 105;
68 static const int MINOR_BORDER_SIZE = 1;
69 static const int COL_BORDER_SIZE = 3;
71 static const gchar* MONTH_THIS_COLOR =
"lavender";
72 static const gchar* MONTH_THAT_COLOR =
"SlateGray1";
74 static const gchar* MARK_COLOR =
"Yellow";
77 #define G_LOG_DOMAIN "gnc.gui.dense-cal"
81 static void gnc_dense_cal_finalize(GObject *
object);
82 static void gnc_dense_cal_dispose(GObject *
object);
83 static void gnc_dense_cal_realize(GtkWidget *widget, gpointer user_data);
84 static void gnc_dense_cal_configure(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data);
85 static void gnc_dense_cal_draw_to_buffer(
GncDenseCal *dcal);
86 static gboolean gnc_dense_cal_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data);
90 static void gdc_free_all_mark_data(
GncDenseCal *dcal);
92 static void _gdc_compute_min_size(
GncDenseCal *dcal,
93 guint *min_width, guint *min_height);
94 static void _gdc_set_cal_min_size_req(
GncDenseCal *dcal);
95 static gint gnc_dense_cal_motion_notify(GtkWidget *widget,
96 GdkEventMotion *event);
97 static gint gnc_dense_cal_button_press(GtkWidget *widget,
100 static void _gdc_view_option_changed(GtkComboBox *widget, gpointer user_data);
102 static inline int day_width_at(
GncDenseCal *dcal, guint xScale);
104 static inline int day_height_at(
GncDenseCal *dcal, guint yScale);
106 static inline int week_width_at(
GncDenseCal *dcal, guint xScale);
108 static inline int week_height_at(
GncDenseCal *dcal, guint yScale);
110 static inline int col_width_at(
GncDenseCal *dcal, guint xScale);
116 static void _gnc_dense_cal_set_month(
GncDenseCal *dcal, GDateMonth mon, gboolean redraw);
117 static void _gnc_dense_cal_set_year(
GncDenseCal *dcal, guint year, gboolean redraw);
132 static gint wheres_this(
GncDenseCal *dcal,
int x,
int y);
134 static void recompute_x_y_scales(
GncDenseCal *dcal);
135 static void recompute_mark_storage(
GncDenseCal *dcal);
137 static void populate_hover_window(
GncDenseCal *dcal, gint doc);
139 static void month_coords(
GncDenseCal *dcal,
int monthOfCal, GList **outList);
140 static void doc_coords(
GncDenseCal *dcal,
int dayOfCal,
141 int *x1,
int *y1,
int *x2,
int *y2);
143 static void gdc_mark_add(
GncDenseCal *dcal, guint tag, gchar *name, gchar *info, guint size, GDate **dateArray);
144 static void gdc_mark_remove(
GncDenseCal *dcal, guint mark_to_remove, gboolean redraw);
146 static void gdc_add_tag_markings(
GncDenseCal *cal, guint tag);
150 static GObject *parent_class = NULL;
152 #define MONTH_NAME_BUFSIZE 10
160 static gchar buf[MONTH_NAME_BUFSIZE];
162 gint arbitrary_year = 1977;
164 memset(buf, 0, MONTH_NAME_BUFSIZE);
165 g_date_clear(&date, 1);
167 g_date_set_year(&date, arbitrary_year);
168 g_date_set_day(&date, 1);
170 g_date_set_month(&date, mon + 1);
171 g_date_strftime(buf, MONTH_NAME_BUFSIZE,
"%b", &date);
179 day_label(gchar *buf,
int buf_len,
int dow)
183 if (g_utf8_strlen(buf, -1) > 2)
185 gchar *pointer = g_utf8_offset_to_pointer(buf, 2);
191 gnc_dense_cal_get_type()
193 static GType dense_cal_type = 0;
195 if (dense_cal_type == 0)
197 static const GTypeInfo dense_cal_info =
202 (GClassInitFunc) gnc_dense_cal_class_init,
207 (GInstanceInitFunc) gnc_dense_cal_init,
211 dense_cal_type = g_type_register_static(GTK_TYPE_VBOX,
216 return dense_cal_type;
222 GObjectClass *object_class;
223 GtkWidgetClass *widget_class;
225 object_class = G_OBJECT_CLASS (klass);
226 widget_class = GTK_WIDGET_CLASS (klass);
228 parent_class = g_type_class_peek_parent (klass);
230 object_class->finalize = gnc_dense_cal_finalize;
231 object_class->dispose = gnc_dense_cal_dispose;
233 widget_class->motion_notify_event = gnc_dense_cal_motion_notify;
234 widget_class->button_press_event = gnc_dense_cal_button_press;
237 enum _GdcViewOptsColumns
239 VIEW_OPTS_COLUMN_LABEL = 0,
240 VIEW_OPTS_COLUMN_NUM_MONTHS
243 static GtkListStore *_cal_view_options = NULL;
245 _gdc_get_view_options(
void)
247 if (_cal_view_options == NULL)
249 _cal_view_options = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
250 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"12 months"), 1, 12, -1);
251 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"6 months"), 1, 6, -1);
252 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"4 months"), 1, 4, -1);
253 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"3 months"), 1, 3, -1);
254 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"2 months"), 1, 2, -1);
255 gtk_list_store_insert_with_values(_cal_view_options, NULL, G_MAXINT, 0, _(
"1 month"), 1, 1, -1);
258 return _cal_view_options;
264 gboolean colorAllocSuccess[MAX_COLORS];
266 gtk_widget_push_composite_child();
269 GtkTreeModel *options;
270 GtkCellRenderer *text_rend;
272 options = GTK_TREE_MODEL(_gdc_get_view_options());
273 dcal->view_options = GTK_COMBO_BOX(gtk_combo_box_new_with_model(options));
274 gtk_combo_box_set_active(GTK_COMBO_BOX(dcal->view_options), 0);
275 text_rend = GTK_CELL_RENDERER(gtk_cell_renderer_text_new());
276 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dcal->view_options), text_rend, TRUE);
277 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(dcal->view_options),
278 text_rend,
"text", VIEW_OPTS_COLUMN_LABEL);
279 g_signal_connect(G_OBJECT(dcal->view_options),
"changed", G_CALLBACK(_gdc_view_option_changed), (gpointer)dcal);
283 GtkHBox *hbox = GTK_HBOX(gtk_hbox_new(FALSE, 0));
284 GtkAlignment *label_align;
286 float right_align = 1.0, mid_align = 0.5, fill_x = 0.0, fill_y = 1.0;
288 label = GTK_LABEL(gtk_label_new(_(
"View:")));
289 label_align = GTK_ALIGNMENT(gtk_alignment_new(right_align, mid_align, fill_x, fill_y));
290 gtk_container_add(GTK_CONTAINER(label_align), GTK_WIDGET(label));
291 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label_align), TRUE, TRUE, 0);
292 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(dcal->view_options), FALSE, FALSE, 0);
294 gtk_box_pack_start(GTK_BOX(dcal), GTK_WIDGET(hbox), FALSE, FALSE, 0);
296 dcal->cal_drawing_area = GTK_DRAWING_AREA(gtk_drawing_area_new());
297 gtk_widget_add_events(GTK_WIDGET(dcal->cal_drawing_area), (GDK_EXPOSURE_MASK
298 | GDK_BUTTON_PRESS_MASK
299 | GDK_BUTTON_RELEASE_MASK
300 | GDK_POINTER_MOTION_MASK
301 | GDK_POINTER_MOTION_HINT_MASK));
302 gtk_box_pack_start(GTK_BOX(dcal), GTK_WIDGET(dcal->cal_drawing_area), TRUE, TRUE, 0);
303 g_signal_connect(G_OBJECT(dcal->cal_drawing_area),
"expose_event", G_CALLBACK(gnc_dense_cal_expose), (gpointer)dcal);
304 g_signal_connect(G_OBJECT(dcal->cal_drawing_area),
"realize", G_CALLBACK(gnc_dense_cal_realize), (gpointer)dcal);
305 g_signal_connect(G_OBJECT(dcal->cal_drawing_area),
"configure_event", G_CALLBACK(gnc_dense_cal_configure), (gpointer)dcal);
307 dcal->disposed = FALSE;
308 dcal->initialized = FALSE;
312 dcal->lastMarkTag = 0;
314 dcal->showPopup = FALSE;
316 dcal->transPopup = GTK_WINDOW(gtk_window_new(GTK_WINDOW_POPUP));
318 GtkWidget *vbox, *hbox;
320 GtkListStore *tree_data;
321 GtkTreeView *tree_view;
323 vbox = gtk_vbox_new(FALSE, 5);
324 hbox = gtk_hbox_new(FALSE, 5);
326 l = gtk_label_new(_(
"Date: "));
327 gtk_container_add(GTK_CONTAINER(hbox), l);
328 l = gtk_label_new(
"YY/MM/DD");
329 g_object_set_data(G_OBJECT(dcal->transPopup),
"dateLabel", l);
330 gtk_container_add(GTK_CONTAINER(hbox), l);
331 gtk_container_add(GTK_CONTAINER(vbox), hbox);
333 gtk_container_add(GTK_CONTAINER(vbox), gtk_hseparator_new());
335 tree_data = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
336 tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_data)));
337 gtk_tree_view_insert_column_with_attributes(tree_view, -1, _(
"Name"), gtk_cell_renderer_text_new(),
"text", 0, NULL);
338 gtk_tree_view_insert_column_with_attributes(tree_view, -1, _(
"Frequency"), gtk_cell_renderer_text_new(),
"text", 1, NULL);
339 g_object_set_data(G_OBJECT(dcal->transPopup),
"model", tree_data);
340 gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(tree_view));
342 gtk_container_add(GTK_CONTAINER(dcal->transPopup), vbox);
344 gtk_window_set_resizable(GTK_WINDOW(dcal->transPopup), FALSE);
346 gtk_widget_realize(GTK_WIDGET(dcal->transPopup));
349 gdk_color_parse(MONTH_THIS_COLOR, &dcal->weekColors[MONTH_THIS]);
350 gdk_color_parse(MONTH_THAT_COLOR, &dcal->weekColors[MONTH_THAT]);
353 g_assert(MAX_COLORS == (
sizeof(colorAllocSuccess)/
sizeof(gboolean)));
355 if (gdk_colormap_alloc_colors(gdk_colormap_get_system(),
357 MAX_COLORS, TRUE, TRUE,
358 colorAllocSuccess) > 0)
360 g_error(
"error allocating colors");
366 gint maxWidth, maxHeight;
369 PangoFontDescription *font_desc;
371 gint font_size_reduction_units = 1;
373 layout = gtk_widget_create_pango_layout(GTK_WIDGET(dcal), NULL);
375 style = gtk_widget_get_style(GTK_WIDGET(dcal));
377 font_desc = pango_font_description_copy(style->font_desc);
378 font_size = pango_font_description_get_size(font_desc);
379 font_size -= font_size_reduction_units * PANGO_SCALE;
380 pango_font_description_set_size(font_desc, font_size);
381 gtk_widget_modify_font(GTK_WIDGET(dcal), font_desc);
382 pango_font_description_free(font_desc);
384 maxWidth = maxHeight = 0;
385 for (i = 0; i < 12; i++)
388 pango_layout_set_text(layout, month_name(i), -1);
389 pango_layout_get_pixel_size(layout, &w, &h);
390 maxWidth = MAX(maxWidth, w);
391 maxHeight = MAX(maxHeight, h);
395 dcal->label_width = maxWidth;
396 dcal->label_height = maxHeight;
398 g_object_unref(layout);
401 dcal->month = G_DATE_JANUARY;
404 dcal->numMonths = 12;
405 dcal->monthsPerCol = 3;
406 dcal->leftPadding = 2;
407 dcal->topPadding = 2;
411 g_date_clear (&now, 1);
413 _gnc_dense_cal_set_month(dcal, g_date_get_month(&now), FALSE);
414 _gnc_dense_cal_set_year(dcal, g_date_get_year(&now), FALSE);
417 recompute_extents(dcal);
418 recompute_mark_storage(dcal);
424 int width_88, height_88;
425 int width_XXX, height_XXX;
427 layout = gtk_widget_create_pango_layout(GTK_WIDGET(dcal), NULL);
429 pango_layout_set_text(layout,
"88", -1);
430 pango_layout_get_pixel_size(layout, &width_88, &height_88);
432 pango_layout_set_text(layout,
"XXX", -1);
433 pango_layout_get_pixel_size(layout, &width_XXX, &height_XXX);
435 dcal->min_x_scale = dcal->x_scale = width_88 + 2;
436 dcal->min_y_scale = dcal->y_scale = MAX(floor((
float)width_XXX / 3.), height_88 + 2);
438 dcal->dayLabelHeight = height_88;
440 g_object_unref(layout);
443 dcal->initialized = TRUE;
446 dcal->week_starts_monday = 0;
449 const char *week_start_str;
453 #define dgettext_noextract dgettext
457 week_start_str = dgettext_noextract(
"gtk20",
"calendar:week_start:0");
458 #undef dgettext_noextract
460 parts = g_strsplit(week_start_str,
":", 3);
465 if (strcmp(
"1", parts[2]) == 0)
466 dcal->week_starts_monday = 1;
471 gtk_widget_pop_composite_child();
473 gtk_widget_show_all(GTK_WIDGET(dcal));
479 guint min_width, min_height;
481 _gdc_compute_min_size(dcal, &min_width, &min_height);
482 gtk_widget_set_size_request(GTK_WIDGET(dcal->cal_drawing_area), min_width, min_height);
486 gnc_dense_cal_new(
void)
489 dcal = g_object_new(GNC_TYPE_DENSE_CAL, NULL);
490 return GTK_WIDGET(dcal);
494 gnc_dense_cal_new_with_model(GncDenseCalModel *model)
496 GncDenseCal *cal = GNC_DENSE_CAL(gnc_dense_cal_new());
497 gnc_dense_cal_set_model(cal, model);
498 return GTK_WIDGET(cal);
506 tmpDate = g_date_new_dmy(1, dcal->month, dcal->year);
507 dcal->firstOfMonthOffset = g_date_get_weekday(tmpDate) % 7;
508 g_date_free(tmpDate);
512 gnc_dense_cal_set_month(
GncDenseCal *dcal, GDateMonth mon)
514 _gnc_dense_cal_set_month(dcal, mon, TRUE);
518 _gnc_dense_cal_set_month(
GncDenseCal *dcal, GDateMonth mon, gboolean redraw)
520 GTimer *t = g_timer_new();
521 if (dcal->month == mon)
525 recompute_first_of_month_offset(dcal);
526 g_debug(
"recompute_first_of_month_offset: %f", g_timer_elapsed(t, NULL) * 1000.);
528 recompute_extents(dcal);
529 g_debug(
"recompute_extents: %f", g_timer_elapsed(t, NULL) * 1000.);
530 if (redraw && gtk_widget_get_realized(GTK_WIDGET(dcal)))
533 recompute_x_y_scales(dcal);
534 g_debug(
"recompute_x_y_scales: %f", g_timer_elapsed(t, NULL) * 1000.);
536 gnc_dense_cal_draw_to_buffer(dcal);
537 g_debug(
"draw_to_buffer: %f", g_timer_elapsed(t, NULL) * 1000.);
539 gtk_widget_queue_draw(GTK_WIDGET(dcal->cal_drawing_area));
540 g_debug(
"queue_draw: %f", g_timer_elapsed(t, NULL) * 1000.);
547 gnc_dense_cal_set_year(
GncDenseCal *dcal, guint year)
549 _gnc_dense_cal_set_year(dcal, year, TRUE);
553 _gnc_dense_cal_set_year(
GncDenseCal *dcal, guint year, gboolean redraw)
555 if (dcal->year == year)
558 recompute_first_of_month_offset(dcal);
559 recompute_extents(dcal);
560 if (redraw && gtk_widget_get_realized(GTK_WIDGET(dcal)))
562 recompute_x_y_scales(dcal);
563 gnc_dense_cal_draw_to_buffer(dcal);
564 gtk_widget_queue_draw(GTK_WIDGET(dcal->cal_drawing_area));
569 gnc_dense_cal_set_num_months(
GncDenseCal *dcal, guint num_months)
572 GtkListStore *options = _gdc_get_view_options();
573 GtkTreeIter view_opts_iter, iter_closest_to_req;
574 int closest_index_distance = G_MAXINT;
577 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(options), &view_opts_iter))
579 g_critical(
"no view options?");
585 gint months_val, delta_months;
587 gtk_tree_model_get(GTK_TREE_MODEL(options), &view_opts_iter, VIEW_OPTS_COLUMN_NUM_MONTHS, &months_val, -1);
588 delta_months = abs(months_val - (gint)num_months);
589 if (delta_months < closest_index_distance)
591 iter_closest_to_req = view_opts_iter;
592 closest_index_distance = delta_months;
595 while (closest_index_distance != 0
596 && (gtk_tree_model_iter_next(GTK_TREE_MODEL(options), &view_opts_iter)));
599 g_signal_handlers_block_by_func(dcal->view_options, _gdc_view_option_changed, dcal);
600 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dcal->view_options), &iter_closest_to_req);
601 g_signal_handlers_unblock_by_func(dcal->view_options, _gdc_view_option_changed, dcal);
604 dcal->numMonths = num_months;
605 recompute_extents(dcal);
606 recompute_mark_storage(dcal);
607 if (gtk_widget_get_realized(GTK_WIDGET(dcal)))
609 recompute_x_y_scales(dcal);
610 gnc_dense_cal_draw_to_buffer(dcal);
611 gtk_widget_queue_draw(GTK_WIDGET(dcal->cal_drawing_area));
618 return dcal->numMonths;
622 gnc_dense_cal_set_months_per_col(
GncDenseCal *dcal, guint monthsPerCol)
624 dcal->monthsPerCol = monthsPerCol;
625 recompute_x_y_scales(dcal);
641 gnc_dense_cal_dispose (GObject *
object)
644 g_return_if_fail(
object != NULL);
645 g_return_if_fail(GNC_IS_DENSE_CAL(
object));
647 dcal = GNC_DENSE_CAL(
object);
651 dcal->disposed = TRUE;
653 if (gtk_widget_get_realized(GTK_WIDGET(dcal->transPopup)))
655 gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
656 gtk_widget_destroy(GTK_WIDGET(dcal->transPopup));
657 dcal->transPopup = NULL;
662 g_object_unref(dcal->drawbuf);
663 dcal->drawbuf = NULL;
668 gdc_free_all_mark_data(dcal);
670 g_object_unref(G_OBJECT(dcal->model));
672 if (G_OBJECT_CLASS (parent_class)->dispose)
673 G_OBJECT_CLASS(parent_class)->dispose(
object);
677 gnc_dense_cal_finalize (GObject *
object)
679 g_return_if_fail (
object != NULL);
680 g_return_if_fail (GNC_IS_DENSE_CAL (
object));
682 if (G_OBJECT_CLASS (parent_class)->finalize)
683 G_OBJECT_CLASS(parent_class)->finalize(
object);
687 gnc_dense_cal_configure(GtkWidget *widget,
688 GdkEventConfigure *event,
692 recompute_x_y_scales(dcal);
694 gtk_widget_queue_draw_area(widget,
696 event->width, event->height);
700 gnc_dense_cal_realize (GtkWidget *widget, gpointer user_data)
704 g_return_if_fail(widget != NULL);
705 g_return_if_fail(GNC_IS_DENSE_CAL (user_data));
706 dcal = GNC_DENSE_CAL(user_data);
708 recompute_x_y_scales(dcal);
711 gtk_style_set_background(widget->style, widget->window, GTK_STATE_ACTIVE);
718 g_object_unref(dcal->drawbuf);
719 dcal->drawbuf = gdk_pixmap_new(GTK_WIDGET(dcal->cal_drawing_area)->window,
720 GTK_WIDGET(dcal->cal_drawing_area)->allocation.width,
721 GTK_WIDGET(dcal->cal_drawing_area)->allocation.height,
723 gnc_dense_cal_draw_to_buffer(dcal);
727 _gdc_compute_min_size(
GncDenseCal *dcal, guint *min_width, guint *min_height)
729 if (min_width != NULL)
732 (dcal->leftPadding * 2)
733 + (num_cols(dcal) * (col_width_at(dcal, dcal->min_x_scale)
734 + dcal->label_width))
735 + ((num_cols(dcal) - 1) * COL_BORDER_SIZE);
738 if (min_height != NULL)
741 (dcal->topPadding * 2)
743 + dcal->dayLabelHeight
744 + (num_weeks_per_col(dcal)
745 * week_height_at(dcal, dcal->min_y_scale));
755 width = DENSE_CAL_DEFAULT_WIDTH;
756 height = DENSE_CAL_DEFAULT_HEIGHT;
757 if (dcal->initialized)
759 width = GTK_WIDGET(dcal->cal_drawing_area)->allocation.width;
760 height = GTK_WIDGET(dcal->cal_drawing_area)->allocation.height;
765 denom = 7 * num_cols(dcal);
766 g_assert(denom != 0);
767 dcal->x_scale = ((gint)(width
768 - (dcal->leftPadding * 2)
769 - (num_cols(dcal) * ((8 * MINOR_BORDER_SIZE)
770 + dcal->label_width))
771 - ((num_cols(dcal) - 1) * COL_BORDER_SIZE))
773 dcal->x_scale = MAX(dcal->x_scale, dcal->min_x_scale);
775 denom = num_weeks_per_col(dcal);
776 g_assert(denom != 0);
777 dcal->y_scale = ((gint)(height
778 - (dcal->topPadding * 2)
780 - dcal->dayLabelHeight
781 - (num_weeks_per_col(dcal) - 1
782 * MINOR_BORDER_SIZE))
784 dcal->y_scale = MAX(dcal->y_scale, dcal->min_y_scale);
786 _gdc_set_cal_min_size_req(dcal);
794 for (i = 0; i < dcal->numMarks; i++)
798 g_list_free(dcal->marks[i]);
803 for (l = dcal->
markData; l; l = l->next)
815 if (dcal->marks == NULL)
817 gdc_free_all_mark_data(dcal);
820 dcal->numMarks = num_weeks(dcal) * 7;
821 dcal->marks = g_new0(GList*, dcal->numMarks);
823 gdc_add_markings(dcal);
830 gint start_week, end_week;
832 g_date_clear(&date, 1);
833 g_date_set_dmy(&date, 1, dcal->month, dcal->year);
834 start_week = (dcal->week_starts_monday
835 ? g_date_get_monday_week_of_year(&date)
836 : g_date_get_sunday_week_of_year(&date));
837 g_date_add_months(&date, dcal->numMonths);
838 end_week = (dcal->week_starts_monday
839 ? g_date_get_monday_week_of_year(&date)
840 : g_date_get_sunday_week_of_year(&date));
841 if (g_date_get_year(&date) != dcal->year)
843 end_week += (dcal->week_starts_monday
844 ? g_date_get_monday_weeks_in_year(dcal->year)
845 : g_date_get_sunday_weeks_in_year(dcal->year));
847 dcal->num_weeks = end_week - start_week + 1;
851 free_rect(gpointer data, gpointer ud)
853 g_free((GdkRectangle*)data);
857 gnc_dense_cal_expose(GtkWidget *widget,
858 GdkEventExpose *event,
864 g_return_val_if_fail(widget != NULL, FALSE);
865 g_return_val_if_fail(GNC_IS_DENSE_CAL(user_data), FALSE);
866 g_return_val_if_fail(event != NULL, FALSE);
868 if (event->count > 0)
871 dcal = GNC_DENSE_CAL(user_data);
872 gc = widget->style->fg_gc[gtk_widget_get_state(widget)];
873 gdk_draw_drawable(GDK_DRAWABLE(GTK_WIDGET(dcal->cal_drawing_area)->window),
874 gc, GDK_DRAWABLE(dcal->drawbuf),
880 #define LOG_AND_RESET(timer, msg) do { g_debug("%s: %f", msg, g_timer_elapsed(timer, NULL) * 1000.); g_timer_reset(timer); } while (0);
891 timer = g_timer_new();
893 widget = GTK_WIDGET(dcal);
898 g_timer_start(timer);
899 layout = gtk_widget_create_pango_layout(GTK_WIDGET(dcal), NULL);
900 LOG_AND_RESET(timer,
"create_pango_layout");
902 gdk_draw_rectangle(dcal->drawbuf,
903 widget->style->white_gc,
906 GTK_WIDGET(dcal->cal_drawing_area)->allocation.width,
907 GTK_WIDGET(dcal->cal_drawing_area)->allocation.height);
914 GList *mcList, *mcListIter;
916 gc = gdk_gc_new(GTK_WIDGET(dcal)->window);
917 gdk_gc_copy(gc, widget->style->fg_gc[gtk_widget_get_state(widget)]);
920 for (i = 0; i < 12; i++)
922 dcal->monthPositions[i].x = dcal->monthPositions[i].y = -1;
926 for (i = 0; i < dcal->numMonths; i++)
928 gdk_gc_set_foreground(gc, &dcal->weekColors[ i % 2 ]);
931 month_coords(dcal, i, &mcList);
932 dcal->monthPositions[i].x
933 = floor(i / dcal->monthsPerCol)
934 * (col_width(dcal) + COL_BORDER_SIZE);
935 dcal->monthPositions[i].y = ((GdkRectangle*)mcList->next->next->data)->y;
936 for (mcListIter = mcList; mcListIter != NULL; mcListIter = mcListIter->next)
938 rect = (GdkRectangle*)mcListIter->data;
939 gdk_draw_rectangle(dcal->drawbuf, gc,
940 TRUE, rect->x, rect->y,
941 rect->width, rect->height);
943 g_list_foreach(mcList, free_rect, NULL);
949 LOG_AND_RESET(timer,
"alternating month colors");
956 GdkGCValues current_values;
958 gdk_gc_get_values(widget->style->fg_gc[widget->state], ¤t_values);
960 gdk_color_parse(MARK_COLOR, &markColor);
961 gdk_colormap_alloc_color(gdk_colormap_get_system(), &markColor, TRUE, TRUE);
963 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], &markColor);
964 for (i = 0; i < dcal->numMarks; i++)
966 if (dcal->marks[i] != NULL)
968 int w, h, x_offset, y_offset, circle_delta;
970 doc_coords(dcal, i, &x1, &y1, &x2, &y2);
977 circle_delta = ABS(w - h) / 2;
980 y_offset += circle_delta;
984 x_offset += circle_delta;
987 gdk_draw_arc(dcal->drawbuf,
988 widget->style->fg_gc[widget->state],
990 x_offset, y_offset, MIN(w, h), MIN(w, h),
997 gdk_gc_set_foreground(widget->style->fg_gc[widget->state], ¤t_values.foreground);
999 LOG_AND_RESET(timer,
"marked days");
1001 for (i = 0; i < num_cols(dcal); i++)
1006 pango_layout_set_text(layout,
"S", -1);
1007 pango_layout_get_pixel_size(layout, NULL, &dcal->dayLabelHeight);
1009 x = dcal->leftPadding
1010 + (i * (col_width(dcal) + COL_BORDER_SIZE))
1011 + dcal->label_width;
1012 y = dcal->topPadding + dcal->dayLabelHeight;
1013 w = col_width(dcal) - COL_BORDER_SIZE - dcal->label_width;
1014 h = col_height(dcal);
1017 gdk_draw_rectangle(dcal->drawbuf,
1018 widget->style->fg_gc[widget->state],
1021 for (j = 0; j < num_weeks_per_col(dcal); j++)
1023 gint wy = y + (j * week_height(dcal));
1024 gdk_draw_line(dcal->drawbuf,
1025 widget->style->fg_gc[widget->state],
1031 for (j = 1; j < 7; j++)
1033 gint dx = x + (j * day_width(dcal));
1034 gdk_draw_line(dcal->drawbuf,
1035 widget->style->fg_gc[widget->state],
1037 dx, y + col_height(dcal));
1041 pango_layout_set_text(layout,
"88", -1);
1042 pango_layout_get_pixel_size(layout, &maxWidth, NULL);
1044 if (dcal->x_scale > maxWidth)
1046 for (j = 0; j < 7; j++)
1048 int day_label_width;
1049 gint label_x_offset, label_y_offset;
1050 gint day_label_str_len = 3;
1051 gchar day_label_str[day_label_str_len+1];
1053 day_label(day_label_str, day_label_str_len, (j + dcal->week_starts_monday) % 7);
1054 pango_layout_set_text(layout, day_label_str, -1);
1055 pango_layout_get_pixel_size(layout, &day_label_width, NULL);
1057 + (j * day_width(dcal))
1058 + (day_width(dcal) / 2)
1059 - (day_label_width / 2);
1060 label_y_offset = y - dcal->dayLabelHeight;
1061 pango_layout_set_text(layout, day_label_str, -1);
1062 gdk_draw_layout(GDK_DRAWABLE(dcal->drawbuf), widget->style->fg_gc[widget->state],
1063 label_x_offset, label_y_offset,
1069 LOG_AND_RESET(timer,
"lines and labels");
1074 PangoMatrix matrix = PANGO_MATRIX_INIT;
1076 pango_matrix_rotate(&matrix, 90.);
1077 pango_context_set_matrix(gtk_widget_get_pango_context(GTK_WIDGET(dcal)), &matrix);
1079 for (i = 0; i < 12; i++)
1083 if (dcal->monthPositions[i].x == -1)
1085 idx = (dcal->month - 1 + i) % 12;
1086 pango_layout_set_text(layout, month_name(idx), -1);
1087 gdk_draw_layout(GDK_DRAWABLE(dcal->drawbuf),
1088 widget->style->fg_gc[widget->state],
1089 dcal->leftPadding + dcal->monthPositions[i].x,
1090 dcal->monthPositions[i].y,
1095 pango_matrix_rotate(&matrix, -90.);
1096 pango_context_set_matrix(gtk_widget_get_pango_context(GTK_WIDGET(dcal)), &matrix);
1098 LOG_AND_RESET(timer,
"month labels");
1106 gint x1, y1, x2, y2, w, h;
1108 g_date_set_dmy(&d, 1, dcal->month, dcal->year);
1110 g_date_add_months(&eoc, dcal->numMonths);
1111 for (doc = 0; g_date_get_julian(&d) < g_date_get_julian(&eoc); g_date_add_days(&d, 1), doc++)
1113 doc_coords(dcal, doc, &x1, &y1, &x2, &y2);
1114 memset(dayNumBuf, 0, 3);
1115 snprintf(dayNumBuf, 3,
"%d", g_date_get_day(&d));
1116 pango_layout_set_text(layout, dayNumBuf, -1);
1117 pango_layout_get_pixel_size(layout, &numW, &numH);
1120 gdk_draw_layout(GDK_DRAWABLE(dcal->drawbuf),
1121 widget->style->fg_gc[widget->state],
1122 x1 + (w / 2) - (numW / 2),
1123 y1 + (h / 2) - (numH / 2),
1127 LOG_AND_RESET(timer,
"dates");
1129 gtk_widget_queue_draw_area(GTK_WIDGET(dcal),
1130 widget->allocation.x,
1131 widget->allocation.y,
1132 widget->allocation.width,
1133 widget->allocation.height);
1135 LOG_AND_RESET(timer,
"queue draw");
1137 g_object_unref(layout);
1139 g_timer_destroy(timer);
1143 populate_hover_window(
GncDenseCal *dcal, gint doc)
1147 static const int MAX_STRFTIME_BUF_LEN = 64;
1148 gchar strftimeBuf[MAX_STRFTIME_BUF_LEN];
1153 GtkListStore *model;
1156 w = GTK_WIDGET(g_object_get_data(G_OBJECT(dcal->transPopup),
"dateLabel"));
1157 date = g_date_new_dmy(1, dcal->month, dcal->year);
1158 g_date_add_days(date, doc);
1164 g_date_strftime(strftimeBuf, MAX_STRFTIME_BUF_LEN - 1,
"%x", date);
1165 gtk_label_set_text(GTK_LABEL(w), strftimeBuf);
1167 o = G_OBJECT(dcal->transPopup);
1168 model = GTK_LIST_STORE(g_object_get_data(o,
"model"));
1169 gtk_list_store_clear(model);
1170 for (l = dcal->marks[doc]; l; l = l->next)
1176 gtk_list_store_insert(model, &iter, INT_MAX);
1177 gtk_list_store_set(model, &iter, 0, (gdcmd->name ? gdcmd->name : _(
"(unnamed)")), 1, gdcmd->info, -1);
1185 gnc_dense_cal_button_press(GtkWidget *widget,
1186 GdkEventButton *evt)
1191 doc = wheres_this(dcal, evt->x, evt->y);
1192 dcal->showPopup = ~(dcal->showPopup);
1193 if (dcal->showPopup && doc >= 0)
1201 gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root + 5, evt->y_root + 5);
1202 populate_hover_window(dcal, doc);
1203 gtk_widget_queue_resize(GTK_WIDGET(dcal->transPopup));
1204 gtk_widget_show_all(GTK_WIDGET(dcal->transPopup));
1205 gtk_window_move(GTK_WINDOW(dcal->transPopup), evt->x_root + 5, evt->y_root + 5);
1209 gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
1215 gnc_dense_cal_motion_notify(GtkWidget *widget,
1216 GdkEventMotion *event)
1221 int x_root_offset, y_root_offset;
1222 GdkModifierType unused2;
1224 dcal = GNC_DENSE_CAL(widget);
1225 if (!dcal->showPopup)
1228 x_root_offset =
event->x_root;
1229 y_root_offset =
event->y_root;
1233 gdk_window_get_pointer(event->window, &unused, &unused, &unused2);
1234 gdk_window_move(GTK_WIDGET(dcal->transPopup)->window,
1235 x_root_offset + 5, y_root_offset + 5);
1236 doc = wheres_this(dcal, event->x, event->y);
1239 populate_hover_window(dcal, doc);
1240 gtk_widget_queue_resize(GTK_WIDGET(dcal->transPopup));
1241 gtk_widget_show_all(GTK_WIDGET(dcal->transPopup));
1245 gtk_widget_hide(GTK_WIDGET(dcal->transPopup));
1252 _gdc_view_option_changed(GtkComboBox *widget, gpointer user_data)
1255 GtkTreeModel *model;
1258 model = GTK_TREE_MODEL(gtk_combo_box_get_model(widget));
1259 if (!gtk_combo_box_get_active_iter(widget, &iter))
1261 gtk_tree_model_get(model, &iter, VIEW_OPTS_COLUMN_NUM_MONTHS, &months_val, -1);
1262 g_debug(
"changing to %d months", months_val);
1263 gnc_dense_cal_set_num_months(GNC_DENSE_CAL(user_data), months_val);
1269 return xScale + MINOR_BORDER_SIZE;
1275 return day_width_at(dcal, dcal->x_scale);
1281 return yScale + MINOR_BORDER_SIZE;
1287 return day_height_at(dcal, dcal->y_scale);
1293 return day_width_at(dcal, xScale) * 7;
1299 return week_width_at(dcal, dcal->x_scale);
1305 return day_height_at(dcal, yScale);
1311 return week_height_at(dcal, dcal->y_scale);
1317 return (week_width_at(dcal, xScale)
1325 return col_width_at(dcal, dcal->x_scale);
1331 return week_height(dcal) * num_weeks_per_col(dcal);
1337 return ceil((
float)dcal->numMonths / (
float)dcal->monthsPerCol);
1343 return dcal->num_weeks;
1349 int num_weeks_toRet, numCols, i;
1351 int startWeek, endWeek;
1353 start = g_date_new();
1356 num_weeks_toRet = 0;
1357 numCols = num_cols(dcal);
1359 for (i = 0; i < numCols; i++)
1361 g_date_set_dmy(start, 1,
1363 + (i * dcal->monthsPerCol)) % 12)
1365 dcal->year + floor((dcal->month - 1
1366 + (i * dcal->monthsPerCol))
1372 g_date_add_months(end, MIN(dcal->numMonths,
1373 MIN(dcal->monthsPerCol,
1376 * dcal->monthsPerCol))));
1377 g_date_subtract_days(end, 1);
1378 startWeek = (dcal->week_starts_monday
1379 ? g_date_get_monday_week_of_year(start)
1380 : g_date_get_sunday_week_of_year(start));
1381 endWeek = (dcal->week_starts_monday
1382 ? g_date_get_monday_week_of_year(end)
1383 : g_date_get_sunday_week_of_year(end));
1384 if (endWeek < startWeek)
1386 endWeek += (dcal->week_starts_monday
1387 ? g_date_get_monday_weeks_in_year(g_date_get_year(start))
1388 : g_date_get_sunday_weeks_in_year(g_date_get_year(start)));
1390 num_weeks_toRet = MAX(num_weeks_toRet, (endWeek - startWeek) + 1);
1394 return num_weeks_toRet;
1404 month_coords(
GncDenseCal *dcal,
int monthOfCal, GList **outList)
1406 gint weekRow, colNum, previousMonthsInCol, monthOffset;
1408 GDate *startD, *endD;
1410 gint startWk, endWk;
1412 if (monthOfCal > dcal->numMonths)
1415 colNum = floor(monthOfCal / dcal->monthsPerCol);
1416 monthOffset = colNum * dcal->monthsPerCol;
1417 previousMonthsInCol = MAX(0, (monthOfCal % dcal->monthsPerCol));
1419 startD = g_date_new();
1420 endD = g_date_new();
1425 if (previousMonthsInCol > 0)
1427 g_date_set_dmy(startD, 1,
1428 ((dcal->month - 1 + monthOffset) % 12) + 1,
1429 dcal->year + floor((dcal->month - 1 + monthOffset) / 12));
1431 startWk = (dcal->week_starts_monday
1432 ? g_date_get_monday_week_of_year(startD)
1433 : g_date_get_sunday_week_of_year(startD));
1436 g_date_add_months(endD, previousMonthsInCol);
1437 g_date_subtract_days(endD, 1);
1438 endWk = (dcal->week_starts_monday
1439 ? g_date_get_monday_week_of_year(endD)
1440 : g_date_get_sunday_week_of_year(endD));
1441 if (endWk < startWk)
1443 endWk += (dcal->week_starts_monday
1444 ? g_date_get_monday_weeks_in_year(g_date_get_year(startD))
1445 : g_date_get_sunday_weeks_in_year(g_date_get_year(startD)));
1449 weekRow = endWk - startWk;
1450 if (g_date_get_weekday(endD) == (dcal->week_starts_monday ? G_DATE_SUNDAY : G_DATE_SATURDAY))
1456 g_date_set_dmy(startD, 1,
1457 ((dcal->month - 1 + monthOfCal) % 12) + 1,
1458 dcal->year + floor((dcal->month - 1 + monthOfCal) / 12));
1460 g_date_add_months(endD, 1);
1461 g_date_subtract_days(endD, 1);
1464 start = (g_date_get_weekday(startD) - dcal->week_starts_monday) % 7;
1465 rect = g_new0(GdkRectangle, 1);
1466 rect->x = dcal->leftPadding
1468 + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
1470 + (start * day_width(dcal));
1471 rect->y = dcal->topPadding
1472 + dcal->dayLabelHeight
1474 + (weekRow * week_height(dcal));
1475 rect->width = (7 - start) * day_width(dcal);
1476 rect->height = week_height(dcal);
1477 *outList = g_list_append(*outList, (gpointer)rect);
1483 gint i, weekStart, weekEnd;
1485 weekStart = (dcal->week_starts_monday
1486 ? g_date_get_monday_week_of_year(startD)
1487 : g_date_get_sunday_week_of_year(startD)) + 1;
1488 weekEnd = (dcal->week_starts_monday
1489 ? g_date_get_monday_week_of_year(endD)
1490 : g_date_get_sunday_week_of_year(endD));
1491 for (i = weekStart; i < weekEnd; i++)
1493 rect = g_new0(GdkRectangle, 1);
1494 rect->x = dcal->leftPadding
1497 + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
1498 rect->y = dcal->topPadding
1499 + dcal->dayLabelHeight
1501 + ((weekRow + (i - weekStart) + 1) * week_height(dcal));
1502 rect->width = week_width(dcal);
1503 rect->height = week_height(dcal);
1505 *outList = g_list_append(*outList, (gpointer)rect);
1512 gint end_week_of_year = g_date_get_sunday_week_of_year(endD);
1513 gint start_week_of_year = g_date_get_sunday_week_of_year(startD);
1514 if (dcal->week_starts_monday == 1)
1516 end_week_of_year = g_date_get_monday_week_of_year(endD);
1517 start_week_of_year = g_date_get_monday_week_of_year(startD);
1520 rect = g_new0(GdkRectangle, 1);
1521 rect->x = dcal->leftPadding
1524 + (colNum * (col_width(dcal) + COL_BORDER_SIZE));
1525 rect->y = dcal->topPadding
1527 + dcal->dayLabelHeight
1529 + (end_week_of_year - start_week_of_year))
1530 * week_height(dcal));
1531 rect->width = (((g_date_get_weekday(endD) - dcal->week_starts_monday) % 7) + 1) * day_width(dcal);
1532 rect->height = week_height(dcal);
1534 *outList = g_list_append(*outList, (gpointer)rect);
1538 g_date_free(startD);
1545 int *x1,
int *y1,
int *x2,
int *y2)
1549 gint d_week_of_cal, top_of_col_week_of_cal;
1550 gint colNum, dayCol, weekRow;
1553 g_date_set_dmy(&d, 1, dcal->month, dcal->year);
1554 g_date_add_days(&d, dayOfCal);
1555 docMonth = g_date_get_month(&d);
1556 if (g_date_get_year(&d) != dcal->year)
1560 colNum = floor((
float)(docMonth - dcal->month) / (
float)dcal->monthsPerCol);
1561 dayCol = (g_date_get_weekday(&d) - dcal->week_starts_monday) % 7;
1562 d_week_of_cal = g_date_get_sunday_week_of_year(&d);
1563 if (dcal->week_starts_monday == 1)
1565 d_week_of_cal = g_date_get_monday_week_of_year(&d);
1567 g_date_set_dmy(&d, 1, dcal->month, dcal->year);
1568 g_date_add_months(&d, (colNum * dcal->monthsPerCol));
1569 top_of_col_week_of_cal = (dcal->week_starts_monday
1570 ? g_date_get_monday_week_of_year(&d)
1571 : g_date_get_sunday_week_of_year(&d));
1572 if (d_week_of_cal < top_of_col_week_of_cal)
1575 week_offset = g_date_get_sunday_weeks_in_year(dcal->year);
1576 if (dcal->week_starts_monday == 1)
1578 week_offset = g_date_get_monday_weeks_in_year(dcal->year);
1580 d_week_of_cal += week_offset;
1582 weekRow = d_week_of_cal - top_of_col_week_of_cal;
1587 *x1 = dcal->leftPadding
1590 + (colNum * (col_width(dcal) + COL_BORDER_SIZE))
1591 + (dayCol * day_width(dcal))
1592 + (day_width(dcal) / 4);
1593 *y1 = dcal->topPadding
1595 + dcal->dayLabelHeight
1596 + (weekRow * week_height(dcal))
1597 + (day_height(dcal) / 4);
1599 *x2 = *x1 + (day_width(dcal) / 2);
1600 *y2 = *y1 + (day_height(dcal) / 2);
1610 gint colNum, weekRow, dayCol, dayOfCal;
1613 x -= dcal->leftPadding;
1614 y -= dcal->topPadding;
1616 if ((x < 0) || (y < 0))
1620 if ((x >= GTK_WIDGET(dcal)->allocation.width)
1621 || (y >= GTK_WIDGET(dcal)->allocation.height))
1627 if (x >= (num_cols(dcal) * (col_width(dcal) + COL_BORDER_SIZE)))
1631 if (y >= dcal->dayLabelHeight + col_height(dcal))
1637 colNum = floor(x / (col_width(dcal) + COL_BORDER_SIZE));
1639 x %= (col_width(dcal) + COL_BORDER_SIZE);
1640 x -= dcal->label_width;
1645 if (x >= day_width(dcal) * 7)
1650 y -= dcal->dayLabelHeight;
1656 dayCol = floor((
float)x / (
float)day_width(dcal));
1657 weekRow = floor((
float)y / (
float)week_height(dcal));
1659 g_date_set_dmy(&startD, 1, dcal->month, dcal->year);
1661 g_date_add_months(&d, (colNum * dcal->monthsPerCol));
1662 dayCol -= ((g_date_get_weekday(&d) - dcal->week_starts_monday) % 7);
1670 g_date_add_days(&d, dayCol + (weekRow * 7));
1675 g_date_set_dmy(&ccd, 1, dcal->month, dcal->year);
1676 g_date_add_months(&ccd, (colNum + 1) * dcal->monthsPerCol);
1677 if (g_date_get_julian(&d) >= g_date_get_julian(&ccd))
1683 dayOfCal = g_date_get_julian(&d) - g_date_get_julian(&startD);
1686 g_date_subtract_months(&d, dcal->numMonths);
1687 if (g_date_get_julian(&d) >= g_date_get_julian(&startD))
1690 g_debug(
"%d >= %d", g_date_get_julian(&d), g_date_get_julian(&startD));
1704 g_date_clear(&soc, 1);
1705 g_date_set_dmy(&soc, 1, dcal->month, dcal->year);
1707 if (g_date_get_julian(d) < g_date_get_julian(&soc))
1711 toRet = g_date_get_julian(d) - g_date_get_julian(&soc);
1713 g_date_add_months(&soc, dcal->numMonths);
1714 if (g_date_get_julian(d) >= g_date_get_julian(&soc))
1724 gint num_marks, idx;
1729 name = gnc_dense_cal_model_get_name(cal->model, tag);
1730 info = gnc_dense_cal_model_get_info(cal->model, tag);
1731 num_marks = gnc_dense_cal_model_get_instance_count(cal->model, tag);
1736 dates = g_new0(GDate*, num_marks);
1737 calDate = g_date_new_dmy(1, cal->month, cal->year);
1739 for (idx = 0; idx < num_marks; idx++)
1741 dates[idx] = g_date_new();
1742 gnc_dense_cal_model_get_instance(cal->model, tag, idx, dates[idx]);
1745 if (g_date_valid(dates[0]))
1747 if (g_date_get_julian(dates[0]) < g_date_get_julian(calDate))
1749 _gnc_dense_cal_set_month(cal, g_date_get_month(dates[0]), FALSE);
1750 _gnc_dense_cal_set_year(cal, g_date_get_year(dates[0]), FALSE);
1755 g_warning(
"Bad date, skipped.");
1757 gdc_mark_add(cal, tag, name, info, num_marks, dates);
1759 for (idx = 0; idx < num_marks; idx++)
1761 g_date_free(dates[idx]);
1764 g_date_free(calDate);
1774 tags = gnc_dense_cal_model_get_contained(cal->model);
1775 for (; tags != NULL; tags = tags->next)
1777 guint tag = GPOINTER_TO_UINT(tags->data);
1778 gdc_add_tag_markings(cal, tag);
1787 tags = gnc_dense_cal_model_get_contained(cal->model);
1788 for (; tags != NULL; tags = tags->next)
1790 guint tag = GPOINTER_TO_UINT(tags->data);
1791 gdc_mark_remove(cal, tag, FALSE);
1797 gdc_model_added_cb(GncDenseCalModel *model, guint added_tag, gpointer user_data)
1800 g_debug(
"gdc_model_added_cb update\n");
1801 gdc_add_tag_markings(cal, added_tag);
1805 gdc_model_update_cb(GncDenseCalModel *model, guint update_tag, gpointer user_data)
1808 g_debug(
"gdc_model_update_cb update for tag [%d]\n", update_tag);
1809 gdc_mark_remove(cal, update_tag, FALSE);
1810 gdc_add_tag_markings(cal, update_tag);
1815 gdc_model_removing_cb(GncDenseCalModel *model, guint remove_tag, gpointer user_data)
1818 g_debug(
"gdc_model_removing_cb update [%d]\n", remove_tag);
1819 gdc_mark_remove(cal, remove_tag, TRUE);
1823 gnc_dense_cal_set_model(
GncDenseCal *cal, GncDenseCalModel *model)
1825 if (cal->model != NULL)
1827 gdc_remove_markings(cal);
1828 g_object_unref(G_OBJECT(cal->model));
1832 g_object_ref(G_OBJECT(model));
1833 g_signal_connect(G_OBJECT(cal->model),
"added", (GCallback)gdc_model_added_cb, cal);
1834 g_signal_connect(G_OBJECT(cal->model),
"update", (GCallback)gdc_model_update_cb, cal);
1835 g_signal_connect(G_OBJECT(cal->model),
"removing", (GCallback)gdc_model_removing_cb, cal);
1837 gdc_add_markings(cal);
1858 g_error(
"0 size not allowed\n");
1863 newMark->name = NULL;
1865 newMark->name = g_strdup(name);
1866 newMark->info = NULL;
1868 newMark->info = g_strdup(info);
1871 g_debug(
"saving mark with tag [%d]\n", newMark->tag);
1873 for (i = 0; i < size; i++)
1876 doc = gdc_get_doc_offset(dcal, d);
1879 if (doc >= dcal->numMarks)
1885 dcal->marks[doc] = g_list_append(dcal->marks[doc], newMark);
1887 GINT_TO_POINTER(doc));
1890 gnc_dense_cal_draw_to_buffer(dcal);
1891 gtk_widget_queue_draw(GTK_WIDGET(dcal->cal_drawing_area));
1895 gdc_mark_remove(
GncDenseCal *dcal, guint mark_to_remove, gboolean redraw)
1897 GList *iter, *calendar_marks;
1902 if ((gint)mark_to_remove == -1)
1904 g_debug(
"mark_to_remove = -1");
1909 for (iter = dcal->
markData; iter != NULL; iter = iter->next)
1912 if (mark_data->tag == mark_to_remove)
1917 g_message(
"couldn't find tag [%d]", mark_to_remove);
1920 if (mark_data == NULL)
1922 g_debug(
"mark_data == null");
1926 for (calendar_marks = mark_data->
ourMarks; calendar_marks != NULL; calendar_marks = calendar_marks->next)
1928 day_of_cal = GPOINTER_TO_INT(calendar_marks->data);
1929 dcal->marks[day_of_cal] = g_list_remove(dcal->marks[day_of_cal], mark_data);
1937 gnc_dense_cal_draw_to_buffer(dcal);
1938 gtk_widget_queue_draw(GTK_WIDGET(dcal->cal_drawing_area));
void gnc_gdate_set_today(GDate *gd)
void gnc_dow_abbrev(gchar *buf, int buf_len, int dow)
All type declarations for the whole Gnucash engine.