1 /*
2 * Osmo - a handy personal organizer
3 *
4 * Copyright (C) 2007-2009 Tomasz Maka <pasp@users.sourceforge.net>
5 * 2007-2009 Piotr Maka <silloz@users.sourceforge.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "about.h"
23 #include "i18n.h"
24 #include "options_prefs.h"
25 #include "stock_icons.h"
26 #include "utils_gui.h"
27
28 static void display_license (GUI *appGUI);
29 static void display_help (GUI *appGUI);
30 static void add_credits_section (const gchar *section_title, OsmoCreditEntry *credits,
31 guint32 n_credits, GUI *appGUI);
32 static void display_about (GUI *appGUI);
33 static void about_switch_buttons (gboolean left, GUI *appGUI);
34 static void button_released_cb (GtkButton *button, GUI *appGUI);
35 static void gui_create_about (GtkWidget *vbox_top, GUI *appGUI);
36
37 static OsmoCreditEntry credits_programming[] = {
38 { NULL, "Tomasz Mąka", "pasp@users.sourceforge.net" },
39 { NULL, "Piotr Mąka", "silloz@users.sourceforge.net" }
40 };
41
42 static OsmoCreditEntry credits_graphics[] = {
43 { NULL, "Maja Kocoń", "http://pinky-babble.org" }
44 };
45
46 static OsmoCreditEntry credits_contributors[] = {
47 { NULL, "Markus Dahms", "mad@automagically.de" },
48 { NULL, "Nacho Alonso González", "nacho.alonso.gonzalez@gmail.com" },
49 { NULL, "Maxim Gordienko", "mgordienko@users.sourceforge.net" }
50 };
51
52 static OsmoCreditEntry credits_translators[] = {
53 { "bg", "Borislav Totev", "btotev@hotmail.com" },
54 { "ca", "Roger Adell", "roger.adell@gmail.com" },
55 { "cs", "Jaroslav Lichtblau", "dragonlord@seznam.cz" },
56 { "da", "Joakim Seeberg", "joak@users.sourceforge.net" }, /* da */
57 { NULL, "Joe Hansen", "joedalton2@yahoo.dk" }, /* da */
58 { "de", "Markus Dahms", "mad@automagically.de" }, /* de */
59 { NULL, "Mario Blättermann", "mariobl@gnome.org" }, /* de */
60 { NULL, "Roland Siegbert", "roland.siegbert@gmail.com" }, /* de */
61 { "el", "Konstantinos Tsakaloglou", "tsakf@yahoo.com" },
62 { "en_GB", "Steve Cook (Yorvyk)", "yorvik.ubunto@googlemail.com" },
63 { "es", "Nacho Alonso González", "nacho.alonso.gonzalez@gmail.com" },
64 { "fi", "Toivo Miettinen", "toivo.miettinen@panuma.fi" },
65 { "fr", "Jean-Jacques Moulinier", "postmaster@moulinier.net" }, /* fr */
66 { NULL, "Rémi Roupsard", "remi.roupsard@gmail.com"}, /* fr */
67 { NULL, "Lylliann Essandre", "lylambda@gmail.com"}, /* fr */
68 { "gl", "Miguel Anxo Bouzada", "mbouzada@gmail.com"}, /* gl */
69 { NULL, "xesusmosquera", "xesusmosquera@gmail.com"}, /* gl */
70 { "gl_ES", "Miguel Anxo Bouzada", "mbouzada@gmail.com"}, /* gl_ES */
71 { NULL, "xesusmosquera", "xesusmosquera@gmail.com"}, /* gl_ES */
72 { "he", "Hebrew", "Hebrew@transifex"},
73 { "hu", "Peter Polonkai", "polesz@nedudu.hu" },
74 { "it", "Bautz", "bautz@email.com" }, /* it */
75 { NULL, "Calogero Bonasia", "kbonasia@gmail.com" }, /* it */
76 { "ja", "Norihiro Yoneda", "aoba@avis.ne.jp" },
77 { "lt", "Vaidotas Kazla", "joshas@gmail.com" }, /* lt */
78 { NULL, "Moo", "Moo@transifex" }, /* lt */
79 { "nl", "Tiger!P", "tigerp@tigerp.net" },
80 { "pl", "Piotr Mąka", "silloz@users.sourceforge.net" },
81 { "pt", "Bruno Miguel", "brunoalexandremiguel@gmail.com" },
82 { "pt_BR", "Átila Camurça", "camurca.home@gmail.com" }, /* pt_BR */
83 { NULL, "Alexandro Casanova", "shorterfire@gmail.com" }, /* pt_BR */
84 { "ro", "Alexandru Gavriș", "alexandrugavrish@gmail.com" }, /* ro */
85 { "ru", "Vyacheslav A. Trishkin", "dedovsk@mail.ru" }, /* ru */
86 { NULL, "Alexander Vozhennikov", "vodka_ploho@mail.ru" }, /* ru */
87 { NULL, "Sergey Panasenko", "nitay@users.sourceforge.net" }, /* ru */
88 { NULL, "Dmitry Korzhevin", "dkorzhevin@lsupport.net" }, /* ru */
89 { "sr", "Саша Петровић", "salepetronije@gmail.com" }, /* sr */
90 { "sv", "Niklas Grahn", "terra.unknown@yahoo.com" },
91 { "te", "Praveen Illa", "mail2ipn@gmail.com" },
92 { "tr", "Hasan Yılmaz", "hasanyilmaz@users.sourceforge.net" },
93 { "uk", "Sergey Panasenko", "nitay@users.sourceforge.net" }, /* uk */
94 { NULL, "Dmitry Korzhevin", "dkorzhevin@lsupport.net" }, /* uk */
95 { NULL, "Yury Bulka", "yurkobb@gmail.com" }, /* uk */
96 { "ur", "Muhammad Ali Makki", "makkiabufaris@aol.com" }, /* ur */
97 { "ur_PK", "Muhammad Ali Makki", "makkiabufaris@aol.com" }, /* ur_pk */
98 { "zh_CN", "Sasaqqdan", "sasaqqdan@gmail.com" }, /* zh_cn */
99 { NULL, "Darcsis", "darcsis@gmail.com" } /* zh_cn */
100 };
101
102 /* ========================================================================== */
103
104 static void
close_window(GtkWidget * widget,GtkWidget * window)105 close_window (GtkWidget *widget, GtkWidget *window)
106 {
107 gtk_widget_destroy (window);
108 }
109
110 /* ========================================================================== */
111
112 static gint
key_press(GtkWidget * widget,GdkEventKey * event,GUI * appGUI)113 key_press (GtkWidget *widget, GdkEventKey *event, GUI *appGUI)
114 {
115 switch (event->keyval) {
116
117 case GDK_KEY_Escape:
118 close_window (NULL, widget);
119 return TRUE;
120
121 case GDK_KEY_Page_Down:
122 about_switch_buttons (FALSE, appGUI);
123 return TRUE;
124
125 case GDK_KEY_Page_Up:
126 about_switch_buttons (TRUE, appGUI);
127 return TRUE;
128
129 }
130
131 return FALSE;
132 }
133
134 /* ========================================================================== */
135
136 GtkWidget *
opt_create_about_window(GUI * appGUI)137 opt_create_about_window (GUI *appGUI)
138 {
139 GtkWidget *window, *vbox_top;
140 GtkWidget *hbuttonbox, *button_close;
141
142 window = utl_gui_create_window (_("About"), 510, 600, appGUI);
143 gtk_widget_set_events (window, GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
144 g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (key_press), appGUI);
145
146 vbox_top = gtk_box_new (GTK_ORIENTATION_VERTICAL, VBOX_SPACING);
147 gtk_container_add (GTK_CONTAINER (window), vbox_top);
148
149 gui_create_about (vbox_top, appGUI);
150
151 /* Close button */
152 hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
153 gtk_box_pack_start (GTK_BOX (vbox_top), hbuttonbox, FALSE, TRUE, 0);
154 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
155 gtk_box_set_spacing (GTK_BOX (hbuttonbox), HBOX_SPACING);
156
157 button_close = gtk_button_new_with_mnemonic(_("_Close"));
158 gtk_container_add (GTK_CONTAINER (hbuttonbox), button_close);
159 gtk_widget_set_can_default (button_close, TRUE);
160 g_signal_connect (G_OBJECT (button_close), "clicked", G_CALLBACK (close_window), window);
161 gtk_widget_grab_focus (button_close);
162
163 gtk_widget_show_all (vbox_top);
164
165 return window;
166 }
167
168 /* ========================================================================== */
169
170 static void
display_license(GUI * appGUI)171 display_license (GUI *appGUI)
172 {
173 const gchar license_text[] = {
174 "\nThis program is free software; you can redistribute it and/or modify "
175 "it under the terms of the GNU General Public License as published by "
176 "the Free Software Foundation; either version 2 of the License, or "
177 "(at your option) any later version."
178 "\n\n"
179 "This program is distributed in the hope that it will be useful, "
180 "but WITHOUT ANY WARRANTY; without even the implied warranty of "
181 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
182 "GNU General Public License for more details."
183 "\n\n"
184 "You should have received a copy of the GNU General Public License "
185 "along with this program; if not, write to the Free Software "
186 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
187 };
188
189 utl_gui_clear_text_buffer (appGUI->about_entry_buffer, &appGUI->about_entry_iter);
190 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, license_text, -1);
191 gtk_widget_grab_focus (GTK_WIDGET (appGUI->scrolled_window));
192 }
193
194 /* ========================================================================== */
195
196 static void
display_help(GUI * appGUI)197 display_help (GUI *appGUI)
198 {
199 const gchar *general_keys_text[] = {
200 N_("Ctrl+PageUp"), N_("switch to previous tab"),
201 N_("Ctrl+PageDn"), N_("switch to next tab"),
202 "Alt+1...6, F1-F4", N_("switch to selected page"),
203 "F5", N_("show options window"),
204 "F6", N_("show about window"),
205 "F11", N_("toggle fullscreen mode"),
206 N_("PageUp/PageDn"), N_("switch page in options and about tab"),
207 "Ctrl+q", N_("exit")
208 };
209
210 const gchar *calendar_keys_text[] = {
211 N_("Space"), N_("select current date"),
212 N_("Ctrl+Space"), N_("toggle personal data visibility"),
213 N_("Arrows"), N_("change day"),
214 N_("Ctrl+Up/Down"), N_("scroll the contents in the day info panel"),
215 N_("PageUp/PageDn"), N_("change month"),
216 N_("Home/End"), N_("change year"),
217 "a", N_("toggle calendars for the previous and next month"),
218 "b", N_("day notes browser"),
219 "c", N_("assign background color to day note"),
220 "d", N_("date calculator"),
221 "f", N_("show full-year calendar"),
222 "g", N_("jump to date"),
223 N_("Delete"), N_("remove day note")
224 };
225
226 const gchar *calendar_editor_keys_text[] = {
227 N_("Alt+Arrows"), N_("change day"),
228 N_("Esc"), N_("close editor"),
229 "Ctrl+b", N_("toggle bold"),
230 "Ctrl+i", N_("toggle italic"),
231 "Ctrl+u", N_("toggle underline"),
232 "Ctrl+t", N_("toggle strikethrough"),
233 "Ctrl+m", N_("toggle highlight")
234 };
235
236 const gchar *calendar_fy_keys_text[] = {
237 N_("Arrows Up/Down"), N_("change year"),
238 "F1", N_("toggle alternative view"),
239 "F2", N_("year info"),
240 "F3", N_("set current year"),
241 N_("Esc"), N_("close full-year calendar")
242 };
243
244 #ifdef TASKS_ENABLED
245 const gchar *tasks_keys_text[] = {
246 N_("Alt+a, Insert"), N_("add task"),
247 N_("Alt+e, Ctrl+Enter"), N_("edit task"),
248 N_("Alt+r, Delete"), N_("remove task"),
249 "Ctrl+h", N_("toggle hidden tasks"),
250 "Ctrl+l", N_("activate search field"),
251 N_("Left, Right"), N_("change category filter"),
252 N_("Esc"), N_("close task info panel")
253 };
254 #endif /* TASKS_ENABLED */
255
256 #ifdef CONTACTS_ENABLED
257 const gchar *contacts_keys_text[] = {
258 N_("Insert"), N_("add contact"),
259 N_("Ctrl+Enter"), N_("edit contact"),
260 N_("Delete"), N_("remove contact"),
261 "Ctrl+l", N_("activate search field"),
262 N_("Ctrl+Up/Down"), N_("change search mode"),
263 N_("Esc"), N_("close contact details panel")
264 };
265 #endif /* CONTACTS_ENABLED */
266
267 #ifdef NOTES_ENABLED
268 const gchar *notes_selector_keys_text[] = {
269 N_("Enter"), N_("open note"),
270 N_("Insert"), N_("add note"),
271 N_("Delete"), N_("remove note"),
272 N_("Ctrl+Enter"), N_("edit note name and category"),
273 "Ctrl+l", N_("activate search field"),
274 N_("Left, Right"), N_("change category filter")
275 };
276
277 const gchar *notes_editor_keys_text[] = {
278 "Ctrl+w", N_("close note editor"),
279 "Ctrl+s", N_("save note"),
280 "Ctrl+f", N_("find text"),
281 "Ctrl+b", N_("toggle bold"),
282 "Ctrl+i", N_("toggle italic"),
283 "Ctrl+u", N_("toggle underline"),
284 "Ctrl+t", N_("toggle strikethrough"),
285 "Ctrl+m", N_("toggle highlight"),
286 "Ctrl+n", N_("clear selection attributes"),
287 "Ctrl+o", N_("open URLs"),
288 "Ctrl+.", N_("show document statistics")
289 };
290 #endif /* NOTES_ENABLED */
291
292 gchar *str;
293 gint i;
294
295 utl_gui_clear_text_buffer (appGUI->about_entry_buffer, &appGUI->about_entry_iter);
296
297 str = g_strdup_printf ("\n%s\n\n", _("OSMO was designed keeping in mind the user convenience, so there are many key shortcuts. Here is the full list:"));
298 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
299 g_free (str);
300
301 /* ============================== */
302
303 str = g_strdup_printf ("* %s\n", _("General"));
304 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
305 g_free (str);
306
307 for (i = 0; i < G_N_ELEMENTS (general_keys_text) / 2; i++) {
308 str = g_strdup_printf ("\t<%s> - %s\n", gettext (general_keys_text[i*2]), gettext (general_keys_text[i*2+1]));
309 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
310 g_free (str);
311 }
312 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
313
314 /* ============================== */
315
316 str = g_strdup_printf ("* %s\n", _("Calendar"));
317 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
318 g_free (str);
319
320 for (i = 0; i < G_N_ELEMENTS (calendar_keys_text) / 2; i++) {
321 str = g_strdup_printf ("\t<%s> - %s\n", gettext (calendar_keys_text[i*2]), gettext (calendar_keys_text[i*2+1]));
322 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
323 g_free (str);
324 }
325
326 str = g_strdup_printf ("\t%s:\n", _("Note editor"));
327 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
328 g_free (str);
329
330 for (i = 0; i < G_N_ELEMENTS (calendar_editor_keys_text) / 2; i++) {
331 str = g_strdup_printf ("\t<%s> - %s\n", gettext (calendar_editor_keys_text[i*2]), gettext (calendar_editor_keys_text[i*2+1]));
332 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
333 g_free (str);
334 }
335
336 str = g_strdup_printf ("\t%s:\n", _("Full-year calendar"));
337 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
338 g_free (str);
339
340 for (i = 0; i < G_N_ELEMENTS (calendar_fy_keys_text) / 2; i++) {
341 str = g_strdup_printf ("\t<%s> - %s\n", gettext (calendar_fy_keys_text[i*2]), gettext (calendar_fy_keys_text[i*2+1]));
342 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
343 g_free (str);
344 }
345
346 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
347
348 /* ============================== */
349
350 #ifdef TASKS_ENABLED
351 str = g_strdup_printf ("* %s\n", _("Tasks"));
352 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
353 g_free (str);
354
355 for (i = 0; i < G_N_ELEMENTS (tasks_keys_text) / 2; i++) {
356 str = g_strdup_printf ("\t<%s> - %s\n", gettext (tasks_keys_text[i*2]), gettext (tasks_keys_text[i*2+1]));
357 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
358 g_free (str);
359 }
360 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
361 #endif /* TASKS_ENABLED */
362
363 /* ============================== */
364
365 #ifdef CONTACTS_ENABLED
366 str = g_strdup_printf ("* %s\n", _("Contacts"));
367 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
368 g_free (str);
369
370 for (i = 0; i < G_N_ELEMENTS (contacts_keys_text) / 2; i++) {
371 str = g_strdup_printf ("\t<%s> - %s\n", gettext (contacts_keys_text[i*2]), gettext (contacts_keys_text[i*2+1]));
372 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
373 g_free (str);
374 }
375 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
376 #endif /* CONTACTS_ENABLED */
377
378 /* ============================== */
379
380 #ifdef NOTES_ENABLED
381 str = g_strdup_printf ("* %s\n", _("Notes"));
382 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
383 g_free (str);
384
385 str = g_strdup_printf ("\t%s:\n", _("Selector"));
386 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
387 g_free (str);
388
389 for (i = 0; i < G_N_ELEMENTS (notes_selector_keys_text) / 2; i++) {
390 str = g_strdup_printf ("\t<%s> - %s\n", gettext (notes_selector_keys_text[i*2]), gettext (notes_selector_keys_text[i*2+1]));
391 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
392 g_free (str);
393 }
394
395 str = g_strdup_printf ("\t%s:\n", _("Editor"));
396 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1, "bold", NULL);
397 g_free (str);
398
399 for (i = 0; i < G_N_ELEMENTS (notes_editor_keys_text) / 2; i++) {
400 str = g_strdup_printf ("\t<%s> - %s\n", gettext (notes_editor_keys_text[i*2]), gettext (notes_editor_keys_text[i*2+1]));
401 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
402 g_free (str);
403 }
404 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
405 #endif /* NOTES_ENABLED */
406
407 gtk_widget_grab_focus (GTK_WIDGET (appGUI->scrolled_window));
408 }
409
410 /* ========================================================================== */
411
412 static void
add_credits_section(const gchar * section_title,OsmoCreditEntry * credits,guint32 n_credits,GUI * appGUI)413 add_credits_section (const gchar *section_title, OsmoCreditEntry *credits, guint32 n_credits, GUI *appGUI)
414 {
415 gint32 i, j, d;
416 gchar *s;
417
418 s = g_strdup_printf ("\n %s:\n", section_title);
419 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
420 &appGUI->about_entry_iter, s, -1, "bold", NULL);
421 g_free (s);
422
423 for (i = 0; i < n_credits; i++) {
424
425 if (credits[i].tag) {
426 if(strlen(credits[i].tag) > 2) {
427 s = g_strdup_printf (" [%s]", credits[i].tag);
428 } else {
429 s = g_strdup_printf (" [%s] ", credits[i].tag);
430 }
431 } else {
432 s = g_strdup (" ");
433 }
434
435 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
436 &appGUI->about_entry_iter, s, -1, "fixed", NULL);
437 g_free (s);
438
439 s = g_strdup_printf (" %s <", credits[i].name);
440 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, s, -1);
441 g_free (s);
442
443 j = d = 0;
444 while (credits[i].email[j] != '\0')
445 if (credits[i].email[j++] == '.') d++;
446
447 if (d == 0) {
448 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, credits[i].email, -1);
449 } else {
450 utl_gui_url_insert_link (&appGUI->about_links_list,
451 &appGUI->about_link_index, appGUI->about_textview,
452 &appGUI->about_entry_iter, config.link_color, NULL, credits[i].email, FALSE, appGUI);
453 }
454
455 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, ">\n", -1);
456 }
457 }
458
459 /* ========================================================================== */
460
461 static void
display_about(GUI * appGUI)462 display_about (GUI *appGUI)
463 {
464 gchar *str;
465
466 utl_gui_url_remove_links (&appGUI->about_links_list, &appGUI->about_link_index);
467 utl_gui_clear_text_buffer (appGUI->about_entry_buffer, &appGUI->about_entry_iter);
468
469 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
470 str = g_strdup_printf ("%s\n", _("A handy personal organizer"));
471 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
472 &appGUI->about_entry_iter, str, -1, "big", "center", NULL);
473 g_free (str);
474 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
475
476 utl_gui_url_insert_link (&appGUI->about_links_list, &appGUI->about_link_index,
477 appGUI->about_textview, &appGUI->about_entry_iter, config.link_color,
478 NULL, OSMO_WEBSITE, TRUE, appGUI);
479 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
480
481 #ifndef REPRODUCIBLE_BUILD
482 str = g_strdup_printf ("\n(%s %s, %s)\n\n", _("compiled on"), __DATE__, __TIME__);
483 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
484 &appGUI->about_entry_iter, str, -1, "center", "italic", NULL);
485 g_free (str);
486 #endif
487
488 add_credits_section (_("Programming"), credits_programming, G_N_ELEMENTS (credits_programming), appGUI);
489 add_credits_section (_("Graphics"), credits_graphics, G_N_ELEMENTS (credits_graphics), appGUI);
490 add_credits_section (_("Contributors"), credits_contributors, G_N_ELEMENTS (credits_contributors), appGUI);
491 add_credits_section (_("Translators"), credits_translators, G_N_ELEMENTS (credits_translators), appGUI);
492
493 /* Links */
494
495 str = g_strdup_printf ("\n %s:\n", _("Mailing lists"));
496 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
497 &appGUI->about_entry_iter, str, -1, "bold", NULL);
498 g_free (str);
499
500 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\t ", -1);
501 utl_gui_url_insert_link (&appGUI->about_links_list, &appGUI->about_link_index,
502 appGUI->about_textview, &appGUI->about_entry_iter, config.link_color,
503 NULL, MAILING_LIST, FALSE, appGUI);
504 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
505
506 str = g_strdup_printf ("\n %s:\n", _("Bug tracker"));
507 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
508 &appGUI->about_entry_iter, str, -1, "bold", NULL);
509 g_free (str);
510
511 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\t ", -1);
512 utl_gui_url_insert_link (&appGUI->about_links_list, &appGUI->about_link_index,
513 appGUI->about_textview, &appGUI->about_entry_iter, config.link_color,
514 NULL, BUG_TRACKER, FALSE, appGUI);
515 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
516
517 str = g_strdup_printf ("\n %s:\n", _("Feature requests"));
518 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
519 &appGUI->about_entry_iter, str, -1, "bold", NULL);
520 g_free (str);
521
522 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\t ", -1);
523 utl_gui_url_insert_link (&appGUI->about_links_list, &appGUI->about_link_index,
524 appGUI->about_textview, &appGUI->about_entry_iter, config.link_color,
525 NULL, FEATURE_REQUESTS, FALSE, appGUI);
526 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, "\n", -1);
527
528
529 /* Available modules */
530
531 str = g_strdup_printf ("\n %s:\n", _("Available modules"));
532 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
533 &appGUI->about_entry_iter, str, -1, "bold", NULL);
534 g_free (str);
535
536 str = g_strdup_printf (" [+]\t%s\n", _("Calendar"));
537 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
538 g_free (str);
539
540 #ifdef TASKS_ENABLED
541 str = g_strdup_printf (" [+]\t%s\n", _("Tasks"));
542 #else
543 str = g_strdup_printf (" [-]\t%s\n", _("Tasks"));
544 #endif /* TASKS_ENABLED */
545 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
546 g_free (str);
547
548 #ifdef CONTACTS_ENABLED
549 str = g_strdup_printf (" [+]\t%s\n", _("Contacts"));
550 #else
551 str = g_strdup_printf (" [-]\t%s\n", _("Contacts"));
552 #endif /* CONTACTS_ENABLED */
553 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
554 g_free (str);
555
556 #ifdef NOTES_ENABLED
557 str = g_strdup_printf (" [+]\t%s\n", _("Notes"));
558 #else
559 str = g_strdup_printf (" [-]\t%s\n", _("Notes"));
560 #endif /* NOTES_ENABLED */
561 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
562 g_free (str);
563
564
565 /* Compiled-in features */
566
567 str = g_strdup_printf ("\n %s:\n", _("Compiled-in features"));
568 gtk_text_buffer_insert_with_tags_by_name (appGUI->about_entry_buffer,
569 &appGUI->about_entry_iter, str, -1, "bold", NULL);
570 g_free (str);
571
572 #ifdef HAVE_LIBICAL
573 str = g_strdup_printf (" [+]\t%s (libical)\n", _("iCalendar support"));
574 #else
575 str = g_strdup_printf (" [-]\t%s (libical)\n", _("iCalendar support"));
576 #endif /* HAVE_LIBICAL */
577 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
578 g_free (str);
579
580 #ifdef HAVE_LIBGRINGOTTS
581 str = g_strdup_printf (" [+]\t%s (libgringotts)\n", _("Encrypted notes support"));
582 #else
583 str = g_strdup_printf (" [-]\t%s (libgringotts)\n", _("Encrypted notes support"));
584 #endif /* HAVE_LIBGRINGOTTS */
585 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
586 g_free (str);
587
588 #if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
589 str = g_strdup_printf (" [+]\t%s (libarchive + libgringotts)\n", _("Backup support"));
590 #else
591 str = g_strdup_printf (" [-]\t%s (libarchive + libgringotts)\n", _("Backup support"));
592 #endif /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
593 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
594 g_free (str);
595
596 #ifdef PRINTING_SUPPORT
597 str = g_strdup_printf (" [+]\t%s\n", _("Printing support"));
598 #else
599 str = g_strdup_printf (" [-]\t%s\n", _("Printing support"));
600 #endif /* PRINTING_SUPPORT */
601 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
602 g_free (str);
603
604 #ifdef HAVE_GSPELL
605 str = g_strdup_printf (" [+]\t%s (gspell)\n", _("Spell checker support"));
606 #else
607 str = g_strdup_printf (" [-]\t%s (gspell)\n", _("Spell checker support"));
608 #endif /* HAVE_GSPELL */
609 gtk_text_buffer_insert (appGUI->about_entry_buffer, &appGUI->about_entry_iter, str, -1);
610 g_free (str);
611
612 gtk_widget_grab_focus (GTK_WIDGET (appGUI->scrolled_window));
613 }
614
615 /* ========================================================================== */
616
617 static void
about_switch_buttons(gboolean left,GUI * appGUI)618 about_switch_buttons (gboolean left, GUI *appGUI)
619 {
620 if (left == TRUE && appGUI->about_counter > 0) {
621 --appGUI->about_counter;
622 } else if (left == FALSE && appGUI->about_counter < 2) {
623 appGUI->about_counter++;
624 }
625
626 if (appGUI->about_counter == 0){
627 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->about_radiobutton), TRUE);
628 g_signal_emit_by_name (G_OBJECT (appGUI->about_radiobutton), "released");
629 } else if (appGUI->about_counter == 1) {
630 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->help_radiobutton), TRUE);
631 g_signal_emit_by_name (G_OBJECT (appGUI->help_radiobutton), "released");
632 } else {
633 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->license_radiobutton), TRUE);
634 g_signal_emit_by_name (G_OBJECT (appGUI->license_radiobutton), "released");
635 }
636 }
637
638 /* ========================================================================== */
639
640 static void
button_released_cb(GtkButton * button,GUI * appGUI)641 button_released_cb (GtkButton *button, GUI *appGUI)
642 {
643 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->about_radiobutton)) == TRUE) {
644
645 display_about (appGUI);
646 appGUI->about_counter = 0;
647
648 } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->help_radiobutton)) == TRUE) {
649
650 display_help (appGUI);
651 appGUI->about_counter = 1;
652
653 } else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->license_radiobutton)) == TRUE) {
654
655 display_license (appGUI);
656 appGUI->about_counter = 2;
657
658 }
659 }
660
661 /* ========================================================================== */
662
663 void
gui_create_about(GtkWidget * vbox_top,GUI * appGUI)664 gui_create_about (GtkWidget *vbox_top, GUI *appGUI)
665 {
666 GtkWidget *vbox = NULL;
667 GtkWidget *label;
668 GtkWidget *hseparator;
669 GtkWidget *logo_area;
670 GdkPixbuf *logo;
671 GtkWidget *viewport;
672 GtkWidget *hbuttonbox = NULL;
673 GSList *radiobutton_group = NULL;
674 gchar *str, *filename;
675
676 appGUI->about_counter = 0;
677 appGUI->about_vbox = GTK_BOX (vbox_top);
678
679 logo_area = gtk_image_new ();
680 gtk_widget_show (logo_area);
681 gtk_box_pack_start (GTK_BOX (vbox_top), logo_area, FALSE, TRUE, 0);
682
683 /*
684 * http://stackoverflow.com/questions/3781520/how-to-test-if-preprocessor-symbol-is-defined-but-has-no-value
685 */
686 #define DO_EXPAND(VAL) VAL ## 1
687 #define EXPAND(VAL) DO_EXPAND(VAL)
688
689 #if (EXPAND(REPO) == 1)
690 str = g_strdup_printf ("%s %s", _("version"), VERSION);
691 #else
692 #define xstr(a) str(a)
693 #define str(a) #a
694 str = g_strdup_printf ("%s (%s)", _("GIT version"), xstr(REVISION));
695 #endif
696
697 label = gtk_label_new (str);
698 g_free (str);
699 gtk_widget_show (label);
700 gtk_box_pack_start (GTK_BOX (vbox_top), label, FALSE, TRUE, 4);
701
702 filename = g_strdup_printf(PIXMAPSDIR G_DIR_SEPARATOR_S "osmo_logo.png");
703 logo = gdk_pixbuf_new_from_file(filename, NULL);
704 g_free(filename);
705
706 gtk_image_set_from_pixbuf(GTK_IMAGE(logo_area), logo);
707 g_object_unref(logo);
708 /*--------------------------------------------------------------------------*/
709
710 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
711 gtk_widget_show (vbox);
712 gtk_box_pack_start (GTK_BOX (vbox_top), vbox, FALSE, TRUE, 0);
713
714 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
715 gtk_widget_show (hseparator);
716 gtk_box_pack_start (GTK_BOX (vbox), hseparator, FALSE, TRUE, 0);
717
718 hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
719 gtk_widget_show (hbuttonbox);
720 gtk_box_pack_start (GTK_BOX (vbox), hbuttonbox, FALSE, TRUE, 0);
721 gtk_widget_set_halign(hbuttonbox, GTK_ALIGN_CENTER);
722 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
723
724 appGUI->about_radiobutton = utl_gui_icon_label_radio_button (_("About"), OSMO_STOCK_ABOUT, GTK_ICON_SIZE_LARGE_TOOLBAR);
725 gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->about_radiobutton);
726 gtk_widget_show (appGUI->about_radiobutton);
727
728 gtk_button_set_relief (GTK_BUTTON (appGUI->about_radiobutton), GTK_RELIEF_NONE);
729 gtk_widget_set_can_focus (appGUI->about_radiobutton, FALSE);
730 gtk_radio_button_set_group (GTK_RADIO_BUTTON (appGUI->about_radiobutton), radiobutton_group);
731 radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (appGUI->about_radiobutton));
732 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->about_radiobutton), TRUE);
733 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (appGUI->about_radiobutton), FALSE);
734
735 g_signal_connect (G_OBJECT (appGUI->about_radiobutton), "released",
736 G_CALLBACK (button_released_cb), appGUI);
737
738 appGUI->help_radiobutton = utl_gui_icon_label_radio_button (_("Key shortcuts"), OSMO_STOCK_HELP, GTK_ICON_SIZE_LARGE_TOOLBAR);
739 gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->help_radiobutton);
740 gtk_widget_show (appGUI->help_radiobutton);
741 gtk_button_set_relief (GTK_BUTTON (appGUI->help_radiobutton), GTK_RELIEF_NONE);
742 gtk_widget_set_can_focus (appGUI->help_radiobutton, FALSE);
743 gtk_radio_button_set_group (GTK_RADIO_BUTTON (appGUI->help_radiobutton), radiobutton_group);
744 radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (appGUI->help_radiobutton));
745 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (appGUI->help_radiobutton), FALSE);
746
747 g_signal_connect (G_OBJECT (appGUI->help_radiobutton), "released",
748 G_CALLBACK (button_released_cb), appGUI);
749
750 appGUI->license_radiobutton = utl_gui_icon_label_radio_button (_("License"), OSMO_STOCK_LICENSE, GTK_ICON_SIZE_LARGE_TOOLBAR);
751 gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->license_radiobutton);
752 gtk_widget_show (appGUI->license_radiobutton);
753 gtk_button_set_relief (GTK_BUTTON (appGUI->license_radiobutton), GTK_RELIEF_NONE);
754 gtk_widget_set_can_focus (appGUI->license_radiobutton, FALSE);
755 gtk_radio_button_set_group (GTK_RADIO_BUTTON (appGUI->license_radiobutton), radiobutton_group);
756 radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (appGUI->license_radiobutton));
757 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (appGUI->license_radiobutton), FALSE);
758
759 g_signal_connect (G_OBJECT (appGUI->license_radiobutton), "released",
760 G_CALLBACK (button_released_cb), appGUI);
761
762 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
763 gtk_widget_show (hseparator);
764 gtk_box_pack_start (GTK_BOX (vbox), hseparator, FALSE, TRUE, 0);
765
766 /*--------------------------------------------------------------------------*/
767
768 appGUI->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
769 gtk_box_pack_start (GTK_BOX (vbox_top), appGUI->scrolled_window, TRUE, TRUE, 0);
770 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->scrolled_window),
771 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
772 gtk_widget_show (appGUI->scrolled_window);
773
774 viewport = gtk_viewport_new (NULL, NULL);
775 gtk_widget_show (viewport);
776 gtk_container_set_border_width (GTK_CONTAINER (viewport), 0);
777 gtk_container_add (GTK_CONTAINER (appGUI->scrolled_window), viewport);
778
779 appGUI->about_entry_buffer = gtk_text_buffer_new (NULL);
780 gtk_text_buffer_get_iter_at_offset (appGUI->about_entry_buffer, &appGUI->about_entry_iter, 0);
781 gtk_text_buffer_create_tag (appGUI->about_entry_buffer, "fixed", "family", "monospace", NULL);
782 gtk_text_buffer_create_tag (appGUI->about_entry_buffer, "bold", "weight", PANGO_WEIGHT_ULTRABOLD, NULL);
783 gtk_text_buffer_create_tag (appGUI->about_entry_buffer, "big", "size", 16 * PANGO_SCALE, NULL);
784 gtk_text_buffer_create_tag (appGUI->about_entry_buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
785 gtk_text_buffer_create_tag (appGUI->about_entry_buffer, "center", "justification", GTK_JUSTIFY_CENTER, NULL);
786 gtk_text_buffer_get_iter_at_offset (appGUI->about_entry_buffer, &appGUI->about_entry_iter, 0);
787
788 appGUI->about_textview = gtk_text_view_new_with_buffer (appGUI->about_entry_buffer);
789 gtk_container_set_border_width (GTK_CONTAINER (appGUI->about_textview), 1);
790 gtk_text_view_set_editable (GTK_TEXT_VIEW (appGUI->about_textview), FALSE);
791 gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (appGUI->about_textview), FALSE);
792 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->about_textview), GTK_WRAP_WORD);
793 gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (appGUI->about_textview), 2);
794 gtk_text_view_set_left_margin (GTK_TEXT_VIEW (appGUI->about_textview), 6);
795 gtk_text_view_set_right_margin (GTK_TEXT_VIEW (appGUI->about_textview), 6);
796 gtk_widget_show (appGUI->about_textview);
797 gtk_container_add (GTK_CONTAINER (viewport), appGUI->about_textview);
798
799 utl_gui_url_setup (&appGUI->about_links_list, &appGUI->about_link_index, appGUI->about_textview, appGUI);
800
801 display_about (appGUI);
802 }
803
804 /* ========================================================================== */
805
806