/*
* copyright (c) 1998 cesar miquel, shawn t. amundson, mattias grжnlund
* copyright (c) 2000 tony gale
*
* this program is free software; you can redistribute it and/or modify
* it under the terms of the gnu general public license as published by
* the free software foundation; either version 2 of the license, or
* (at your option) any later version.
*
* this program is distributed in the hope that it will be useful,
* but without any warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose. see the
* gnu general public license for more details.
*
* you should have received a copy of the gnu general public license
* along with this program; if not, write to the free software
* foundation, inc., 675 mass ave, cambridge, ma 02139, usa.
*/
#include <gtk/gtk.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define def_pad 10
#define def_pad_small 5
#define tm_year_base 1900
typedef struct _calendardata {
gtkwidget *flag_checkboxes[5];
gboolean settings[5];
gchar *font;
gtkwidget *font_dialog;
gtkwidget *window;
gtkwidget *prev2_sig;
gtkwidget *prev_sig;
gtkwidget *last_sig;
gtkwidget *month;
} calendardata;
enum {
calendar_show_header,
calendar_show_days,
calendar_month_change,
calendar_show_week,
calendar_monday_first
};
/*
* gtkcalendar
*/
void calendar_date_to_string( calendardata *data,
char *buffer,
gint buff_len )
{
struct tm tm;
time_t time;
memset (&tm, 0, sizeof (tm));
gtk_calendar_get_date (gtk_calendar (data->window),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
tm.tm_year -= tm_year_base;
time = mktime (&tm);
strftime (buffer, buff_len-1, "%x", gmtime (&time));
}
void calendar_set_signal_strings( char *sig_str,
calendardata *data)
{
const gchar *prev_sig;
prev_sig = gtk_label_get_text (gtk_label (data->prev_sig));
gtk_label_set_text (gtk_label (data->prev2_sig), prev_sig);
prev_sig = gtk_label_get_text (gtk_label (data->last_sig));
gtk_label_set_text (gtk_label (data->prev_sig), prev_sig);
gtk_label_set_text (gtk_label (data->last_sig), sig_str);
}
void calendar_month_changed( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "month_changed: ";
calendar_date_to_string (data, buffer+15, 256-15);
calendar_set_signal_strings (buffer, data);
}
void calendar_day_selected( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "day_selected: ";
calendar_date_to_string (data, buffer+14, 256-14);
calendar_set_signal_strings (buffer, data);
}
void calendar_day_selected_double_click( gtkwidget *widget,
calendardata *data )
{
struct tm tm;
char buffer[256] = "day_selected_double_click: ";
calendar_date_to_string (data, buffer+27, 256-27);
calendar_set_signal_strings (buffer, data);
memset (&tm, 0, sizeof (tm));
gtk_calendar_get_date (gtk_calendar (data->window),
&tm.tm_year, &tm.tm_mon, &tm.tm_mday);
tm.tm_year -= tm_year_base;
if (gtk_calendar (data->window)->marked_date[tm.tm_mday-1] == 0)
{
gtk_calendar_mark_day (gtk_calendar (data->window), tm.tm_mday);
}
else
{
gtk_calendar_unmark_day (gtk_calendar (data->window), tm.tm_mday);
}
}
void calendar_prev_month( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "prev_month: ";
calendar_date_to_string (data, buffer+12, 256-12);
calendar_set_signal_strings (buffer, data);
}
void calendar_next_month( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "next_month: ";
calendar_date_to_string (data, buffer+12, 256-12);
calendar_set_signal_strings (buffer, data);
}
void calendar_prev_year( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "prev_year: ";
calendar_date_to_string (data, buffer+11, 256-11);
calendar_set_signal_strings (buffer, data);
}
void calendar_next_year( gtkwidget *widget,
calendardata *data )
{
char buffer[256] = "next_year: ";
calendar_date_to_string (data, buffer+11, 256-11);
calendar_set_signal_strings (buffer, data);
}
void calendar_set_flags( calendardata *calendar )
{
gint i;
gint options = 0;
for (i = 0; i < 5; i++)
if (calendar->settings[i])
{
options=options + (1<<i);
}
if (calendar->window)
gtk_calendar_display_options (gtk_calendar (calendar->window), options);
}
void calendar_toggle_flag( gtkwidget *toggle,
calendardata *calendar )
{
gint i;
gint j;
j = 0;
for (i = 0; i < 5; i++)
if (calendar->flag_checkboxes[i] == toggle)
j = i;
calendar->settings[j] = !calendar->settings[j];
calendar_set_flags (calendar);
}
void calendar_font_selection_ok( gtkwidget *button,
calendardata *calendar )
{
gtkstyle *style;
pangofontdescription *font_desc;
calendar->font = gtk_font_selection_dialog_get_font_name (
gtk_font_selection_dialog (calendar->font_dialog));
if (calendar->window)
{
font_desc = pango_font_description_from_string (calendar->font);
if (font_desc)
{
style = gtk_style_copy (gtk_widget_get_style (calendar->window));
style->font_desc = font_desc;
gtk_widget_set_style (calendar->window, style);
}
}
}
void calendar_select_font( gtkwidget *button,
calendardata *calendar )
{
gtkwidget *window;
if (!calendar->font_dialog) {
window = gtk_font_selection_dialog_new ("font selection dialog");
g_return_if_fail (gtk_is_font_selection_dialog (window));
calendar->font_dialog = window;
gtk_window_set_position (gtk_window (window), gtk_win_pos_mouse);
g_signal_connect (g_object (window), "destroy",
g_callback (gtk_widget_destroyed),
(gpointer) &calendar->font_dialog);
g_signal_connect (g_object (gtk_font_selection_dialog (window)->ok_button),
"clicked", g_callback (calendar_font_selection_ok),
(gpointer) calendar);
g_signal_connect_swapped (g_object (gtk_font_selection_dialog (window)->cancel_button),
"clicked",
g_callback (gtk_widget_destroy),
g_object (calendar->font_dialog));
}
window=calendar->font_dialog;
if (!gtk_widget_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
}
void create_calendar()
{
gtkwidget *window;
gtkwidget *vbox, *vbox2, *vbox3;
gtkwidget *hbox;
gtkwidget *hbbox;
gtkwidget *calendar;
gtkwidget *toggle;
gtkwidget *button;
gtkwidget *frame;
gtkwidget *separator;
gtkwidget *label;
gtkwidget *bbox;
static calendardata calendar_data;
gint i;
struct {
char *label;
} flags[] =
{
{ "show heading" },
{ "show day names" },
{ "no month change" },
{ "show week numbers" },
{ "week start monday" }
};
calendar_data.window = null;
calendar_data.font = null;
calendar_data.font_dialog = null;
for (i = 0; i < 5; i++) {
calendar_data.settings[i] = 0;
}
window = gtk_window_new (gtk_window_toplevel);
gtk_window_set_title (gtk_window (window), "gtkcalendar example");
gtk_container_set_border_width (gtk_container (window), 5);
g_signal_connect (g_object (window), "destroy",
g_callback (gtk_main_quit),
null);
g_signal_connect (g_object (window), "delete-event",
g_callback (gtk_false),
null);
gtk_window_set_resizable (gtk_window (window), false);
vbox = gtk_vbox_new (false, def_pad);
gtk_container_add (gtk_container (window), vbox);
/*
* главная часть окна, календарь, переключатели и выбор шрифта.
*/
hbox = gtk_hbox_new (false, def_pad);
gtk_box_pack_start (gtk_box (vbox), hbox, true, true, def_pad);
hbbox = gtk_hbutton_box_new ();
gtk_box_pack_start (gtk_box (hbox), hbbox, false, false, def_pad);
gtk_button_box_set_layout (gtk_button_box(hbbox), gtk_buttonbox_spread);
gtk_box_set_spacing (gtk_box (hbbox), 5);
/* calendar widget */
frame = gtk_frame_new ("calendar");
gtk_box_pack_start (gtk_box (hbbox), frame, false, true, def_pad);
calendar=gtk_calendar_new ();
calendar_data.window = calendar;
calendar_set_flags (&calendar_data);
gtk_calendar_mark_day (gtk_calendar (calendar), 19);
gtk_container_add( gtk_container (frame), calendar);
g_signal_connect (g_object (calendar), "month_changed",
g_callback (calendar_month_changed),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "day_selected",
g_callback (calendar_day_selected),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "day_selected_double_click",
g_callback (calendar_day_selected_double_click),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "prev_month",
g_callback (calendar_prev_month),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "next_month",
g_callback (calendar_next_month),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "prev_year",
g_callback (calendar_prev_year),
(gpointer) &calendar_data);
g_signal_connect (g_object (calendar), "next_year",
g_callback (calendar_next_year),
(gpointer) &calendar_data);
separator = gtk_vseparator_new ();
gtk_box_pack_start (gtk_box (hbox), separator, false, true, 0);
vbox2 = gtk_vbox_new (false, def_pad);
gtk_box_pack_start (gtk_box (hbox), vbox2, false, false, def_pad);
/* создаём рамку справа для размещения в ней переключателей */
frame = gtk_frame_new ("flags");
gtk_box_pack_start (gtk_box (vbox2), frame, true, true, def_pad);
vbox3 = gtk_vbox_new (true, def_pad_small);
gtk_container_add (gtk_container (frame), vbox3);
for (i = 0; i < 5; i++)
{
toggle = gtk_check_button_new_with_label (flags[i].label);
g_signal_connect (g_object (toggle),
"toggled",
g_callback (calendar_toggle_flag),
(gpointer) &calendar_data);
gtk_box_pack_start (gtk_box (vbox3), toggle, true, true, 0);
calendar_data.flag_checkboxes[i] = toggle;
}
/* создаём правую кнопку выбора шрифта (font-button) */
button = gtk_button_new_with_label ("font...");
g_signal_connect (g_object (button),
"clicked",
g_callback (calendar_select_font),
(gpointer) &calendar_data);
gtk_box_pack_start (gtk_box (vbox2), button, false, false, 0);
/*
* создаём сигналы и события (build the signal-event part).
*/
frame = gtk_frame_new ("signal events");
gtk_box_pack_start (gtk_box (vbox), frame, true, true, def_pad);
vbox2 = gtk_vbox_new (true, def_pad_small);
gtk_container_add (gtk_container (frame), vbox2);
hbox = gtk_hbox_new (false, 3);
gtk_box_pack_start (gtk_box (vbox2), hbox, false, true, 0);
label = gtk_label_new ("signal:");
gtk_box_pack_start (gtk_box (hbox), label, false, true, 0);
calendar_data.last_sig = gtk_label_new ("");
gtk_box_pack_start (gtk_box (hbox), calendar_data.last_sig, false, true, 0);
hbox = gtk_hbox_new (false, 3);
gtk_box_pack_start (gtk_box (vbox2), hbox, false, true, 0);
label = gtk_label_new ("previous signal:");
gtk_box_pack_start (gtk_box (hbox), label, false, true, 0);
calendar_data.prev_sig = gtk_label_new ("");
gtk_box_pack_start (gtk_box (hbox), calendar_data.prev_sig, false, true, 0);
hbox = gtk_hbox_new (false, 3);
gtk_box_pack_start (gtk_box (vbox2), hbox, false, true, 0);
label = gtk_label_new ("second previous signal:");
gtk_box_pack_start (gtk_box (hbox), label, false, true, 0);
calendar_data.prev2_sig = gtk_label_new ("");
gtk_box_pack_start (gtk_box (hbox), calendar_data.prev2_sig, false, true, 0);
bbox = gtk_hbutton_box_new ();
gtk_box_pack_start (gtk_box (vbox), bbox, false, false, 0);
gtk_button_box_set_layout (gtk_button_box (bbox), gtk_buttonbox_end);
button = gtk_button_new_with_label ("close");
g_signal_connect (g_object (button), "clicked",
g_callback (gtk_main_quit),
null);
gtk_container_add (gtk_container (bbox), button);
gtk_widget_set_flags (button, gtk_can_default);
gtk_widget_grab_default (button);
gtk_widget_show_all (window);
}
int main(int argc,
char *argv[] )
{
gtk_init (&argc, &argv);
create_calendar ();
gtk_main ();
return 0;
}
|