[almanah] core: Port to GMenu



commit 256b03d095fa534ea46317e1180cd3b300d7a617
Author: Ãlvaro PeÃa <alvaropg gmail com>
Date:   Sun Nov 18 18:58:54 2012 +0100

    core: Port to GMenu
    
    This patch remove the main menubar from the main window replaced by a menu button in the
    toolbar following the new GNOME style. Rearranged the menu items, removing some of them,
    e.g. the print items (just "Print diary" in the GMenu).
    
    Moved the code about the GMenu actions  from the main window to the application object.
    
    Added a new .ui file for the GMenu because the Bug 667970
    https://bugzilla.gnome.org/show_bug.cgi?id=667970.
    
    You can read about the menu reorganization discussion in Bug 676600
    https://bugzilla.gnome.org/show_bug.cgi?id=676600.

 configure.ac                  |    2 +-
 data/Makefile.am              |    1 +
 data/almanah-app-menu.ui      |   39 ++++++
 data/almanah.ui               |  141 +++------------------
 po/POTFILES.in                |    1 +
 src/application.c             |  251 ++++++++++++++++++++++++++++++++++++-
 src/interface.c               |    9 ++
 src/interface.h               |    1 +
 src/main-window.c             |  283 +++++++---------------------------------
 src/main-window.h             |    5 +-
 src/widgets/calendar-button.c |   34 +++++
 src/widgets/calendar-button.h |    2 +
 12 files changed, 408 insertions(+), 361 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 169c037..a529568 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,7 +78,7 @@ dnl Dependencies
 dnl ***************************************************************************
 
 dnl Required dependencies
-PKG_CHECK_MODULES(STANDARD, glib-2.0 gtk+-3.0 >= 3.3.20 gmodule-2.0 gthread-2.0 gio-2.0 >= 2.28.0 sqlite3 cairo atk)
+PKG_CHECK_MODULES(STANDARD, glib-2.0 gtk+-3.0 >= 3.5.6 gmodule-2.0 gthread-2.0 gio-2.0 >= 2.28.0 sqlite3 cairo atk)
 AC_SUBST(STANDARD_CFLAGS)
 AC_SUBST(STANDARD_LIBS)
 
diff --git a/data/Makefile.am b/data/Makefile.am
index 1726f23..c64dff3 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -24,6 +24,7 @@ update-icon-cache:
 uidir = $(datadir)/almanah
 ui_DATA = \
 	almanah.ui		\
+	almanah-app-menu.ui	\
 	calendar-window.css
 
 ###############################################################################
diff --git a/data/almanah-app-menu.ui b/data/almanah-app-menu.ui
new file mode 100644
index 0000000..2714aef
--- /dev/null
+++ b/data/almanah-app-menu.ui
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<interface>
+	<menu id="almanah_app_menu">
+		<section>
+			<item>
+				<attribute name="label" translatable="yes">_Search</attribute>
+				<attribute name="action">app.search</attribute>
+			</item>
+		</section>
+		<section>
+			<item>
+				<attribute name="label" translatable="yes">Pr_eferences</attribute>
+				<attribute name="action">app.preferences</attribute>
+			</item>
+			<item>
+				<attribute name="label" translatable="yes">_Import</attribute>
+				<attribute name="action">app.import</attribute>
+			</item>
+			<item>
+				<attribute name="label" translatable="yes">_Export</attribute>
+				<attribute name="action">app.export</attribute>
+			</item>
+			<item>
+				<attribute name="label" translatable="yes">_Print diary</attribute>
+				<attribute name="action">app.print</attribute>
+			</item>
+		</section>
+		<section>
+			<item>
+				<attribute name="label" translatable="yes">_About Almanah Diary</attribute>
+				<attribute name="action">app.about</attribute>
+			</item>
+			<item>
+				<attribute name="label" translatable="yes">_Quit</attribute>
+				<attribute name="action">app.quit</attribute>
+			</item>
+		</section>
+	</menu>
+</interface>
diff --git a/data/almanah.ui b/data/almanah.ui
index 455fb83..5be21ff 100644
--- a/data/almanah.ui
+++ b/data/almanah.ui
@@ -4,64 +4,6 @@
 		<child>
 			<object class="GtkActionGroup" id="actiongroup1">
 				<child>
-					<object class="GtkAction" id="almanah_ui_file">
-						<property name="name">file</property>
-						<property name="label" translatable="yes">_File</property>
-					</object>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_import">
-						<property name="name">file-import</property>
-						<property name="label" translatable="yes">_Importâ</property>
-						<signal name="activate" handler="mw_import_activate_cb"/>
-					</object>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_export">
-						<property name="name">file-export</property>
-						<property name="label" translatable="yes">_Exportâ</property>
-						<signal name="activate" handler="mw_export_activate_cb"/>
-					</object>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_page_setup">
-						<property name="stock-id">gtk-page-setup</property>
-						<property name="name">file-page-setup</property>
-						<signal name="activate" handler="mw_page_setup_activate_cb"/>
-					</object>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_print_preview">
-						<property name="stock-id">gtk-print-preview</property>
-						<property name="name">file-print-preview</property>
-						<signal name="activate" handler="mw_print_preview_activate_cb"/>
-					</object>
-					<accelerator key="P" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK"/>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_print">
-						<property name="stock-id">gtk-print</property>
-						<property name="name">file-print</property>
-						<property name="label" translatable="yes">_Printâ</property>
-						<signal name="activate" handler="mw_print_activate_cb"/>
-					</object>
-					<accelerator key="P" modifiers="GDK_CONTROL_MASK"/>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_quit">
-						<property name="stock-id">gtk-quit</property>
-						<property name="name">file-quit</property>
-						<signal name="activate" handler="mw_quit_activate_cb"/>
-					</object>
-					<accelerator key="Q" modifiers="GDK_CONTROL_MASK"/>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_edit">
-						<property name="name">edit</property>
-						<property name="label" translatable="yes">_Edit</property>
-					</object>
-				</child>
-				<child>
 					<object class="GtkAction" id="almanah_ui_cut">
 						<property name="stock-id">gtk-cut</property>
 						<property name="name">edit-cut</property>
@@ -101,22 +43,6 @@
 					</object>
 				</child>
 				<child>
-					<object class="GtkAction" id="almanah_ui_search">
-						<property name="stock-id">gtk-find</property>
-						<property name="label" translatable="yes">_Searchâ</property>
-						<property name="name">edit-search</property>
-						<signal name="activate" handler="mw_search_activate_cb"/>
-					</object>
-				</child>
-				<child>
-					<object class="GtkAction" id="almanah_ui_preferences">
-						<property name="stock-id">gtk-preferences</property>
-						<property name="label" translatable="yes">Pr_eferences</property>
-						<property name="name">edit-preferences</property>
-						<signal name="activate" handler="mw_preferences_activate_cb"/>
-					</object>
-				</child>
-				<child>
 					<object class="GtkAction" id="almanah_ui_format">
 						<property name="name">format</property>
 						<property name="label" translatable="yes">F_ormat</property>
@@ -181,13 +107,6 @@
 					</object>
 				</child>
 				<child>
-					<object class="GtkAction" id="almanah_ui_about">
-						<property name="stock-id">gtk-about</property>
-						<property name="name">help-about</property>
-						<signal name="activate" handler="mw_about_activate_cb"/>
-					</object>
-				</child>
-				<child>
 					<object class="GtkAction" id="almanah_ui_jump_to_today">
 						<property name="stock-id">gtk-jump-to</property>
 						<property name="name">jump-to-today</property>
@@ -215,43 +134,14 @@
 			</object>
 		</child>
 		<ui>
-			<menubar name="almanah_mw_menu_bar">
-				<menu action="almanah_ui_file">
-					<menuitem action="almanah_ui_import"/>
-					<menuitem action="almanah_ui_export"/>
-					<separator/>
-					<menuitem action="almanah_ui_page_setup"/>
-					<menuitem action="almanah_ui_print_preview"/>
-					<menuitem action="almanah_ui_print"/>
-					<separator/>
-					<menuitem action="almanah_ui_jump_to_today"/>
-					<separator/>
-					<menuitem action="almanah_ui_quit"/>
-				</menu>
-				<menu action="almanah_ui_edit">
-					<menuitem action="almanah_ui_cut"/>
-					<menuitem action="almanah_ui_copy"/>
-					<menuitem action="almanah_ui_paste"/>
-					<menuitem action="almanah_ui_delete"/>
-					<separator/>
-					<menuitem action="almanah_ui_select_date"/>
-					<menuitem action="almanah_ui_search"/>
-					<separator/>
-					<menuitem action="almanah_ui_preferences"/>
-				</menu>
-				<menu action="almanah_ui_format">
-					<menuitem action="almanah_ui_bold"/>
-					<menuitem action="almanah_ui_italic"/>
-					<menuitem action="almanah_ui_underline"/>
-					<menuitem action="almanah_ui_hyperlink"/>
-					<separator/>
-					<menuitem action="almanah_ui_insert_time"/>
-					<menuitem action="almanah_ui_important"/>
-				</menu>
-				<menu action="almanah_ui_help">
-					<menuitem action="almanah_ui_about"/>
-				</menu>
-			</menubar>
+			<popup name="almanah_mw_menu_button">
+				<menuitem action="almanah_ui_cut"/>
+				<menuitem action="almanah_ui_copy"/>
+				<menuitem action="almanah_ui_paste"/>
+				<menuitem action="almanah_ui_delete"/>
+				<separator/>
+				<menuitem action="almanah_ui_insert_time"/>
+			</popup>
 			<toolbar name="almanah_mw_toolbar">
 				<toolitem action="almanah_ui_font_style">
 					<menu action="almanah_ui_font_style_menu">
@@ -313,6 +203,15 @@
 								<property name="expand">False</property>
 							</packing>
 						</child>
+						<child>
+							<object class="GtkButton" id="almanah_cw_select_date_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>
@@ -326,12 +225,6 @@
 		<child>
 			<object class="GtkVBox" id="vbox1">
 				<child>
-					<object class="GtkMenuBar" constructor="almanah_ui_manager" id="almanah_mw_menu_bar"/>
-					<packing>
-						<property name="expand">False</property>
-					</packing>
-				</child>
-				<child>
 					<object class="GtkToolbar" constructor="almanah_ui_manager" id="almanah_mw_toolbar">
 						<style>
 							<class name="primary-toolbar"/>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6d3db45..ff04fcc 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,6 +3,7 @@
 data/almanah.desktop.in
 data/org.gnome.almanah.gschema.xml.in.in
 [type: gettext/glade]data/almanah.ui
+[type: gettext/glade]data/almanah-app-menu.ui
 src/application.c
 src/date-entry-dialog.c
 src/entry.c
diff --git a/src/application.c b/src/application.c
index 1f6855b..b1f4dab 100644
--- a/src/application.c
+++ b/src/application.c
@@ -24,9 +24,13 @@
 #include <gtk/gtk.h>
 
 #include "application.h"
-#include "storage-manager.h"
 #include "event-manager.h"
+#include "import-export-dialog.h"
 #include "main-window.h"
+#include "preferences-dialog.h"
+#include "printing.h"
+#include "search-dialog.h"
+#include "storage-manager.h"
 
 static void constructed (GObject *object);
 static void dispose (GObject *object);
@@ -38,6 +42,17 @@ static void activate (GApplication *application);
 static gint handle_command_line (GApplication *application, GApplicationCommandLine *command_line);
 static void quit_main_loop (GApplication *application);
 
+static void almanah_application_init_actions (AlmanahApplication *self);
+
+/* GMenu application actions */
+static void action_search_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_preferences_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_import_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_export_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_print_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_about_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+static void action_quit_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data);
+
 struct _AlmanahApplicationPrivate {
 	gboolean debug;
 
@@ -46,12 +61,25 @@ struct _AlmanahApplicationPrivate {
 	AlmanahEventManager *event_manager;
 
 	AlmanahMainWindow *main_window;
+
+	GtkPrintSettings *print_settings;
+	GtkPageSetup *page_setup;
 };
 
 enum {
 	PROP_DEBUG = 1
 };
 
+static GActionEntry app_entries[] = {
+	{"search", action_search_cb, NULL, NULL, NULL},
+	{"preferences", action_preferences_cb, NULL, NULL, NULL },
+	{"import", action_import_cb, NULL, NULL, NULL },
+	{"export", action_export_cb, NULL, NULL, NULL },
+	{"print", action_print_cb, NULL, NULL, NULL },
+	{"about", action_about_cb, NULL, NULL, NULL },
+	{"quit", action_quit_cb, NULL, NULL, NULL },
+};
+
 G_DEFINE_TYPE (AlmanahApplication, almanah_application, GTK_TYPE_APPLICATION)
 
 static void
@@ -126,6 +154,14 @@ dispose (GObject *object)
 		g_object_unref (priv->settings);
 	priv->settings = NULL;
 
+	if (priv->page_setup != NULL)
+		g_object_unref (priv->page_setup);
+	priv->page_setup = NULL;
+
+	if (priv->print_settings != NULL)
+		g_object_unref (priv->print_settings);
+	priv->print_settings = NULL;
+
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (almanah_application_parent_class)->dispose (object);
 }
@@ -213,6 +249,19 @@ startup (GApplication *application)
 
 	/* Create the event manager */
 	priv->event_manager = almanah_event_manager_new ();
+
+	/* Set up printing objects */
+	priv->print_settings = gtk_print_settings_new ();
+
+#ifdef GTK_PRINT_SETTINGS_OUTPUT_BASENAME
+	/* Translators: This is the default name of the PDF/PS/SVG file the diary is printed to if "Print to File" is chosen. */
+	gtk_print_settings_set (priv->print_settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME, _("Diary"));
+#endif
+
+	priv->page_setup = gtk_page_setup_new ();
+
+	/* Load GMenu application actions */
+	almanah_application_init_actions (ALMANAH_APPLICATION (application));
 }
 
 /* Nullify our pointer to the main window when it gets destroyed (e.g. when we quit) so that we don't then try
@@ -327,6 +376,206 @@ quit_main_loop (GApplication *application)
 	 * the storage manager has encrypted the DB and disconnected from it. */
 }
 
+static void
+almanah_application_init_actions (AlmanahApplication *self)
+{
+	GtkBuilder *builder;
+	GError *error = NULL;
+	const gchar *interface_filename = almanah_get_interface_app_menu_filename ();
+
+	g_action_map_add_action_entries (G_ACTION_MAP (self), app_entries, G_N_ELEMENTS (app_entries), self);
+
+	builder = gtk_builder_new ();
+	if (gtk_builder_add_from_file (builder, interface_filename, &error) == FALSE) {
+		/* Show an error */
+		GtkWidget *dialog = gtk_message_dialog_new (NULL,
+							    GTK_DIALOG_MODAL,
+							    GTK_MESSAGE_ERROR,
+							    GTK_BUTTONS_OK,
+							    _("UI file \"%s\" could not be loaded"), interface_filename);
+		gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
+		gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+
+		g_error_free (error);
+		g_object_unref (builder);
+
+		exit (1);
+	}
+
+	gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
+	gtk_application_set_app_menu (GTK_APPLICATION (self), G_MENU_MODEL (gtk_builder_get_object (builder, "almanah_app_menu")));
+
+#ifndef ENABLE_ENCRYPTION
+#ifndef ENABLE_SPELL_CHECKING
+	/* Remove the "Preferences" entry from the menu */
+	g_action_map_remove_action (G_ACTION_MAP (self), "preferences");
+#endif /* !ENABLE_SPELL_CHECKING */
+#endif /* !ENABLE_ENCRYPTION */
+
+	g_object_unref (builder);
+}
+
+static void
+action_search_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahApplication *application;
+	AlmanahSearchDialog *dialog = almanah_search_dialog_new ();
+
+	application = ALMANAH_APPLICATION (user_data);
+	gtk_window_set_application (GTK_WINDOW (dialog), GTK_APPLICATION (application));
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (application->priv->main_window));
+	gtk_widget_show (GTK_WIDGET (dialog));
+	gtk_dialog_run (GTK_DIALOG (dialog));
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+action_preferences_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+#if defined(ENABLE_ENCRYPTION) || defined(ENABLE_SPELL_CHECKING)
+	AlmanahApplication *application;
+	GSettings *settings;
+	AlmanahPreferencesDialog *dialog;
+
+	application = ALMANAH_APPLICATION (user_data);
+	settings = almanah_application_dup_settings (application);
+	dialog = almanah_preferences_dialog_new (settings);
+	g_object_unref (settings);
+
+	gtk_widget_show_all (GTK_WIDGET (dialog));
+	gtk_dialog_run (GTK_DIALOG (dialog));
+
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+#endif /* ENABLE_ENCRYPTION || ENABLE_SPELL_CHECKING */
+}
+
+static void
+action_import_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahApplication *application;
+	AlmanahStorageManager *storage_manager;
+	GtkWidget *dialog;
+
+	application = ALMANAH_APPLICATION (user_data);
+	storage_manager = almanah_application_dup_storage_manager (application);
+	dialog = GTK_WIDGET (almanah_import_export_dialog_new (storage_manager, TRUE));
+	g_object_unref (storage_manager);
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (application->priv->main_window));
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+	/* The dialog destroys itself once done */
+	gtk_widget_show_all (dialog);
+}
+
+static void
+action_export_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahApplication *application;
+	AlmanahStorageManager *storage_manager;
+	GtkWidget *dialog;
+
+	application = ALMANAH_APPLICATION (user_data);
+	storage_manager = almanah_application_dup_storage_manager (application);
+	dialog = GTK_WIDGET (almanah_import_export_dialog_new (storage_manager, FALSE));
+	g_object_unref (storage_manager);
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (application->priv->main_window));
+	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+	/* The dialog destroys itself once done */
+	gtk_widget_show_all (dialog);
+}
+
+static void
+action_print_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahApplication *application;
+	AlmanahStorageManager *storage_manager;
+
+	application = ALMANAH_APPLICATION (user_data);
+	storage_manager = almanah_application_dup_storage_manager (application);
+	almanah_print_entries (FALSE, GTK_WINDOW (application->priv->main_window), &(application->priv->page_setup), &(application->priv->print_settings), storage_manager);
+	g_object_unref (storage_manager);
+}
+
+static void
+action_about_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahApplication *application;
+	AlmanahStorageManager *storage_manager;
+	gchar *license, *description;
+	guint entry_count;
+
+	const gchar *authors[] =
+	{
+		"Philip Withnall <philip tecnocode co uk>",
+		NULL
+	};
+	const gchar *license_parts[] = {
+		N_("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."),
+		N_("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."),
+		N_("You should have received a copy of the GNU General Public License "
+		   "along with Almanah.  If not, see <http://www.gnu.org/licenses/>."),
+	};
+
+	license = g_strjoin ("\n\n",
+			  _(license_parts[0]),
+			  _(license_parts[1]),
+			  _(license_parts[2]),
+			  NULL);
+
+	application = ALMANAH_APPLICATION (user_data);
+	storage_manager = almanah_application_dup_storage_manager (application);
+	almanah_storage_manager_get_statistics (storage_manager, &entry_count);
+	g_object_unref (storage_manager);
+
+	description = g_strdup_printf (_("A helpful diary keeper, storing %u entries."), entry_count);
+
+	gtk_show_about_dialog (GTK_WINDOW (application->priv->main_window),
+				"version", VERSION,
+				"copyright", _("Copyright \xc2\xa9 2008-2009 Philip Withnall"),
+				"comments", description,
+				"authors", authors,
+				/* Translators: please include your names here to be credited for your hard work!
+				 * Format:
+				 * "Translator name 1 <translator email address>\n"
+				 * "Translator name 2 <translator2 email address>"
+				 */
+				"translator-credits", _("translator-credits"),
+				"logo-icon-name", "almanah",
+				"license", license,
+				"wrap-license", TRUE,
+				"website-label", _("Almanah Website"),
+				"website", "http://live.gnome.org/Almanah_Diary";,
+				NULL);
+
+	g_free (license);
+	g_free (description);
+}
+
+static void
+action_quit_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data)
+{
+	AlmanahMainWindow *main_window;
+
+	main_window = ALMANAH_APPLICATION (user_data)->priv->main_window;
+
+	/* Hide the window to make things look faster */
+	gtk_widget_hide (GTK_WIDGET (main_window));
+
+	almanah_main_window_save_current_entry (main_window, TRUE);
+	gtk_widget_destroy (GTK_WIDGET (main_window));
+}
+
 AlmanahApplication *
 almanah_application_new (void)
 {
diff --git a/src/interface.c b/src/interface.c
index 1e4c45e..ea93784 100644
--- a/src/interface.c
+++ b/src/interface.c
@@ -35,6 +35,15 @@ almanah_get_interface_filename (void)
 }
 
 const gchar *
+almanah_get_interface_app_menu_filename (void)
+{
+	if (g_file_test ("./data/almanah-app-menu.ui", G_FILE_TEST_EXISTS) == TRUE)
+		return "./data/almanah-app-menu.ui";
+	else
+		return PACKAGE_DATA_DIR"/almanah/almanah-app-menu.ui";
+}
+
+const gchar *
 almanah_get_css_path (void)
 {
 	if (g_file_test ("./data", G_FILE_TEST_IS_DIR) == TRUE)
diff --git a/src/interface.h b/src/interface.h
index f3017d7..e4e4f6f 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -25,6 +25,7 @@
 G_BEGIN_DECLS
 
 const gchar *almanah_get_interface_filename (void);
+const gchar *almanah_get_interface_app_menu_filename (void);
 const gchar *almanah_get_css_path (void);
 void almanah_interface_create_text_tags (GtkTextBuffer *text_buffer, gboolean connect_events);
 void almanah_calendar_month_changed_cb (GtkCalendar *calendar, gpointer user_data);
diff --git a/src/main-window.c b/src/main-window.c
index cfcb6db..4e2a1f1 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -29,15 +29,11 @@
 
 #include "main-window.h"
 #include "interface.h"
-#include "preferences-dialog.h"
-#include "search-dialog.h"
 #include "date-entry-dialog.h"
-#include "printing.h"
 #include "entry.h"
 #include "storage-manager.h"
 #include "event-manager.h"
 #include "event.h"
-#include "import-export-dialog.h"
 #include "uri-entry-dialog.h"
 #include "widgets/calendar.h"
 #include "widgets/calendar-button.h"
@@ -69,15 +65,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);
+static void mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action, GtkAction *select_date_action, GtkWidget *menu_popup);
 
 /* GtkBuilder callbacks */
-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);
-void mw_print_preview_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
-void mw_print_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
-void mw_quit_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_cut_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_copy_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_paste_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
@@ -85,9 +75,6 @@ void mw_delete_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_insert_time_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_important_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
 void mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
-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);
@@ -95,6 +82,7 @@ void mw_font_style_activate_cb (AlmanahFontStyleMenuAction *action, AlmanahMainW
 
 /* Other callbacks */
 void mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar, AlmanahMainWindow *main_window);
+static void mw_menu_button_popup_visible_cb (GtkWidget *menu, GParamSpec *pspec, GtkWidget *button);
 
 struct _AlmanahMainWindowPrivate {
 	GtkTextView *entry_view;
@@ -123,16 +111,13 @@ struct _AlmanahMainWindowPrivate {
 	gulong current_entry_notify_id; /* signal handler for current_entry::notify */
 	guint save_entry_timeout_id; /* source ID for timer to save current entry periodically */
 
-	GtkPrintSettings *print_settings;
-	GtkPageSetup *page_setup;
-
 #ifdef ENABLE_SPELL_CHECKING
 	GSettings *settings;
 	gulong spell_checking_enabled_changed_id; /* signal handler for application->settings::changed::spell-checking-enabled */
 #endif /* ENABLE_SPELL_CHECKING */
 };
 
-G_DEFINE_TYPE (AlmanahMainWindow, almanah_main_window, GTK_TYPE_WINDOW)
+G_DEFINE_TYPE (AlmanahMainWindow, almanah_main_window, GTK_TYPE_APPLICATION_WINDOW)
 #define ALMANAH_MAIN_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ALMANAH_TYPE_MAIN_WINDOW, AlmanahMainWindowPrivate))
 
 static void
@@ -164,14 +149,6 @@ almanah_main_window_dispose (GObject *object)
 
 	set_current_entry (ALMANAH_MAIN_WINDOW (object), NULL);
 
-	if (priv->page_setup != NULL)
-		g_object_unref (priv->page_setup);
-	priv->page_setup = NULL;
-
-	if (priv->print_settings != NULL)
-		g_object_unref (priv->print_settings);
-	priv->print_settings = NULL;
-
 #ifdef ENABLE_SPELL_CHECKING
 	if (priv->settings != NULL) {
 		if (priv->spell_checking_enabled_changed_id != 0) {
@@ -196,7 +173,9 @@ almanah_main_window_new (AlmanahApplication *application)
 	AlmanahMainWindow *main_window;
 	AlmanahMainWindowPrivate *priv;
 	GtkToolbar *toolbar;
-	GtkAction *today_action;
+	GtkAction *today_action, *select_date_action;
+	GtkUIManager *manager;
+	GtkWidget *menu_popup;
 	GError *error = NULL;
 	const gchar *interface_filename = almanah_get_interface_filename ();
 	const gchar *object_names[] = {
@@ -297,20 +276,13 @@ almanah_main_window_new (AlmanahApplication *application)
 	g_signal_connect (event_manager, "events-updated", G_CALLBACK (mw_events_updated_cb), main_window);
 	g_object_unref (event_manager);
 
-	/* Set up printing objects */
-	priv->print_settings = gtk_print_settings_new ();
-
-#ifdef GTK_PRINT_SETTINGS_OUTPUT_BASENAME
-	/* Translators: This is the default name of the PDF/PS/SVG file the diary is printed to if "Print to File" is chosen. */
-	gtk_print_settings_set (priv->print_settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME, _("Diary"));
-#endif
-
-	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_date_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_select_date"));
+	manager = GTK_UI_MANAGER (gtk_builder_get_object (builder, "almanah_ui_manager"));
+	menu_popup = gtk_ui_manager_get_widget (manager, "/almanah_mw_menu_button");
+	mw_setup_toolbar (main_window, application, toolbar, today_action, select_date_action, menu_popup);
 
 	/* Select the current day and month */
 	mw_jump_to_today_activate_cb (NULL, main_window);
@@ -318,13 +290,6 @@ almanah_main_window_new (AlmanahApplication *application)
 	/* Set up a timeout for saving the current entry every so often. */
 	priv->save_entry_timeout_id = g_timeout_add_seconds (SAVE_ENTRY_INTERVAL, (GSourceFunc) save_entry_timeout_cb, main_window);
 
-#ifndef ENABLE_ENCRYPTION
-#ifndef ENABLE_SPELL_CHECKING
-	/* Remove the "Preferences" entry from the menu */
-	gtk_action_set_visible (GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_preferences")), FALSE);
-#endif /* !ENABLE_SPELL_CHECKING */
-#endif /* !ENABLE_ENCRYPTION */
-
 	g_object_unref (builder);
 
 	restore_window_state (main_window);
@@ -558,8 +523,8 @@ restore_window_state (AlmanahMainWindow *self)
 	g_object_unref (key_file_path);
 }
 
-static void
-save_current_entry (AlmanahMainWindow *self, gboolean prompt_user)
+void
+almanah_main_window_save_current_entry (AlmanahMainWindow *self, gboolean prompt_user)
 {
 	gboolean entry_exists, existing_entry_is_empty, entry_is_empty;
 	GDate date, last_edited;
@@ -673,7 +638,7 @@ done:
 static gboolean
 save_entry_timeout_cb (AlmanahMainWindow *self)
 {
-	save_current_entry (self, FALSE);
+	almanah_main_window_save_current_entry (self, FALSE);
 	return TRUE;
 }
 
@@ -814,7 +779,7 @@ mw_entry_buffer_has_selection_cb (GObject *object, GParamSpec *pspec, AlmanahMai
 static gboolean
 mw_delete_event_cb (GtkWindow *window, gpointer user_data)
 {
-	save_current_entry (ALMANAH_MAIN_WINDOW (window), TRUE);
+	almanah_main_window_save_current_entry (ALMANAH_MAIN_WINDOW (window), TRUE);
 	save_window_state (ALMANAH_MAIN_WINDOW (window));
 
 	gtk_widget_destroy (GTK_WIDGET (window));
@@ -823,92 +788,6 @@ mw_delete_event_cb (GtkWindow *window, gpointer user_data)
 }
 
 void
-mw_import_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahApplication *application;
-	AlmanahStorageManager *storage_manager;
-	GtkWidget *dialog;
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	storage_manager = almanah_application_dup_storage_manager (application);
-	dialog = GTK_WIDGET (almanah_import_export_dialog_new (storage_manager, TRUE));
-	g_object_unref (storage_manager);
-
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
-	/* The dialog destroys itself once done */
-	gtk_widget_show_all (dialog);
-}
-
-void
-mw_export_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahApplication *application;
-	AlmanahStorageManager *storage_manager;
-	GtkWidget *dialog;
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	storage_manager = almanah_application_dup_storage_manager (application);
-	dialog = GTK_WIDGET (almanah_import_export_dialog_new (storage_manager, FALSE));
-	g_object_unref (storage_manager);
-
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
-	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
-	/* The dialog destroys itself once done */
-	gtk_widget_show_all (dialog);
-}
-
-void
-mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahMainWindowPrivate *priv = main_window->priv;
-	GtkPageSetup *page_setup;
-
-	page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window), priv->page_setup, priv->print_settings);
-	if (priv->page_setup != NULL)
-		g_object_unref (priv->page_setup);
-	priv->page_setup = page_setup;
-}
-
-void
-mw_print_preview_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahMainWindowPrivate *priv = main_window->priv;
-	AlmanahApplication *application;
-	AlmanahStorageManager *storage_manager;
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	storage_manager = almanah_application_dup_storage_manager (application);
-	almanah_print_entries (TRUE, GTK_WINDOW (main_window), &(priv->page_setup), &(priv->print_settings), storage_manager);
-	g_object_unref (storage_manager);
-}
-
-void
-mw_print_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahMainWindowPrivate *priv = main_window->priv;
-	AlmanahApplication *application;
-	AlmanahStorageManager *storage_manager;
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	storage_manager = almanah_application_dup_storage_manager (application);
-	almanah_print_entries (FALSE, GTK_WINDOW (main_window), &(priv->page_setup), &(priv->print_settings), storage_manager);
-	g_object_unref (storage_manager);
-}
-
-void
-mw_quit_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	/* Hide the window to make things look faster */
-	gtk_widget_hide (GTK_WIDGET (main_window));
-
-	save_current_entry (main_window, TRUE);
-	gtk_widget_destroy (GTK_WIDGET (main_window));
-}
-
-void
 mw_cut_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 {
 	GtkClipboard *clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (main_window)), GDK_SELECTION_CLIPBOARD);
@@ -957,6 +836,8 @@ mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 {
 	AlmanahDateEntryDialog *dialog = almanah_date_entry_dialog_new ();
 
+	almanah_calendar_button_popdown (main_window->priv->calendar_button);
+
 	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
 	gtk_widget_show_all (GTK_WIDGET (dialog));
 	if (almanah_date_entry_dialog_run (dialog) == TRUE) {
@@ -970,39 +851,6 @@ mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 	gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
-void
-mw_search_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahSearchDialog *dialog = almanah_search_dialog_new ();
-
-	gtk_window_set_application (GTK_WINDOW (dialog), gtk_window_get_application (GTK_WINDOW (main_window)));
-	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
-	gtk_widget_show (GTK_WIDGET (dialog));
-	gtk_dialog_run (GTK_DIALOG (dialog));
-
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-void
-mw_preferences_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-#if defined(ENABLE_ENCRYPTION) || defined(ENABLE_SPELL_CHECKING)
-	AlmanahApplication *application;
-	GSettings *settings;
-	AlmanahPreferencesDialog *dialog;
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	settings = almanah_application_dup_settings (application);
-	dialog = almanah_preferences_dialog_new (settings);
-	g_object_unref (settings);
-
-	gtk_widget_show_all (GTK_WIDGET (dialog));
-	gtk_dialog_run (GTK_DIALOG (dialog));
-
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-#endif /* ENABLE_ENCRYPTION || ENABLE_SPELL_CHECKING */
-}
-
 static void
 apply_formatting (AlmanahMainWindow *self, const gchar *tag_name, gboolean applying)
 {
@@ -1162,67 +1010,6 @@ mw_hyperlink_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *self)
 }
 
 void
-mw_about_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
-{
-	AlmanahApplication *application;
-	AlmanahStorageManager *storage_manager;
-	gchar *license, *description;
-	guint entry_count;
-
-	const gchar *authors[] =
-	{
-		"Philip Withnall <philip tecnocode co uk>",
-		NULL
-	};
-	const gchar *license_parts[] = {
-		N_("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."),
-		N_("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."),
-		N_("You should have received a copy of the GNU General Public License "
-		   "along with Almanah.  If not, see <http://www.gnu.org/licenses/>."),
-	};
-
-	license = g_strjoin ("\n\n",
-			  _(license_parts[0]),
-			  _(license_parts[1]),
-			  _(license_parts[2]),
-			  NULL);
-
-	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
-	storage_manager = almanah_application_dup_storage_manager (application);
-	almanah_storage_manager_get_statistics (storage_manager, &entry_count);
-	g_object_unref (storage_manager);
-
-	description = g_strdup_printf (_("A helpful diary keeper, storing %u entries."), entry_count);
-
-	gtk_show_about_dialog (GTK_WINDOW (main_window),
-				"version", VERSION,
-				"copyright", _("Copyright \xc2\xa9 2008-2009 Philip Withnall"),
-				"comments", description,
-				"authors", authors,
-				/* Translators: please include your names here to be credited for your hard work!
-				 * Format:
-				 * "Translator name 1 <translator email address>\n"
-				 * "Translator name 2 <translator2 email address>"
-				 */
-				"translator-credits", _("translator-credits"),
-				"logo-icon-name", "almanah",
-				"license", license,
-				"wrap-license", TRUE,
-				"website-label", _("Almanah Website"),
-				"website", "http://live.gnome.org/Almanah_Diary";,
-				NULL);
-
-	g_free (license);
-	g_free (description);
-}
-
-void
 mw_jump_to_today_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 {
 	GDate current_date;
@@ -1233,7 +1020,7 @@ mw_jump_to_today_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 void
 mw_old_entries_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
 {
-	// TODO: Show the old entries
+	/* TODO: Show the old entries */
 	g_debug ("Old entries clicked, but nothing implemented yet...");
 }
 
@@ -1437,7 +1224,7 @@ mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar_button, AlmanahMain
 	application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
 
 	/* Save the previous entry */
-	save_current_entry (main_window, TRUE);
+	almanah_main_window_save_current_entry (main_window, TRUE);
 
 	/* Update the date label */
 	almanah_calendar_button_get_date (main_window->priv->calendar_button, &calendar_date);
@@ -1517,11 +1304,24 @@ mw_events_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path,
 }
 
 static void
-mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action)
+mw_menu_button_popup_visible_cb (GtkWidget *menu, GParamSpec *pspec, GtkWidget *button)
+{
+	/* Set on/off the active menu style when the menu is visible */
+	if (gtk_widget_get_visible (menu))
+		gtk_style_context_add_class (gtk_widget_get_style_context (button), "active-menu");
+	else
+		gtk_style_context_remove_class (gtk_widget_get_style_context (button), "active-menu");
+}
+
+static void
+mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action, GtkAction *select_date_action, GtkWidget *menu_popup)
 {
-	GtkToolItem *calendar_button_item, *separator;
+	GtkToolItem *calendar_button_item, *separator, *menu_button_item;
+	GtkWidget *menu_button, *menu_button_image;
 	AlmanahStorageManager *storage_manager;
 
+	gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (toolbar)), GTK_STYLE_CLASS_MENUBAR);
+
 	/* 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
 	 */
@@ -1537,12 +1337,29 @@ mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *applicatio
 	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);
+	almanah_calendar_button_set_select_date_action (main_window->priv->calendar_button, select_date_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);
+
+	/* Another dynamic separator */
+	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_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (separator));
+
+	/* Menu button with the common GNOME applications style (Nautilus, Epiphany, ...) */
+	menu_button_item = gtk_tool_item_new ();
+	menu_button = gtk_menu_button_new ();
+	gtk_menu_button_set_popup (GTK_MENU_BUTTON (menu_button), menu_popup);
+	menu_button_image = gtk_image_new_from_icon_name ("emblem-system-symbolic", gtk_toolbar_get_icon_size (toolbar));
+	gtk_button_set_image (GTK_BUTTON (menu_button), menu_button_image);
+	gtk_container_add (GTK_CONTAINER (menu_button_item), menu_button);
+	gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (menu_button_item));
+	g_signal_connect (menu_popup, "notify::visible", G_CALLBACK (mw_menu_button_popup_visible_cb), menu_button);
 }
 
 #ifdef ENABLE_SPELL_CHECKING
diff --git a/src/main-window.h b/src/main-window.h
index 58cf8e0..0cfa43a 100644
--- a/src/main-window.h
+++ b/src/main-window.h
@@ -38,18 +38,19 @@ G_BEGIN_DECLS
 typedef struct _AlmanahMainWindowPrivate	AlmanahMainWindowPrivate;
 
 typedef struct {
-	GtkWindow parent;
+	GtkApplicationWindow parent;
 	AlmanahMainWindowPrivate *priv;
 } AlmanahMainWindow;
 
 typedef struct {
-	GtkWindowClass parent;
+	GtkApplicationWindowClass parent;
 } AlmanahMainWindowClass;
 
 GType almanah_main_window_get_type (void);
 AlmanahMainWindow *almanah_main_window_new (AlmanahApplication *application) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
 
 void almanah_main_window_select_date (AlmanahMainWindow *self, GDate *date);
+void almanah_main_window_save_current_entry (AlmanahMainWindow *self, gboolean prompt_user);
 
 G_END_DECLS
 
diff --git a/src/widgets/calendar-button.c b/src/widgets/calendar-button.c
index 1c36d5c..3c238d3 100644
--- a/src/widgets/calendar-button.c
+++ b/src/widgets/calendar-button.c
@@ -51,6 +51,7 @@ struct _AlmanahCalendarButtonPrivate {
 	guchar user_event;
 	AlmanahCalendar *calendar;
 	GtkWidget *today_button;
+	GtkWidget *select_date_button;
 	AlmanahStorageManager *storage_manager;
 };
 
@@ -64,6 +65,7 @@ static void almanah_calendar_button_toggled (GtkToggleButton *togglebutton, gpoi
 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 gboolean almanah_calendar_button_select_date_press_cb (GtkWidget *widget, GdkEvent *event, AlmanahCalendarButton *self);
 
 static void dock_position_func (AlmanahCalendarButton *self, gint *x, gint *y);
 
@@ -161,6 +163,11 @@ almanah_calendar_button_init (AlmanahCalendarButton *self)
 	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);
 
+	/* Select a day button */
+	/* @TODO: No the button press event, instead the 'activate' action funcion (if not, the select day window dosn't showed... */
+	self->priv->select_date_button = GTK_WIDGET (gtk_builder_get_object (builder, "almanah_cw_select_date_button"));
+	g_signal_connect (self->priv->select_date_button, "button-press-event", G_CALLBACK (almanah_calendar_button_select_date_press_cb), self);
+
 	g_object_unref (builder);
 }
 
@@ -347,6 +354,14 @@ almanah_calendar_button_today_press_cb (GtkWidget *widget, GdkEvent *event, Alma
 	return FALSE;
 }
 
+static gboolean
+almanah_calendar_button_select_date_press_cb (GtkWidget *widget, GdkEvent *event, AlmanahCalendarButton *self)
+{
+	self->priv->user_event = NONE_EVENT;
+
+	return FALSE;
+}
+
 GtkWidget *
 almanah_calendar_button_new (AlmanahStorageManager *storage_manager)
 {
@@ -381,6 +396,17 @@ almanah_calendar_button_set_today_action (AlmanahCalendarButton *self, GtkAction
 }
 
 void
+almanah_calendar_button_set_select_date_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->select_date_button)) {
+		gtk_activatable_set_related_action (GTK_ACTIVATABLE (self->priv->select_date_button), action);
+	}
+}
+
+void
 almanah_calendar_button_select_date (AlmanahCalendarButton *self, GDate *date)
 {
 	g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
@@ -397,3 +423,11 @@ almanah_calendar_button_get_date (AlmanahCalendarButton *self, GDate *date)
 
 	almanah_calendar_get_date (self->priv->calendar, date);
 }
+
+void
+almanah_calendar_button_popdown (AlmanahCalendarButton *self)
+{
+	g_return_if_fail (ALMANAH_IS_CALENDAR_BUTTON (self));
+
+	almanah_calendar_window_popdown (ALMANAH_CALENDAR_WINDOW (self->priv->dock));
+}
diff --git a/src/widgets/calendar-button.h b/src/widgets/calendar-button.h
index 2e8fc3e..3c39bc2 100644
--- a/src/widgets/calendar-button.h
+++ b/src/widgets/calendar-button.h
@@ -51,9 +51,11 @@ typedef struct {
 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_select_date_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);
+void almanah_calendar_button_popdown (AlmanahCalendarButton *self);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]