[almanah] Create a date button in the toolbar
- From: Ãlvaro PeÃa <alvaropg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [almanah] Create a date button in the toolbar
- Date: Sat, 26 May 2012 17:02:54 +0000 (UTC)
commit f7a2e0098ad9dca5e7e1741234af8b81cb95e4cc
Author: Ãlvaro PeÃa <alvaropg gmail com>
Date: Sat May 26 18:58:41 2012 +0200
Create a date button in the toolbar
data/almanah.ui | 259 +++++++++++++--------------
po/POTFILES.in | 2 +
src/Makefile.am | 4 +
src/main-window.c | 76 ++++++---
src/widgets/calendar-button.c | 391 +++++++++++++++++++++++++++++++++++++++++
src/widgets/calendar-button.h | 60 +++++++
src/widgets/calendar-window.c | 165 +++++++++++++++++
src/widgets/calendar-window.h | 59 ++++++
8 files changed, 858 insertions(+), 158 deletions(-)
---
diff --git a/data/almanah.ui b/data/almanah.ui
index 75a82a5..fdb0a5f 100644
--- a/data/almanah.ui
+++ b/data/almanah.ui
@@ -260,10 +260,8 @@
<menuitem action="almanah_ui_underline"/>
</menu>
</toolitem>
- <toolitem action="almanah_ui_jump_to_today"/>
- <toolitem action="almanah_ui_important"/>
- <separator/>
<toolitem action="almanah_ui_hyperlink"/>
+ <toolitem action="almanah_ui_important"/>
</toolbar>
</ui>
</object>
@@ -278,6 +276,52 @@
</columns>
</object>
+ <object class="AlmanahCalendarWindow" id="almanah_calendar_window">
+ <property name="border-width">12</property>
+ <property name="can-focus">True</property>
+ <property name="type">GTK_WINDOW_POPUP</property>
+ <child>
+ <object class="GtkBox" id="almanah_cw_vbox">
+ <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="AlmanahCalendar" id="almanah_cw_calendar">
+ <property name="width-request">200</property>
+ <property name="can-focus">True</property>
+ <property name="show-details">False</property>
+ <signal name="day-selected" handler="mw_calendar_day_selected_cb"/>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-almanah_mw_calendar">
+ <property name="AtkObject::accessible-name" translatable="yes">Calendar</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButtonBox" id="almanah_cw_button_box">
+ <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <object class="GtkButton" id="almanah_cw_today_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+
<object class="AlmanahMainWindow" id="almanah_main_window">
<child>
<object class="GtkVBox" id="vbox1">
@@ -299,174 +343,115 @@
</child>
<child>
<object class="GtkAlignment" id="mw_alignment">
- <property name="top-padding">6</property>
<child>
- <object class="GtkHPaned" id="hpaned1">
- <property name="can-focus">True</property>
+ <object class="GtkVBox" id="vbox3">
+ <property name="spacing">6</property>
<child>
- <object class="GtkVBox" id="vbox3">
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="almanah_mw_date_label">
- <property name="use-markup">True</property>
- <attributes>
- <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="can-focus">True</property>
+ <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow-type">GTK_SHADOW_NONE</property>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <object class="GtkTextView" id="almanah_mw_entry_view">
+ <property name="width-request">300</property>
+ <property name="height-request">300</property>
<property name="can-focus">True</property>
- <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow-type">GTK_SHADOW_IN</property>
- <child>
- <object class="GtkTextView" id="almanah_mw_entry_view">
- <property name="width-request">300</property>
- <property name="height-request">300</property>
- <property name="can-focus">True</property>
- <property name="has-focus">True</property>
- <property name="wrap-mode">GTK_WRAP_WORD</property>
- <property name="left-margin">3</property>
- <property name="right-margin">3</property>
- <child internal-child="accessible">
- <object class="AtkObject" id="a11y-almanah_mw_entry_view">
- <property name="AtkObject::accessible-name" translatable="yes">Entry editing area</property>
- </object>
- </child>
+ <property name="has-focus">True</property>
+ <property name="wrap-mode">GTK_WRAP_WORD</property>
+ <property name="left-margin">3</property>
+ <property name="right-margin">3</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-almanah_mw_entry_view">
+ <property name="AtkObject::accessible-name" translatable="yes">Entry editing area</property>
</object>
</child>
</object>
</child>
</object>
<packing>
- <property name="resize">True</property>
- <property name="shrink">False</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox2">
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="almanah_mw_calendar_label">
- <property name="label" translatable="yes">Calendar</property>
+ <object class="GtkExpander" id="almanah_mw_events_expander">
+ <child type="label">
+ <object class="GtkLabel" id="almanah_mw_events_label">
+ <property name="label" translatable="yes">Past Events</property>
<accessibility>
- <relation target="almanah_mw_calendar" type="label-for"/>
+ <relation target="almanah_mw_events_tree_view" type="label-for"/>
</accessibility>
<attributes>
<attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
</attributes>
</object>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
<child>
- <object class="AlmanahCalendar" id="almanah_mw_calendar">
- <property name="width-request">200</property>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="can-focus">True</property>
- <property name="show-details">False</property>
- <signal name="day-selected" handler="mw_calendar_day_selected_cb"/>
- <accessibility>
- <relation target="almanah_mw_calendar_label" type="labelled-by"/>
- </accessibility>
- <child internal-child="accessible">
- <object class="AtkObject" id="a11y-almanah_mw_calendar">
- <property name="AtkObject::accessible-name" translatable="yes">Calendar</property>
+ <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow-type">GTK_SHADOW_IN</property>
+ <child>
+ <object class="GtkTreeView" id="almanah_mw_events_tree_view">
+ <property name="model">almanah_mw_event_store</property>
+ <property name="can-focus">True</property>
+ <property name="headers-visible">False</property>
+ <signal name="row-activated" handler="mw_events_tree_view_row_activated_cb"/>
+ <accessibility>
+ <relation target="almanah_mw_events_label" type="labelled-by"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-almanah_mw_events_tree_view">
+ <property name="AtkObject::accessible-name" translatable="yes">Past Event List</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="column3">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="renderer3"/>
+ <attributes>
+ <attribute name="icon-name">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="almanah_mw_event_value_column">
+ <property name="expand">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="almanah_mw_event_value_renderer"/>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="almanah_mw_event_source_column">
+ <child>
+ <object class="GtkCellRendererText" id="almanah_mw_event_source_renderer"/>
+ <attributes>
+ <attribute name="markup">4</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
</object>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
</object>
<packing>
- <property name="resize">False</property>
- <property name="shrink">False</property>
+ <property name="fill">False</property>
+ <property name="expand">False</property>
</packing>
</child>
</object>
</child>
</object>
</child>
- <child>
- <object class="GtkExpander" id="almanah_mw_events_expander">
- <child type="label">
- <object class="GtkLabel" id="almanah_mw_events_label">
- <property name="label" translatable="yes">Past Events</property>
- <accessibility>
- <relation target="almanah_mw_events_tree_view" type="label-for"/>
- </accessibility>
- <attributes>
- <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
- </attributes>
- </object>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="can-focus">True</property>
- <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar-policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow-type">GTK_SHADOW_IN</property>
- <child>
- <object class="GtkTreeView" id="almanah_mw_events_tree_view">
- <property name="model">almanah_mw_event_store</property>
- <property name="can-focus">True</property>
- <property name="headers-visible">False</property>
- <signal name="row-activated" handler="mw_events_tree_view_row_activated_cb"/>
- <accessibility>
- <relation target="almanah_mw_events_label" type="labelled-by"/>
- </accessibility>
- <child internal-child="accessible">
- <object class="AtkObject" id="a11y-almanah_mw_events_tree_view">
- <property name="AtkObject::accessible-name" translatable="yes">Past Event List</property>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="column3">
- <child>
- <object class="GtkCellRendererPixbuf" id="renderer3"/>
- <attributes>
- <attribute name="icon-name">1</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="almanah_mw_event_value_column">
- <property name="expand">True</property>
- <child>
- <object class="GtkCellRendererText" id="almanah_mw_event_value_renderer"/>
- <attributes>
- <attribute name="text">3</attribute>
- </attributes>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkTreeViewColumn" id="almanah_mw_event_source_column">
- <child>
- <object class="GtkCellRendererText" id="almanah_mw_event_source_renderer"/>
- <attributes>
- <attribute name="markup">4</attribute>
- </attributes>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="fill">False</property>
- <property name="expand">False</property>
- </packing>
- </child>
</object>
</child>
</object>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e8d72b5..6d3db45 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -19,4 +19,6 @@ src/printing.c
src/search-dialog.c
src/storage-manager.c
src/widgets/calendar.c
+src/widgets/calendar-button.c
+src/widgets/calendar-window.c
src/uri-entry-dialog.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 425e4bd..3951d63 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,10 @@ almanah_SOURCES = \
uri-entry-dialog.h \
widgets/calendar.c \
widgets/calendar.h \
+ widgets/calendar-button.h \
+ widgets/calendar-button.c \
+ widgets/calendar-window.h \
+ widgets/calendar-window.c \
widgets/font-style-menu-action.h \
widgets/font-style-menu-action.c \
widgets/hyperlink-tag.c \
diff --git a/src/main-window.c b/src/main-window.c
index 77617a5..a7acf59 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -40,6 +40,7 @@
#include "import-export-dialog.h"
#include "uri-entry-dialog.h"
#include "widgets/calendar.h"
+#include "widgets/calendar-button.h"
#include "widgets/font-style-menu-action.h"
#include "widgets/hyperlink-tag.h"
@@ -68,9 +69,9 @@ static void mw_events_updated_cb (AlmanahEventManager *event_manager, AlmanahEve
static void mw_font_style_menu_position_func (GtkMenu *menu, int *x, int *y, gboolean *push_in, GtkMenuToolButton *button);
static GtkMenuToolButton *mw_get_font_style_tool_button_from_action (GtkAction *action);
static gboolean save_entry_timeout_cb (AlmanahMainWindow *self);
+static void mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action);
/* GtkBuilder callbacks */
-void mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window);
void mw_import_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_export_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
@@ -88,14 +89,17 @@ void mw_search_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_preferences_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_about_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_jump_to_today_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
+void mw_old_entries_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
void mw_events_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, AlmanahMainWindow *main_window);
void mw_font_style_activate_cb (AlmanahFontStyleMenuAction *action, AlmanahMainWindow *main_window);
+/* Other callbacks */
+void mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar, AlmanahMainWindow *main_window);
+
struct _AlmanahMainWindowPrivate {
GtkTextView *entry_view;
GtkTextBuffer *entry_buffer;
- AlmanahCalendar *calendar;
- GtkLabel *date_label;
+ AlmanahCalendarButton *calendar_button;
GtkListStore *event_store;
GtkTreeSelection *events_selection;
GtkToggleAction *bold_action;
@@ -186,10 +190,11 @@ AlmanahMainWindow *
almanah_main_window_new (AlmanahApplication *application)
{
GtkBuilder *builder;
- AlmanahStorageManager *storage_manager;
AlmanahEventManager *event_manager;
AlmanahMainWindow *main_window;
AlmanahMainWindowPrivate *priv;
+ GtkToolbar *toolbar;
+ GtkAction *today_action;
GError *error = NULL;
const gchar *interface_filename = almanah_get_interface_filename ();
const gchar *object_names[] = {
@@ -237,8 +242,6 @@ almanah_main_window_new (AlmanahApplication *application)
/* Grab our child widgets */
priv->entry_view = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "almanah_mw_entry_view"));
priv->entry_buffer = gtk_text_view_get_buffer (priv->entry_view);
- priv->calendar = ALMANAH_CALENDAR (gtk_builder_get_object (builder, "almanah_mw_calendar"));
- priv->date_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_mw_date_label"));
priv->event_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "almanah_mw_event_store"));
priv->events_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (gtk_builder_get_object (builder, "almanah_mw_events_tree_view")));
priv->bold_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (builder, "almanah_ui_bold"));;
@@ -285,11 +288,6 @@ almanah_main_window_new (AlmanahApplication *application)
g_signal_connect (priv->underline_action, "toggled", G_CALLBACK (mw_underline_toggled_cb), main_window);
g_signal_connect (priv->hyperlink_action, "toggled", (GCallback) mw_hyperlink_toggled_cb, main_window);
- /* Notification for calendar changes */
- storage_manager = almanah_application_dup_storage_manager (application);
- almanah_calendar_set_storage_manager (priv->calendar, storage_manager);
- g_object_unref (storage_manager);
-
/* Notification for event changes */
event_manager = almanah_application_dup_event_manager (application);
g_signal_connect (event_manager, "events-updated", G_CALLBACK (mw_events_updated_cb), main_window);
@@ -299,6 +297,11 @@ almanah_main_window_new (AlmanahApplication *application)
priv->print_settings = gtk_print_settings_new ();
priv->page_setup = gtk_page_setup_new ();
+ /* Set up the toolbar */
+ toolbar = GTK_TOOLBAR (gtk_builder_get_object (builder, "almanah_mw_toolbar"));
+ today_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_jump_to_today"));
+ mw_setup_toolbar (main_window, application, toolbar, today_action);
+
/* Select the current day and month */
mw_jump_to_today_activate_cb (NULL, main_window);
@@ -667,7 +670,7 @@ save_entry_timeout_cb (AlmanahMainWindow *self)
void
almanah_main_window_select_date (AlmanahMainWindow *self, GDate *date)
{
- almanah_calendar_select_date (self->priv->calendar, date);
+ almanah_calendar_button_select_date (self->priv->calendar_button, date);
}
static void
@@ -1214,7 +1217,14 @@ mw_jump_to_today_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
{
GDate current_date;
g_date_set_time_t (¤t_date, time (NULL));
- almanah_main_window_select_date (main_window, ¤t_date);
+ almanah_calendar_button_select_date (main_window->priv->calendar_button, ¤t_date);
+}
+
+void
+mw_old_entries_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
+{
+ // TODO: Show the old entries
+ g_debug ("Old entries clicked, but nothing implemented yet...");
}
/**
@@ -1349,7 +1359,7 @@ mw_events_updated_cb (AlmanahEventManager *event_manager, AlmanahEventFactoryTyp
GSList *_events, *events;
GDate date;
- almanah_calendar_get_date (main_window->priv->calendar, &date);
+ almanah_calendar_button_get_date (main_window->priv->calendar_button, &date);
_events = almanah_event_manager_get_events (event_manager, type_id, &date);
/* Clear all the events generated by this factory out of the list store first */
@@ -1381,13 +1391,12 @@ mw_events_updated_cb (AlmanahEventManager *event_manager, AlmanahEventFactoryTyp
}
void
-mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window)
+mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar_button, AlmanahMainWindow *main_window)
{
AlmanahApplication *application;
AlmanahStorageManager *storage_manager;
AlmanahEventManager *event_manager;
GDate calendar_date;
- gchar calendar_string[100];
#ifdef ENABLE_SPELL_CHECKING
GtkSpell *gtkspell;
#endif /* ENABLE_SPELL_CHECKING */
@@ -1401,11 +1410,7 @@ mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_wind
save_current_entry (main_window, TRUE);
/* Update the date label */
- almanah_calendar_get_date (main_window->priv->calendar, &calendar_date);
-
- /* Translators: This is a strftime()-format string for the date displayed at the top of the main window. */
- g_date_strftime (calendar_string, sizeof (calendar_string), _("%A, %e %B %Y"), &calendar_date);
- gtk_label_set_markup (priv->date_label, calendar_string);
+ almanah_calendar_button_get_date (main_window->priv->calendar_button, &calendar_date);
/* Update the entry */
storage_manager = almanah_application_dup_storage_manager (application);
@@ -1481,6 +1486,35 @@ mw_events_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path,
almanah_event_view (event, GTK_WINDOW (main_window));
}
+static void
+mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action)
+{
+ GtkToolItem *calendar_button_item, *separator;
+ AlmanahStorageManager *storage_manager;
+
+ /* Insert a dynamic space between the text style and calendar & important.
+ * This can't be done using the <separator/> in the UI file at the moment
+ */
+ separator = gtk_separator_tool_item_new ();
+ gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (separator), FALSE);
+ gtk_tool_item_set_expand (separator, TRUE);
+ gtk_toolbar_insert (toolbar, separator, 2);
+
+ /* Setup the calendar button */
+ storage_manager = almanah_application_dup_storage_manager (application);
+ main_window->priv->calendar_button = ALMANAH_CALENDAR_BUTTON (almanah_calendar_button_new (storage_manager));
+ g_object_unref (storage_manager);
+ g_signal_connect (main_window->priv->calendar_button, "day-selected", G_CALLBACK (mw_calendar_day_selected_cb), main_window);
+ /* Use the same action for the today button in the dropdown window */
+ almanah_calendar_button_set_today_action (main_window->priv->calendar_button, today_action);
+
+ /* Insert the calendar button into the toolbar through a GtkToolItem but button style */
+ calendar_button_item = gtk_tool_item_new ();
+ gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (calendar_button_item)), GTK_STYLE_CLASS_RAISED);
+ gtk_container_add (GTK_CONTAINER (calendar_button_item), GTK_WIDGET (main_window->priv->calendar_button));
+ gtk_toolbar_insert (toolbar, calendar_button_item, 3);
+}
+
#ifdef ENABLE_SPELL_CHECKING
static void
spell_checking_enabled_changed_cb (GSettings *settings, gchar *key, AlmanahMainWindow *self)
diff --git a/src/widgets/calendar-button.c b/src/widgets/calendar-button.c
new file mode 100644
index 0000000..d9635bd
--- /dev/null
+++ b/src/widgets/calendar-button.c
@@ -0,0 +1,391 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Ãlvaro PeÃa 2011-2012 <alvaropg gmail com>
+ *
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <config.h>
+
+#include "calendar-button.h"
+#include "calendar.h"
+#include "calendar-window.h"
+#include "interface.h"
+
+/* This enum allows to know the reason why the calendar date has been changed */
+enum {
+ NONE_EVENT = 1, /* The window is showed */
+ FIRST_EVENT, /* The widget is instatiated the first time */
+ TODAY_EVENT, /* The user clicks on "Today" button */
+ DAY_EVENT, /* The user selects a concret day in the calendar widget */
+ MONTH_EVENT /* The user changes the month, or the year clicking in the calendar widget */
+};
+
+enum {
+ DAY_SELECTED_SIGNAL,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_STORAGE_MANAGER = 1
+};
+
+static guint calendar_button_signals[LAST_SIGNAL] = { 0 };
+
+struct _AlmanahCalendarButtonPrivate {
+ GtkWidget *label;
+ GtkWidget *dock;
+ guchar user_event;
+ AlmanahCalendar *calendar;
+ GtkWidget *today_button;
+ AlmanahStorageManager *storage_manager;
+};
+
+static void almanah_calendar_button_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void almanah_calendar_button_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void almanah_calendar_button_finalize (GObject *object);
+
+static void almanah_calendar_button_dock_hiden (GtkWidget *widget, gpointer user_data);
+
+static void almanah_calendar_button_toggled (GtkToggleButton *togglebutton, gpointer user_data);
+static void almanah_calendar_button_day_selected_cb (GtkCalendar *calendar, AlmanahCalendarButton *self);
+static void almanah_calendar_button_month_changed_cb (GtkCalendar *calendar, AlmanahCalendarButton *self);
+static gboolean almanah_calendar_button_today_press_cb (GtkWidget *widget, GdkEvent *event, AlmanahCalendarButton *self);
+
+static void dock_position_func (AlmanahCalendarButton *self, gint *x, gint *y);
+
+G_DEFINE_TYPE (AlmanahCalendarButton, almanah_calendar_button, GTK_TYPE_TOGGLE_BUTTON)
+
+static void
+almanah_calendar_button_class_init (AlmanahCalendarButtonClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (AlmanahCalendarButtonPrivate));
+
+ gobject_class->get_property = almanah_calendar_button_get_property;
+ gobject_class->set_property = almanah_calendar_button_set_property;
+ gobject_class->finalize = almanah_calendar_button_finalize;
+
+ g_object_class_install_property (gobject_class, PROP_STORAGE_MANAGER,
+ g_param_spec_object ("storage-manager",
+ "Storage manager", "The storage manager whose entries should be listed.",
+ ALMANAH_TYPE_STORAGE_MANAGER,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * AlmanahCalendarButton::day-selected:
+ * @calendar_button: the object which received the signal.
+ *
+ * Emitted when the user selects a day in the dock window.
+ */
+ calendar_button_signals[DAY_SELECTED_SIGNAL] = g_signal_new ("day-selected",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (AlmanahCalendarButtonClass, day_selected),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+}
+
+static void
+almanah_calendar_button_init (AlmanahCalendarButton *self)
+{
+ GtkWidget *arrow;
+ GtkBox *main_box;
+ GtkBuilder *builder;
+ GError *error = NULL;
+ const gchar *interface_filename = almanah_get_interface_filename ();
+ const gchar *object_names[] = {
+ "almanah_calendar_window",
+ NULL
+ };
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_CALENDAR_BUTTON, AlmanahCalendarButtonPrivate);
+ self->priv->user_event = FIRST_EVENT;
+
+ /* The button elements */
+ self->priv->label = gtk_label_new (NULL);
+ arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ main_box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6));
+ gtk_box_pack_start (main_box, self->priv->label, TRUE, TRUE, 0);
+ gtk_box_pack_start (main_box, arrow, FALSE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (main_box));
+
+ gtk_button_set_focus_on_click (GTK_BUTTON (self), TRUE);
+
+ g_signal_connect (self, "toggled", G_CALLBACK (almanah_calendar_button_toggled), NULL);
+
+ /* Calendar dock window from the UI file */
+ builder = gtk_builder_new ();
+ if (gtk_builder_add_objects_from_file (builder, interface_filename, (gchar **) object_names, &error) == FALSE) {
+ g_warning (_("UI file \"%s\" could not be loaded: %s"), interface_filename, error->message);
+ g_error_free (error);
+ g_object_unref (builder);
+
+ return;
+ }
+
+ gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
+ self->priv->dock = GTK_WIDGET (gtk_builder_get_object (builder, "almanah_calendar_window"));
+ if (self->priv->dock == NULL) {
+ g_warning (_("Can't load calendar window object from UI file"));
+ g_object_unref (builder);
+
+ return;
+ }
+
+ g_signal_connect (self->priv->dock, "hide", G_CALLBACK (almanah_calendar_button_dock_hiden), self);
+
+ /* The calendar widget */
+ self->priv->calendar = ALMANAH_CALENDAR (gtk_builder_get_object (builder, "almanah_cw_calendar"));
+ g_object_ref (self->priv->calendar);
+ g_signal_connect (self->priv->calendar, "day-selected", G_CALLBACK (almanah_calendar_button_day_selected_cb), self);
+ g_signal_connect (self->priv->calendar, "month_changed", G_CALLBACK (almanah_calendar_button_month_changed_cb), self);
+
+ /* Today button */
+ self->priv->today_button = GTK_WIDGET (gtk_builder_get_object (builder, "almanah_cw_today_button"));
+ g_signal_connect (self->priv->today_button, "button-press-event", G_CALLBACK (almanah_calendar_button_today_press_cb), self);
+
+ g_object_unref (builder);
+}
+
+static void
+almanah_calendar_button_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ AlmanahCalendarButtonPrivate *priv = ALMANAH_CALENDAR_BUTTON (object)->priv;
+
+ switch (property_id) {
+ case PROP_STORAGE_MANAGER:
+ g_value_set_object (value, priv->storage_manager);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+almanah_calendar_button_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ AlmanahCalendarButton *self = ALMANAH_CALENDAR_BUTTON (object);
+
+ switch (property_id) {
+ case PROP_STORAGE_MANAGER:
+ almanah_calendar_button_set_storage_manager (self, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+almanah_calendar_button_finalize (GObject *object)
+{
+ AlmanahCalendarButtonPrivate *priv = ALMANAH_CALENDAR_BUTTON (object)->priv;
+
+ g_clear_object (&priv->calendar);
+ g_clear_object (&priv->storage_manager);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (almanah_calendar_button_parent_class)->finalize (object);
+}
+
+/**
+ * Calculate the window position
+ */
+static void
+dock_position_func (AlmanahCalendarButton *self, gint *x, gint *y)
+{
+ GdkScreen *screen;
+ GdkRectangle monitor;
+ GtkAllocation allocation;
+ GtkRequisition dock_req;
+ gint new_x, new_y, monitor_num;
+ AlmanahCalendarWindow *calendar_window = ALMANAH_CALENDAR_WINDOW (self->priv->dock);
+
+ /* Get the screen and monitor geometry */
+ screen = gtk_widget_get_screen (GTK_WIDGET (self));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, gtk_widget_get_window (GTK_WIDGET (self)));
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ /* Get the AlmanahCalendarButton position */
+ gtk_widget_get_allocation (GTK_WIDGET (self), &allocation);
+ gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (self)), &new_x, &new_y);
+ /* The dock window starting position is over the calendar button widget */
+ new_x += allocation.x;
+ new_y += allocation.y;
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (calendar_window), &dock_req, NULL);
+ if (new_x + dock_req.width > monitor.x + monitor.width) {
+ /* Move the required pixels to the left if the dock don't showed complety
+ * in the screen
+ */
+ new_x -= (new_x + dock_req.width) - (monitor.x + monitor.width);
+ }
+
+ if ((new_y + allocation.height + dock_req.height) <= monitor.y + monitor.height) {
+ /*The dock window height isn't bigger than the monitor size */
+ new_y += allocation.height;
+ } else if (new_y - dock_req.height >= monitor.y) {
+ /* If the dock window height can't showed complety in the monitor,
+ * and the dock height isn't to bigg to show on top the calendar button
+ * move it on top of the calendar button
+ */
+ new_y -= dock_req.height;
+ } else if (monitor.y + monitor.height - (new_y + allocation.height) > new_y) {
+ /* in other case, we show under the calendar button if the space is enought */
+ new_y += allocation.height;
+ } else {
+ /* we need to put the dock in somewhere... even the monitor is to small */
+ new_y -= dock_req.height;
+ }
+
+ /* Put the dock window in the correct screen */
+ gtk_window_set_screen (GTK_WINDOW (calendar_window), screen);
+
+ *x = new_x;
+ *y = new_y;
+}
+
+static void
+almanah_calendar_button_dock_hiden (GtkWidget *widget, gpointer user_data)
+{
+ /* Reset the calendar user event and toggle off the button */
+ ALMANAH_CALENDAR_BUTTON (user_data)->priv->user_event = NONE_EVENT;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data), FALSE);
+}
+
+static void
+almanah_calendar_button_toggled (GtkToggleButton *togglebutton, gpointer user_data)
+{
+ gint x, y;
+ AlmanahCalendarButton *self;
+ GtkStyleContext *style_context;
+
+ self = ALMANAH_CALENDAR_BUTTON (togglebutton);
+ style_context = gtk_widget_get_style_context (GTK_WIDGET (togglebutton));
+ if (gtk_toggle_button_get_active (togglebutton)) {
+ /* FIXME: Changing the style don't work!?! */
+ gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_MENUBAR);
+ gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_MENUITEM);
+ /* Show the dock */
+ dock_position_func (self, &x, &y);
+ almanah_calendar_window_popup (ALMANAH_CALENDAR_WINDOW (self->priv->dock));
+ gtk_window_move (GTK_WINDOW (self->priv->dock), x, y);
+ } else {
+ gtk_style_context_remove_class (style_context, GTK_STYLE_CLASS_MENUBAR);
+ gtk_style_context_remove_class (style_context, GTK_STYLE_CLASS_MENUITEM);
+ /* Isn't necesary to hide the dock */
+ }
+
+ gtk_widget_reset_style (GTK_WIDGET (togglebutton));
+}
+
+static void
+almanah_calendar_button_day_selected_cb (GtkCalendar *calendar, AlmanahCalendarButton *self)
+{
+ GDate calendar_date;
+ gchar calendar_string[100];
+
+ almanah_calendar_get_date (self->priv->calendar, &calendar_date);
+ /* Translators: This is a strftime()-format string for the date displayed at the top of the main window. */
+ g_date_strftime (calendar_string, sizeof (calendar_string), _("%A, %e %B %Y"), &calendar_date);
+ gtk_label_set_text (GTK_LABEL (self->priv->label), calendar_string);
+ if (self->priv->user_event < DAY_EVENT) {
+ /* Only hide the dock window when the user has clicked in a calendar day */
+ self->priv->user_event = DAY_EVENT;
+ almanah_calendar_window_popdown (ALMANAH_CALENDAR_WINDOW (self->priv->dock));
+ }
+
+ self->priv->user_event = NONE_EVENT;
+
+ /* Emmits the signal at the end */
+ g_signal_emit (self, calendar_button_signals[DAY_SELECTED_SIGNAL], 0);
+}
+
+static void
+almanah_calendar_button_month_changed_cb (GtkCalendar *calendar, AlmanahCalendarButton *self)
+{
+ if (self->priv->user_event != TODAY_EVENT) {
+ /* Save the month changed event just if the user hasn't click the today button
+ * beacuse the dock window should not hide in this case */
+ self->priv->user_event = MONTH_EVENT;
+ }
+}
+
+static gboolean
+almanah_calendar_button_today_press_cb (GtkWidget *widget, GdkEvent *event, AlmanahCalendarButton *self)
+{
+ /* Save this event to not hide the dock window */
+ self->priv->user_event = TODAY_EVENT;
+
+ return FALSE;
+}
+
+GtkWidget *
+almanah_calendar_button_new (AlmanahStorageManager *storage_manager)
+{
+ g_return_val_if_fail (ALMANAH_IS_STORAGE_MANAGER (storage_manager), NULL);
+ return GTK_WIDGET (g_object_new (ALMANAH_TYPE_CALENDAR_BUTTON, "storage-manager", storage_manager, NULL));
+}
+
+void
+almanah_calendar_button_set_storage_manager (AlmanahCalendarButton *self, AlmanahStorageManager *storage_manager)
+{
+ g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
+ g_return_if_fail (ALMANAH_IS_STORAGE_MANAGER (storage_manager));
+
+ g_clear_object (&self->priv->storage_manager);
+ self->priv->storage_manager = storage_manager;
+ g_object_ref (self->priv->storage_manager);
+
+ if (self->priv->calendar != NULL && ALMANAH_IS_CALENDAR (self->priv->calendar)) {
+ almanah_calendar_set_storage_manager (self->priv->calendar, self->priv->storage_manager);
+ }
+}
+
+void
+almanah_calendar_button_set_today_action (AlmanahCalendarButton *self, GtkAction *action)
+{
+ g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
+ g_return_if_fail (GTK_IS_ACTION (action));
+
+ if (GTK_IS_BUTTON (self->priv->today_button)) {
+ gtk_activatable_set_related_action (GTK_ACTIVATABLE (self->priv->today_button), action);
+ }
+}
+
+void
+almanah_calendar_button_select_date (AlmanahCalendarButton *self, GDate *date)
+{
+ g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
+ g_return_if_fail (date != NULL);
+
+ almanah_calendar_select_date (self->priv->calendar, date);
+}
+
+void
+almanah_calendar_button_get_date (AlmanahCalendarButton *self, GDate *date)
+{
+ g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
+ g_return_if_fail (date != NULL);
+
+ almanah_calendar_get_date (self->priv->calendar, date);
+}
diff --git a/src/widgets/calendar-button.h b/src/widgets/calendar-button.h
new file mode 100644
index 0000000..2e8fc3e
--- /dev/null
+++ b/src/widgets/calendar-button.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Ãlvaro PeÃa 2011 <alvaropg gmail com>
+ *
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALMANAH_CALENDAR_BUTTON_H
+#define ALMANAH_CALENDAR_BUTTON_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "widgets/calendar.h"
+#include "storage-manager.h"
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_CALENDAR_BUTTON (almanah_calendar_button_get_type ())
+#define ALMANAH_CALENDAR_BUTTON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_CALENDAR_BUTTON, AlmanahCalendarButton))
+#define ALMANAH_CALENDAR_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_CALENDAR_BUTTON, AlmanahCalendarButtonClass))
+#define ALMANAH_IS_CALENDAR_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_CALENDAR_BUTTON))
+#define ALMANAH_IS_CALENDAR_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_CALENDAR_BUTTON))
+#define ALMANAH_CALENDAR_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_CALENDAR_BUTTON, AlmanahCalendarButtonClass))
+
+typedef struct _AlmanahCalendarButtonPrivate AlmanahCalendarButtonPrivate;
+
+typedef struct {
+ GtkToggleButton parent;
+ AlmanahCalendarButtonPrivate *priv;
+} AlmanahCalendarButton;
+
+typedef struct {
+ GtkToggleButtonClass parent;
+ void (* day_selected) (AlmanahCalendarButton *self);
+} AlmanahCalendarButtonClass;
+
+GType almanah_calendar_button_get_type (void) G_GNUC_CONST;
+GtkWidget *almanah_calendar_button_new (AlmanahStorageManager *storage_manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void almanah_calendar_button_set_today_action (AlmanahCalendarButton *self, GtkAction *action);
+void almanah_calendar_button_set_storage_manager (AlmanahCalendarButton *self, AlmanahStorageManager *storage_manager);
+void almanah_calendar_button_select_date (AlmanahCalendarButton *self, GDate *date);
+void almanah_calendar_button_get_date (AlmanahCalendarButton *self, GDate *date);
+
+G_END_DECLS
+
+#endif /* !ALMANAH_CALENDAR_BUTTON_H */
diff --git a/src/widgets/calendar-window.c b/src/widgets/calendar-window.c
new file mode 100644
index 0000000..74a77bd
--- /dev/null
+++ b/src/widgets/calendar-window.c
@@ -0,0 +1,165 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Ãlvaro PeÃa 2012 <alvaropg gmail com>
+ *
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+
+#include "calendar-window.h"
+#include "widgets/calendar.h"
+#include "interface.h"
+
+static void show (GtkWidget *self);
+static gboolean button_press_event (GtkWidget *self, GdkEventButton *event);
+static gboolean key_press_event (GtkWidget *self, GdkEventKey *event);
+
+struct _AlmanahCalendarWindowPrivate {
+ GdkDevice *grab_pointer;
+};
+
+G_DEFINE_TYPE (AlmanahCalendarWindow, almanah_calendar_window, GTK_TYPE_WINDOW)
+#define ALMANAH_CALENDAR_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_CALENDAR_WINDOW, AlmanahCalendarWindowPrivate))
+
+static void
+almanah_calendar_window_class_init (AlmanahCalendarWindowClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (AlmanahCalendarWindowPrivate));
+
+ widget_class->show = show;
+ widget_class->button_press_event = button_press_event;
+ widget_class->key_press_event = key_press_event;
+}
+
+static void
+almanah_calendar_window_init (AlmanahCalendarWindow *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ALMANAH_TYPE_CALENDAR_WINDOW, AlmanahCalendarWindowPrivate);
+}
+
+static void
+show (GtkWidget *self)
+{
+ GdkDevice *device, *keyboard, *pointer;
+ GdkWindow *window;
+
+ GTK_WIDGET_CLASS (almanah_calendar_window_parent_class)->show (self);
+
+ window = gtk_widget_get_window (self);
+
+ device = gtk_get_current_event_device ();
+ switch (gdk_device_get_source (device)) {
+ case GDK_SOURCE_KEYBOARD:
+ keyboard = device;
+ pointer = gdk_device_get_associated_device (device);
+ break;
+ case GDK_SOURCE_MOUSE:
+ case GDK_SOURCE_PEN:
+ case GDK_SOURCE_ERASER:
+ case GDK_SOURCE_CURSOR:
+ pointer = device;
+ keyboard = gdk_device_get_associated_device (device);
+ break;
+ default:
+ g_warning (_("Unknown input device"));
+ return;
+ }
+
+ gtk_grab_add (self);
+
+ gdk_device_grab (keyboard, window,
+ GDK_OWNERSHIP_WINDOW, TRUE,
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
+ NULL, GDK_CURRENT_TIME);
+
+ gdk_device_grab (pointer, window,
+ GDK_OWNERSHIP_WINDOW, TRUE,
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL, GDK_CURRENT_TIME);
+
+ ALMANAH_CALENDAR_WINDOW_GET_PRIVATE(ALMANAH_CALENDAR_WINDOW (self))->grab_pointer = pointer;
+}
+
+static gboolean
+button_press_event (GtkWidget *self, GdkEventButton *event)
+{
+ GtkAllocation allocation;
+ gint window_x, window_y;
+
+ if (event->type != GDK_BUTTON_PRESS) {
+ return TRUE;
+ }
+
+ /* Take the dock window position and dimensions */
+ gdk_window_get_position (gtk_widget_get_window (self), &window_x, &window_y);
+ gtk_widget_get_allocation (self, &allocation);
+
+ /* Hide the dock when the user clicks out of the dock window */
+ if (event->x_root < window_x || event->x_root > window_x + allocation.width ||
+ event->y_root < window_y || event->y_root > window_y + allocation.height) {
+ almanah_calendar_window_popdown (ALMANAH_CALENDAR_WINDOW (self));
+ }
+
+ return FALSE;
+}
+
+static gboolean
+key_press_event (GtkWidget *self, GdkEventKey *event)
+{
+ if (event->keyval != GDK_KEY_Escape) {
+ return FALSE;
+ }
+
+ almanah_calendar_window_popdown (ALMANAH_CALENDAR_WINDOW (self));
+
+ return TRUE;
+}
+
+GtkWidget *
+almanah_calendar_window_new (void)
+{
+ return GTK_WIDGET (g_object_new (ALMANAH_TYPE_CALENDAR_WINDOW, NULL));
+}
+
+void
+almanah_calendar_window_popup (AlmanahCalendarWindow *self)
+{
+ g_return_if_fail (ALMANAH_IS_CALENDAR_WINDOW (self));
+
+ gtk_widget_show_all (GTK_WIDGET (self));
+}
+
+void
+almanah_calendar_window_popdown (AlmanahCalendarWindow *self)
+{
+ GdkDevice *pointer, *keyboard;
+
+ g_return_if_fail (ALMANAH_IS_CALENDAR_WINDOW (self));
+
+ pointer = self->priv->grab_pointer;
+ gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
+ keyboard = gdk_device_get_associated_device (pointer);
+ if (keyboard)
+ gdk_device_ungrab (keyboard, GDK_CURRENT_TIME);
+
+ gtk_grab_remove (GTK_WIDGET (self));
+
+ gtk_widget_hide (GTK_WIDGET (self));
+}
diff --git a/src/widgets/calendar-window.h b/src/widgets/calendar-window.h
new file mode 100644
index 0000000..88b48c2
--- /dev/null
+++ b/src/widgets/calendar-window.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Almanah
+ * Copyright (C) Ãlvaro PeÃa 2012 <alvaropg gmail com>
+ *
+ * Almanah 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Almanah 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 Almanah. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ALMANAH_CALENDAR_WINDOW_H
+#define ALMANAH_CALENDAR_WINDOW_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "application.h"
+
+G_BEGIN_DECLS
+
+#define ALMANAH_TYPE_CALENDAR_WINDOW (almanah_calendar_window_get_type ())
+#define ALMANAH_CALENDAR_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ALMANAH_TYPE_CALENDAR_WINDOW, AlmanahCalendarWindow))
+#define ALMANAH_CALENDAR_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), ALMANAH_TYPE_CALENDAR_WINDOW, AlmanahCalendarWindowClass))
+#define ALMANAH_IS_CALENDAR_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ALMANAH_TYPE_CALENDAR_WINDOW))
+#define ALMANAH_IS_CALENDAR_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ALMANAH_TYPE_CALENDAR_WINDOW))
+#define ALMANAH_CALENDAR_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ALMANAH_TYPE_CALENDAR_WINDOW, AlmanahCalendarWindowClass))
+
+typedef struct _AlmanahCalendarWindow AlmanahCalendarWindow;
+typedef struct _AlmanahCalendarWindowClass AlmanahCalendarWindowClass;
+typedef struct _AlmanahCalendarWindowPrivate AlmanahCalendarWindowPrivate;
+
+struct _AlmanahCalendarWindow{
+ GtkWindow parent;
+ AlmanahCalendarWindowPrivate *priv;
+};
+
+struct _AlmanahCalendarWindowClass {
+ GtkWindowClass parent;
+};
+
+GType almanah_calendar_window_get_type (void) G_GNUC_CONST;
+
+GtkWidget *almanah_calendar_window_new (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+void almanah_calendar_window_popup (AlmanahCalendarWindow *self);
+void almanah_calendar_window_popdown (AlmanahCalendarWindow *self);
+
+G_END_DECLS
+
+#endif /* !ALMANAH_CALENDAR_WINDOW_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]