1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
4
* Copyright (C) Philip Withnall 2008 <philip@tecnocode.co.uk>
6
* Diary is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* Diary is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with Diary. If not, see <http://www.gnu.org/licenses/>.
22
#include <glib/gi18n.h>
23
#include <gtkspell/gtkspell.h>
26
#include "storage-manager.h"
28
#include "add-link-dialog.h"
29
#include "interface.h"
30
#include "main-window.h"
33
static void save_current_entry ();
34
static void add_link_to_current_entry ();
35
static void remove_link_from_current_entry ();
37
void mw_calendar_day_selected_cb (GtkCalendar *calendar, gpointer user_data);
38
void mw_links_selection_changed_cb (GtkTreeSelection *tree_selection, gpointer user_data);
39
void mw_links_value_data_cb (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data);
44
GtkTextIter start_iter, end_iter;
46
guint year, month, day;
48
g_assert (diary->entry_buffer != NULL);
50
/* Don't save if it hasn't been/can't be edited */
51
if (gtk_text_view_get_editable (diary->entry_view) == FALSE ||
52
gtk_text_buffer_get_modified (diary->entry_buffer) == FALSE)
56
gtk_text_buffer_get_bounds (diary->entry_buffer, &start_iter, &end_iter);
57
entry_text = gtk_text_buffer_get_text (diary->entry_buffer, &start_iter, &end_iter, FALSE);
59
gtk_calendar_get_date (diary->calendar, &year, &month, &day);
62
/* Mark the day on the calendar if the entry was non-empty (and deleted)
63
* and update the state of the add link button. */
64
if (diary_storage_manager_set_entry (diary->storage_manager, year, month, day, entry_text) == FALSE) {
65
gtk_calendar_unmark_day (diary->calendar, day);
67
gtk_widget_set_sensitive (GTK_WIDGET (diary->add_button), FALSE);
68
gtk_action_set_sensitive (diary->add_action, FALSE);
70
gtk_calendar_mark_day (diary->calendar, day);
72
gtk_widget_set_sensitive (GTK_WIDGET (diary->add_button), TRUE);
73
gtk_action_set_sensitive (diary->add_action, TRUE);
76
gtk_text_buffer_set_modified (diary->entry_buffer, FALSE);
81
add_link_to_current_entry ()
83
guint year, month, day;
85
const DiaryLinkType *link_type;
89
g_assert (diary->entry_buffer != NULL);
90
g_assert (gtk_text_buffer_get_char_count (diary->entry_buffer) != 0);
92
/* Ensure that something is selected and its widgets displayed */
93
g_signal_emit_by_name (diary->ald_type_combo_box, "changed", NULL, NULL);
94
gtk_widget_show_all (diary->add_link_dialog);
96
if (gtk_dialog_run (GTK_DIALOG (diary->add_link_dialog)) == GTK_RESPONSE_OK) {
97
if (gtk_combo_box_get_active_iter (diary->ald_type_combo_box, &iter) == FALSE)
100
/* Get the link type, then the values entered in the dialogue (specific to the type) */
101
gtk_tree_model_get (GTK_TREE_MODEL (diary->ald_type_store), &iter, 1, &type, -1);
102
link_type = diary_link_get_type (type);
103
g_assert (link_type != NULL);
105
link_type->get_values_func (&link);
108
gtk_calendar_get_date (diary->calendar, &year, &month, &day);
110
diary_storage_manager_add_entry_link (diary->storage_manager,
116
/* Add to the treeview */
117
gtk_list_store_append (diary->links_store, &iter);
118
gtk_list_store_set (diary->links_store, &iter,
122
3, link_type->icon_name,
127
g_free (link.value2);
133
remove_link_from_current_entry ()
136
guint year, month, day;
141
g_assert (diary->entry_buffer != NULL);
142
g_assert (gtk_text_buffer_get_char_count (diary->entry_buffer) != 0);
144
links = gtk_tree_selection_get_selected_rows (diary->links_selection, &model);
145
gtk_calendar_get_date (diary->calendar, &year, &month, &day);
148
for (; links != NULL; links = links->next) {
149
gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) links->data);
150
gtk_tree_model_get (model, &iter, 0, &link_type, -1);
152
/* Remove it from the DB */
153
diary_storage_manager_remove_entry_link (diary->storage_manager, year, month, day, link_type);
155
/* Remove it from the treeview */
156
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
158
gtk_tree_path_free (links->data);
165
diary_main_window_setup (GtkBuilder *builder)
167
GError *error = NULL;
169
/* Select the current day and month */
170
diary_calendar_month_changed_cb (diary->calendar, NULL);
171
mw_calendar_day_selected_cb (diary->calendar, NULL);
173
/* Set up the treeview */
174
g_signal_connect (diary->links_selection, "changed", (GCallback) mw_links_selection_changed_cb, NULL);
175
gtk_tree_view_column_set_cell_data_func (diary->link_value_column, GTK_CELL_RENDERER (diary->link_value_renderer), mw_links_value_data_cb, NULL, NULL);
177
if (gtkspell_new_attach (diary->entry_view, NULL, &error) == FALSE) {
178
gchar *error_message = g_strdup_printf (_("The spelling checker could not be initialized: %s"), error->message);
179
diary_interface_error (error_message, NULL);
180
g_free (error_message);
185
mw_select_date (GDate *date)
187
gtk_calendar_select_month (diary->calendar, g_date_get_month (date) - 1, g_date_get_year (date));
188
gtk_calendar_select_day (diary->calendar, g_date_get_day (date));
192
mw_delete_event_cb (GtkWindow *window, gpointer user_data)
194
save_current_entry ();
201
mw_print_activate_cb (GtkAction *action, gpointer user_data)
203
diary_print_entries ();
207
mw_quit_activate_cb (GtkAction *action, gpointer user_data)
209
save_current_entry ();
214
mw_cut_activate_cb (GtkAction *action, gpointer user_data)
216
GtkClipboard *clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (diary->main_window)), GDK_SELECTION_CLIPBOARD);
217
gtk_text_buffer_cut_clipboard (diary->entry_buffer, clipboard, TRUE);
221
mw_copy_activate_cb (GtkAction *action, gpointer user_data)
223
GtkClipboard *clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (diary->main_window)), GDK_SELECTION_CLIPBOARD);
224
gtk_text_buffer_copy_clipboard (diary->entry_buffer, clipboard);
228
mw_paste_activate_cb (GtkAction *action, gpointer user_data)
230
GtkClipboard *clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (GTK_WIDGET (diary->main_window)), GDK_SELECTION_CLIPBOARD);
231
gtk_text_buffer_paste_clipboard (diary->entry_buffer, clipboard, NULL, TRUE);
235
mw_delete_activate_cb (GtkAction *action, gpointer user_data)
237
gtk_text_buffer_delete_selection (diary->entry_buffer, TRUE, TRUE);
241
mw_search_activate_cb (GtkAction *action, gpointer user_data)
243
/* Ensure everything's tidy first */
244
gtk_list_store_clear (diary->sd_results_store);
245
gtk_entry_set_text (diary->sd_search_entry, "");
247
/* Run the dialogue */
248
gtk_widget_show_all (diary->search_dialog);
249
gtk_dialog_run (GTK_DIALOG (diary->search_dialog));
250
gtk_widget_hide_all (diary->search_dialog);
254
mw_about_activate_cb (GtkAction *action, gpointer user_data)
256
gchar *license, *description;
257
guint entry_count, link_count, character_count;
259
const gchar *authors[] =
261
"Philip Withnall <philip@tecnocode.co.uk>",
264
const gchar *license_parts[] = {
265
N_("Diary is free software: you can redistribute it and/or modify "
266
"it under the terms of the GNU General Public License as published by "
267
"the Free Software Foundation, either version 3 of the License, or "
268
"(at your option) any later version."),
269
N_("Diary is distributed in the hope that it will be useful, "
270
"but WITHOUT ANY WARRANTY; without even the implied warranty of "
271
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
272
"GNU General Public License for more details."),
273
N_("You should have received a copy of the GNU General Public License "
274
"along with Diary. If not, see <http://www.gnu.org/licenses/>."),
277
license = g_strjoin ("\n\n",
283
diary_storage_manager_get_statistics (diary->storage_manager, &entry_count, &link_count, &character_count);
284
description = g_strdup_printf (_("A helpful diary keeper, storing %u entries with %u links and a total of %u characters."),
289
gtk_show_about_dialog (GTK_WINDOW (diary->main_window),
291
"copyright", _("Copyright \xc2\xa9 2008 Philip Withnall"),
292
"comments", description,
294
/* Translators: please include your names here to be credited for your hard work!
296
* "Translator name 1 <translator@email.address>\n"
297
* "Translator name 2 <translator2@email.address>"
299
"translator-credits", _("translator-credits"),
300
"logo-icon-name", "diary",
302
"wrap-license", TRUE,
303
"website-label", _("Diary Website"),
304
"website", "http://tecnocode.co.uk/projects/diary",
308
g_free (description);
312
mw_jump_to_today_activate_cb (GtkAction *action, gpointer user_data)
315
g_date_set_time_t (¤t_date, time (NULL));
316
mw_select_date (¤t_date);
320
mw_add_link_activate_cb (GtkAction *action, gpointer user_data)
322
add_link_to_current_entry ();
326
mw_remove_link_activate_cb (GtkAction *action, gpointer user_data)
328
remove_link_from_current_entry ();
332
mw_calendar_day_selected_cb (GtkCalendar *calendar, gpointer user_data)
335
gchar calendar_string[100], *entry_text;
336
guint year, month, day;
340
const DiaryLinkType *link_type;
342
/* Update the date label */
343
gtk_calendar_get_date (calendar, &year, &month, &day);
345
g_date_set_dmy (&calendar_date, day, month, year);
347
/* Translators: This is a strftime()-format string for the date displayed at the top of the main window. */
348
g_date_strftime (calendar_string, sizeof (calendar_string), _("%A, %e %B %Y"), &calendar_date);
349
gtk_label_set_markup (diary->date_label, calendar_string);
350
diary_interface_embolden_label (diary->date_label);
352
/* Update the entry */
353
entry_text = diary_storage_manager_get_entry (diary->storage_manager, year, month, day);
354
gtk_text_view_set_editable (diary->entry_view, diary_storage_manager_entry_is_editable (diary->storage_manager, year, month, day));
355
gtk_text_buffer_set_modified (diary->entry_buffer, FALSE);
357
if (entry_text != NULL) {
358
gtk_text_buffer_set_text (diary->entry_buffer, entry_text, -1);
359
gtk_widget_set_sensitive (GTK_WIDGET (diary->add_button), TRUE);
360
gtk_action_set_sensitive (diary->add_action, TRUE);
362
gtk_text_buffer_set_text (diary->entry_buffer, "", -1);
363
gtk_widget_set_sensitive (GTK_WIDGET (diary->add_button), FALSE);
364
gtk_action_set_sensitive (diary->add_action, FALSE);
366
gtk_widget_set_sensitive (GTK_WIDGET (diary->remove_button), FALSE); /* Only sensitive if something's selected */
367
gtk_action_set_sensitive (diary->remove_action, FALSE);
368
gtk_widget_set_sensitive (GTK_WIDGET (diary->view_button), FALSE);
372
/* List the entry's links */
373
gtk_list_store_clear (diary->links_store);
374
links = diary_storage_manager_get_entry_links (diary->storage_manager, year, month, day);
377
while (links[i] != NULL) {
378
link_type = diary_link_get_type (links[i]->type);
380
if (link_type != NULL) {
381
gtk_list_store_append (diary->links_store, &iter);
382
gtk_list_store_set (diary->links_store, &iter,
386
3, link_type->icon_name,
390
g_free (links[i]->type);
391
g_free (links[i]->value);
392
g_free (links[i]->value2);
393
g_slice_free (DiaryLink, links[i]);
402
mw_links_selection_changed_cb (GtkTreeSelection *tree_selection, gpointer user_data)
404
if (gtk_tree_selection_count_selected_rows (tree_selection) == 0) {
405
gtk_widget_set_sensitive (GTK_WIDGET (diary->remove_button), FALSE);
406
gtk_widget_set_sensitive (GTK_WIDGET (diary->view_button), FALSE);
407
gtk_action_set_sensitive (diary->remove_action, FALSE);
409
gtk_widget_set_sensitive (GTK_WIDGET (diary->remove_button), TRUE);
410
gtk_widget_set_sensitive (GTK_WIDGET (diary->view_button), TRUE);
411
gtk_action_set_sensitive (diary->remove_action, TRUE);
416
mw_links_value_data_cb (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
421
gtk_tree_model_get (model, iter, 0, &(link.type), 1, &(link.value), 2, &(link.value2), -1);
423
new_value = diary_link_format_value (&link);
424
g_object_set (renderer, "text", new_value, NULL);
429
g_free (link.value2);
433
mw_links_tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
438
gtk_tree_model_get_iter (GTK_TREE_MODEL (diary->links_store), &iter, path);
439
gtk_tree_model_get (GTK_TREE_MODEL (diary->links_store), &iter, 0, &(link.type), 1, &(link.value), 2, &(link.value2), -1);
441
/* NOTE: Link types should display their own errors, so one won't be displayed here. */
442
diary_link_view (&link);
446
g_free (link.value2);
450
mw_entry_view_focus_out_event_cb (GtkWidget *entry_view, GdkEventFocus *event, gpointer user_data)
452
save_current_entry ();
457
mw_add_button_clicked_cb (GtkButton *button, gpointer user_data)
459
add_link_to_current_entry ();
463
mw_remove_button_clicked_cb (GtkButton *button, gpointer user_data)
465
remove_link_from_current_entry ();
469
mw_view_button_clicked_cb (GtkButton *button, gpointer user_data)
476
links = gtk_tree_selection_get_selected_rows (diary->links_selection, &model);
478
for (; links != NULL; links = links->next) {
479
gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) links->data);
480
gtk_tree_model_get (model, &iter, 0, &(link.type), 1, &(link.value), 2, &(link.value2), -1);
482
/* NOTE: Link types should display their own errors, so one won't be displayed here. */
483
diary_link_view (&link);
487
g_free (link.value2);
489
gtk_tree_path_free (links->data);