source: trunk/third/gnome-utils/logview/calendar.c @ 18641

Revision 18641, 13.6 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18640, which included commits to RCS files with non-trunk default branches.
Line 
1/*  ----------------------------------------------------------------------
2
3    Copyright (C) 1998  Cesar Miquel  (miquel@df.uba.ar)
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19    ---------------------------------------------------------------------- */
20
21
22#include <config.h>
23#include <time.h>
24#include <gnome.h>
25#include "gtk/gtk.h"
26#include "logview.h"
27
28#define CALENDAR_WIDTH           180
29#define CALENDAR_HEIGHT          150
30
31#define SUNDAY                   0
32#define MONDAY                   1
33#define FRIDAY                   5
34#define SATURDAY                 6
35#define FEBRUARY                 1
36#define XSEP                     3
37#define CALLEFTMARGIN            5
38#define BASELINESKIP             4
39
40#define THISMONTH                1
41#define OTHERMONTH               2
42#define MARKEDDATE               3
43
44/*
45 *       --------
46 *       Typedefs
47 *       --------
48 */
49
50
51/*
52 *    -------------------
53 *    Function Prototypes
54 *    -------------------
55 */
56
57void CalendarMenu (GtkWidget * widget, gpointer user_data);
58void close_calendar (GtkWidget * widget, gpointer client_data);
59void set_scrollbar_size (int num_lines);
60void calendar_month_changed (GtkWidget *widget, gpointer data);
61void read_marked_dates (CalendarData *data);
62void calendar_month_changed (GtkWidget *widget, gpointer data);
63void calendar_day_selected (GtkWidget *widget, gpointer unused_data);
64void calendar_day_selected_double_click (GtkWidget *widget, gpointer data);
65CalendarData* init_calendar_data ();
66DateMark* find_prev_mark (CalendarData*);
67DateMark* find_next_mark (CalendarData*);
68DateMark* get_mark_from_month (CalendarData *data, gint month, gint year);
69DateMark *get_mark_from_date (CalendarData *, gint, gint, gint);
70GtkWidget *new_pixmap_from_data(char **xpm_data, GdkWindow *w, GdkColor *b);
71void log_repaint (GtkWidget * canvas, GdkRectangle * area);
72
73
74
75/*
76 *       ----------------
77 *       Global variables
78 *       ----------------
79 */
80
81extern ConfigData *cfg;
82extern GdkGC *gc;
83extern Log *curlog, *loglist[];
84extern int numlogs, curlognum;
85extern char *month[12];
86extern GtkWidget *main_win_scrollbar;
87extern GnomeUIInfo view_menu[];
88GtkWidget *CalendarDialog = NULL;
89GtkWidget *CalendarWidget;
90int calendarvisible;
91
92
93/* ----------------------------------------------------------------------
94   NAME:          CalendarMenu
95   DESCRIPTION:   Display the calendar.
96   ---------------------------------------------------------------------- */
97
98void
99CalendarMenu (GtkWidget * widget, gpointer user_data)
100{
101   GtkCalendar *calendar;
102   GtkWidget *frame;
103   GtkWidget *vbox;
104
105   if (curlog == NULL || calendarvisible)
106      return;
107
108   if (CalendarDialog == NULL)
109   {
110      CalendarDialog = gtk_dialog_new ();
111
112      gtk_window_set_title (GTK_WINDOW (CalendarDialog), _("Calendar"));
113      gtk_window_set_resizable (GTK_WINDOW (CalendarDialog), FALSE);
114      gtk_dialog_add_button (GTK_DIALOG (CalendarDialog),
115                             GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
116      g_signal_connect (G_OBJECT (CalendarDialog), "response",
117                        G_CALLBACK (close_calendar),
118                        &CalendarDialog);
119      g_signal_connect (G_OBJECT (CalendarDialog), "destroy",
120                        G_CALLBACK (close_calendar),
121                        NULL);
122      g_signal_connect (G_OBJECT (CalendarDialog), "delete_event",
123                        G_CALLBACK (gtk_true),
124                        NULL);
125
126      vbox = gtk_vbox_new (FALSE, 2);
127
128      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (CalendarDialog)->vbox), vbox,
129                          TRUE, TRUE, 0);
130      gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
131
132      frame = gtk_frame_new (NULL);
133
134      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
135      gtk_container_set_border_width (GTK_CONTAINER (frame), 3);
136
137      calendar = (GtkCalendar *)gtk_calendar_new();
138
139      gtk_signal_connect (GTK_OBJECT (calendar), "month_changed",
140                          GTK_SIGNAL_FUNC (calendar_month_changed),
141                          NULL);
142      gtk_signal_connect (GTK_OBJECT (calendar), "day_selected",
143                          GTK_SIGNAL_FUNC (calendar_day_selected),
144                          NULL);
145      gtk_signal_connect (GTK_OBJECT (calendar), "day_selected_double_click",
146                          GTK_SIGNAL_FUNC (calendar_day_selected_double_click),
147                          NULL);
148      gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (calendar));
149      gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
150      gtk_widget_show (GTK_WIDGET (calendar));
151      gtk_widget_show (frame);
152
153      gtk_dialog_set_default_response (GTK_DIALOG (CalendarDialog), GTK_RESPONSE_CLOSE);
154   
155      gtk_widget_show (vbox);
156     
157      CalendarWidget = GTK_WIDGET (calendar);
158      init_calendar_data ();
159   }
160   calendarvisible = TRUE;
161
162   gtk_widget_show (CalendarDialog);
163
164}
165
166/* ----------------------------------------------------------------------
167   NAME:        new_pixmap_from_data
168   DESCRIPTION:
169   ---------------------------------------------------------------------- */
170
171GtkWidget *
172new_pixmap_from_data (char      **xpm_data,
173                      GdkWindow *window,
174                      GdkColor  *background)
175{
176  GtkWidget *wpixmap;
177  GdkPixmap *pixmap;
178  GdkBitmap *mask;
179
180  pixmap = gdk_pixmap_create_from_xpm_d (window, &mask,
181                                         background,
182                                         xpm_data);
183  wpixmap = gtk_pixmap_new (pixmap, mask);
184
185  return wpixmap;
186}
187
188/* ----------------------------------------------------------------------
189   NAME:          read_marked_dates
190   DESCRIPTION:   Reads all the marked dates for this month and marks
191                  them in the calendar widget.
192   ---------------------------------------------------------------------- */
193
194void
195read_marked_dates (CalendarData *data)
196{
197  GtkCalendar *calendar;
198  DateMark *mark;
199  gint day, month, year;
200
201  g_return_if_fail (data);
202  calendar = GTK_CALENDAR (CalendarWidget);
203  g_return_if_fail (calendar);
204
205  gtk_calendar_clear_marks (calendar);
206  gtk_calendar_get_date (calendar, &year, &month, &day);
207  year -= 1900;
208
209  /* find the current month and year (if there is one)  */
210  mark = data->curmonthmark;
211
212  while (mark)
213    {
214      if (mark->fulldate.tm_mon != month ||
215          mark->fulldate.tm_year != year)
216        break;
217      gtk_calendar_mark_day (calendar, mark->fulldate.tm_mday);
218      mark = mark->next;
219    }
220
221  return;
222}
223
224       
225/* ----------------------------------------------------------------------
226   NAME:          init_calendar_data
227   DESCRIPTION:   Sets up calendar data asociated with this log.
228   ---------------------------------------------------------------------- */
229
230CalendarData*
231init_calendar_data ()
232{
233   CalendarData *data;
234
235   data = curlog->caldata;
236   if (data == NULL)
237     data = (CalendarData*) malloc (sizeof (CalendarData));
238
239   if (data)
240     {
241       data->curmonthmark = curlog->lstats.firstmark;
242       curlog->caldata = data;
243
244#if 0
245       /* Move mark to first marked date in this month */
246       data->curmonthmark =
247         get_mark_from_month (data, curlog->curmark->fulldate.tm_mon,
248                              curlog->curmark->fulldate.tm_year);
249#endif
250       
251       /* signal a redraw event */
252       gtk_signal_emit_by_name (GTK_OBJECT (CalendarWidget), "month_changed");
253       
254     }
255
256   return data;
257}
258
259/* ----------------------------------------------------------------------
260   NAME:          calendar_month_changed
261   DESCRIPTION:   User changed the month in the calendar.
262   ---------------------------------------------------------------------- */
263
264void
265calendar_month_changed (GtkWidget *widget, gpointer unused_data)
266{
267  GtkCalendar *calendar;
268  CalendarData *data;
269  DateMark *mark;
270  gint day, month, year;
271
272  calendar = GTK_CALENDAR (CalendarWidget);
273  g_return_if_fail (calendar);
274
275  data = curlog->caldata;
276  g_return_if_fail (data);
277
278  /* Get current date */
279  gtk_calendar_get_date (calendar, &year, &month, &day);
280  /* This is Y2K compatible but internally we keep track of years
281     starting from 1900. This is because of Unix and not because
282     I like it!! */
283  year -= 1900;
284  mark = get_mark_from_month (data, month, year);
285  if (mark)
286    data->curmonthmark = mark;
287  read_marked_dates (data);
288}
289
290
291/* ----------------------------------------------------------------------
292   NAME:          calendar_day_selected
293   DESCRIPTION:   User clicked on a calendar entry
294   ---------------------------------------------------------------------- */
295
296void
297calendar_day_selected (GtkWidget *widget, gpointer unused_data)
298{
299#ifdef FIXME
300  /* need to update the calander days with with the ones in logfile */
301
302  GtkCalendar *calendar;
303  CalendarData *data;
304  gint day, month, year;
305
306  calendar = GTK_CALENDAR (CalendarWidget);
307  gtk_calendar_get_date (calendar, &year, &month, &day);
308  /* This is Y2K compatible but internally we keep track of years
309     starting from 1900. This is because of Unix and not because
310     I like it!! */
311  year -= 1900;
312  g_return_if_fail (calendar);
313
314  data = curlog->caldata;
315  g_return_if_fail (data);
316 
317  /* TODO This is an ugly HACK until I add this function into
318     the widget!!!!!!
319  */
320  /* Dates go from 0-30 in this array!!! I really need to
321     add the function gtk_calendar_day_marked (day) */
322  if (calendar->marked_date[day-1])
323    {
324      curlog->curmark = get_mark_from_date (data, day, month, year);
325      MoveToMark (curlog);
326      curlog->firstline = 0;
327      curlog->ln = curlog->curmark->ln;
328      gtk_adjustment_set_value ( GTK_RANGE(main_win_scrollbar)->adjustment,
329                                 curlog->ln);
330      /* set_scrollbar_size (curlog->lstats.numlines); */
331      log_repaint(NULL, NULL);
332    }
333#endif 
334}
335
336/* ----------------------------------------------------------------------
337   NAME:          calendar_day_selected
338   DESCRIPTION:   User clicked on a calendar entry
339   ---------------------------------------------------------------------- */
340
341void
342calendar_day_selected_double_click (GtkWidget *widget, gpointer data)
343{
344  calendar_day_selected(widget, data);
345}
346
347/* ----------------------------------------------------------------------
348   NAME:          close_calendar
349   DESCRIPTION:   Callback called when the log info window is closed.
350   ---------------------------------------------------------------------- */
351
352void
353close_calendar (GtkWidget *widget, gpointer client_data)
354{
355   if (calendarvisible) {
356      gtk_widget_hide (CalendarDialog);
357      gtk_check_menu_item_set_active  (GTK_CHECK_MENU_ITEM (view_menu[0].widget), FALSE);
358   }
359   calendarvisible = FALSE;
360}
361
362
363/* ----------------------------------------------------------------------
364   NAME:        get_mark_from_month
365   DESCRIPTION: Move curmonthmark to current month if there is a log
366                entry that month.
367   ---------------------------------------------------------------------- */
368
369DateMark *
370get_mark_from_date (CalendarData *data, gint day, gint month, gint year)
371{
372  DateMark *mark;
373
374  g_return_val_if_fail (data, NULL);
375  mark = get_mark_from_month (data, month, year);
376 
377  while (mark)
378    {
379      if (mark->fulldate.tm_mday == day)
380        return mark;
381      mark = mark->next;
382    }
383
384  return mark;
385}
386
387/* ----------------------------------------------------------------------
388   NAME:        get_mark_from_month
389   DESCRIPTION: Move curmonthmark to current month if there is a log
390                entry that month.
391   ---------------------------------------------------------------------- */
392
393DateMark *
394get_mark_from_month (CalendarData *data, gint month, gint year)
395{
396   DateMark *mark = data->curmonthmark;
397
398   if (mark == NULL)
399      return mark;
400
401   /* Are we on top of the mark: return if so      */
402   if (month == mark->fulldate.tm_mon &&
403       year == mark->fulldate.tm_year)
404      return mark;
405
406   /* Check if we are on the next or previous mark */
407   if (year > mark->fulldate.tm_year)
408      mark = find_next_mark (data);
409   else if (year < mark->fulldate.tm_year)
410      mark = find_prev_mark (data);
411   else if (year == mark->fulldate.tm_year) {
412      if (month > mark->fulldate.tm_mon)
413         mark = find_next_mark (data);
414      else
415         mark = find_prev_mark (data);
416   }
417
418   if (mark == NULL)
419      return NULL;
420
421   if (month == mark->fulldate.tm_mon &&
422       year == mark->fulldate.tm_year)
423     return mark;
424
425   return NULL;
426}
427
428/* ----------------------------------------------------------------------
429   NAME:          find_prev_mark
430   DESCRIPTION:   Returns the previous mark with a different month.
431   ---------------------------------------------------------------------- */
432
433DateMark *
434find_prev_mark (CalendarData *data)
435{
436   DateMark *mark = data->curmonthmark;
437
438   if (mark->prev == NULL)
439      return NULL;
440   mark = mark->prev;
441   while (TRUE)
442   {
443      if (mark->prev == NULL)
444         break;
445      mark = mark->prev;
446      if (mark->fulldate.tm_mon != mark->next->fulldate.tm_mon ||
447          mark->fulldate.tm_year != mark->next->fulldate.tm_year)
448      {
449         mark = mark->next;
450         break;
451      }
452   }
453
454   return mark;
455}
456
457/* ----------------------------------------------------------------------
458   NAME:          find_next_mark
459   DESCRIPTION:   Returns the next mark with a different month.
460   ---------------------------------------------------------------------- */
461
462DateMark *
463find_next_mark (CalendarData *data)
464{
465   DateMark *mark = data->curmonthmark;
466
467   while (TRUE)
468   {
469      if (mark->next == NULL)
470         return NULL;
471      mark = mark->next;
472      if (mark->fulldate.tm_mon != mark->prev->fulldate.tm_mon ||
473          mark->fulldate.tm_year != mark->prev->fulldate.tm_year)
474         break;
475   }
476
477   return mark;
478}
479
Note: See TracBrowser for help on using the repository browser.