28
28
#endif /* ENABLE_SPELL_CHECKING */
30
30
#include "main-window.h"
32
31
#include "interface.h"
33
#include "add-definition-dialog.h"
34
32
#include "preferences-dialog.h"
35
33
#include "search-dialog.h"
36
34
#include "date-entry-dialog.h"
37
35
#include "printing.h"
39
37
#include "storage-manager.h"
38
#include "event-manager.h"
41
#include "definition.h"
42
#include "definition-manager-window.h"
43
40
#include "import-export-dialog.h"
41
#include "uri-entry-dialog.h"
44
42
#include "widgets/calendar.h"
43
#include "widgets/calendar-button.h"
44
#include "widgets/font-style-menu-action.h"
45
#include "widgets/hyperlink-tag.h"
47
/* Interval for automatically saving the current entry. Currently an arbitrary 10 minutes. */
48
#define SAVE_ENTRY_INTERVAL 10 * 60 /* seconds */
46
50
static void almanah_main_window_dispose (GObject *object);
47
51
#ifdef ENABLE_SPELL_CHECKING
48
static void almanah_main_window_finalize (GObject *object);
52
static void spell_checking_enabled_changed_cb (GSettings *settings, gchar *key, AlmanahMainWindow *self);
53
static gboolean enable_spell_checking (AlmanahMainWindow *self, GError **error);
54
static void disable_spell_checking (AlmanahMainWindow *self);
49
55
#endif /* ENABLE_SPELL_CHECKING */
50
56
static void set_current_entry (AlmanahMainWindow *self, AlmanahEntry *entry);
51
57
static void save_window_state (AlmanahMainWindow *self);
55
61
static void mw_entry_buffer_insert_text_cb (GtkTextBuffer *text_buffer, GtkTextIter *start, gchar *text, gint len, AlmanahMainWindow *main_window);
56
62
static void mw_entry_buffer_insert_text_after_cb (GtkTextBuffer *text_buffer, GtkTextIter *start, gchar *text, gint len, AlmanahMainWindow *main_window);
57
63
static void mw_entry_buffer_has_selection_cb (GObject *object, GParamSpec *pspec, AlmanahMainWindow *main_window);
58
static void mw_entry_buffer_apply_tag_cb (GtkTextBuffer *buffer, GtkTextTag *tag, GtkTextIter *start_iter, GtkTextIter *end_iter, AlmanahMainWindow *main_window);
59
64
static void mw_bold_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
60
65
static void mw_italic_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
61
66
static void mw_underline_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
67
static void mw_hyperlink_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *main_window);
62
68
static void mw_events_updated_cb (AlmanahEventManager *event_manager, AlmanahEventFactoryType type_id, AlmanahMainWindow *main_window);
63
static void mw_events_selection_changed_cb (GtkTreeSelection *tree_selection, AlmanahMainWindow *main_window);
64
static void mw_events_value_data_cb (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
65
static void mw_definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahMainWindow *main_window);
69
static void mw_font_style_menu_position_func (GtkMenu *menu, int *x, int *y, gboolean *push_in, GtkMenuToolButton *button);
70
static GtkMenuToolButton *mw_get_font_style_tool_button_from_action (GtkAction *action);
71
static gboolean save_entry_timeout_cb (AlmanahMainWindow *self);
72
static void mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action);
67
74
/* GtkBuilder callbacks */
68
void mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window);
69
75
void mw_import_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
70
76
void mw_export_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
71
77
void mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
83
89
void mw_preferences_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
84
90
void mw_about_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
85
91
void mw_jump_to_today_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
86
void mw_add_definition_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
87
void mw_remove_definition_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
88
void mw_view_definitions_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
92
void mw_old_entries_activate_cb (GtkAction *action, AlmanahMainWindow *main_window);
89
93
void mw_events_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, AlmanahMainWindow *main_window);
90
void mw_view_button_clicked_cb (GtkButton *button, AlmanahMainWindow *main_window);
94
void mw_font_style_activate_cb (AlmanahFontStyleMenuAction *action, AlmanahMainWindow *main_window);
97
void mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar, AlmanahMainWindow *main_window);
92
99
struct _AlmanahMainWindowPrivate {
93
100
GtkTextView *entry_view;
94
101
GtkTextBuffer *entry_buffer;
95
AlmanahCalendar *calendar;
97
GtkButton *view_button;
98
GtkAction *add_action;
99
GtkAction *remove_action;
102
AlmanahCalendarButton *calendar_button;
100
103
GtkListStore *event_store;
104
GtkWidget *events_expander;
105
GtkLabel *events_count_label;
101
106
GtkTreeSelection *events_selection;
102
GtkTreeViewColumn *event_value_column;
103
GtkCellRendererText *event_value_renderer;
104
107
GtkToggleAction *bold_action;
105
108
GtkToggleAction *italic_action;
106
109
GtkToggleAction *underline_action;
110
GtkToggleAction *hyperlink_action;
107
111
GtkAction *cut_action;
108
112
GtkAction *copy_action;
109
113
GtkAction *delete_action;
110
114
GtkAction *important_action;
115
GtkMenuToolButton *font_style_tool_button;
112
117
gboolean updating_formatting;
113
118
gboolean pending_bold_active;
144
151
gtk_window_set_title (GTK_WINDOW (self), _("Almanah Diary"));
145
152
g_signal_connect (self, "delete-event", G_CALLBACK (mw_delete_event_cb), NULL);
147
#ifdef ENABLE_SPELL_CHECKING
148
/* We don't use g_settings_bind() because enabling spell checking could fail, and we need to show an error dialogue */
149
self->priv->spell_checking_enabled_changed_id = g_signal_connect (almanah->settings, "changed::spell-checking-enabled",
150
(GCallback) spell_checking_enabled_changed_cb, self);
151
#endif /* ENABLE_SPELL_CHECKING */
155
156
almanah_main_window_dispose (GObject *object)
158
AlmanahMainWindowPrivate *priv = ALMANAH_MAIN_WINDOW (object)->priv;
160
if (priv->save_entry_timeout_id != 0) {
161
g_source_remove (priv->save_entry_timeout_id);
162
priv->save_entry_timeout_id = 0;
157
165
set_current_entry (ALMANAH_MAIN_WINDOW (object), NULL);
167
if (priv->page_setup != NULL)
168
g_object_unref (priv->page_setup);
169
priv->page_setup = NULL;
171
if (priv->print_settings != NULL)
172
g_object_unref (priv->print_settings);
173
priv->print_settings = NULL;
175
#ifdef ENABLE_SPELL_CHECKING
176
if (priv->settings != NULL) {
177
if (priv->spell_checking_enabled_changed_id != 0) {
178
g_signal_handler_disconnect (priv->settings, priv->spell_checking_enabled_changed_id);
179
priv->spell_checking_enabled_changed_id = 0;
182
g_object_unref (priv->settings);
183
priv->settings = NULL;
185
#endif /* ENABLE_SPELL_CHECKING */
159
187
/* Chain up to the parent class */
160
188
G_OBJECT_CLASS (almanah_main_window_parent_class)->dispose (object);
163
#ifdef ENABLE_SPELL_CHECKING
165
almanah_main_window_finalize (GObject *object)
167
AlmanahMainWindowPrivate *priv = ALMANAH_MAIN_WINDOW (object)->priv;
169
g_signal_handler_disconnect (object, priv->spell_checking_enabled_changed_id);
171
/* Chain up to the parent class */
172
G_OBJECT_CLASS (almanah_main_window_parent_class)->finalize (object);
174
#endif /* ENABLE_SPELL_CHECKING */
176
191
AlmanahMainWindow *
177
almanah_main_window_new (void)
192
almanah_main_window_new (AlmanahApplication *application)
179
194
GtkBuilder *builder;
195
AlmanahEventManager *event_manager;
180
196
AlmanahMainWindow *main_window;
181
197
AlmanahMainWindowPrivate *priv;
199
GtkAction *today_action;
182
200
GError *error = NULL;
183
201
const gchar *interface_filename = almanah_get_interface_filename ();
184
202
const gchar *object_names[] = {
185
203
"almanah_main_window",
186
204
"almanah_mw_event_store",
187
"almanah_mw_view_button_image",
188
205
"almanah_ui_manager",
209
g_return_val_if_fail (ALMANAH_IS_APPLICATION (application), NULL);
192
211
builder = gtk_builder_new ();
194
213
if (gtk_builder_add_objects_from_file (builder, interface_filename, (gchar**) object_names, &error) == FALSE) {
239
/* Set up the application */
240
gtk_window_set_application (GTK_WINDOW (main_window), GTK_APPLICATION (application));
220
242
priv = ALMANAH_MAIN_WINDOW (main_window)->priv;
222
244
/* Grab our child widgets */
223
245
priv->entry_view = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "almanah_mw_entry_view"));
224
246
priv->entry_buffer = gtk_text_view_get_buffer (priv->entry_view);
225
priv->calendar = ALMANAH_CALENDAR (gtk_builder_get_object (builder, "almanah_mw_calendar"));
226
priv->date_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_mw_date_label"));
227
priv->view_button = GTK_BUTTON (gtk_builder_get_object (builder, "almanah_mw_view_button"));
228
priv->add_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_add_definition"));
229
priv->remove_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_remove_definition"));
230
247
priv->event_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "almanah_mw_event_store"));
248
priv->events_expander = GTK_WIDGET (gtk_builder_get_object (builder, "almanah_mw_events_expander"));
249
priv->events_count_label = GTK_LABEL (gtk_builder_get_object (builder, "almanah_mw_events_count_label"));
231
250
priv->events_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (gtk_builder_get_object (builder, "almanah_mw_events_tree_view")));
232
priv->event_value_column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (builder, "almanah_mw_event_value_column"));
233
priv->event_value_renderer = GTK_CELL_RENDERER_TEXT (gtk_builder_get_object (builder, "almanah_mw_event_value_renderer"));
234
251
priv->bold_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (builder, "almanah_ui_bold"));;
235
252
priv->italic_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (builder, "almanah_ui_italic"));
236
253
priv->underline_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (builder, "almanah_ui_underline"));
254
priv->hyperlink_action = GTK_TOGGLE_ACTION (gtk_builder_get_object (builder, "almanah_ui_hyperlink"));
237
255
priv->cut_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_cut"));
238
256
priv->copy_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_copy"));
239
257
priv->delete_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_delete"));
240
258
priv->important_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_important"));
259
priv->font_style_tool_button = mw_get_font_style_tool_button_from_action (GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_font_style")));
242
261
#ifdef ENABLE_SPELL_CHECKING
243
262
/* Set up spell checking, if it's enabled */
244
if (g_settings_get_boolean (almanah->settings, "spell-checking-enabled") == TRUE)
263
priv->settings = almanah_application_dup_settings (application);
265
if (g_settings_get_boolean (priv->settings, "spell-checking-enabled") == TRUE) {
245
266
enable_spell_checking (main_window, NULL);
269
/* We don't use g_settings_bind() because enabling spell checking could fail, and we need to show an error dialogue */
270
priv->spell_checking_enabled_changed_id = g_signal_connect (priv->settings, "changed::spell-checking-enabled",
271
(GCallback) spell_checking_enabled_changed_cb, main_window);
246
272
#endif /* ENABLE_SPELL_CHECKING */
248
274
/* Set up text formatting. It's important this is done after setting up GtkSpell, so that we know whether to
260
286
/* Similarly, make sure we're notified when there's a selection so we can change the status of cut/copy/paste actions */
261
287
g_signal_connect (priv->entry_buffer, "notify::has-selection", G_CALLBACK (mw_entry_buffer_has_selection_cb), main_window);
263
/* Get notified of applied tags so we can check if referenced definitions still exist */
264
g_signal_connect_after (priv->entry_buffer, "apply-tag", G_CALLBACK (mw_entry_buffer_apply_tag_cb), main_window);
266
289
/* Connect up the formatting actions */
267
290
g_signal_connect (priv->bold_action, "toggled", G_CALLBACK (mw_bold_toggled_cb), main_window);
268
291
g_signal_connect (priv->italic_action, "toggled", G_CALLBACK (mw_italic_toggled_cb), main_window);
269
292
g_signal_connect (priv->underline_action, "toggled", G_CALLBACK (mw_underline_toggled_cb), main_window);
293
g_signal_connect (priv->hyperlink_action, "toggled", (GCallback) mw_hyperlink_toggled_cb, main_window);
271
295
/* Notification for event changes */
272
g_signal_connect (almanah->event_manager, "events-updated", G_CALLBACK (mw_events_updated_cb), main_window);
274
/* Notification for changes to definitions in the database */
275
g_signal_connect (almanah->storage_manager, "definition-removed", G_CALLBACK (mw_definition_removed_cb), main_window);
296
event_manager = almanah_application_dup_event_manager (application);
297
g_signal_connect (event_manager, "events-updated", G_CALLBACK (mw_events_updated_cb), main_window);
298
g_object_unref (event_manager);
300
/* Set up printing objects */
301
priv->print_settings = gtk_print_settings_new ();
303
#ifdef GTK_PRINT_SETTINGS_OUTPUT_BASENAME
304
/* Translators: This is the default name of the PDF/PS/SVG file the diary is printed to if "Print to File" is chosen. */
305
gtk_print_settings_set (priv->print_settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME, _("Diary"));
308
priv->page_setup = gtk_page_setup_new ();
310
/* Set up the toolbar */
311
toolbar = GTK_TOOLBAR (gtk_builder_get_object (builder, "almanah_mw_toolbar"));
312
today_action = GTK_ACTION (gtk_builder_get_object (builder, "almanah_ui_jump_to_today"));
313
mw_setup_toolbar (main_window, application, toolbar, today_action);
277
315
/* Select the current day and month */
278
316
mw_jump_to_today_activate_cb (NULL, main_window);
280
/* Set up the treeview */
281
g_signal_connect (priv->events_selection, "changed", G_CALLBACK (mw_events_selection_changed_cb), main_window);
282
gtk_tree_view_column_set_cell_data_func (priv->event_value_column, GTK_CELL_RENDERER (priv->event_value_renderer), mw_events_value_data_cb, NULL, NULL);
318
/* Set up a timeout for saving the current entry every so often. */
319
priv->save_entry_timeout_id = g_timeout_add_seconds (SAVE_ENTRY_INTERVAL, (GSourceFunc) save_entry_timeout_cb, main_window);
284
321
#ifndef ENABLE_ENCRYPTION
285
322
#ifndef ENABLE_SPELL_CHECKING
609
659
almanah_entry_set_last_edited (priv->current_entry, &last_edited);
611
661
/* Store the entry! */
612
almanah_storage_manager_set_entry (almanah->storage_manager, priv->current_entry);
662
almanah_storage_manager_set_entry (storage_manager, priv->current_entry);
614
664
if (entry_is_empty == TRUE) {
615
665
/* Since the entry is empty, remove all the events from the treeview */
616
666
gtk_list_store_clear (priv->event_store);
621
add_definition_to_current_entry (AlmanahMainWindow *self)
623
AlmanahMainWindowPrivate *priv = self->priv;
624
GtkTextIter start_iter, end_iter;
626
AlmanahDefinition *definition;
628
g_assert (priv->entry_buffer != NULL);
629
g_assert (gtk_text_buffer_get_char_count (priv->entry_buffer) != 0);
631
if (gtk_text_buffer_get_selection_bounds (priv->entry_buffer, &start_iter, &end_iter) == FALSE)
634
text = gtk_text_buffer_get_text (priv->entry_buffer, &start_iter, &end_iter, FALSE);
636
/* If the definition already exists, don't display the dialogue */
637
definition = almanah_storage_manager_get_definition (almanah->storage_manager, text);
638
if (definition != NULL) {
639
g_object_unref (definition);
641
/* Add a GtkTextTag to the GtkTextBuffer to mark the definition */
642
gtk_text_buffer_apply_tag_by_name (priv->entry_buffer, "definition", &start_iter, &end_iter);
643
gtk_text_buffer_set_modified (priv->entry_buffer, TRUE);
649
/* Create the Add Definition dialogue if it doesn't already exist */
650
if (almanah->add_definition_dialog == NULL)
651
almanah->add_definition_dialog = GTK_WIDGET (almanah_add_definition_dialog_new ());
653
/* Ensure that something is selected and its widget's displayed */
654
almanah_add_definition_dialog_set_text (ALMANAH_ADD_DEFINITION_DIALOG (almanah->add_definition_dialog), text);
656
gtk_widget_show_all (almanah->add_definition_dialog);
658
if (gtk_dialog_run (GTK_DIALOG (almanah->add_definition_dialog)) == GTK_RESPONSE_OK) {
659
definition = almanah_add_definition_dialog_get_definition (ALMANAH_ADD_DEFINITION_DIALOG (almanah->add_definition_dialog));
660
if (definition == NULL)
664
almanah_storage_manager_add_definition (almanah->storage_manager, definition);
666
/* Add a GtkTextTag to the GtkTextBuffer to mark the definition */
667
gtk_text_buffer_apply_tag_by_name (priv->entry_buffer, "definition", &start_iter, &end_iter);
668
gtk_text_buffer_set_modified (priv->entry_buffer, TRUE);
673
remove_definition_from_current_entry (AlmanahMainWindow *self)
675
/* We don't actually remove the definition from the database, since other entries may use it;
676
* we simply remove the formatting. */
677
AlmanahMainWindowPrivate *priv = self->priv;
678
GtkTextIter start_iter, end_iter;
680
GtkTextTagTable *tag_table;
682
/* Find the tag in the tag table */
683
tag_table = gtk_text_buffer_get_tag_table (priv->entry_buffer);
684
tag = gtk_text_tag_table_lookup (tag_table, "definition");
685
g_assert (tag != NULL);
687
/* Find the boundaries of the tag (ignoring everything except the position
688
* of the start iter of any selection the user's made). */
689
gtk_text_buffer_get_selection_bounds (priv->entry_buffer, &start_iter, NULL);
690
end_iter = start_iter;
692
if (gtk_text_iter_begins_tag (&start_iter, tag) == TRUE) {
693
/* We're at the start of the tag */
694
gtk_text_iter_forward_to_tag_toggle (&end_iter, tag);
695
} else if (gtk_text_iter_ends_tag (&start_iter, tag) == TRUE) {
696
/* We're at the end of the tag */
697
end_iter = start_iter;
698
gtk_text_iter_backward_to_tag_toggle (&start_iter, tag);
700
/* We're somewhere in the middle of the tag */
701
gtk_text_iter_backward_to_tag_toggle (&start_iter, tag);
702
end_iter = start_iter;
703
gtk_text_iter_forward_to_tag_toggle (&end_iter, tag);
707
gtk_text_buffer_remove_tag (priv->entry_buffer, tag, &start_iter, &end_iter);
708
gtk_text_buffer_set_modified (priv->entry_buffer, TRUE);
670
g_object_unref (storage_manager);
674
save_entry_timeout_cb (AlmanahMainWindow *self)
676
save_current_entry (self, FALSE);
712
681
almanah_main_window_select_date (AlmanahMainWindow *self, GDate *date)
714
almanah_calendar_select_date (self->priv->calendar, date);
683
almanah_calendar_button_select_date (self->priv->calendar_button, date);
736
705
if (range_selected == FALSE)
737
706
_tag_list = gtk_text_iter_get_tags (&iter);
739
/* We can only have the "add definition" action sensitive if there's a range selected */
740
gtk_action_set_sensitive (priv->add_action, (range_selected == TRUE) ? TRUE : FALSE);
742
708
/* Block signal handlers for the formatting actions while we're executing,
743
709
* so formatting doesn't get unwittingly changed. */
744
710
priv->updating_formatting = TRUE;
746
712
tag_list = _tag_list;
747
713
while (tag_list != NULL) {
749
716
GtkToggleAction *action = NULL;
751
g_object_get (tag_list->data, "name", &tag_name, NULL);
718
tag = GTK_TEXT_TAG (tag_list->data);
719
g_object_get (tag, "name", &tag_name, NULL);
753
721
/* See if we can do anything with the tag */
754
if (strcmp (tag_name, "bold") == 0) {
755
action = priv->bold_action;
757
} else if (strcmp (tag_name, "italic") == 0) {
758
action = priv->italic_action;
759
italic_toggled = TRUE;
760
} else if (strcmp (tag_name, "underline") == 0) {
761
action = priv->underline_action;
762
underline_toggled = TRUE;
765
if (strcmp (tag_name, "definition") == 0) {
766
/* Deal with definition tags slightly differently --- just toggle the sensitivity of the "remove definition" action */
767
gtk_action_set_sensitive (priv->remove_action, TRUE);
768
remove_definition_toggled = TRUE;
769
} else if (action != NULL) {
722
if (tag_name != NULL) {
723
if (strcmp (tag_name, "bold") == 0) {
724
action = priv->bold_action;
726
} else if (strcmp (tag_name, "italic") == 0) {
727
action = priv->italic_action;
728
italic_toggled = TRUE;
729
} else if (strcmp (tag_name, "underline") == 0) {
730
action = priv->underline_action;
731
underline_toggled = TRUE;
736
if (ALMANAH_IS_HYPERLINK_TAG (tag)) {
737
action = priv->hyperlink_action;
738
hyperlink_toggled = TRUE;
741
if (action != NULL) {
770
742
/* Force the toggle status on the action */
771
743
gtk_toggle_action_set_active (action, TRUE);
772
} else if (strcmp (tag_name, "gtkspell-misspelled") != 0) {
744
} else if (tag_name == NULL || strcmp (tag_name, "gtkspell-misspelled") != 0) {
773
745
/* Print a warning about the unknown tag */
774
746
g_warning (_("Unknown or duplicate text tag \"%s\" in entry. Ignoring."), tag_name);
837
811
gtk_action_set_sensitive (main_window->priv->delete_action, has_selection);
841
mw_entry_buffer_apply_tag_cb (GtkTextBuffer *buffer, GtkTextTag *tag, GtkTextIter *start_iter, GtkTextIter *end_iter, AlmanahMainWindow *main_window)
845
g_object_get (G_OBJECT (tag), "name", &name, NULL);
846
if (strcmp (name, "definition") == 0) {
847
AlmanahDefinition *definition;
848
gchar *definition_text;
850
/* Check to see if the definition still exists in the DB */
851
definition_text = gtk_text_buffer_get_text (buffer, start_iter, end_iter, FALSE);
852
definition = almanah_storage_manager_get_definition (almanah->storage_manager, definition_text);
853
g_free (definition_text);
855
/* If the definition doesn't exist, remove the tag */
856
if (definition == NULL) {
857
gtk_text_buffer_remove_tag (buffer, tag, start_iter, end_iter);
858
gtk_text_buffer_set_modified (buffer, TRUE);
860
g_object_unref (definition);
868
815
mw_delete_event_cb (GtkWindow *window, gpointer user_data)
870
save_current_entry (ALMANAH_MAIN_WINDOW (window));
817
save_current_entry (ALMANAH_MAIN_WINDOW (window), TRUE);
871
818
save_window_state (ALMANAH_MAIN_WINDOW (window));
820
gtk_widget_destroy (GTK_WIDGET (window));
901
864
mw_page_setup_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
903
almanah_print_page_setup ();
866
AlmanahMainWindowPrivate *priv = main_window->priv;
867
GtkPageSetup *page_setup;
869
page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window), priv->page_setup, priv->print_settings);
870
if (priv->page_setup != NULL)
871
g_object_unref (priv->page_setup);
872
priv->page_setup = page_setup;
907
876
mw_print_preview_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
909
almanah_print_entries (TRUE);
878
AlmanahMainWindowPrivate *priv = main_window->priv;
879
AlmanahApplication *application;
880
AlmanahStorageManager *storage_manager;
882
application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
883
storage_manager = almanah_application_dup_storage_manager (application);
884
almanah_print_entries (TRUE, GTK_WINDOW (main_window), &(priv->page_setup), &(priv->print_settings), storage_manager);
885
g_object_unref (storage_manager);
913
889
mw_print_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
915
almanah_print_entries (FALSE);
891
AlmanahMainWindowPrivate *priv = main_window->priv;
892
AlmanahApplication *application;
893
AlmanahStorageManager *storage_manager;
895
application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
896
storage_manager = almanah_application_dup_storage_manager (application);
897
almanah_print_entries (FALSE, GTK_WINDOW (main_window), &(priv->page_setup), &(priv->print_settings), storage_manager);
898
g_object_unref (storage_manager);
919
902
mw_quit_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
921
save_current_entry (main_window);
904
/* Hide the window to make things look faster */
905
gtk_widget_hide (GTK_WIDGET (main_window));
907
save_current_entry (main_window, TRUE);
908
gtk_widget_destroy (GTK_WIDGET (main_window));
970
956
mw_select_date_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
972
if (almanah->date_entry_dialog == NULL)
973
almanah->date_entry_dialog = GTK_WIDGET (almanah_date_entry_dialog_new ());
958
AlmanahDateEntryDialog *dialog = almanah_date_entry_dialog_new ();
975
gtk_widget_show_all (almanah->date_entry_dialog);
976
if (almanah_date_entry_dialog_run (ALMANAH_DATE_ENTRY_DIALOG (almanah->date_entry_dialog)) == TRUE) {
960
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
961
gtk_widget_show_all (GTK_WIDGET (dialog));
962
if (almanah_date_entry_dialog_run (dialog) == TRUE) {
979
965
/* Switch to the specified date */
980
almanah_date_entry_dialog_get_date (ALMANAH_DATE_ENTRY_DIALOG (almanah->date_entry_dialog), &new_date);
966
almanah_date_entry_dialog_get_date (dialog, &new_date);
981
967
almanah_main_window_select_date (main_window, &new_date);
970
gtk_widget_destroy (GTK_WIDGET (dialog));
986
974
mw_search_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
988
if (almanah->search_dialog == NULL)
989
almanah->search_dialog = GTK_WIDGET (almanah_search_dialog_new ());
991
gtk_widget_show_all (almanah->search_dialog);
992
gtk_dialog_run (GTK_DIALOG (almanah->search_dialog));
976
AlmanahSearchDialog *dialog = almanah_search_dialog_new ();
978
gtk_window_set_application (GTK_WINDOW (dialog), gtk_window_get_application (GTK_WINDOW (main_window)));
979
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
980
gtk_widget_show (GTK_WIDGET (dialog));
981
gtk_dialog_run (GTK_DIALOG (dialog));
983
gtk_widget_destroy (GTK_WIDGET (dialog));
996
987
mw_preferences_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
998
#ifdef ENABLE_ENCRYPTION
999
if (almanah->preferences_dialog == NULL)
1000
almanah->preferences_dialog = GTK_WIDGET (almanah_preferences_dialog_new ());
1002
gtk_widget_show_all (almanah->preferences_dialog);
1003
gtk_dialog_run (GTK_DIALOG (almanah->preferences_dialog));
1004
#endif /* ENABLE_ENCRYPTION */
989
#if defined(ENABLE_ENCRYPTION) || defined(ENABLE_SPELL_CHECKING)
990
AlmanahApplication *application;
992
AlmanahPreferencesDialog *dialog;
994
application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
995
settings = almanah_application_dup_settings (application);
996
dialog = almanah_preferences_dialog_new (settings);
997
g_object_unref (settings);
999
gtk_widget_show_all (GTK_WIDGET (dialog));
1000
gtk_dialog_run (GTK_DIALOG (dialog));
1002
gtk_widget_destroy (GTK_WIDGET (dialog));
1003
#endif /* ENABLE_ENCRYPTION || ENABLE_SPELL_CHECKING */
1041
1040
apply_formatting (main_window, "underline", gtk_toggle_action_get_active (action));
1044
hyperlink_tag_event_cb (GtkTextTag *tag, GObject *object, GdkEvent *event, GtkTextIter *iter, AlmanahMainWindow *self)
1046
AlmanahHyperlinkTag *hyperlink_tag = ALMANAH_HYPERLINK_TAG (tag);
1048
/* Open the hyperlink if it's control-clicked */
1049
if (event->type == GDK_BUTTON_RELEASE && event->button.state & GDK_CONTROL_MASK) {
1051
GError *error = NULL;
1053
uri = almanah_hyperlink_tag_get_uri (hyperlink_tag);
1055
/* Attempt to open the URI */
1056
gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (self)), uri, gdk_event_get_time (event), &error);
1058
if (error != NULL) {
1060
GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (self),
1061
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1062
_("Error opening URI"));
1063
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
1064
gtk_dialog_run (GTK_DIALOG (dialog));
1065
gtk_widget_destroy (dialog);
1067
g_error_free (error);
1077
mw_hyperlink_toggled_cb (GtkToggleAction *action, AlmanahMainWindow *self)
1079
AlmanahMainWindowPrivate *priv = self->priv;
1080
GtkTextIter start, end;
1082
/* Make sure we don't muck up the formatting when the actions are having
1083
* their sensitivity set by the code. */
1084
if (priv->updating_formatting == TRUE)
1087
gtk_text_buffer_get_selection_bounds (priv->entry_buffer, &start, &end);
1089
if (gtk_toggle_action_get_active (action) == TRUE) {
1090
/* Add a new hyperlink on the selected text */
1091
AlmanahUriEntryDialog *uri_entry_dialog;
1093
/* Get a URI from the user */
1094
uri_entry_dialog = almanah_uri_entry_dialog_new ();
1095
gtk_window_set_transient_for (GTK_WINDOW (uri_entry_dialog), GTK_WINDOW (self));
1096
gtk_widget_show_all (GTK_WIDGET (uri_entry_dialog));
1098
if (almanah_uri_entry_dialog_run (uri_entry_dialog) == TRUE) {
1100
GtkTextTagTable *table;
1102
/* Create and apply a new anonymous tag */
1103
tag = GTK_TEXT_TAG (almanah_hyperlink_tag_new (almanah_uri_entry_dialog_get_uri (uri_entry_dialog)));
1105
table = gtk_text_buffer_get_tag_table (priv->entry_buffer);
1106
gtk_text_tag_table_add (table, tag);
1108
gtk_text_buffer_apply_tag (priv->entry_buffer, tag, &start, &end);
1110
/* Connect up events */
1111
g_signal_connect (tag, "event", (GCallback) hyperlink_tag_event_cb, self);
1113
/* The text tag table keeps a reference */
1114
g_object_unref (tag);
1117
gtk_widget_destroy (GTK_WIDGET (uri_entry_dialog));
1119
GtkTextIter iter = start;
1122
/* Remove all hyperlinks which are active at the start iter. This covers the case of hyperlinks which span more than the
1123
* selected text (i.e. begin before the start iter and end after the end iter). All other spanning hyperlinks will have an end point
1124
* inside the selected text, and will be caught below. */
1125
tags = gtk_text_iter_get_tags (&start);
1127
for (i = tags; i != NULL; i = i->next) {
1128
GtkTextTag *tag = GTK_TEXT_TAG (i->data);
1130
if (ALMANAH_IS_HYPERLINK_TAG (tag)) {
1131
GtkTextIter tag_start = start, tag_end = start;
1133
if (gtk_text_iter_backward_to_tag_toggle (&tag_start, tag) == TRUE &&
1134
gtk_text_iter_forward_to_tag_toggle (&tag_end, tag) == TRUE) {
1135
gtk_text_buffer_remove_tag (priv->entry_buffer, tag, &tag_start, &tag_end);
1140
g_slist_free (tags);
1142
/* Remove all hyperlinks which span the selected text and have an end point inside the selected text */
1143
while (gtk_text_iter_forward_to_tag_toggle (&iter, NULL) == TRUE) {
1144
/* Break once we've passed the end of the selected text range */
1145
if (gtk_text_iter_compare (&iter, &end) > 0) {
1149
tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
1151
for (i = tags; i != NULL; i = i->next) {
1152
if (ALMANAH_IS_HYPERLINK_TAG (i->data)) {
1153
gtk_text_buffer_remove_tag (priv->entry_buffer, GTK_TEXT_TAG (i->data), &start, &end);
1157
g_slist_free (tags);
1161
gtk_text_buffer_set_modified (priv->entry_buffer, TRUE);
1045
1165
mw_about_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
1167
AlmanahApplication *application;
1168
AlmanahStorageManager *storage_manager;
1047
1169
gchar *license, *description;
1048
guint entry_count, definition_count;
1050
1172
const gchar *authors[] =
1104
1228
GDate current_date;
1105
1229
g_date_set_time_t (¤t_date, time (NULL));
1106
almanah_main_window_select_date (main_window, ¤t_date);
1110
mw_add_definition_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
1112
add_definition_to_current_entry (main_window);
1116
mw_remove_definition_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
1118
remove_definition_from_current_entry (main_window);
1122
mw_view_definitions_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
1124
if (almanah->definition_manager_window == NULL)
1125
almanah->definition_manager_window = GTK_WIDGET (almanah_definition_manager_window_new ());
1127
gtk_widget_show_all (almanah->definition_manager_window);
1230
almanah_calendar_button_select_date (main_window->priv->calendar_button, ¤t_date);
1234
mw_old_entries_activate_cb (GtkAction *action, AlmanahMainWindow *main_window)
1236
// TODO: Show the old entries
1237
g_debug ("Old entries clicked, but nothing implemented yet...");
1241
* Just copied from GtkMenuToolButton (menu_position_func),
1242
* but using the button widget (not the arrow widget) for
1243
* menu position calc, and removing the code for a vertical
1244
* toolbar situation.
1246
* Copyright (C) 2003 Ricardo Fernandez Pascual
1247
* Copyright (C) 2004 Paolo Borelli
1248
* Licensed under the GPL v2
1251
mw_font_style_menu_position_func (GtkMenu *menu, int *x, int *y, gboolean *push_in, GtkMenuToolButton *button)
1253
GtkAllocation arrow_allocation;
1254
GtkWidget *widget = GTK_WIDGET (button);
1255
GtkRequisition menu_req;
1256
GtkTextDirection direction;
1257
GdkRectangle monitor;
1261
GtkAllocation allocation;
1263
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
1264
direction = gtk_widget_get_direction (widget);
1265
window = gtk_widget_get_window (widget);
1267
screen = gtk_widget_get_screen (GTK_WIDGET (menu));
1268
monitor_num = gdk_screen_get_monitor_at_window (screen, window);
1269
if (monitor_num < 0)
1271
gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
1273
gtk_widget_get_allocation (widget, &allocation);
1275
gdk_window_get_origin (window, x, y);
1279
if (direction == GTK_TEXT_DIR_LTR)
1280
*x += MAX (allocation.width - menu_req.width, 0);
1281
else if (menu_req.width > allocation.width)
1282
*x -= menu_req.width - allocation.width;
1284
if ((*y + arrow_allocation.height + menu_req.height) <= monitor.y + monitor.height)
1285
*y += allocation.height;
1286
else if ((*y - menu_req.height) >= monitor.y)
1287
*y -= menu_req.height;
1288
else if (monitor.y + monitor.height - (*y + arrow_allocation.height) > *y)
1289
*y += allocation.height;
1291
*y -= menu_req.height;
1297
mw_font_style_activate_cb (AlmanahFontStyleMenuAction *action, AlmanahMainWindow *main_window)
1299
AlmanahMainWindowPrivate *priv = ALMANAH_MAIN_WINDOW_GET_PRIVATE(main_window);
1300
GtkMenu *menu = NULL;
1302
if (GTK_IS_MENU_TOOL_BUTTON (priv->font_style_tool_button)) {
1303
menu = GTK_MENU (gtk_menu_tool_button_get_menu (priv->font_style_tool_button));
1306
if (GTK_IS_MENU (menu)) {
1307
gtk_menu_popup (menu, NULL, NULL,
1308
(GtkMenuPositionFunc) mw_font_style_menu_position_func,
1309
priv->font_style_tool_button,
1311
gtk_get_current_event_time());
1315
static GtkMenuToolButton *
1316
mw_get_font_style_tool_button_from_action (GtkAction *action)
1319
GtkMenuToolButton *tool_button = NULL;
1321
proxies = gtk_action_get_proxies (GTK_ACTION (action));
1322
while (proxies != NULL) {
1323
if (GTK_IS_MENU_TOOL_BUTTON (proxies->data)) {
1324
tool_button = GTK_MENU_TOOL_BUTTON (proxies->data);
1327
proxies = proxies->next;
1145
1347
gtk_tree_model_get (model, &iter, 2, &row_type_id, -1);
1147
1349
if (row_type_id == type_id) {
1148
if (almanah->debug == TRUE) {
1149
AlmanahEvent *event;
1150
gtk_tree_model_get (model, &iter, 0, &event, -1);
1151
g_debug ("\t%s", almanah_event_format_value (event));
1350
AlmanahEvent *event;
1351
gtk_tree_model_get (model, &iter, 0, &event, -1);
1352
g_debug ("\t%s", almanah_event_format_value (event));
1154
1354
if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter) == FALSE)
1169
1368
AlmanahMainWindowPrivate *priv = main_window->priv;
1170
1369
GSList *_events, *events;
1371
guint events_count = 0;
1173
almanah_calendar_get_date (main_window->priv->calendar, &date);
1374
almanah_calendar_button_get_date (main_window->priv->calendar_button, &date);
1174
1375
_events = almanah_event_manager_get_events (event_manager, type_id, &date);
1176
1377
/* Clear all the events generated by this factory out of the list store first */
1177
1378
clear_factory_events (main_window, type_id);
1179
if (almanah->debug == TRUE)
1180
g_debug ("Adding events from factory %u to the list store...", type_id);
1380
g_debug ("Adding events from factory %u to the list store...", type_id);
1182
1382
for (events = _events; events != NULL; events = g_slist_next (events)) {
1183
1383
GtkTreeIter iter;
1184
1384
AlmanahEvent *event = events->data;
1186
if (almanah->debug == TRUE)
1187
g_debug ("\t%s", almanah_event_format_value (event));
1386
g_debug ("\t%s", almanah_event_format_value (event));
1189
1388
gtk_list_store_append (priv->event_store, &iter);
1190
1389
gtk_list_store_set (priv->event_store, &iter,
1192
1391
1, almanah_event_get_icon_name (event),
1393
3, almanah_event_format_value (event),
1394
4, g_strdup_printf ("<small>%s @ %s</small>", almanah_event_format_time (event), almanah_event_get_name (event)),
1196
1399
g_object_unref (event);
1199
if (almanah->debug == TRUE)
1200
g_debug ("Finished adding events.");
1402
events_text = g_strdup_printf ("%u", events_count);
1403
gtk_label_set_label (priv->events_count_label, events_text);
1404
g_free (events_text);
1406
if (events_count > 0) {
1407
gtk_widget_set_sensitive (priv->events_expander, TRUE);
1409
gtk_expander_set_expanded (GTK_EXPANDER (priv->events_expander), FALSE);
1410
gtk_widget_set_sensitive (priv->events_expander, FALSE);
1413
g_debug ("Finished adding events.");
1202
1415
g_slist_free (_events);
1206
mw_calendar_day_selected_cb (GtkCalendar *calendar, AlmanahMainWindow *main_window)
1419
mw_calendar_day_selected_cb (AlmanahCalendarButton *calendar_button, AlmanahMainWindow *main_window)
1421
AlmanahApplication *application;
1422
AlmanahStorageManager *storage_manager;
1423
AlmanahEventManager *event_manager;
1208
1424
GDate calendar_date;
1209
gchar calendar_string[100];
1210
1425
#ifdef ENABLE_SPELL_CHECKING
1211
1426
GtkSpell *gtkspell;
1212
1427
#endif /* ENABLE_SPELL_CHECKING */
1213
1428
AlmanahMainWindowPrivate *priv = main_window->priv;
1214
1429
AlmanahEntry *entry;
1432
application = ALMANAH_APPLICATION (gtk_window_get_application (GTK_WINDOW (main_window)));
1216
1434
/* Save the previous entry */
1217
save_current_entry (main_window);
1435
save_current_entry (main_window, TRUE);
1219
1437
/* Update the date label */
1220
almanah_calendar_get_date (main_window->priv->calendar, &calendar_date);
1222
/* Translators: This is a strftime()-format string for the date displayed at the top of the main window. */
1223
g_date_strftime (calendar_string, sizeof (calendar_string), _("%A, %e %B %Y"), &calendar_date);
1224
gtk_label_set_markup (priv->date_label, calendar_string);
1438
almanah_calendar_button_get_date (main_window->priv->calendar_button, &calendar_date);
1226
1440
/* Update the entry */
1227
entry = almanah_storage_manager_get_entry (almanah->storage_manager, &calendar_date);
1441
storage_manager = almanah_application_dup_storage_manager (application);
1442
entry = almanah_storage_manager_get_entry (storage_manager, &calendar_date);
1443
g_object_unref (storage_manager);
1228
1445
if (entry == NULL)
1229
1446
entry = almanah_entry_new (&calendar_date);
1230
1447
set_current_entry (main_window, entry);
1237
1454
/* Prepare for the possibility of failure --- do as much of the general interface changes as possible first */
1238
1455
gtk_list_store_clear (priv->event_store);
1239
gtk_action_set_sensitive (priv->add_action, FALSE);
1240
gtk_action_set_sensitive (priv->remove_action, FALSE); /* Only sensitive if something's selected */
1241
gtk_widget_set_sensitive (GTK_WIDGET (priv->view_button), FALSE);
1243
1457
if (almanah_entry_is_empty (priv->current_entry) == FALSE) {
1244
1458
GError *error = NULL;
1246
1460
gtk_text_buffer_set_text (priv->entry_buffer, "", 0);
1247
1461
if (almanah_entry_get_content (priv->current_entry, priv->entry_buffer, FALSE, &error) == FALSE) {
1248
GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (almanah->main_window),
1462
GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
1249
1463
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1250
1464
_("Entry content could not be loaded"));
1251
1465
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
1277
1491
gtk_text_buffer_set_modified (priv->entry_buffer, FALSE);
1279
1493
/* List the entry's events */
1280
almanah_event_manager_query_events (almanah->event_manager, ALMANAH_EVENT_FACTORY_UNKNOWN, &calendar_date);
1284
mw_events_selection_changed_cb (GtkTreeSelection *tree_selection, AlmanahMainWindow *main_window)
1286
AlmanahMainWindowPrivate *priv = main_window->priv;
1287
gtk_widget_set_sensitive (GTK_WIDGET (priv->view_button), (gtk_tree_selection_count_selected_rows (tree_selection) == 0) ? FALSE : TRUE);
1291
mw_events_value_data_cb (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
1293
const gchar *new_value;
1294
AlmanahEvent *event;
1296
/* TODO: Should really create a new model to render AlmanahEvents */
1298
gtk_tree_model_get (model, iter,
1302
new_value = almanah_event_format_value (event);
1303
g_object_set (renderer, "text", new_value, NULL);
1494
event_manager = almanah_application_dup_event_manager (application);
1495
almanah_event_manager_query_events (event_manager, ALMANAH_EVENT_FACTORY_UNKNOWN, &calendar_date);
1496
g_object_unref (event_manager);
1317
1510
/* NOTE: event types should display their own errors, so one won't be displayed here. */
1318
almanah_event_view (event);
1322
mw_view_button_clicked_cb (GtkButton *button, AlmanahMainWindow *main_window)
1325
GtkTreeModel *model;
1327
events = gtk_tree_selection_get_selected_rows (main_window->priv->events_selection, &model);
1329
for (; events != NULL; events = events->next) {
1330
AlmanahEvent *event;
1333
gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) events->data);
1334
gtk_tree_model_get (model, &iter,
1338
/* NOTE: event types should display their own errors, so one won't be displayed here. */
1339
almanah_event_view (event);
1341
gtk_tree_path_free (events->data);
1344
g_list_free (events);
1511
almanah_event_view (event, GTK_WINDOW (main_window));
1348
mw_definition_removed_cb (AlmanahStorageManager *storage_manager, const gchar *definition_text, AlmanahMainWindow *main_window)
1515
mw_setup_toolbar (AlmanahMainWindow *main_window, AlmanahApplication *application, GtkToolbar *toolbar, GtkAction *today_action)
1350
/* We need to remove any definition tags in the current entry which match @definition_text. It's
1351
* probably easier to just reload the current entry, though. */
1352
mw_calendar_day_selected_cb (GTK_CALENDAR (main_window->priv->calendar), main_window);
1517
GtkToolItem *calendar_button_item, *separator;
1518
AlmanahStorageManager *storage_manager;
1520
/* Insert a dynamic space between the text style and calendar & important.
1521
* This can't be done using the <separator/> in the UI file at the moment
1523
separator = gtk_separator_tool_item_new ();
1524
gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (separator), FALSE);
1525
gtk_tool_item_set_expand (separator, TRUE);
1526
gtk_toolbar_insert (toolbar, separator, 2);
1528
/* Setup the calendar button */
1529
storage_manager = almanah_application_dup_storage_manager (application);
1530
main_window->priv->calendar_button = ALMANAH_CALENDAR_BUTTON (almanah_calendar_button_new (storage_manager));
1531
g_object_unref (storage_manager);
1532
g_signal_connect (main_window->priv->calendar_button, "day-selected", G_CALLBACK (mw_calendar_day_selected_cb), main_window);
1533
/* Use the same action for the today button in the dropdown window */
1534
almanah_calendar_button_set_today_action (main_window->priv->calendar_button, today_action);
1536
/* Insert the calendar button into the toolbar through a GtkToolItem but button style */
1537
calendar_button_item = gtk_tool_item_new ();
1538
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (calendar_button_item)), GTK_STYLE_CLASS_RAISED);
1539
gtk_container_add (GTK_CONTAINER (calendar_button_item), GTK_WIDGET (main_window->priv->calendar_button));
1540
gtk_toolbar_insert (toolbar, calendar_button_item, 3);
1355
1543
#ifdef ENABLE_SPELL_CHECKING