aboutsummaryrefslogblamecommitdiffstats
path: root/calendar/year-view.c
blob: 8a5bedc038ac1c1d0dcd6142f352402e9779bbca (plain) (tree)
1
2
3
4
5
6
7
8
                              


                                                  

                                                    

   





















































































































































































































































































                                                                                                                    
                            
                     
                     



                                                        
                                                   
 




                                      
                                     


                       
                          


                                                







                               




















































                                                                         
        
                           

                                 


           
                                                          




                                                        
                         



                                                           

                                     

                                       







                                                         





                                                          


                                                                                 



                                              

                                                                                        
                  


                                                                                                 
                                   
                                                        






                                                                                 
                                                       
                                             
                                                 






                                                                    
                                          



                                  



                                                                              
                       



                                        
 


                                                    
                



                                                                                      


         












                                                          
 
                                  
                                                                         
                                                                                                    
                                                                             



                                                   
 


                                                                                  
 

                                                                              


                                                                       













                                                       

                                                                         
 



                                                       
                                                       

                       
                                                      
 

      
/* Year view display for gncal
 *
 * Copyright (C) 1998 The Free Software Foundation
 *
 * Authors: Arturo Espinosa <arturo@nuclecu.unam.mx>
 *          Federico Mena <federico@nuclecu.unam.mx>
 */

#include <config.h>
#include <libgnomeui/gnome-canvas-text.h>
#include "year-view.h"
#include "main.h"


#define HEAD_SPACING 4      /* Spacing between year heading and months */
#define TITLE_SPACING 2     /* Spacing between title and calendar */
#define SPACING 4       /* Spacing between months */


static void year_view_class_init    (YearViewClass  *class);
static void year_view_init          (YearView       *yv);
static void year_view_size_request  (GtkWidget      *widget,
                     GtkRequisition *requisition);
static void year_view_size_allocate (GtkWidget      *widget,
                     GtkAllocation  *allocation);


static GnomeCanvas *parent_class;


GtkType
year_view_get_type (void)
{
    static GtkType year_view_type = 0;

    if (!year_view_type) {
        GtkTypeInfo year_view_info = {
            "YearView",
            sizeof (YearView),
            sizeof (YearViewClass),
            (GtkClassInitFunc) year_view_class_init,
            (GtkObjectInitFunc) year_view_init,
            NULL, /* reserved_1 */
            NULL, /* reserved_2 */
            (GtkClassInitFunc) NULL
        };

        year_view_type = gtk_type_unique (gnome_canvas_get_type (), &year_view_info);
    }

    return year_view_type;
}

static void
year_view_class_init (YearViewClass *class)
{
    GtkWidgetClass *widget_class;

    widget_class = (GtkWidgetClass *) class;

    parent_class = gtk_type_class (gnome_canvas_get_type ());

    widget_class->size_request = year_view_size_request;
    widget_class->size_allocate = year_view_size_allocate;
}

static void
year_view_init (YearView *yv)
{
    int i;
    char buf[100];
    struct tm tm;

    memset (&tm, 0, sizeof (tm));

    /* Heading */

    yv->heading = gnome_canvas_item_new (GNOME_CANVAS_GROUP (yv->canvas.root),
                         gnome_canvas_text_get_type (),
                         "anchor", GTK_ANCHOR_N,
                         "font", "-*-helvetica-bold-r-normal--14-*-*-*-*-*-iso8859-1",
                         "fill_color", "black",
                         NULL);

    /* Months */

    for (i = 0; i < 12; i++) {
        /* Title */

        strftime (buf, 100, "%B", &tm);
        tm.tm_mon++;

        yv->titles[i] = gnome_canvas_item_new (GNOME_CANVAS_GROUP (yv->canvas.root),
                               gnome_canvas_text_get_type (),
                               "text", buf,
                               "anchor", GTK_ANCHOR_N,
                               "font", "-*-helvetica-bold-r-normal--12-*-*-*-*-*-iso8859-1",
                               "fill_color", "black",
                               NULL);

        /* Month item */

        yv->mitems[i] = gnome_month_item_new (GNOME_CANVAS_GROUP (yv->canvas.root));
        gnome_canvas_item_set (yv->mitems[i],
                       "anchor", GTK_ANCHOR_NW,
                       "start_on_monday", week_starts_on_monday,
                       "heading_color", "white",
                       NULL);
    }
}

GtkWidget *
year_view_new (GnomeCalendar *calendar, time_t year)
{
    YearView *yv;

    g_return_val_if_fail (calendar != NULL, NULL);
    g_return_val_if_fail (GNOME_IS_CALENDAR (calendar), NULL);

    yv = gtk_type_new (year_view_get_type ());
    yv->calendar = calendar;

    year_view_set (yv, year);
    return GTK_WIDGET (yv);
}

static void
year_view_size_request (GtkWidget *widget, GtkRequisition *requisition)
{
    YearView *yv;

    g_return_if_fail (widget != NULL);
    g_return_if_fail (IS_YEAR_VIEW (widget));
    g_return_if_fail (requisition != NULL);

    yv = YEAR_VIEW (widget);

    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
year_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
{
    YearView *yv;
    double width, height;
    double mwidth, mheight;
    double h_yofs;
    double m_yofs;
    double x, y;
    int i;
    GtkArg arg;
    GdkFont *head_font, *title_font;

    g_return_if_fail (widget != NULL);
    g_return_if_fail (IS_YEAR_VIEW (widget));
    g_return_if_fail (allocation != NULL);

    yv = YEAR_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 (yv), 0, 0, allocation->width, allocation->height);

    arg.name = "font_gdk";
    gtk_object_getv (GTK_OBJECT (yv->heading), 1, &arg);
    head_font = GTK_VALUE_BOXED (arg);

    arg.name = "font_gdk";
    gtk_object_getv (GTK_OBJECT (yv->titles[0]), 1, &arg);
    title_font = GTK_VALUE_BOXED (arg);

    /* Adjust heading */

    gnome_canvas_item_set (yv->heading,
                   "x", (double) allocation->width / 2.0,
                   "y", (double) HEAD_SPACING,
                   NULL);

    /* Adjust months */

    h_yofs = 2 * HEAD_SPACING + head_font->ascent + head_font->descent;
    m_yofs = SPACING + title_font->ascent + title_font->descent;

    width = (allocation->width + SPACING) / 3.0;
    height = (allocation->height - h_yofs + SPACING) / 4.0;

    mwidth = (allocation->width - 2 * SPACING) / 3.0;
    mheight = (allocation->height - h_yofs - 3 * SPACING - 4 * m_yofs) / 4.0;

    for (i = 0; i < 12; i++) {
        x = (i % 3) * width;
        y = (i / 3) * height + h_yofs;

        /* Title */

        gnome_canvas_item_set (yv->titles[i],
                       "x", x + width / 2.0,
                       "y", y,
                       NULL);

        /* Month item */

        gnome_canvas_item_set (yv->mitems[i],
                       "x", x,
                       "y", y + m_yofs,
                       "width", mwidth,
                       "height", mheight,
                       NULL);
    }
}

void
year_view_update (YearView *yv, iCalObject *object, int flags)
{
    g_return_if_fail (yv != NULL);
    g_return_if_fail (IS_YEAR_VIEW (yv));

    /* FIXME */
}

void
year_view_set (YearView *yv, time_t year)
{
    struct tm tm;
    int i;
    char buf[100];

    g_return_if_fail (yv != NULL);
    g_return_if_fail (IS_YEAR_VIEW (yv));

    tm = *localtime (&year);

    /* Heading */

    sprintf (buf, "%d", tm.tm_year + 1900);
    gnome_canvas_item_set (yv->heading,
                   "text", buf,
                   NULL);

    /* Months */

    for (i = 0; i < 12; i++)
        gnome_canvas_item_set (yv->mitems[i],
                       "year", tm.tm_year + 1900,
                       "month", i,
                       NULL);

    /* FIXME: update events */
}

void
year_view_time_format_changed (YearView *yv)
{
    int i;

    g_return_if_fail (yv != NULL);
    g_return_if_fail (IS_YEAR_VIEW (yv));

    for (i = 0; i < 12; i++)
        gnome_canvas_item_set (yv->mitems[i],
                       "start_on_monday", week_starts_on_monday,
                       NULL);

    /* FIXME: update events */
}














#if 0

#include "gncal-year-view.h"
#include "calendar.h"
#include "timeutil.h"

static void gncal_year_view_init (GncalYearView *yview);

static void
double_click(GtkCalendar *gc, GncalYearView *yview)
{
    struct tm tm;
    time_t t;

    tm.tm_mday = gc->selected_day;
    tm.tm_mon  = gc->month;
    tm.tm_year = gc->year - 1900;
    tm.tm_hour = 0;
    tm.tm_min  = 0;
    tm.tm_sec  = 0;
    tm.tm_isdst  = -1;
    t = mktime (&tm);

    gnome_calendar_dayjump (yview->gcal, t);
}
    
static void
do_nothing(GtkCalendarClass *c)
{
}

static void
select_day(GtkWidget *widget, gpointer data)
{
    int i;
    
    GncalYearView *yview;
    
    yview = GNCAL_YEAR_VIEW(data);
    
    for (i = 0; i < 12; i++)
      gtk_signal_handler_block(GTK_OBJECT(yview->calendar[i]),
                   yview->handler[i]);
    
    for (i = 0; i < 12; i++)
      if (GTK_CALENDAR(yview->calendar[i]) != GTK_CALENDAR(widget))
        gtk_calendar_select_day(GTK_CALENDAR(yview->calendar[i]), 0);
                          
    for (i = 0; i < 12; i++)
      gtk_signal_handler_unblock(GTK_OBJECT(yview->calendar[i]),
                   yview->handler[i]);
}

guint
gncal_year_view_get_type (void)
{
        static guint year_view_type = 0;

    if (!year_view_type) {
        GtkTypeInfo year_view_info = {
            "GncalYearView",
            sizeof (GncalYearView),
            sizeof (GncalYearViewClass),
            (GtkClassInitFunc) NULL,
            (GtkObjectInitFunc) gncal_year_view_init,
            (GtkArgSetFunc) NULL,
            (GtkArgGetFunc) NULL
        };

        year_view_type = gtk_type_unique (gtk_table_get_type (), 
                          &year_view_info);
    }

    return year_view_type;
}

static void
gncal_year_view_init (GncalYearView *yview)
{
    int i;
    
    for (i = 0; i < 12; i++) {
        yview->calendar[i] = NULL;
        yview->handler [i] = 0;
    }
    
    yview->gcal = NULL;
    yview->year_label = NULL;
    yview->year = 0;
}

GtkWidget *
gncal_year_view_new (GnomeCalendar *calendar, time_t date)
{
    struct tm my_tm = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    char monthbuff[40];
    GncalYearView *yview;
    GtkWidget *frame, *vbox, *label;
    struct tm *tmptm;
    int i, x, y;

    yview = gtk_type_new (gncal_year_view_get_type ());

    tmptm = localtime(&date);
    yview->year = tmptm->tm_year;
    yview->gcal = calendar;
    my_tm.tm_year = tmptm->tm_year;
    yview->year_label = gtk_label_new("");
    gtk_table_attach (GTK_TABLE (yview), 
              GTK_WIDGET (yview->year_label),
              1, 2,
              0, 1,
              0, 0, 0, 5);
    gtk_widget_show(GTK_WIDGET(yview->year_label));
    
    for (x = 0; x < 3; x++)
      for (y = 0; y < 4; y++) {
          
          i = y * 3 + x;
          
          yview->calendar[i] = gtk_calendar_new();
          gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), 
                           GTK_CALENDAR_SHOW_DAY_NAMES |
                           GTK_CALENDAR_NO_MONTH_CHANGE);
          frame = gtk_frame_new(NULL);
          vbox = gtk_vbox_new(0,0);
        
          yview->handler[i] = 
            gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected", 
                       GTK_SIGNAL_FUNC(select_day), (gpointer *) yview);
          
          gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected_double_click",
                     GTK_SIGNAL_FUNC(double_click), (gpointer *) yview);

          my_tm.tm_mon = i;
          strftime(monthbuff, 40, "%B", &my_tm);
          label = gtk_label_new(monthbuff);
        
          gtk_container_add(GTK_CONTAINER(frame), vbox);
          gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
          gtk_box_pack_start(GTK_BOX(vbox), yview->calendar[i], 0, 0, 0);
          
          gtk_table_attach (GTK_TABLE (yview), 
                    GTK_WIDGET (frame),
                    x, x + 1,
                    y + 1, y + 2,
                    0, 0, 0, 0);

          gtk_widget_show (frame);
          gtk_widget_show (vbox);
          gtk_widget_show (GTK_WIDGET (yview->calendar[i]));
      }

    gncal_year_view_set (yview, date);
    
    return GTK_WIDGET (yview);
}

static void
year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure)
{
    GncalYearView *yview = (GncalYearView *) closure;
    struct tm tm_s;
    time_t t, day_end;

    tm_s = *localtime (&start);
    day_end = time_end_of_day (end);

    for (t = start; t <= day_end; t+= 60*60*24){
        time_t new = mktime (&tm_s);
        struct tm tm_day;
        
        tm_day = *localtime (&new);
        gtk_calendar_mark_day (GTK_CALENDAR (yview->calendar [tm_day.tm_mon]),
                       tm_day.tm_mday);
        tm_s.tm_mday++;
    }
}

static void
gncal_year_view_set_year (GncalYearView *yview, int year)
{
    time_t year_begin, year_end;
    char buff[20];
    GList  *l;
    int i;

    if (!yview->gcal->cal)
        return;
    
    snprintf(buff, 20, "%d", yview->year + 1900);
    gtk_label_set(GTK_LABEL(yview->year_label), buff);

    for (i = 0; i < 12; i++) {
        gtk_calendar_freeze (GTK_CALENDAR (yview->calendar [i]));
        gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year + 1900);
        gtk_calendar_clear_marks (GTK_CALENDAR (yview->calendar[i]));
    }
    
    year_begin = time_year_begin (yview->year);
    year_end   = time_year_end   (yview->year);

    l = calendar_get_events_in_range (yview->gcal->cal, year_begin, year_end);
    for (; l; l = l->next){
        CalendarObject *co = l->data;

        year_view_mark_day (co->ico, co->ev_start, co->ev_end, yview);
    }
    for (i = 0; i < 12; i++) 
        gtk_calendar_thaw (GTK_CALENDAR (yview->calendar [i]));

    calendar_destroy_event_list (l);
}

void
gncal_year_view_set (GncalYearView *yview, time_t date)
{
    struct tm *tmptm;

    tmptm = localtime(&date);
    yview->year = tmptm->tm_year;

    gncal_year_view_set_year (yview, yview->year);
}

void
gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags)
{
    g_return_if_fail (yview != NULL);
    g_return_if_fail (GNCAL_IS_YEAR_VIEW (yview));

    /* If only the summary changed, we dont care */
    if (flags && (flags & CHANGE_SUMMARY) == flags)
        return;

    gncal_year_view_set_year (yview, yview->year);
}

#endif