Merge lp:~ghugesss/xpad/code_refactor into lp:xpad

Proposed by Sagar Ghuge
Status: Needs review
Proposed branch: lp:~ghugesss/xpad/code_refactor
Merge into: lp:xpad
Diff against target: 8138 lines (+3350/-3252)
21 files modified
src/fio.h (+7/-3)
src/help.c (+3/-1)
src/help.h (+3/-3)
src/prefix.h (+3/-3)
src/xpad-app.c (+239/-232)
src/xpad-grip-tool-item.c (+38/-39)
src/xpad-pad-group.c (+15/-11)
src/xpad-pad-properties.c (+144/-143)
src/xpad-pad.c (+1200/-1203)
src/xpad-periodic.c (+230/-207)
src/xpad-periodic.h (+7/-3)
src/xpad-preferences.c (+477/-491)
src/xpad-session-manager.c (+60/-57)
src/xpad-session-manager.h (+4/-0)
src/xpad-settings.c (+225/-210)
src/xpad-text-buffer.c (+137/-124)
src/xpad-text-view.c (+99/-100)
src/xpad-toolbar.c (+279/-269)
src/xpad-tray.c (+85/-75)
src/xpad-tray.h (+4/-0)
src/xpad-undo.c (+91/-78)
To merge this branch: bzr merge lp:~ghugesss/xpad/code_refactor
Reviewer Review Type Date Requested Status
Arthur Borsboom code review no testing Needs Fixing
Review via email: mp+233722@code.launchpad.net

Description of the change

https://wiki.gnome.org/Projects/GTK%2B/BestPractices

As our app is under GNOME so we need to follow the global coding style and also follow the header includes for .c files.

I have tested a code and working fine. As I know you will going to see lot of changes, so from onwards before accepting any patch from other contributors we ask him to also follow the standard coding style.

To post a comment you must log in.
Revision history for this message
Arthur Borsboom (arthurborsboom) wrote :

Hi Sagar,

I went through most of the code changes.
Some things I dislike, some things I like.
Let's see if we can agree on the parts.
I summarize below what I would like to see different.
Feel free to disagree and explain,

1. Split and group changes (and merge requests)

When working with other developers, in general it is better to produce small changes.
And if the changes are bigger, than at least group the different changes together.
In this merge proposal there are many different changes, with some I agree (which I would like to merge) and some I disagree, which I would like to request fixing.

Splitting the changes also makes it easier to find issues introduced by changes. It also makes it easier to undo a change.

So my request is to split the different changes. Below I try to do a start, since I discuss each group of changes by subject.

2. Order of includes

Agree totally. I would like to merge this directly.

3. Improving head guards

I Agree totally. I would like to merge this directly.

4. Improving function declarations by G_BEGIN_DECLS and G_END_DECLS

I Agree totally. I would like to merge this directly.

5. Removal of function prototypes by reordering functions

I am in a split here.
I agree that it is nicer and easier to maintain if these are removed.
I disagree since it sometimes make readability and therefore maintainability harder.

So, only if the readability of the code stays more or less the same, I am in favor of this. Two examples:

I do like the removal of the forward declaration in xpad-pad-group.c

I dislike reading the xpad-pad.c and xpad-app.c from the bottom to the top (instead of the other way around), and therefore I don't like this to be changed.

6. Reformatting of function parameters, each parameter on a new line.

I strongly dislike this. In my opinion this makes reading the code much harder.

I guess it comes from the old-fashioned Linux kernel coding rule: 80 character limit. I used to dislike it and I still dislike it. These days almost each developer has a screen with at least 200 characters if not 500.

Only when the function declaration becomes extremely long, breaking this line in two or three pieces might be better.

7. Reformatting of function and return type on a new line.

I guess this is better. This might be my Java coding habit from the old days.

/* good */
static void
xpad_undo_class_init (XpadUndoClass *klass)

/* bad */
static void xpad_undo_class_init (XpadUndoClass *klass)

I prefer the one defined by me as 'bad', but I don't think it changes readability a lot and the code conforms to the best practice.

***

In general, best practices are good, but are not the law. In my opinion if you have a good reason to disagree with the best practice, it is okay.

For me, most of the disagreements above have to do with readability and maintainability. And since I (we) are maintaining the software, I like to do this as easy as possible.

Again, everything is open for discussing.

Nevertheless, I would like you to start with discussion point 1.
Then I can merge all the subjects we agree on and we can discuss the others after that.

Cheers,
Arthur.

review: Needs Fixing (code review no testing)

Unmerged revisions

705. By Sagar Ghuge

Typo corrected.

704. By Sagar Ghuge

Code refactoring done.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/fio.h'
2--- src/fio.h 2014-06-15 10:02:50 +0000
3+++ src/fio.h 2014-09-08 13:22:52 +0000
4@@ -19,11 +19,13 @@
5
6 */
7
8-#ifndef _FIO_H_
9-#define _FIO_H_
10+#ifndef __FIO_H__
11+#define __FIO_H__
12
13 #include <glib.h>
14
15+G_BEGIN_DECLS
16+
17 gchar *fio_get_file (const gchar *name);
18 gboolean fio_set_file (const gchar *name, const gchar *value);
19 void fio_remove_file (const gchar *filename);
20@@ -35,4 +37,6 @@
21
22 gchar *fio_unique_name (const gchar *prefix);
23
24-#endif /* _FIO_H_ */
25+G_END_DECLS
26+
27+#endif /* __FIO_H__ */
28
29=== modified file 'src/help.c'
30--- src/help.c 2014-06-21 11:03:38 +0000
31+++ src/help.c 2014-09-08 13:22:52 +0000
32@@ -20,10 +20,12 @@
33 */
34
35 #include "../config.h"
36+
37 #include "help.h"
38+#include "xpad-app.h"
39 #include <gtk/gtk.h>
40 #include <glib/gi18n.h>
41-#include "xpad-app.h"
42+
43
44 GtkWindow *help_window = NULL;
45
46
47=== modified file 'src/help.h'
48--- src/help.h 2014-06-10 20:55:56 +0000
49+++ src/help.h 2014-09-08 13:22:52 +0000
50@@ -19,9 +19,9 @@
51
52 */
53
54-#ifndef HELP_H
55-#define HELP_H
56+#ifndef __HELP_H__
57+#define __HELP_H__
58
59 void show_help (void);
60
61-#endif
62+#endif /* __HELP_H__ */
63
64=== modified file 'src/prefix.h'
65--- src/prefix.h 2008-09-21 00:03:40 +0000
66+++ src/prefix.h 2014-09-08 13:22:52 +0000
67@@ -26,8 +26,8 @@
68 * to br_*", try renaming prefix.c to prefix.cpp
69 */
70
71-#ifndef _PREFIX_H_
72-#define _PREFIX_H_
73+#ifndef __PREFIX_H__
74+#define __PREFIX_H__
75
76 #ifdef __cplusplus
77 extern "C" {
78@@ -126,4 +126,4 @@
79 }
80 #endif /* __cplusplus */
81
82-#endif /* _PREFIX_H_ */
83+#endif /* __PREFIX_H__ */
84
85=== modified file 'src/xpad-app.c'
86--- src/xpad-app.c 2014-07-23 10:03:02 +0000
87+++ src/xpad-app.c 2014-09-08 13:22:52 +0000
88@@ -25,15 +25,8 @@
89 Unfortunately, we lose portability... */
90
91 #include "../config.h"
92+
93 #include "xpad-app.h"
94-#include <glib.h>
95-#include <glib/gi18n.h>
96-#include <glib/gstdio.h>
97-#include <string.h>
98-#include <sys/socket.h>
99-#include <sys/un.h>
100-#include <stdio.h>
101-#include <stdlib.h>
102 #include "help.h"
103 #include "xpad-pad.h"
104 #include "xpad-pad-group.h"
105@@ -41,6 +34,16 @@
106 #include "xpad-session-manager.h"
107 #include "xpad-tray.h"
108
109+#include <string.h>
110+#include <sys/socket.h>
111+#include <sys/un.h>
112+#include <stdio.h>
113+#include <stdlib.h>
114+
115+#include <glib.h>
116+#include <glib/gi18n.h>
117+#include <glib/gstdio.h>
118+
119 /* Seems that some systems (sun-sparc-solaris2.8 at least), need the following three #defines.
120 These were provided by Alan Mizrahi <alan@cesma.usb.ve>.
121 */
122@@ -76,137 +79,36 @@
123 static gint pads_loaded_on_start = 0;
124 static XpadSettings *settings;
125
126-static gboolean process_local_args (gint *argc, gchar **argv[]);
127-static gboolean process_remote_args (gint *argc, gchar **argv[], gboolean have_gtk, XpadSettings *xpad_settings);
128-
129-static gboolean config_dir_exists (void);
130-static gchar *make_config_dir (void);
131-static void register_stock_icons (void);
132-static gint xpad_app_load_pads (void);
133-static gboolean xpad_app_quit_if_no_pads (XpadPadGroup *group);
134-static gboolean xpad_app_first_idle_check (XpadPadGroup *group);
135-static gboolean xpad_app_pass_args (void);
136-static gboolean xpad_app_open_proc_file (void);
137-
138-static void
139-xpad_app_init (int argc, char **argv)
140-{
141- gboolean first_time;
142- gboolean have_gtk;
143-
144- /* Set up support different languages */
145-#ifdef ENABLE_NLS
146- bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
147- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
148- textdomain (GETTEXT_PACKAGE);
149-#endif
150-
151- have_gtk = gtk_init_check (&argc, &argv);
152- xpad_argc = argc;
153- xpad_argv = argv;
154- output = stdout;
155-
156- /* Set up config directory. */
157- first_time = !config_dir_exists ();
158- config_dir = make_config_dir ();
159-
160- /* create master socket name */
161- server_filename = g_build_filename (xpad_app_get_config_dir (), "server", NULL);
162-
163- if (!have_gtk)
164- {
165- /* We don't have GTK+, but we can still do
166- --version or --help and such. Plus, we
167- can pass commands to a remote instance. */
168- process_local_args (&xpad_argc, &xpad_argv);
169- if (!xpad_app_pass_args ())
170- {
171- process_remote_args (&xpad_argc, &xpad_argv, FALSE, settings);
172- fprintf (output, "%s\n", _("Xpad is a graphical program. Please run it from your desktop."));
173- }
174- exit (0);
175- }
176-
177- g_set_application_name (_("Xpad"));
178- gdk_set_program_class (PACKAGE);
179-
180- /* Set up program path. */
181- if (xpad_argc > 0)
182- program_path = g_find_program_in_path (xpad_argv[0]);
183- else
184- program_path = NULL;
185-
186- process_local_args (&xpad_argc, &xpad_argv);
187-
188- if (xpad_app_pass_args ())
189- exit (0);
190-
191- /* Race condition here, between calls */
192- xpad_app_open_proc_file ();
193-
194- register_stock_icons ();
195- gtk_window_set_default_icon_name (PACKAGE);
196-
197- /* Read the Xpad configuration file from disk (if exists) */
198- settings = xpad_settings_new ();
199-
200- /* Delay program startup, if user configured it, to wait for example for the loading of the systray. */
201- guint autostart_delay;
202- g_object_get (settings, "autostart-delay", &autostart_delay, NULL);
203-
204- if (autostart_delay)
205- sleep(autostart_delay);
206-
207- pad_group = xpad_pad_group_new();
208- process_remote_args (&xpad_argc, &xpad_argv, TRUE, settings);
209-
210- xpad_tray_init (settings);
211- xpad_session_manager_init ();
212-
213- /* Initialize Xpad-periodic module */
214- xpad_periodic_init ();
215- xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content);
216- xpad_periodic_set_callback ("save-info", (XpadPeriodicFunc) xpad_pad_save_info);
217-
218- /* load all pads */
219- pads_loaded_on_start = xpad_app_load_pads ();
220- if (pads_loaded_on_start == 0 && !option_new) {
221- if (!option_nonew) {
222- GtkWidget *pad = xpad_pad_new (pad_group, settings);
223- gtk_widget_show (pad);
224- }
225- }
226-
227- /* Since all pads have been loaded, reprocess the show/hide/toggle option for all pads */
228- if (have_gtk && (option_show))
229- xpad_pad_group_show_all (pad_group);
230- if (have_gtk && (option_hide))
231- xpad_pad_group_close_all (pad_group);
232- if (have_gtk && option_toggle)
233- xpad_pad_group_toggle_hide (pad_group);
234-
235- g_idle_add ((GSourceFunc)xpad_app_first_idle_check, pad_group);
236-
237- if (first_time)
238- show_help ();
239-
240- g_free (server_filename);
241- server_filename = NULL;
242-}
243-
244-gint main (gint argc, gchar **argv)
245-{ xpad_app_init (argc, argv);
246-
247- gtk_main ();
248-
249- return 0;
250-}
251+/**
252+ * Here are the functions called when arguments are passed to us.
253+ */
254+
255+static GOptionEntry local_options[] =
256+{
257+ {"version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Show version number and quit"), NULL},
258+ {"no-new", 'N', 0, G_OPTION_ARG_NONE, &option_nonew, N_("Don't create a new pad on startup if no previous pads exist"), NULL},
259+ {NULL}
260+};
261+
262+static GOptionEntry remote_options[] =
263+{
264+ {"new", 'n', 0, G_OPTION_ARG_NONE, &option_new, N_("Create a new pad on startup even if pads already exist"), NULL},
265+ {"hide", 'h', 0, G_OPTION_ARG_NONE, &option_hide, N_("Hide all pads"), NULL},
266+ {"show", 's', 0, G_OPTION_ARG_NONE, &option_show, N_("Show all pads"), NULL},
267+ {"toggle", 't', 0, G_OPTION_ARG_NONE, &option_toggle, N_("Toggle between show and hide all pads"), NULL},
268+ {"new-from-file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &option_files, N_("Create a new pad with the contents of a file"), N_("FILE")},
269+ {"quit", 'q', 0, G_OPTION_ARG_NONE, &option_quit, N_("Close all pads"), NULL},
270+ {"sm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &option_smid, NULL, NULL},
271+ {NULL}
272+};
273
274 /* parent and secondary may be NULL.
275 * Returns when user dismisses error.
276 */
277 void
278-xpad_app_error (GtkWindow *parent, const gchar *primary, const gchar *secondary)
279+xpad_app_error (GtkWindow *parent,
280+ const gchar *primary,
281+ const gchar *secondary)
282 {
283 GtkWidget *dialog;
284
285@@ -215,7 +117,7 @@
286
287 g_printerr ("%s\n", primary);
288
289- dialog = xpad_app_alert_dialog (parent, "dialog-error", primary, secondary);
290+ dialog = xpad_app_alert_dialog (parent, "dialog-error", primary, secondary);
291 gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Ok"), GTK_RESPONSE_OK, NULL);
292 gtk_dialog_run (GTK_DIALOG (dialog));
293 gtk_widget_destroy (dialog);
294@@ -349,7 +251,10 @@
295 * secondary text of 'secondary'. No buttons are added.
296 */
297 GtkWidget *
298-xpad_app_alert_dialog (GtkWindow *parent, const gchar *icon_name, const gchar *primary, const gchar *secondary)
299+xpad_app_alert_dialog (GtkWindow *parent,
300+ const gchar *icon_name,
301+ const gchar *primary,
302+ const gchar *secondary)
303 {
304 GtkWidget *dialog, *hbox, *image, *label;
305 gchar *buf;
306@@ -360,7 +265,7 @@
307 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
308
309 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
310- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG);
311+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG);
312 label = gtk_label_new (NULL);
313
314 if (secondary)
315@@ -440,13 +345,13 @@
316 }
317
318 static void
319-xpad_app_pad_added (XpadPadGroup *group, XpadPad *pad)
320+xpad_app_pad_added (XpadPadGroup *group,
321+ XpadPad *pad)
322 {
323 g_signal_connect_swapped (pad, "closed", G_CALLBACK (xpad_app_quit_if_no_pads), group);
324 g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_app_quit_if_no_pads), group);
325 }
326
327-
328 /* Scans config directory for pad files and loads them. */
329 static gint
330 xpad_app_load_pads (void)
331@@ -499,7 +404,9 @@
332 puts allocated string in dest, and returns size
333 */
334 static guint
335-args_to_string (int argc, char **argv, char **dest)
336+args_to_string (int argc,
337+ char **argv,
338+ char **dest)
339 {
340 gint i = 0;
341 guint size = 0;
342@@ -541,7 +448,8 @@
343 returns number of strings in newly allocated argv
344 */
345 static guint
346-string_to_args (const char *string, char ***argv)
347+string_to_args (const char *string,
348+ char ***argv)
349 {
350 guint num, i;
351 const gchar *tmp;
352@@ -589,6 +497,82 @@
353 return num;
354 }
355
356+static gboolean
357+process_remote_args (gint *argc,
358+ gchar **argv[],
359+ gboolean have_gtk,
360+ XpadSettings *xpad_settings)
361+{
362+ GError *error = NULL;
363+ GOptionContext *context;
364+
365+ option_new = FALSE;
366+ option_files = NULL;
367+ option_quit = FALSE;
368+ option_smid = NULL;
369+ option_hide = FALSE;
370+ option_show = FALSE;
371+ option_toggle = FALSE;
372+
373+ context = g_option_context_new (NULL);
374+ g_option_context_set_ignore_unknown_options (context, TRUE);
375+ g_option_context_set_help_enabled (context, FALSE);
376+ g_option_context_add_main_entries (context, remote_options, GETTEXT_PACKAGE);
377+ if (g_option_context_parse (context, argc, argv, &error))
378+ {
379+ if (have_gtk && option_smid)
380+ xpad_session_manager_set_id (option_smid);
381+
382+ if (!option_new)
383+ g_object_get (settings, "autostart-new-pad", &option_new, NULL);
384+
385+ if (have_gtk && option_new)
386+ {
387+ GtkWidget *pad = xpad_pad_new (pad_group, settings);
388+ gtk_widget_show (pad);
389+ }
390+
391+ if (!option_hide && !option_show) {
392+ guint display_pads;
393+ g_object_get (xpad_settings, "autostart-display-pads", &display_pads, NULL);
394+ if (display_pads == 0)
395+ option_show = TRUE;
396+ else if (display_pads == 1)
397+ option_hide = TRUE;
398+ }
399+
400+ if (have_gtk && option_files)
401+ {
402+ int i;
403+ for (i = 0; option_files[i]; i++)
404+ {
405+ GtkWidget *pad = xpad_pad_new_from_file (pad_group, settings, option_files[i]);
406+ if (pad)
407+ gtk_widget_show (pad);
408+ }
409+ }
410+
411+ if (option_quit)
412+ {
413+ if (have_gtk && gtk_main_level () > 0)
414+ xpad_app_quit ();
415+ else
416+ exit (0);
417+ }
418+ }
419+ else
420+ {
421+ fprintf (output, "%s\n", error->message);
422+ /* Don't quit. Bad options passed to the main xpad program by other
423+ iterations shouldn't close the main one. */
424+ }
425+
426+ g_option_context_free (context);
427+
428+ return(option_new || option_quit || option_smid || option_files ||
429+ option_hide || option_show || option_toggle);
430+}
431+
432 /* This reads a line from the proc file. This line will contain arguments to process. */
433 static void
434 xpad_app_read_from_proc_file (void)
435@@ -661,7 +645,9 @@
436 }
437
438 static gboolean
439-can_read_from_server_fd (GIOChannel *source, GIOCondition condition, gpointer data)
440+can_read_from_server_fd (GIOChannel *source,
441+ GIOCondition condition,
442+ gpointer data)
443 {
444 /* A dirty way to silence the compiler for these unused variables. */
445 (void) source;
446@@ -702,7 +688,6 @@
447 return TRUE;
448 }
449
450-
451 static gboolean
452 xpad_app_pass_args (void)
453 {
454@@ -770,31 +755,9 @@
455 return connected;
456 }
457
458-/**
459- * Here are the functions called when arguments are passed to us.
460- */
461-
462-static GOptionEntry local_options[] =
463-{
464- {"version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Show version number and quit"), NULL},
465- {"no-new", 'N', 0, G_OPTION_ARG_NONE, &option_nonew, N_("Don't create a new pad on startup if no previous pads exist"), NULL},
466- {NULL}
467-};
468-
469-static GOptionEntry remote_options[] =
470-{
471- {"new", 'n', 0, G_OPTION_ARG_NONE, &option_new, N_("Create a new pad on startup even if pads already exist"), NULL},
472- {"hide", 'h', 0, G_OPTION_ARG_NONE, &option_hide, N_("Hide all pads"), NULL},
473- {"show", 's', 0, G_OPTION_ARG_NONE, &option_show, N_("Show all pads"), NULL},
474- {"toggle", 't', 0, G_OPTION_ARG_NONE, &option_toggle, N_("Toggle between show and hide all pads"), NULL},
475- {"new-from-file", 'f', 0, G_OPTION_ARG_FILENAME_ARRAY, &option_files, N_("Create a new pad with the contents of a file"), N_("FILE")},
476- {"quit", 'q', 0, G_OPTION_ARG_NONE, &option_quit, N_("Close all pads"), NULL},
477- {"sm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &option_smid, NULL, NULL},
478- {NULL}
479-};
480-
481 static gboolean
482-process_local_args (gint *argc, gchar **argv[])
483+process_local_args (gint *argc,
484+ gchar **argv[])
485 {
486 GError *error = NULL;
487 GOptionContext *context;
488@@ -836,75 +799,119 @@
489 return (option_version || option_nonew);
490 }
491
492-static gboolean
493-process_remote_args (gint *argc, gchar **argv[], gboolean have_gtk, XpadSettings *xpad_settings)
494+static void
495+xpad_app_init (int argc,
496+ char **argv)
497 {
498- GError *error = NULL;
499- GOptionContext *context;
500-
501- option_new = FALSE;
502- option_files = NULL;
503- option_quit = FALSE;
504- option_smid = NULL;
505- option_hide = FALSE;
506- option_show = FALSE;
507- option_toggle = FALSE;
508-
509- context = g_option_context_new (NULL);
510- g_option_context_set_ignore_unknown_options (context, TRUE);
511- g_option_context_set_help_enabled (context, FALSE);
512- g_option_context_add_main_entries (context, remote_options, GETTEXT_PACKAGE);
513- if (g_option_context_parse (context, argc, argv, &error))
514+ gboolean first_time;
515+ gboolean have_gtk;
516+
517+ /* Set up support different languages */
518+#ifdef ENABLE_NLS
519+ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
520+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
521+ textdomain (GETTEXT_PACKAGE);
522+#endif
523+
524+ have_gtk = gtk_init_check (&argc, &argv);
525+ xpad_argc = argc;
526+ xpad_argv = argv;
527+ output = stdout;
528+
529+ /* Set up config directory. */
530+ first_time = !config_dir_exists ();
531+ config_dir = make_config_dir ();
532+
533+ /* create master socket name */
534+ server_filename = g_build_filename (xpad_app_get_config_dir (), "server", NULL);
535+
536+ if (!have_gtk)
537 {
538- if (have_gtk && option_smid)
539- xpad_session_manager_set_id (option_smid);
540-
541- if (!option_new)
542- g_object_get (settings, "autostart-new-pad", &option_new, NULL);
543-
544- if (have_gtk && option_new)
545+ /* We don't have GTK+, but we can still do
546+ --version or --help and such. Plus, we
547+ can pass commands to a remote instance. */
548+ process_local_args (&xpad_argc, &xpad_argv);
549+ if (!xpad_app_pass_args ())
550 {
551+ process_remote_args (&xpad_argc, &xpad_argv, FALSE, settings);
552+ fprintf (output, "%s\n", _("Xpad is a graphical program. Please run it from your desktop."));
553+ }
554+ exit (0);
555+ }
556+
557+ g_set_application_name (_("Xpad"));
558+ gdk_set_program_class (PACKAGE);
559+
560+ /* Set up program path. */
561+ if (xpad_argc > 0)
562+ program_path = g_find_program_in_path (xpad_argv[0]);
563+ else
564+ program_path = NULL;
565+
566+ process_local_args (&xpad_argc, &xpad_argv);
567+
568+ if (xpad_app_pass_args ())
569+ exit (0);
570+
571+ /* Race condition here, between calls */
572+ xpad_app_open_proc_file ();
573+
574+ register_stock_icons ();
575+ gtk_window_set_default_icon_name (PACKAGE);
576+
577+ /* Read the Xpad configuration file from disk (if exists) */
578+ settings = xpad_settings_new ();
579+
580+ /* Delay program startup, if user configured it, to wait for example for the loading of the systray. */
581+ guint autostart_delay;
582+ g_object_get (settings, "autostart-delay", &autostart_delay, NULL);
583+
584+ if (autostart_delay)
585+ sleep(autostart_delay);
586+
587+ pad_group = xpad_pad_group_new();
588+ process_remote_args (&xpad_argc, &xpad_argv, TRUE, settings);
589+
590+ xpad_tray_init (settings);
591+ xpad_session_manager_init ();
592+
593+ /* Initialize Xpad-periodic module */
594+ xpad_periodic_init ();
595+ xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content);
596+ xpad_periodic_set_callback ("save-info", (XpadPeriodicFunc) xpad_pad_save_info);
597+
598+ /* load all pads */
599+ pads_loaded_on_start = xpad_app_load_pads ();
600+ if (pads_loaded_on_start == 0 && !option_new) {
601+ if (!option_nonew) {
602 GtkWidget *pad = xpad_pad_new (pad_group, settings);
603 gtk_widget_show (pad);
604 }
605-
606- if (!option_hide && !option_show) {
607- guint display_pads;
608- g_object_get (xpad_settings, "autostart-display-pads", &display_pads, NULL);
609- if (display_pads == 0)
610- option_show = TRUE;
611- else if (display_pads == 1)
612- option_hide = TRUE;
613- }
614-
615- if (have_gtk && option_files)
616- {
617- int i;
618- for (i = 0; option_files[i]; i++)
619- {
620- GtkWidget *pad = xpad_pad_new_from_file (pad_group, settings, option_files[i]);
621- if (pad)
622- gtk_widget_show (pad);
623- }
624- }
625-
626- if (option_quit)
627- {
628- if (have_gtk && gtk_main_level () > 0)
629- xpad_app_quit ();
630- else
631- exit (0);
632- }
633- }
634- else
635- {
636- fprintf (output, "%s\n", error->message);
637- /* Don't quit. Bad options passed to the main xpad program by other
638- iterations shouldn't close the main one. */
639- }
640-
641- g_option_context_free (context);
642-
643- return(option_new || option_quit || option_smid || option_files ||
644- option_hide || option_show || option_toggle);
645+ }
646+
647+ /* Since all pads have been loaded, reprocess the show/hide/toggle option for all pads */
648+ if (have_gtk && (option_show))
649+ xpad_pad_group_show_all (pad_group);
650+ if (have_gtk && (option_hide))
651+ xpad_pad_group_close_all (pad_group);
652+ if (have_gtk && option_toggle)
653+ xpad_pad_group_toggle_hide (pad_group);
654+
655+ g_idle_add ((GSourceFunc)xpad_app_first_idle_check, pad_group);
656+
657+ if (first_time)
658+ show_help ();
659+
660+ g_free (server_filename);
661+ server_filename = NULL;
662+}
663+
664+gint main (gint argc,
665+ gchar **argv)
666+{
667+ xpad_app_init (argc, argv);
668+
669+ gtk_main ();
670+
671+ return 0;
672 }
673
674=== modified file 'src/xpad-grip-tool-item.c'
675--- src/xpad-grip-tool-item.c 2014-06-17 18:22:49 +0000
676+++ src/xpad-grip-tool-item.c 2014-09-08 13:22:52 +0000
677@@ -20,6 +20,7 @@
678 */
679
680 #include "../config.h"
681+
682 #include "xpad-grip-tool-item.h"
683
684 struct XpadGripToolItemPrivate
685@@ -29,45 +30,9 @@
686
687 G_DEFINE_TYPE_WITH_PRIVATE(XpadGripToolItem, xpad_grip_tool_item, GTK_TYPE_TOOL_ITEM)
688
689-static gboolean xpad_grip_tool_item_event_box_draw (GtkWidget *widget, cairo_t *cr);
690-static void xpad_grip_tool_item_event_box_realize (GtkWidget *widget);
691-static gboolean xpad_grip_tool_item_button_pressed_event (GtkWidget *widget, GdkEventButton *event);
692-
693-GtkToolItem *
694-xpad_grip_tool_item_new (void)
695-{
696- return GTK_TOOL_ITEM (g_object_new (XPAD_TYPE_GRIP_TOOL_ITEM, NULL));
697-}
698-
699-static void
700-xpad_grip_tool_item_class_init (XpadGripToolItemClass *klass)
701-{
702-}
703-
704-static void
705-xpad_grip_tool_item_init (XpadGripToolItem *grip)
706-{
707- GtkWidget *alignment;
708- gboolean right;
709-
710- grip->priv = xpad_grip_tool_item_get_instance_private(grip);
711-
712- grip->priv->drawbox = gtk_drawing_area_new ();
713- gtk_widget_add_events (grip->priv->drawbox, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
714- g_signal_connect (grip->priv->drawbox, "button-press-event", G_CALLBACK (xpad_grip_tool_item_button_pressed_event), NULL);
715- g_signal_connect (grip->priv->drawbox, "realize", G_CALLBACK (xpad_grip_tool_item_event_box_realize), NULL);
716- g_signal_connect (grip->priv->drawbox, "draw", G_CALLBACK (xpad_grip_tool_item_event_box_draw), NULL);
717- gtk_widget_set_size_request (grip->priv->drawbox, 18, 18);
718-
719- right = gtk_widget_get_direction (grip->priv->drawbox) == GTK_TEXT_DIR_LTR;
720- alignment = gtk_alignment_new (right ? 1 : 0, 1, 0, 0);
721-
722- gtk_container_add (GTK_CONTAINER (alignment), grip->priv->drawbox);
723- gtk_container_add (GTK_CONTAINER (grip), alignment);
724-}
725-
726 static gboolean
727-xpad_grip_tool_item_button_pressed_event (GtkWidget *widget, GdkEventButton *event)
728+xpad_grip_tool_item_button_pressed_event (GtkWidget *widget,
729+ GdkEventButton *event)
730 {
731 if (event->button == 1)
732 {
733@@ -105,7 +70,8 @@
734 }
735
736 static gboolean
737-xpad_grip_tool_item_event_box_draw (GtkWidget *widget, cairo_t *cr)
738+xpad_grip_tool_item_event_box_draw (GtkWidget *widget,
739+ cairo_t *cr)
740 {
741 gtk_render_handle(gtk_widget_get_style_context(widget),
742 cr,
743@@ -115,3 +81,36 @@
744
745 return FALSE;
746 }
747+
748+static void
749+xpad_grip_tool_item_class_init (XpadGripToolItemClass *klass)
750+{
751+}
752+
753+static void
754+xpad_grip_tool_item_init (XpadGripToolItem *grip)
755+{
756+ GtkWidget *alignment;
757+ gboolean right;
758+
759+ grip->priv = xpad_grip_tool_item_get_instance_private(grip);
760+
761+ grip->priv->drawbox = gtk_drawing_area_new ();
762+ gtk_widget_add_events (grip->priv->drawbox, GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE_MASK);
763+ g_signal_connect (grip->priv->drawbox, "button-press-event", G_CALLBACK (xpad_grip_tool_item_button_pressed_event), NULL);
764+ g_signal_connect (grip->priv->drawbox, "realize", G_CALLBACK (xpad_grip_tool_item_event_box_realize), NULL);
765+ g_signal_connect (grip->priv->drawbox, "draw", G_CALLBACK (xpad_grip_tool_item_event_box_draw), NULL);
766+ gtk_widget_set_size_request (grip->priv->drawbox, 18, 18);
767+
768+ right = gtk_widget_get_direction (grip->priv->drawbox) == GTK_TEXT_DIR_LTR;
769+ alignment = gtk_alignment_new (right ? 1 : 0, 1, 0, 0);
770+
771+ gtk_container_add (GTK_CONTAINER (alignment), grip->priv->drawbox);
772+ gtk_container_add (GTK_CONTAINER (grip), alignment);
773+}
774+
775+GtkToolItem *
776+xpad_grip_tool_item_new (void)
777+{
778+ return GTK_TOOL_ITEM (g_object_new (XPAD_TYPE_GRIP_TOOL_ITEM, NULL));
779+}
780
781=== modified file 'src/xpad-pad-group.c'
782--- src/xpad-pad-group.c 2014-07-23 10:03:02 +0000
783+++ src/xpad-pad-group.c 2014-09-08 13:22:52 +0000
784@@ -21,6 +21,7 @@
785 */
786
787 #include "../config.h"
788+
789 #include "xpad-pad-group.h"
790 #include "xpad-pad.h"
791
792@@ -31,8 +32,6 @@
793
794 G_DEFINE_TYPE_WITH_PRIVATE (XpadPadGroup, xpad_pad_group, G_TYPE_OBJECT)
795
796-static void xpad_pad_group_save_unsaved_all (XpadPadGroup *group);
797-
798 enum {
799 PROP_0
800 };
801@@ -75,7 +74,7 @@
802 G_TYPE_NONE,
803 1,
804 GTK_TYPE_WIDGET);
805-
806+
807 signals[PAD_REMOVED] =
808 g_signal_new ("pad_removed",
809 G_OBJECT_CLASS_TYPE (object_class),
810@@ -96,10 +95,11 @@
811
812 /* Add a pad to this group */
813 void
814-xpad_pad_group_add (XpadPadGroup *group, GtkWidget *pad)
815+xpad_pad_group_add (XpadPadGroup *group,
816+ GtkWidget *pad)
817 {
818 g_object_ref(pad);
819-
820+
821 group->priv->pads = g_slist_append (group->priv->pads, XPAD_PAD (pad));
822 g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_pad_group_remove), group);
823
824@@ -108,7 +108,8 @@
825
826 /* Remove a pad from this group */
827 void
828-xpad_pad_group_remove (XpadPadGroup *group, GtkWidget *pad)
829+xpad_pad_group_remove (XpadPadGroup *group,
830+ GtkWidget *pad)
831 {
832 group->priv->pads = g_slist_remove (group->priv->pads, XPAD_PAD (pad));
833 g_object_unref(pad);
834@@ -117,6 +118,13 @@
835 g_signal_emit (group, signals[PAD_REMOVED], 0, pad);
836 }
837
838+static void
839+xpad_pad_group_save_unsaved_all (XpadPadGroup *group)
840+{
841+ if (group)
842+ g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_save_unsaved, NULL);
843+}
844+
845 /* Delete all the current pads in the group */
846 void
847 xpad_pad_group_destroy_pads (XpadPadGroup *group)
848@@ -146,14 +154,10 @@
849 }
850 g_slist_free(i);
851 }
852+
853 return num;
854 }
855
856-static void xpad_pad_group_save_unsaved_all (XpadPadGroup *group) {
857- if (group)
858- g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_save_unsaved, NULL);
859-}
860-
861 void
862 xpad_pad_group_close_all (XpadPadGroup *group)
863 {
864
865=== modified file 'src/xpad-pad-properties.c'
866--- src/xpad-pad-properties.c 2014-06-19 12:35:19 +0000
867+++ src/xpad-pad-properties.c 2014-09-08 13:22:52 +0000
868@@ -21,44 +21,35 @@
869
870 #include "../config.h"
871 #include "xpad-pad-properties.h"
872+#include <gtk/gtk.h>
873 #include <glib/gi18n.h>
874-#include <gtk/gtk.h>
875
876 struct XpadPadPropertiesPrivate
877 {
878 GtkWidget *fontcheck;
879 GtkWidget *colorcheck;
880 GtkWidget *colorbox;
881-
882+
883 GtkWidget *textbutton;
884 GdkRGBA texttmp;
885-
886+
887 GtkWidget *backbutton;
888 GdkRGBA backtmp;
889-
890+
891 GtkWidget *fontbutton;
892 };
893
894 G_DEFINE_TYPE_WITH_PRIVATE (XpadPadProperties, xpad_pad_properties, GTK_TYPE_DIALOG)
895
896-static void xpad_pad_properties_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
897-static void xpad_pad_properties_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
898-static void xpad_pad_properties_response (GtkDialog *dialog, gint response);
899-static void change_color_check (GtkToggleButton *button, XpadPadProperties *prop);
900-static void change_font_check (GtkToggleButton *button, XpadPadProperties *prop);
901-static void change_text_color (XpadPadProperties *prop);
902-static void change_back_color (XpadPadProperties *prop);
903-static void change_font_face (XpadPadProperties *prop);
904-
905 enum
906 {
907- PROP_0,
908- PROP_FOLLOW_FONT_STYLE,
909- PROP_FOLLOW_COLOR_STYLE,
910- PROP_BACK_COLOR,
911- PROP_TEXT_COLOR,
912- PROP_FONTNAME,
913- N_PROPERTIES
914+ PROP_0,
915+ PROP_FOLLOW_FONT_STYLE,
916+ PROP_FOLLOW_COLOR_STYLE,
917+ PROP_BACK_COLOR,
918+ PROP_TEXT_COLOR,
919+ PROP_FONTNAME,
920+ N_PROPERTIES
921 };
922
923 static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, };
924@@ -69,6 +60,125 @@
925 return g_object_new (XPAD_TYPE_PAD_PROPERTIES, NULL);
926 }
927
928+
929+static void
930+xpad_pad_properties_response (GtkDialog *dialog,
931+ gint response)
932+{
933+ if (response == GTK_RESPONSE_CLOSE)
934+ gtk_widget_destroy (GTK_WIDGET (dialog));
935+}
936+
937+static void
938+change_font_check (GtkToggleButton *button,
939+ XpadPadProperties *prop)
940+{
941+ gtk_widget_set_sensitive (prop->priv->fontbutton, gtk_toggle_button_get_active (button));
942+
943+ g_object_notify (G_OBJECT (prop), "follow-font-style");
944+}
945+
946+static void
947+change_color_check (GtkToggleButton *button,
948+ XpadPadProperties *prop)
949+{
950+ gtk_widget_set_sensitive (prop->priv->colorbox, gtk_toggle_button_get_active (button));
951+
952+ g_object_notify (G_OBJECT (prop), "follow-color-style");
953+}
954+
955+static void
956+change_text_color (XpadPadProperties *prop)
957+{
958+ g_object_notify (G_OBJECT (prop), "text-color");
959+}
960+
961+static void
962+change_back_color (XpadPadProperties *prop)
963+{
964+ g_object_notify (G_OBJECT (prop), "back-color");
965+}
966+
967+static void
968+change_font_face (XpadPadProperties *prop)
969+{
970+ g_object_notify (G_OBJECT (prop), "fontname");
971+}
972+
973+static void
974+xpad_pad_properties_set_property (GObject *object,
975+ guint prop_id,
976+ const GValue *value,
977+ GParamSpec *pspec)
978+{
979+ XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object);
980+
981+ switch (prop_id)
982+ {
983+ case PROP_FOLLOW_FONT_STYLE:
984+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck), !g_value_get_boolean (value));
985+ break;
986+
987+ case PROP_FOLLOW_COLOR_STYLE:
988+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck), !g_value_get_boolean (value));
989+ break;
990+
991+ case PROP_BACK_COLOR:
992+ gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), g_value_get_boxed (value));
993+ break;
994+
995+ case PROP_TEXT_COLOR:
996+ gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), g_value_get_boxed (value));
997+ break;
998+
999+ case PROP_FONTNAME:
1000+ gtk_font_button_set_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton), g_value_get_string (value));
1001+ break;
1002+
1003+ default:
1004+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1005+ break;
1006+ }
1007+}
1008+
1009+static void
1010+xpad_pad_properties_get_property (GObject *object,
1011+ guint prop_id,
1012+ GValue *value,
1013+ GParamSpec *pspec)
1014+{
1015+ XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object);
1016+
1017+ switch (prop_id)
1018+ {
1019+ case PROP_FOLLOW_FONT_STYLE:
1020+ g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck)));
1021+ break;
1022+
1023+ case PROP_FOLLOW_COLOR_STYLE:
1024+ g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck)));
1025+ break;
1026+
1027+ case PROP_BACK_COLOR:
1028+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), &prop->priv->backtmp);
1029+ g_value_set_static_boxed (value, &prop->priv->backtmp);
1030+ break;
1031+
1032+ case PROP_TEXT_COLOR:
1033+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), &prop->priv->texttmp);
1034+ g_value_set_static_boxed (value, &prop->priv->texttmp);
1035+ break;
1036+
1037+ case PROP_FONTNAME:
1038+ g_value_set_string (value, gtk_font_button_get_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton)));
1039+ break;
1040+
1041+ default:
1042+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1043+ break;
1044+ }
1045+}
1046+
1047 static void
1048 xpad_pad_properties_class_init (XpadPadPropertiesClass *klass)
1049 {
1050@@ -93,9 +203,9 @@
1051 GtkBox *hbox, *font_hbox, *vbox, *appearance_vbox;
1052 GtkWidget *font_radio, *color_radio, *label, *appearance_frame, *alignment;
1053 GtkSizeGroup *size_group_labels = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
1054-
1055+
1056 prop->priv = xpad_pad_properties_get_instance_private (prop);
1057-
1058+
1059 text = g_strconcat ("<b>", _("Appearance"), "</b>", NULL);
1060 label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL,
1061 "label", text,
1062@@ -119,7 +229,7 @@
1063 "child", alignment,
1064 "border-width", 6,
1065 NULL));
1066-
1067+
1068 prop->priv->fontbutton = gtk_font_button_new ();
1069 prop->priv->textbutton = gtk_color_button_new ();
1070 prop->priv->backbutton = gtk_color_button_new ();
1071@@ -133,7 +243,7 @@
1072
1073 gtk_box_pack_start (font_hbox, prop->priv->fontcheck, FALSE, FALSE, 0);
1074 gtk_box_pack_start (font_hbox, prop->priv->fontbutton, TRUE, TRUE, 0);
1075-
1076+
1077 prop->priv->colorbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1078
1079 hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12));
1080@@ -143,7 +253,7 @@
1081 gtk_box_pack_start (hbox, label, FALSE, FALSE, 0);
1082 gtk_box_pack_start (hbox, prop->priv->textbutton, TRUE, TRUE, 0);
1083 g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL);
1084-
1085+
1086 hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12));
1087 label = gtk_label_new_with_mnemonic (_("Background:"));
1088 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1089@@ -151,22 +261,22 @@
1090 gtk_box_pack_start (hbox, label, FALSE, FALSE, 0);
1091 gtk_box_pack_start (hbox, prop->priv->backbutton, TRUE, TRUE, 0);
1092 g_object_set (G_OBJECT (prop->priv->colorbox), "child", hbox, NULL);
1093-
1094+
1095 alignment = gtk_alignment_new (1, 1, 1, 1);
1096 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
1097 gtk_container_add (GTK_CONTAINER (alignment), prop->priv->colorbox);
1098-
1099+
1100 gtk_dialog_add_button (GTK_DIALOG (prop), "gtk-close", GTK_RESPONSE_CLOSE);
1101 gtk_dialog_set_default_response (GTK_DIALOG (prop), GTK_RESPONSE_CLOSE);
1102 g_signal_connect (prop, "response", G_CALLBACK (xpad_pad_properties_response), NULL);
1103-
1104+
1105 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->textbutton), FALSE);
1106 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (prop->priv->backbutton), TRUE);
1107-
1108+
1109 gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->textbutton), _("Set Foreground Color"));
1110 gtk_color_button_set_title (GTK_COLOR_BUTTON (prop->priv->backbutton), _("Set Background Color"));
1111 gtk_font_button_set_title (GTK_FONT_BUTTON (prop->priv->fontbutton), _("Set Font"));
1112-
1113+
1114 vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6));
1115 hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12));
1116
1117@@ -180,131 +290,22 @@
1118 gtk_box_pack_start (vbox, prop->priv->colorcheck, FALSE, FALSE, 0);
1119 gtk_box_pack_start (vbox, alignment, FALSE, FALSE, 0);
1120 gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0);
1121-
1122+
1123 g_signal_connect (prop->priv->fontcheck, "toggled", G_CALLBACK (change_font_check), prop);
1124 g_signal_connect (prop->priv->colorcheck, "toggled", G_CALLBACK (change_color_check), prop);
1125 g_signal_connect_swapped (prop->priv->fontbutton, "font-set", G_CALLBACK (change_font_face), prop);
1126 g_signal_connect_swapped (prop->priv->textbutton, "color-set", G_CALLBACK (change_text_color), prop);
1127 g_signal_connect_swapped (prop->priv->backbutton, "color-set", G_CALLBACK (change_back_color), prop);
1128-
1129+
1130 /* Setup initial state, which should never be seen, but just in case client doesn't set them itself, we'll be consistent. */
1131 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (font_radio), TRUE);
1132 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (color_radio), TRUE);
1133 gtk_widget_set_sensitive (prop->priv->colorbox, FALSE);
1134 gtk_widget_set_sensitive (prop->priv->fontbutton, FALSE);
1135-
1136+
1137 g_object_unref (size_group_labels);
1138-
1139+
1140 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (prop))), appearance_frame);
1141
1142 gtk_widget_show_all (gtk_dialog_get_content_area (GTK_DIALOG (prop)));
1143 }
1144-
1145-static void
1146-xpad_pad_properties_response (GtkDialog *dialog, gint response)
1147-{
1148- if (response == GTK_RESPONSE_CLOSE)
1149- gtk_widget_destroy (GTK_WIDGET (dialog));
1150-}
1151-
1152-static void
1153-change_font_check (GtkToggleButton *button, XpadPadProperties *prop)
1154-{
1155- gtk_widget_set_sensitive (prop->priv->fontbutton, gtk_toggle_button_get_active (button));
1156-
1157- g_object_notify (G_OBJECT (prop), "follow-font-style");
1158-}
1159-
1160-static void
1161-change_color_check (GtkToggleButton *button, XpadPadProperties *prop)
1162-{
1163- gtk_widget_set_sensitive (prop->priv->colorbox, gtk_toggle_button_get_active (button));
1164-
1165- g_object_notify (G_OBJECT (prop), "follow-color-style");
1166-}
1167-
1168-static void
1169-change_text_color (XpadPadProperties *prop)
1170-{
1171- g_object_notify (G_OBJECT (prop), "text-color");
1172-}
1173-
1174-static void
1175-change_back_color (XpadPadProperties *prop)
1176-{
1177- g_object_notify (G_OBJECT (prop), "back-color");
1178-}
1179-
1180-static void
1181-change_font_face (XpadPadProperties *prop)
1182-{
1183- g_object_notify (G_OBJECT (prop), "fontname");
1184-}
1185-
1186-static void
1187-xpad_pad_properties_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
1188-{
1189- XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object);
1190-
1191- switch (prop_id)
1192- {
1193- case PROP_FOLLOW_FONT_STYLE:
1194- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck), !g_value_get_boolean (value));
1195- break;
1196-
1197- case PROP_FOLLOW_COLOR_STYLE:
1198- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck), !g_value_get_boolean (value));
1199- break;
1200-
1201- case PROP_BACK_COLOR:
1202- gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), g_value_get_boxed (value));
1203- break;
1204-
1205- case PROP_TEXT_COLOR:
1206- gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), g_value_get_boxed (value));
1207- break;
1208-
1209- case PROP_FONTNAME:
1210- gtk_font_button_set_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton), g_value_get_string (value));
1211- break;
1212-
1213- default:
1214- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1215- break;
1216- }
1217-}
1218-
1219-static void
1220-xpad_pad_properties_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
1221-{
1222- XpadPadProperties *prop = XPAD_PAD_PROPERTIES (object);
1223-
1224- switch (prop_id)
1225- {
1226- case PROP_FOLLOW_FONT_STYLE:
1227- g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->fontcheck)));
1228- break;
1229-
1230- case PROP_FOLLOW_COLOR_STYLE:
1231- g_value_set_boolean (value, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prop->priv->colorcheck)));
1232- break;
1233-
1234- case PROP_BACK_COLOR:
1235- gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->backbutton), &prop->priv->backtmp);
1236- g_value_set_static_boxed (value, &prop->priv->backtmp);
1237- break;
1238-
1239- case PROP_TEXT_COLOR:
1240- gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (prop->priv->textbutton), &prop->priv->texttmp);
1241- g_value_set_static_boxed (value, &prop->priv->texttmp);
1242- break;
1243-
1244- case PROP_FONTNAME:
1245- g_value_set_string (value, gtk_font_button_get_font_name (GTK_FONT_BUTTON (prop->priv->fontbutton)));
1246- break;
1247-
1248- default:
1249- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1250- break;
1251- }
1252-}
1253
1254=== modified file 'src/xpad-pad.c'
1255--- src/xpad-pad.c 2014-08-30 18:36:57 +0000
1256+++ src/xpad-pad.c 2014-09-08 13:22:52 +0000
1257@@ -24,9 +24,8 @@
1258 */
1259
1260 #include "../config.h"
1261+
1262 #include "xpad-pad.h"
1263-#include <gtk/gtk.h>
1264-#include <glib/gi18n.h>
1265 #include "fio.h"
1266 #include "help.h"
1267 #include "xpad-app.h"
1268@@ -38,6 +37,9 @@
1269 #include "xpad-toolbar.h"
1270 #include "xpad-tray.h"
1271
1272+#include <gtk/gtk.h>
1273+#include <glib/gi18n.h>
1274+
1275 struct XpadPadPrivate
1276 {
1277 /* saved values */
1278@@ -97,509 +99,105 @@
1279 static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, };
1280 static guint signals[LAST_SIGNAL] = { 0 };
1281
1282-static void xpad_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
1283-static void xpad_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
1284-static void xpad_pad_constructed (GObject *object);
1285-static void xpad_pad_dispose (GObject *object);
1286-static void xpad_pad_finalize (GObject *object);
1287-static void xpad_pad_load_info (XpadPad *pad, gboolean *show);
1288-static GtkWidget *menu_get_popup_highlight (XpadPad *pad, GtkAccelGroup *accel_group);
1289-static GtkWidget *menu_get_popup_no_highlight (XpadPad *pad, GtkAccelGroup *accel_group);
1290-static void xpad_pad_show (XpadPad *pad);
1291-static gboolean xpad_pad_configure_event (XpadPad *pad, GdkEventConfigure *event);
1292-static gboolean xpad_pad_toolbar_size_allocate (XpadPad *pad, GtkAllocation *event);
1293-static gboolean xpad_pad_delete_event (XpadPad *pad, GdkEvent *event);
1294-static gboolean xpad_pad_popup_menu (XpadPad *pad);
1295-static void menu_popup (XpadPad *pad);
1296-static void menu_popdown (XpadPad *pad);
1297-static gboolean xpad_pad_button_press_event (XpadPad *pad, GdkEventButton *event);
1298-static void xpad_pad_text_changed (XpadPad *pad, GtkTextBuffer *buffer);
1299-static void xpad_pad_notify_has_scrollbar (XpadPad *pad);
1300-static void xpad_pad_notify_has_decorations (XpadPad *pad);
1301-static void xpad_pad_notify_has_toolbar (XpadPad *pad);
1302-static void xpad_pad_notify_autohide_toolbar (XpadPad *pad);
1303-static void xpad_pad_hide_toolbar (XpadPad *pad);
1304-static void xpad_pad_show_toolbar (XpadPad *pad);
1305-static void xpad_pad_popup (XpadPad *pad, GdkEventButton *event);
1306-static void xpad_pad_spawn (XpadPad *pad);
1307-static void xpad_pad_clear (XpadPad *pad);
1308-static void xpad_pad_undo (XpadPad *pad);
1309-static void xpad_pad_redo (XpadPad *pad);
1310-static void xpad_pad_cut (XpadPad *pad);
1311-static void xpad_pad_copy (XpadPad *pad);
1312-static void xpad_pad_paste (XpadPad *pad);
1313-static void xpad_pad_delete (XpadPad *pad);
1314-static void xpad_pad_open_properties (XpadPad *pad);
1315-static void xpad_pad_open_preferences (XpadPad *pad);
1316-static void xpad_pad_close_all (XpadPad *pad);
1317-static void xpad_pad_sync_title (XpadPad *pad);
1318-static gboolean xpad_pad_leave_notify_event (GtkWidget *pad, GdkEventCrossing *event);
1319-static gboolean xpad_pad_enter_notify_event (GtkWidget *pad, GdkEventCrossing *event);
1320-
1321 /* Create a new empty pad. */
1322 GtkWidget *
1323-xpad_pad_new (XpadPadGroup *group, XpadSettings *settings)
1324+xpad_pad_new (XpadPadGroup *group,
1325+ XpadSettings *settings)
1326 {
1327 return GTK_WIDGET (g_object_new (XPAD_TYPE_PAD, "group", group, "settings", settings, NULL));
1328 }
1329
1330-/* Create a new pad based on the provided info-xxxxx file from the config directory and return this pad */
1331-GtkWidget *
1332-xpad_pad_new_with_info (XpadPadGroup *group, XpadSettings *settings, const gchar *info_filename, gboolean *show)
1333-{
1334- GtkWidget *pad = xpad_pad_new (group, settings);
1335-
1336- XPAD_PAD (pad)->priv->infoname = g_strdup (info_filename);
1337- xpad_pad_load_info (XPAD_PAD (pad), show);
1338- xpad_pad_load_content (XPAD_PAD (pad));
1339- gtk_window_set_role (GTK_WINDOW (pad), XPAD_PAD (pad)->priv->infoname);
1340-
1341- return pad;
1342-}
1343-
1344-/* Create a new pad based on the provided filename from the command line */
1345-GtkWidget *
1346-xpad_pad_new_from_file (XpadPadGroup *group, XpadSettings *settings, const gchar *filename)
1347-{
1348- GtkWidget *pad = NULL;
1349- gchar *content;
1350-
1351- content = fio_get_file (filename);
1352-
1353- if (!content)
1354- {
1355- gchar *usertext = g_strdup_printf (_("Could not read file %s."), filename);
1356- xpad_app_error (NULL, usertext, NULL);
1357- g_free (usertext);
1358- }
1359- else
1360- {
1361- GtkTextBuffer *buffer;
1362-
1363- xpad_periodic_init ();
1364- xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content);
1365-
1366- pad = xpad_pad_new (group, settings);
1367- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (XPAD_PAD (pad)->priv->textview));
1368-
1369- xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer));
1370- g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad);
1371-
1372- xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : "");
1373- g_free (content);
1374-
1375- g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad);
1376- xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer));
1377-
1378- xpad_pad_text_changed(XPAD_PAD(pad), buffer);
1379- }
1380-
1381- return pad;
1382-}
1383-
1384-/* Class pad - constructor */
1385-static void
1386-xpad_pad_class_init (XpadPadClass *klass)
1387-{
1388- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1389-
1390- gobject_class->constructed = xpad_pad_constructed;
1391- gobject_class->set_property = xpad_pad_set_property;
1392- gobject_class->get_property = xpad_pad_get_property;
1393- gobject_class->dispose = xpad_pad_dispose;
1394- gobject_class->finalize = xpad_pad_finalize;
1395-
1396- signals[CLOSED] =
1397- g_signal_new ("closed",
1398- G_OBJECT_CLASS_TYPE (gobject_class),
1399- G_SIGNAL_RUN_FIRST,
1400- G_STRUCT_OFFSET (XpadPadClass, closed),
1401- NULL, NULL,
1402- g_cclosure_marshal_VOID__VOID,
1403- G_TYPE_NONE,
1404- 0);
1405-
1406- /* Properties */
1407- obj_prop[PROP_GROUP] = g_param_spec_pointer ("group", "Pad group", "Pad group for this pad", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
1408- obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
1409-
1410- g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop);
1411-}
1412-
1413-static void
1414-xpad_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
1415-{
1416- XpadPad *pad = XPAD_PAD (object);
1417-
1418- switch (prop_id)
1419- {
1420- case PROP_GROUP:
1421- pad->priv->group = g_value_get_pointer (value);
1422- g_object_ref (pad->priv->group);
1423- if (pad->priv->group)
1424- xpad_pad_group_add (pad->priv->group, GTK_WIDGET (pad));
1425- break;
1426-
1427- case PROP_SETTINGS:
1428- pad->priv->settings = g_value_get_pointer (value);
1429- g_object_ref (pad->priv->settings);
1430- break;
1431-
1432- default:
1433- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1434- break;
1435- }
1436-}
1437-
1438-static void
1439-xpad_pad_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
1440-{
1441- XpadPad *pad = XPAD_PAD (object);
1442-
1443- switch (prop_id)
1444- {
1445- case PROP_GROUP:
1446- g_value_set_pointer (value, pad->priv->group);
1447- break;
1448-
1449- case PROP_SETTINGS:
1450- g_value_set_pointer (value, pad->priv->settings);
1451- break;
1452-
1453- default:
1454- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1455- break;
1456- }
1457-}
1458-
1459-/* Class pad - initializer */
1460-static void
1461-xpad_pad_init (XpadPad *pad)
1462-{
1463- pad->priv = xpad_pad_get_instance_private (pad);
1464-
1465- pad->priv->x = 0;
1466- pad->priv->y = 0;
1467- pad->priv->location_valid = FALSE;
1468- pad->priv->infoname = NULL;
1469- pad->priv->contentname = NULL;
1470- pad->priv->textview = NULL;
1471- pad->priv->scrollbar = NULL;
1472- pad->priv->toolbar = NULL;
1473- pad->priv->toolbar_timeout = 0;
1474- pad->priv->toolbar_height = 0;
1475- pad->priv->toolbar_expanded = FALSE;
1476- pad->priv->toolbar_pad_resized = TRUE;
1477- pad->priv->properties = NULL;
1478- pad->priv->unsaved_content = FALSE;
1479- pad->priv->unsaved_info = FALSE;
1480-}
1481-
1482-static void xpad_pad_constructed (GObject *object)
1483-{
1484- XpadPad *pad = XPAD_PAD (object);
1485-
1486- gboolean decorations;
1487- GtkBox *vbox;
1488-
1489- g_object_get (pad->priv->settings,
1490- "width", &pad->priv->width,
1491- "height", &pad->priv->height,
1492- "autostart-sticky", &pad->priv->sticky, NULL);
1493-
1494- GtkWindow *pad_window = GTK_WINDOW (pad);
1495-
1496- pad->priv->textview = GTK_WIDGET (XPAD_TEXT_VIEW (xpad_text_view_new (pad->priv->settings, pad)));
1497-
1498- pad->priv->scrollbar = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
1499- "hadjustment", NULL,
1500- "hscrollbar-policy", GTK_POLICY_NEVER,
1501- "shadow-type", GTK_SHADOW_NONE,
1502- "vadjustment", NULL,
1503- "vscrollbar-policy", GTK_POLICY_NEVER,
1504- "child", pad->priv->textview,
1505- NULL));
1506-
1507- pad->priv->toolbar = GTK_WIDGET (xpad_toolbar_new (pad));
1508-
1509- pad->priv->accel_group = gtk_accel_group_new ();
1510- gtk_window_add_accel_group (pad_window, pad->priv->accel_group);
1511- pad->priv->menu = menu_get_popup_no_highlight (pad, pad->priv->accel_group);
1512- pad->priv->highlight_menu = menu_get_popup_highlight (pad, pad->priv->accel_group);
1513- gtk_accel_group_connect (pad->priv->accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0, g_cclosure_new_swap (G_CALLBACK (xpad_app_quit), pad, NULL));
1514-
1515- vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
1516- gtk_box_set_homogeneous (vbox, FALSE);
1517- gtk_box_pack_start (vbox, pad->priv->scrollbar, TRUE, TRUE, 0);
1518- gtk_box_pack_start (vbox, pad->priv->toolbar, FALSE, FALSE, 0);
1519-
1520- gtk_container_child_set (GTK_CONTAINER (vbox), pad->priv->toolbar, "expand", FALSE, NULL);
1521-
1522- g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL);
1523- gtk_window_set_decorated (pad_window, decorations);
1524- gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height);
1525- gtk_window_set_gravity (pad_window, GDK_GRAVITY_STATIC); /* static gravity makes saving pad x,y work */
1526- gtk_window_set_skip_pager_hint (pad_window, decorations);
1527- gtk_window_set_skip_taskbar_hint (pad_window, !decorations);
1528- gtk_window_set_position (pad_window, GTK_WIN_POS_MOUSE);
1529-
1530- g_object_set (G_OBJECT (pad), "child", vbox, NULL);
1531-
1532- xpad_pad_notify_has_scrollbar (pad);
1533- xpad_pad_notify_has_selection (pad);
1534- xpad_pad_notify_clipboard_owner_changed (pad);
1535- xpad_pad_notify_undo_redo_changed (pad);
1536-
1537- pad->priv->clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
1538-
1539- if (pad->priv->sticky)
1540- gtk_window_stick (pad_window);
1541- else
1542- gtk_window_unstick (pad_window);
1543-
1544+static void
1545+xpad_pad_sync_title (XpadPad *pad)
1546+{
1547+ GtkTextBuffer *buffer;
1548+ GtkTextIter s, e;
1549+ gchar *content, *end;
1550+
1551+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
1552+ gtk_text_buffer_get_bounds (buffer, &s, &e);
1553+ content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE);
1554+ end = g_utf8_strchr (content, -1, '\n');
1555+ if (end)
1556+ *end = '\0';
1557+
1558+ gtk_window_set_title (GTK_WINDOW (pad), g_strstrip (content));
1559+
1560+ g_free (content);
1561+}
1562+
1563+static void
1564+xpad_pad_text_changed (XpadPad *pad,
1565+ GtkTextBuffer *buffer)
1566+{
1567+ /* A dirty way to silence the compiler for these unused variables. */
1568+ (void) buffer;
1569+
1570+ /* set title */
1571 xpad_pad_sync_title (pad);
1572-
1573- gtk_widget_show_all (GTK_WIDGET (vbox));
1574-
1575- gtk_widget_hide (pad->priv->toolbar);
1576- xpad_pad_notify_has_toolbar (pad);
1577-
1578- /* Set up signals */
1579- gtk_widget_add_events (GTK_WIDGET (pad), GDK_BUTTON_PRESS_MASK | GDK_PROPERTY_CHANGE_MASK);
1580- gtk_widget_add_events (pad->priv->toolbar, GDK_ALL_EVENTS_MASK);
1581- g_signal_connect_swapped (pad->priv->textview, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), pad);
1582- g_signal_connect_swapped (pad->priv->textview, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), pad);
1583- g_signal_connect_swapped (pad->priv->toolbar, "size-allocate", G_CALLBACK (xpad_pad_toolbar_size_allocate), pad);
1584- g_signal_connect (pad, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), NULL);
1585- g_signal_connect (pad, "configure-event", G_CALLBACK (xpad_pad_configure_event), NULL);
1586- g_signal_connect (pad, "delete-event", G_CALLBACK (xpad_pad_delete_event), NULL);
1587- g_signal_connect (pad, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), NULL);
1588- g_signal_connect (pad, "show", G_CALLBACK (xpad_pad_show), NULL);
1589- g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "changed", G_CALLBACK (xpad_pad_text_changed), pad);
1590-
1591- g_signal_connect (pad, "enter-notify-event", G_CALLBACK (xpad_pad_enter_notify_event), NULL);
1592- g_signal_connect (pad, "leave-notify-event", G_CALLBACK (xpad_pad_leave_notify_event), NULL);
1593-
1594- g_signal_connect_swapped (pad->priv->settings, "notify::has-decorations", G_CALLBACK (xpad_pad_notify_has_decorations), pad);
1595- g_signal_connect_swapped (pad->priv->settings, "notify::has-toolbar", G_CALLBACK (xpad_pad_notify_has_toolbar), pad);
1596- g_signal_connect_swapped (pad->priv->settings, "notify::autohide-toolbar", G_CALLBACK (xpad_pad_notify_autohide_toolbar), pad);
1597- g_signal_connect_swapped (pad->priv->settings, "notify::has-scrollbar", G_CALLBACK (xpad_pad_notify_has_scrollbar), pad);
1598- g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "notify::has-selection", G_CALLBACK (xpad_pad_notify_has_selection), pad);
1599- g_signal_connect_swapped (pad->priv->clipboard, "owner-change", G_CALLBACK (xpad_pad_notify_clipboard_owner_changed), pad);
1600-
1601- g_signal_connect_swapped (pad->priv->toolbar, "activate-new", G_CALLBACK (xpad_pad_spawn), pad);
1602- g_signal_connect_swapped (pad->priv->toolbar, "activate-clear", G_CALLBACK (xpad_pad_clear), pad);
1603- g_signal_connect_swapped (pad->priv->toolbar, "activate-close", G_CALLBACK (xpad_pad_close), pad);
1604- g_signal_connect_swapped (pad->priv->toolbar, "activate-undo", G_CALLBACK (xpad_pad_undo), pad);
1605- g_signal_connect_swapped (pad->priv->toolbar, "activate-redo", G_CALLBACK (xpad_pad_redo), pad);
1606- g_signal_connect_swapped (pad->priv->toolbar, "activate-cut", G_CALLBACK (xpad_pad_cut), pad);
1607- g_signal_connect_swapped (pad->priv->toolbar, "activate-copy", G_CALLBACK (xpad_pad_copy), pad);
1608- g_signal_connect_swapped (pad->priv->toolbar, "activate-paste", G_CALLBACK (xpad_pad_paste), pad);
1609- g_signal_connect_swapped (pad->priv->toolbar, "activate-delete", G_CALLBACK (xpad_pad_delete), pad);
1610- g_signal_connect_swapped (pad->priv->toolbar, "activate-properties", G_CALLBACK (xpad_pad_open_properties), pad);
1611- g_signal_connect_swapped (pad->priv->toolbar, "activate-preferences", G_CALLBACK (xpad_pad_open_preferences), pad);
1612- g_signal_connect_swapped (pad->priv->toolbar, "activate-quit", G_CALLBACK (xpad_pad_close_all), pad);
1613-
1614- g_signal_connect_swapped (pad->priv->toolbar, "popup", G_CALLBACK (menu_popup), pad);
1615- g_signal_connect_swapped (pad->priv->toolbar, "popdown", G_CALLBACK (menu_popdown), pad);
1616-
1617- g_signal_connect_swapped (pad->priv->menu, "deactivate", G_CALLBACK (menu_popdown), pad);
1618- g_signal_connect_swapped (pad->priv->highlight_menu, "deactivate", G_CALLBACK (menu_popdown), pad);
1619-}
1620-
1621-static void
1622-xpad_pad_dispose (GObject *object)
1623-{
1624- XpadPad *pad = XPAD_PAD (object);
1625-
1626- if (pad->priv->group) {
1627- g_object_unref(pad->priv->group);
1628- pad->priv->group = NULL;
1629- }
1630-
1631- if (GTK_IS_WIDGET(pad->priv->menu)) {
1632- gtk_widget_destroy (pad->priv->menu);
1633- pad->priv->menu = NULL;
1634- }
1635-
1636- if (GTK_IS_WIDGET(pad->priv->highlight_menu)) {
1637- gtk_widget_destroy (pad->priv->highlight_menu);
1638- pad->priv->highlight_menu = NULL;
1639- }
1640-
1641- if (XPAD_IS_PAD_PROPERTIES (pad->priv->properties)) {
1642- gtk_widget_destroy (pad->priv->properties);
1643- pad->priv->properties = NULL;
1644- }
1645-
1646- gtk_clipboard_clear (pad->priv->clipboard);
1647-
1648- /* For some reason the toolbar handler does not get automatically disconnected (or not at the right moment), leading to errors after deleting a pad. This manual disconnect prevents this error. */
1649- if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) {
1650- g_signal_handlers_disconnect_matched (pad->priv->toolbar, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad);
1651- gtk_widget_destroy(pad->priv->toolbar);
1652- pad->priv->toolbar = NULL;
1653- }
1654-
1655- G_OBJECT_CLASS (xpad_pad_parent_class)->dispose (object);
1656-}
1657-
1658-static void
1659-xpad_pad_finalize (GObject *object)
1660-{
1661- XpadPad *pad = XPAD_PAD (object);
1662-
1663- if (pad->priv->settings) {
1664- g_signal_handlers_disconnect_matched (pad->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad);
1665- g_object_unref(pad->priv->settings);
1666- pad->priv->settings = NULL;
1667- }
1668-
1669- g_free (pad->priv->infoname);
1670- g_free (pad->priv->contentname);
1671-
1672- G_OBJECT_CLASS (xpad_pad_parent_class)->finalize (object);
1673-}
1674-
1675-static void
1676-xpad_pad_show (XpadPad *pad)
1677-{
1678- /*
1679- * Some wm's might not acknowledge our request for a specific
1680- * location before we are shown. What we do here is a little gimpy
1681- * and not very respectful of wms' sovereignty, but it has the effect
1682- * of making pads' locations very dependable. We just move the pad
1683- * again here after being shown. This may create a visual effect if
1684- * the wm did ignore us, but is better than being in the wrong
1685- * place, I guess.
1686- */
1687- if (pad->priv->location_valid)
1688- gtk_window_move (GTK_WINDOW (pad), pad->priv->x, pad->priv->y);
1689-
1690- if (pad->priv->sticky)
1691- gtk_window_stick (GTK_WINDOW (pad));
1692- else
1693- gtk_window_unstick (GTK_WINDOW (pad));
1694-}
1695-
1696-static gboolean toolbar_timeout (XpadPad *pad)
1697-{
1698- if (!pad || !pad->priv || !pad->priv->toolbar_timeout)
1699- return FALSE;
1700-
1701- gboolean has_toolbar, autohide_toolbar;
1702- g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
1703-
1704- if (pad->priv->toolbar_timeout && autohide_toolbar && has_toolbar)
1705- xpad_pad_hide_toolbar (pad);
1706-
1707- pad->priv->toolbar_timeout = 0;
1708-
1709- return FALSE;
1710-}
1711-
1712-static void
1713-xpad_pad_notify_has_decorations (XpadPad *pad)
1714-{
1715- GtkWidget *pad_widget = GTK_WIDGET (pad);
1716- GtkWindow *pad_window = GTK_WINDOW (pad);
1717- gboolean decorations;
1718- g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL);
1719-
1720- /* Update pad menu with the new status */
1721- GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-decorations");
1722- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), decorations);
1723-
1724- /*
1725- * There are two modes of operation: a normal mode and a 'stealth' mode.
1726- * If decorations are disabled, we also don't show up in the taskbar or pager.
1727- */
1728- gtk_window_set_decorated (pad_window, decorations);
1729- gtk_window_set_skip_taskbar_hint (pad_window, !decorations);
1730- gtk_window_set_skip_pager_hint (pad_window, !decorations);
1731-
1732- /*
1733- * reshow_with_initial_size() seems to set the window back to a never-shown state.
1734- * This is good, as some WMs don't like us changing the above parameters mid-run,
1735- * even if we do a hide/show cycle.
1736- */
1737- gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height);
1738- gtk_widget_hide (pad_widget);
1739- gtk_widget_unrealize (pad_widget);
1740- gtk_widget_show (pad_widget);
1741-}
1742-
1743-static void
1744-xpad_pad_notify_has_toolbar (XpadPad *pad)
1745-{
1746- gboolean has_toolbar, autohide_toolbar;
1747- g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
1748-
1749- /* Update pad menu with the new status */
1750- GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-toolbar");
1751- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_toolbar);
1752- menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar");
1753- gtk_widget_set_sensitive (menu_item, has_toolbar);
1754-
1755- if (has_toolbar && !autohide_toolbar)
1756- xpad_pad_show_toolbar (pad);
1757- else
1758- xpad_pad_hide_toolbar (pad);
1759-}
1760-
1761-static void
1762-xpad_pad_notify_autohide_toolbar (XpadPad *pad)
1763-{
1764- gboolean autohide_toolbar;
1765- g_object_get (pad->priv->settings, "autohide-toolbar", &autohide_toolbar, NULL);
1766-
1767- /* Update pad menu with the new status */
1768- GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar");
1769- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), autohide_toolbar);
1770-
1771- if (autohide_toolbar)
1772- {
1773- /* Likely not to be in pad when turning setting on */
1774- if (!pad->priv->toolbar_timeout)
1775- pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
1776- }
1777- else
1778- {
1779- gboolean has_toolbar;
1780- g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, NULL);
1781-
1782- if (has_toolbar)
1783- xpad_pad_show_toolbar(pad);
1784- }
1785-}
1786-
1787-static void
1788-xpad_pad_notify_has_scrollbar (XpadPad *pad)
1789-{
1790- gboolean has_scrollbar;
1791- g_object_get (pad->priv->settings, "has-scrollbar", &has_scrollbar, NULL);
1792-
1793- /* Update pad menu with the new status */
1794- GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-scrollbar");
1795- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_scrollbar);
1796-
1797- if (has_scrollbar)
1798- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar),
1799- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1800- else
1801- {
1802- GtkAdjustment *v, *h;
1803-
1804- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar),
1805- GTK_POLICY_NEVER, GTK_POLICY_NEVER);
1806-
1807- /* now we need to adjust view so that user can see whole pad */
1808- h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar));
1809- v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar));
1810-
1811- gtk_adjustment_set_value (h, 0);
1812- gtk_adjustment_set_value (v, 0);
1813- }
1814+
1815+ /* record change */
1816+ xpad_pad_save_content_delayed(pad);
1817+}
1818+
1819+void
1820+xpad_pad_load_content (XpadPad *pad)
1821+{
1822+ g_return_if_fail (pad);
1823+
1824+ gchar *content;
1825+ GtkTextBuffer *buffer;
1826+
1827+ if (!pad->priv->contentname)
1828+ return;
1829+
1830+ content = fio_get_file (pad->priv->contentname);
1831+
1832+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
1833+
1834+ xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer));
1835+ g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad);
1836+
1837+ xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : "");
1838+ g_free (content);
1839+
1840+ g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad);
1841+ xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer));
1842+
1843+ xpad_pad_text_changed(pad, buffer);
1844+ pad->priv->unsaved_content = FALSE;
1845+}
1846+
1847+void
1848+xpad_pad_save_content (XpadPad *pad)
1849+{
1850+ g_return_if_fail (pad);
1851+
1852+ gchar *content;
1853+ GtkTextBuffer *buffer;
1854+
1855+ if (!pad->priv->unsaved_content)
1856+ return;
1857+
1858+ /* create content file if it doesn't exist yet */
1859+ if (!pad->priv->contentname)
1860+ {
1861+ pad->priv->contentname = fio_unique_name ("content-");
1862+ if (!pad->priv->contentname)
1863+ return;
1864+ }
1865+
1866+ if (GTK_IS_TEXT_VIEW(pad->priv->textview)) {
1867+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
1868+ content = xpad_text_buffer_get_text_with_tags (XPAD_TEXT_BUFFER (buffer));
1869+ }
1870+ else
1871+ g_warning("There is a problem in the program Xpad. In function 'xpad_pad_save_content' the variable 'pad->priv->textview' is not of type textview. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
1872+
1873+ fio_set_file (pad->priv->contentname, content);
1874+
1875+ pad->priv->unsaved_content = FALSE;
1876+ g_free (content);
1877 }
1878
1879 static guint
1880@@ -629,6 +227,28 @@
1881 }
1882
1883 static void
1884+xpad_pad_hide_toolbar (XpadPad *pad)
1885+{
1886+ if (gtk_widget_get_visible (pad->priv->toolbar))
1887+ {
1888+ GtkWidget *pad_widget = GTK_WIDGET (pad);
1889+ if (gtk_widget_get_window (pad_widget))
1890+ gdk_window_freeze_updates (gtk_widget_get_window (pad_widget));
1891+ gtk_widget_hide (pad->priv->toolbar);
1892+
1893+ if (pad->priv->toolbar_expanded ||
1894+ (pad->priv->toolbar_pad_resized && xpad_pad_text_and_toolbar_height (pad) >= pad->priv->height))
1895+ {
1896+ pad->priv->height -= pad->priv->toolbar_height;
1897+ gtk_window_resize (GTK_WINDOW (pad), (gint) pad->priv->width, (gint) pad->priv->height);
1898+ pad->priv->toolbar_expanded = FALSE;
1899+ }
1900+ if (gtk_widget_get_window (pad_widget))
1901+ gdk_window_thaw_updates (gtk_widget_get_window (pad_widget));
1902+ }
1903+}
1904+
1905+static void
1906 xpad_pad_show_toolbar (XpadPad *pad)
1907 {
1908 if (!gtk_widget_get_visible (pad->priv->toolbar))
1909@@ -669,558 +289,10 @@
1910 }
1911 }
1912
1913-static void
1914-xpad_pad_hide_toolbar (XpadPad *pad)
1915-{
1916- if (gtk_widget_get_visible (pad->priv->toolbar))
1917- {
1918- GtkWidget *pad_widget = GTK_WIDGET (pad);
1919- if (gtk_widget_get_window (pad_widget))
1920- gdk_window_freeze_updates (gtk_widget_get_window (pad_widget));
1921- gtk_widget_hide (pad->priv->toolbar);
1922-
1923- if (pad->priv->toolbar_expanded ||
1924- (pad->priv->toolbar_pad_resized && xpad_pad_text_and_toolbar_height (pad) >= pad->priv->height))
1925- {
1926- pad->priv->height -= pad->priv->toolbar_height;
1927- gtk_window_resize (GTK_WINDOW (pad), (gint) pad->priv->width, (gint) pad->priv->height);
1928- pad->priv->toolbar_expanded = FALSE;
1929- }
1930- if (gtk_widget_get_window (pad_widget))
1931- gdk_window_thaw_updates (gtk_widget_get_window (pad_widget));
1932- }
1933-}
1934-
1935-void
1936-xpad_pad_notify_has_selection (XpadPad *pad)
1937-{
1938- g_return_if_fail (pad);
1939-
1940- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
1941- gboolean has_selection = gtk_text_buffer_get_has_selection (buffer);
1942-
1943- XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
1944- if (toolbar == NULL)
1945- return;
1946-
1947- xpad_toolbar_enable_cut_button (toolbar, has_selection);
1948- xpad_toolbar_enable_copy_button (toolbar, has_selection);
1949-}
1950-
1951-void
1952-xpad_pad_notify_clipboard_owner_changed (XpadPad *pad)
1953-{
1954- g_return_if_fail (pad);
1955-
1956- /* safe cast to toolbar */
1957- if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) {
1958- XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
1959- g_return_if_fail (toolbar);
1960-
1961- GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
1962- xpad_toolbar_enable_paste_button (toolbar, gtk_clipboard_wait_is_text_available (clipboard));
1963- }
1964-}
1965-
1966-void
1967-xpad_pad_notify_undo_redo_changed (XpadPad *pad)
1968-{
1969- g_return_if_fail (pad);
1970-
1971- XpadTextBuffer *buffer = NULL;
1972- buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
1973- g_return_if_fail (buffer);
1974-
1975- XpadToolbar *toolbar = NULL;
1976- toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
1977- g_return_if_fail (toolbar);
1978-
1979- xpad_toolbar_enable_undo_button (toolbar, xpad_text_buffer_undo_available (buffer));
1980- xpad_toolbar_enable_redo_button (toolbar, xpad_text_buffer_redo_available (buffer));
1981-}
1982-
1983-static gboolean
1984-xpad_pad_enter_notify_event (GtkWidget *pad, GdkEventCrossing *event)
1985-{
1986- gboolean has_toolbar, autohide_toolbar;
1987- g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
1988-
1989- if (has_toolbar && autohide_toolbar &&
1990- event->detail != GDK_NOTIFY_INFERIOR &&
1991- event->mode == GDK_CROSSING_NORMAL)
1992- {
1993- XPAD_PAD (pad)->priv->toolbar_timeout = 0;
1994- xpad_pad_show_toolbar (XPAD_PAD (pad));
1995- }
1996-
1997- return FALSE;
1998-}
1999-
2000-static gboolean
2001-xpad_pad_leave_notify_event (GtkWidget *pad, GdkEventCrossing *event)
2002-{
2003- gboolean has_toolbar, autohide_toolbar;
2004- g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
2005-
2006- if (has_toolbar && autohide_toolbar &&
2007- event->detail != GDK_NOTIFY_INFERIOR &&
2008- event->mode == GDK_CROSSING_NORMAL)
2009- {
2010- if (!XPAD_PAD (pad)->priv->toolbar_timeout)
2011- XPAD_PAD (pad)->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
2012- }
2013-
2014- return FALSE;
2015-}
2016-
2017-static void
2018-xpad_pad_spawn (XpadPad *pad)
2019-{
2020- GtkWidget *newpad = xpad_pad_new (pad->priv->group, pad->priv->settings);
2021- gtk_widget_show (newpad);
2022-}
2023-
2024-static void
2025-xpad_pad_clear (XpadPad *pad)
2026-{
2027- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2028- gtk_text_buffer_set_text (buffer, "", -1);
2029-}
2030-
2031-void
2032-xpad_pad_close (XpadPad *pad)
2033-{
2034- gtk_widget_hide (GTK_WIDGET (pad));
2035-
2036- /*
2037- * If no tray and this is the last pad, we don't want to record this
2038- * pad as closed, we want to start with just this pad next open. So
2039- * quit before we record.
2040- */
2041- if (!xpad_tray_is_open () &&
2042- xpad_pad_group_num_visible_pads (pad->priv->group) == 0)
2043- {
2044- xpad_app_quit ();
2045- return;
2046- }
2047-
2048- if (pad->priv->properties)
2049- gtk_widget_destroy (pad->priv->properties);
2050-
2051- xpad_pad_save_info (pad);
2052-
2053- g_signal_emit (pad, signals[CLOSED], 0);
2054-}
2055-
2056-void
2057-xpad_pad_toggle(XpadPad *pad)
2058-{
2059- if (gtk_widget_get_visible (GTK_WIDGET(pad)))
2060- xpad_pad_close (pad);
2061- else
2062- gtk_widget_show (GTK_WIDGET (pad));
2063-}
2064-
2065-static gboolean
2066-should_confirm_delete (XpadPad *pad)
2067-{
2068- GtkTextBuffer *buffer;
2069- GtkTextIter s, e;
2070- gchar *content;
2071- gboolean confirm;
2072-
2073- g_object_get (pad->priv->settings, "confirm-destroy", &confirm, NULL);
2074- if (!confirm)
2075- return FALSE;
2076-
2077- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2078- gtk_text_buffer_get_bounds (buffer, &s, &e);
2079- content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE);
2080-
2081- confirm = strcmp (g_strstrip (content), "") != 0;
2082-
2083- g_free (content);
2084-
2085- return confirm;
2086-}
2087-
2088-static void
2089-xpad_pad_delete (XpadPad *pad)
2090-{
2091- g_return_if_fail (pad);
2092-
2093- /* With the delayed saving functionality, it is necessary to clear the unsaved flags to prevent usage of non-existing object information. */
2094- pad->priv->unsaved_info = FALSE;
2095- pad->priv->unsaved_content = FALSE;
2096-
2097- if (should_confirm_delete (pad))
2098- {
2099- GtkWidget *dialog;
2100- gint response;
2101-
2102- dialog = xpad_app_alert_dialog (GTK_WINDOW (pad), "dialog-warning", _("Delete this pad?"), _("All text of this pad will be irrevocably lost."));
2103-
2104- if (!dialog)
2105- return;
2106-
2107- gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Delete"), GTK_RESPONSE_ACCEPT, _("_Cancel"), GTK_RESPONSE_REJECT, NULL);
2108-
2109- response = gtk_dialog_run (GTK_DIALOG (dialog));
2110-
2111- gtk_widget_destroy (dialog);
2112-
2113- if (response != GTK_RESPONSE_ACCEPT)
2114- return;
2115- }
2116-
2117- /* These two if statements actually erase the pad on the harddisk. */
2118- if (pad->priv->infoname)
2119- fio_remove_file (pad->priv->infoname);
2120- if (pad->priv->contentname)
2121- fio_remove_file (pad->priv->contentname);
2122-
2123- /* Remove the pad from the group and destroy it. */
2124- gtk_widget_destroy (GTK_WIDGET (pad));
2125-}
2126-
2127-static void
2128-pad_properties_sync_title (XpadPad *pad)
2129-{
2130- gchar *title;
2131-
2132- if (!pad->priv->properties)
2133- return;
2134-
2135- title = g_strdup_printf (_("'%s' Properties"), gtk_window_get_title (GTK_WINDOW (pad)));
2136- gtk_window_set_title (GTK_WINDOW (pad->priv->properties), title);
2137- g_free (title);
2138-}
2139-
2140-static void
2141-pad_properties_destroyed (XpadPad *pad)
2142-{
2143- if (!pad->priv->properties)
2144- return;
2145-
2146- g_signal_handlers_disconnect_by_func (pad, (gpointer) pad_properties_sync_title, NULL);
2147- pad->priv->properties = NULL;
2148-}
2149-
2150-static void
2151-prop_notify_font (XpadPad *pad)
2152-{
2153- XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties);
2154-
2155- gboolean follow_font_style;
2156- g_object_get (prop, "follow-font-style", &follow_font_style, NULL);
2157- g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", follow_font_style, NULL);
2158-
2159- if (!follow_font_style)
2160- {
2161- const gchar *font;
2162- g_object_get (prop, "fontname", &font, NULL);
2163- PangoFontDescription *fontdesc;
2164-
2165- fontdesc = font ? pango_font_description_from_string (font) : NULL;
2166- gtk_widget_override_font (pad->priv->textview, fontdesc);
2167- if (fontdesc)
2168- pango_font_description_free (fontdesc);
2169- }
2170-
2171- xpad_pad_save_info_delayed (pad);
2172-}
2173-
2174-static void
2175-prop_notify_colors (XpadPad *pad)
2176-{
2177- XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties);
2178-
2179- gboolean follow_color_style;
2180- const GdkRGBA *text_color, *back_color;
2181-
2182- g_object_get (prop, "follow-color-style", &follow_color_style, NULL);
2183- g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-color-style", follow_color_style, NULL);
2184-
2185- if (follow_color_style)
2186- /* Set the colors to the global preferences colors */
2187- g_object_get (pad->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL);
2188- else
2189- /* Set the color to the individual pad properties colors */
2190- g_object_get (prop, "text-color", &text_color, "back-color", &back_color, NULL);
2191-
2192- gtk_widget_override_cursor (pad->priv->textview, text_color, text_color);
2193- gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, text_color);
2194- gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, back_color);
2195-
2196- /* Inverse the text and background colors for selected text, so it is likely to be visible by any choice of the colors. */
2197- gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, back_color);
2198- gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, text_color);
2199-
2200- xpad_pad_save_info_delayed (pad);
2201-}
2202-
2203-static void
2204-xpad_pad_open_properties (XpadPad *pad)
2205-{
2206- gboolean follow_font_style, follow_color_style;
2207- GtkStyleContext *style = NULL;
2208- PangoFontDescription *font;
2209- GdkRGBA widget_text_color = {0, 0, 0, 0};
2210- GdkRGBA widget_background_color = {0, 0, 0, 0};
2211-
2212- if (pad->priv->properties)
2213- {
2214- gtk_window_present (GTK_WINDOW (pad->priv->properties));
2215- return;
2216- }
2217-
2218- pad->priv->properties = xpad_pad_properties_new ();
2219-
2220- gtk_window_set_transient_for (GTK_WINDOW (pad->priv->properties), GTK_WINDOW (pad));
2221- gtk_window_set_resizable (GTK_WINDOW (pad->priv->properties), FALSE);
2222-
2223- g_signal_connect_swapped (pad->priv->properties, "destroy", G_CALLBACK (pad_properties_destroyed), pad);
2224- g_signal_connect (pad, "notify::title", G_CALLBACK (pad_properties_sync_title), NULL);
2225-
2226- style = gtk_widget_get_style_context (pad->priv->textview);
2227- gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL);
2228- gtk_style_context_get_color (style, GTK_STATE_FLAG_NORMAL, &widget_text_color);
2229- gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &widget_background_color);
2230-
2231- g_object_get (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", &follow_font_style, "follow-color-style", &follow_color_style, NULL);
2232- g_object_set (G_OBJECT (pad->priv->properties),
2233- "follow-font-style", follow_font_style,
2234- "follow-color-style", follow_color_style,
2235- "text-color", &widget_text_color,
2236- "back-color", &widget_background_color,
2237- "fontname", pango_font_description_to_string(font),
2238- NULL);
2239- pango_font_description_free (font);
2240-
2241- g_signal_connect_swapped (pad->priv->properties, "notify::follow-font-style", G_CALLBACK (prop_notify_font), pad);
2242- g_signal_connect_swapped (pad->priv->properties, "notify::follow-color-style", G_CALLBACK (prop_notify_colors), pad);
2243- g_signal_connect_swapped (pad->priv->properties, "notify::text-color", G_CALLBACK (prop_notify_colors), pad);
2244- g_signal_connect_swapped (pad->priv->properties, "notify::back-color", G_CALLBACK (prop_notify_colors), pad);
2245- g_signal_connect_swapped (pad->priv->properties, "notify::fontname", G_CALLBACK (prop_notify_font), pad);
2246-
2247- pad_properties_sync_title (pad);
2248-
2249- gtk_widget_show (pad->priv->properties);
2250-}
2251-
2252-static void
2253-xpad_pad_open_preferences (XpadPad *pad)
2254-{
2255- xpad_preferences_open (pad->priv->settings);
2256-}
2257-
2258-static void
2259-xpad_pad_text_changed (XpadPad *pad, GtkTextBuffer *buffer)
2260-{
2261- /* A dirty way to silence the compiler for these unused variables. */
2262- (void) buffer;
2263-
2264- /* set title */
2265- xpad_pad_sync_title (pad);
2266-
2267- /* record change */
2268- xpad_pad_save_content_delayed(pad);
2269-}
2270-
2271-static gboolean
2272-xpad_pad_toolbar_size_allocate (XpadPad *pad, GtkAllocation *event)
2273-{
2274- /* safe cast from gint to guint */
2275- if (event->height >= 0) {
2276- pad->priv->toolbar_height = (guint) event->height;
2277- }
2278- else {
2279- g_warning("There is a problem in the program Xpad. In function 'xpad_pad_toolbar_size_allocate' the variable 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
2280- pad->priv->toolbar_height = 0;
2281- }
2282- return FALSE;
2283-}
2284-
2285-static gboolean
2286-xpad_pad_configure_event (XpadPad *pad, GdkEventConfigure *event)
2287-{
2288- if (!gtk_widget_get_visible (GTK_WIDGET(pad)))
2289- return FALSE;
2290-
2291- int eWidth = event->width;
2292- int eHeight = event->height;
2293-
2294- /* safe cast from gint to guint */
2295- if (eWidth >= 0 && eHeight >=0 ) {
2296- if (pad->priv->width != (guint) eWidth || pad->priv->height != (guint) eHeight)
2297- pad->priv->toolbar_pad_resized = TRUE;
2298-
2299- pad->priv->width = (guint) event->width;
2300- pad->priv->height = (guint) event->height;
2301- }
2302- else {
2303- g_warning("There is a problem in the program Xpad. In function 'xpad_pad_configure_event' the variable 'event->width' or 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
2304- }
2305-
2306- pad->priv->x = event->x;
2307- pad->priv->y = event->y;
2308- pad->priv->location_valid = TRUE;
2309-
2310- xpad_pad_save_info_delayed(pad);
2311-
2312- /*
2313- * Sometimes when moving, if the toolbar tries to hide itself,
2314- * the window manager will not resize it correctly. So, we make
2315- * sure not to end the timeout while moving.
2316- */
2317- if (pad->priv->toolbar_timeout)
2318- {
2319- g_source_remove (pad->priv->toolbar_timeout);
2320- pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
2321- }
2322-
2323- return FALSE;
2324-}
2325-
2326-static gboolean
2327-xpad_pad_delete_event (XpadPad *pad, GdkEvent *event)
2328-{
2329- /* A dirty way to silence the compiler for these unused variables. */
2330- (void) event;
2331-
2332- xpad_pad_close (pad);
2333-
2334- return TRUE;
2335-}
2336-
2337-static gboolean
2338-xpad_pad_popup_menu (XpadPad *pad)
2339-{
2340- xpad_pad_popup (pad, NULL);
2341-
2342- return TRUE;
2343-}
2344-
2345-static gboolean
2346-xpad_pad_button_press_event (XpadPad *pad, GdkEventButton *event)
2347-{
2348- if (event->type == GDK_BUTTON_PRESS)
2349- {
2350- switch (event->button)
2351- {
2352- case 1:
2353- if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK)
2354- {
2355- gtk_window_begin_move_drag (GTK_WINDOW (pad), (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time);
2356- return TRUE;
2357- }
2358- break;
2359-
2360- case 3:
2361- if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK)
2362- {
2363- GdkWindowEdge edge;
2364-
2365- if (gtk_widget_get_direction (GTK_WIDGET (pad)) == GTK_TEXT_DIR_LTR)
2366- edge = GDK_WINDOW_EDGE_SOUTH_EAST;
2367- else
2368- edge = GDK_WINDOW_EDGE_SOUTH_WEST;
2369-
2370- gtk_window_begin_resize_drag (GTK_WINDOW (pad), edge, (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time);
2371- }
2372- else
2373- {
2374- xpad_pad_popup (pad, event);
2375- }
2376- return TRUE;
2377- }
2378- }
2379-
2380- return FALSE;
2381-}
2382-
2383-static void
2384-xpad_pad_sync_title (XpadPad *pad)
2385-{
2386- GtkTextBuffer *buffer;
2387- GtkTextIter s, e;
2388- gchar *content, *end;
2389-
2390- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2391- gtk_text_buffer_get_bounds (buffer, &s, &e);
2392- content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE);
2393- end = g_utf8_strchr (content, -1, '\n');
2394- if (end)
2395- *end = '\0';
2396-
2397- gtk_window_set_title (GTK_WINDOW (pad), g_strstrip (content));
2398-
2399- g_free (content);
2400-}
2401-
2402-void
2403-xpad_pad_load_content (XpadPad *pad)
2404-{
2405- g_return_if_fail (pad);
2406-
2407- gchar *content;
2408- GtkTextBuffer *buffer;
2409-
2410- if (!pad->priv->contentname)
2411- return;
2412-
2413- content = fio_get_file (pad->priv->contentname);
2414-
2415- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2416-
2417- xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer));
2418- g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad);
2419-
2420- xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : "");
2421- g_free (content);
2422-
2423- g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad);
2424- xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer));
2425-
2426- xpad_pad_text_changed(pad, buffer);
2427- pad->priv->unsaved_content = FALSE;
2428-}
2429-
2430-void
2431-xpad_pad_save_content (XpadPad *pad)
2432-{
2433- g_return_if_fail (pad);
2434-
2435- gchar *content;
2436- GtkTextBuffer *buffer;
2437-
2438- if (!pad->priv->unsaved_content)
2439- return;
2440-
2441- /* create content file if it doesn't exist yet */
2442- if (!pad->priv->contentname)
2443- {
2444- pad->priv->contentname = fio_unique_name ("content-");
2445- if (!pad->priv->contentname)
2446- return;
2447- }
2448-
2449- if (GTK_IS_TEXT_VIEW(pad->priv->textview)) {
2450- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2451- content = xpad_text_buffer_get_text_with_tags (XPAD_TEXT_BUFFER (buffer));
2452- }
2453- else
2454- g_warning("There is a problem in the program Xpad. In function 'xpad_pad_save_content' the variable 'pad->priv->textview' is not of type textview. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
2455-
2456- fio_set_file (pad->priv->contentname, content);
2457-
2458- pad->priv->unsaved_content = FALSE;
2459- g_free (content);
2460-}
2461-
2462 /* Extract all the metadata of a single pad from its info-xxxxx file and store it in the pad object */
2463 static void
2464-xpad_pad_load_info (XpadPad *pad, gboolean *show)
2465+xpad_pad_load_info (XpadPad *pad,
2466+ gboolean *show)
2467 {
2468 gboolean locked = FALSE, follow_font = TRUE, follow_color = TRUE, hidden = FALSE;
2469 gboolean has_toolbar, autohide_toolbar;
2470@@ -1406,29 +478,142 @@
2471 pad->priv->unsaved_info = FALSE;
2472 }
2473
2474-static void
2475-menu_about (XpadPad *pad)
2476-{
2477- const gchar *artists[] = {"Michael Terry <mike@mterry.name>", NULL};
2478- const gchar *authors[] = {"Arthur Borsboom <arthurborsboom@gmail.com>", "Jeroen Vermeulen <jtv@xs4all.nl>", "Michael Terry <mike@mterry.name>", "Paul Ivanov <pivanov@berkeley.edu>", "Sachin Raut <great.sachin@gmail.com>", NULL};
2479- const gchar *comments = _("Sticky notes");
2480- const gchar *copyright = "© 2001-2014 Michael Terry";
2481- /* Translators: please translate this as your own name and optionally email
2482- like so: "Your Name <your@email.com>" */
2483- const gchar *translator_credits = _("translator-credits");
2484- const gchar *website = "https://launchpad.net/xpad";
2485-
2486- gtk_show_about_dialog (GTK_WINDOW (pad),
2487- "artists", artists,
2488- "authors", authors,
2489- "comments", comments,
2490- "copyright", copyright,
2491- "license-type", GTK_LICENSE_GPL_3_0,
2492- "logo-icon-name", PACKAGE,
2493- "translator-credits", translator_credits,
2494- "version", VERSION,
2495- "website", website,
2496- NULL);
2497+/* Create a new pad based on the provided info-xxxxx file from the config directory and return this pad */
2498+GtkWidget *
2499+xpad_pad_new_with_info (XpadPadGroup *group,
2500+ XpadSettings *settings,
2501+ const gchar *info_filename,
2502+ gboolean *show)
2503+{
2504+ GtkWidget *pad = xpad_pad_new (group, settings);
2505+
2506+ XPAD_PAD (pad)->priv->infoname = g_strdup (info_filename);
2507+ xpad_pad_load_info (XPAD_PAD (pad), show);
2508+ xpad_pad_load_content (XPAD_PAD (pad));
2509+ gtk_window_set_role (GTK_WINDOW (pad), XPAD_PAD (pad)->priv->infoname);
2510+
2511+ return pad;
2512+}
2513+
2514+/* Create a new pad based on the provided filename from the command line */
2515+GtkWidget *
2516+xpad_pad_new_from_file (XpadPadGroup *group,
2517+ XpadSettings *settings,
2518+ const gchar *filename)
2519+{
2520+ GtkWidget *pad = NULL;
2521+ gchar *content;
2522+
2523+ content = fio_get_file (filename);
2524+
2525+ if (!content)
2526+ {
2527+ gchar *usertext = g_strdup_printf (_("Could not read file %s."), filename);
2528+ xpad_app_error (NULL, usertext, NULL);
2529+ g_free (usertext);
2530+ }
2531+ else
2532+ {
2533+ GtkTextBuffer *buffer;
2534+
2535+ xpad_periodic_init ();
2536+ xpad_periodic_set_callback ("save-content", (XpadPeriodicFunc) xpad_pad_save_content);
2537+
2538+ pad = xpad_pad_new (group, settings);
2539+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (XPAD_PAD (pad)->priv->textview));
2540+
2541+ xpad_text_buffer_freeze_undo (XPAD_TEXT_BUFFER (buffer));
2542+ g_signal_handlers_block_by_func (buffer, xpad_pad_text_changed, pad);
2543+
2544+ xpad_text_buffer_set_text_with_tags (XPAD_TEXT_BUFFER (buffer), content ? content : "");
2545+ g_free (content);
2546+
2547+ g_signal_handlers_unblock_by_func (buffer, xpad_pad_text_changed, pad);
2548+ xpad_text_buffer_thaw_undo (XPAD_TEXT_BUFFER (buffer));
2549+
2550+ xpad_pad_text_changed(XPAD_PAD(pad), buffer);
2551+ }
2552+
2553+ return pad;
2554+}
2555+
2556+static void
2557+xpad_pad_set_property (GObject *object,
2558+ guint prop_id,
2559+ const GValue *value,
2560+ GParamSpec *pspec)
2561+{
2562+ XpadPad *pad = XPAD_PAD (object);
2563+
2564+ switch (prop_id)
2565+ {
2566+ case PROP_GROUP:
2567+ pad->priv->group = g_value_get_pointer (value);
2568+ g_object_ref (pad->priv->group);
2569+ if (pad->priv->group)
2570+ xpad_pad_group_add (pad->priv->group, GTK_WIDGET (pad));
2571+ break;
2572+
2573+ case PROP_SETTINGS:
2574+ pad->priv->settings = g_value_get_pointer (value);
2575+ g_object_ref (pad->priv->settings);
2576+ break;
2577+
2578+ default:
2579+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2580+ break;
2581+ }
2582+}
2583+
2584+static void
2585+xpad_pad_get_property (GObject *object,
2586+ guint prop_id,
2587+ GValue *value,
2588+ GParamSpec *pspec)
2589+{
2590+ XpadPad *pad = XPAD_PAD (object);
2591+
2592+ switch (prop_id)
2593+ {
2594+ case PROP_GROUP:
2595+ g_value_set_pointer (value, pad->priv->group);
2596+ break;
2597+
2598+ case PROP_SETTINGS:
2599+ g_value_set_pointer (value, pad->priv->settings);
2600+ break;
2601+
2602+ default:
2603+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2604+ break;
2605+ }
2606+}
2607+
2608+static void
2609+xpad_pad_spawn (XpadPad *pad)
2610+{
2611+ GtkWidget *newpad = xpad_pad_new (pad->priv->group, pad->priv->settings);
2612+ gtk_widget_show (newpad);
2613+}
2614+
2615+static void
2616+xpad_pad_undo (XpadPad *pad)
2617+{
2618+ g_return_if_fail (pad->priv->textview);
2619+ XpadTextBuffer *buffer = NULL;
2620+ buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
2621+ g_return_if_fail (buffer);
2622+ xpad_text_buffer_undo (buffer);
2623+}
2624+
2625+static void
2626+xpad_pad_redo (XpadPad *pad)
2627+{
2628+ g_return_if_fail (pad->priv->textview);
2629+ XpadTextBuffer *buffer = NULL;
2630+ buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
2631+ g_return_if_fail (buffer);
2632+ xpad_text_buffer_redo (buffer);
2633 }
2634
2635 static void
2636@@ -1459,26 +644,6 @@
2637 }
2638
2639 static void
2640-xpad_pad_undo (XpadPad *pad)
2641-{
2642- g_return_if_fail (pad->priv->textview);
2643- XpadTextBuffer *buffer = NULL;
2644- buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
2645- g_return_if_fail (buffer);
2646- xpad_text_buffer_undo (buffer);
2647-}
2648-
2649-static void
2650-xpad_pad_redo (XpadPad *pad)
2651-{
2652- g_return_if_fail (pad->priv->textview);
2653- XpadTextBuffer *buffer = NULL;
2654- buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
2655- g_return_if_fail (buffer);
2656- xpad_text_buffer_redo (buffer);
2657-}
2658-
2659-static void
2660 xpad_pad_show_all (XpadPad *pad)
2661 {
2662 xpad_pad_group_show_all (pad->priv->group);
2663@@ -1502,8 +667,202 @@
2664 xpad_app_quit ();
2665 }
2666
2667-static void
2668-menu_toggle_tag (XpadPad *pad, const gchar *name)
2669+static gboolean
2670+should_confirm_delete (XpadPad *pad)
2671+{
2672+ GtkTextBuffer *buffer;
2673+ GtkTextIter s, e;
2674+ gchar *content;
2675+ gboolean confirm;
2676+
2677+ g_object_get (pad->priv->settings, "confirm-destroy", &confirm, NULL);
2678+ if (!confirm)
2679+ return FALSE;
2680+
2681+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
2682+ gtk_text_buffer_get_bounds (buffer, &s, &e);
2683+ content = gtk_text_buffer_get_text (buffer, &s, &e, FALSE);
2684+
2685+ confirm = strcmp (g_strstrip (content), "") != 0;
2686+
2687+ g_free (content);
2688+
2689+ return confirm;
2690+}
2691+
2692+static void
2693+xpad_pad_delete (XpadPad *pad)
2694+{
2695+ g_return_if_fail (pad);
2696+
2697+ /* With the delayed saving functionality, it is necessary to clear the unsaved flags to prevent usage of non-existing object information. */
2698+ pad->priv->unsaved_info = FALSE;
2699+ pad->priv->unsaved_content = FALSE;
2700+
2701+ if (should_confirm_delete (pad))
2702+ {
2703+ GtkWidget *dialog;
2704+ gint response;
2705+
2706+ dialog = xpad_app_alert_dialog (GTK_WINDOW (pad), "dialog-warning", _("Delete this pad?"), _("All text of this pad will be irrevocably lost."));
2707+
2708+ if (!dialog)
2709+ return;
2710+
2711+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), _("_Delete"), GTK_RESPONSE_ACCEPT, _("_Cancel"), GTK_RESPONSE_REJECT, NULL);
2712+
2713+ response = gtk_dialog_run (GTK_DIALOG (dialog));
2714+
2715+ gtk_widget_destroy (dialog);
2716+
2717+ if (response != GTK_RESPONSE_ACCEPT)
2718+ return;
2719+ }
2720+
2721+ /* These two if statements actually erase the pad on the harddisk. */
2722+ if (pad->priv->infoname)
2723+ fio_remove_file (pad->priv->infoname);
2724+ if (pad->priv->contentname)
2725+ fio_remove_file (pad->priv->contentname);
2726+
2727+ /* Remove the pad from the group and destroy it. */
2728+ gtk_widget_destroy (GTK_WIDGET (pad));
2729+}
2730+
2731+static void
2732+pad_properties_sync_title (XpadPad *pad)
2733+{
2734+ gchar *title;
2735+
2736+ if (!pad->priv->properties)
2737+ return;
2738+
2739+ title = g_strdup_printf (_("'%s' Properties"), gtk_window_get_title (GTK_WINDOW (pad)));
2740+ gtk_window_set_title (GTK_WINDOW (pad->priv->properties), title);
2741+ g_free (title);
2742+}
2743+
2744+static void
2745+pad_properties_destroyed (XpadPad *pad)
2746+{
2747+ if (!pad->priv->properties)
2748+ return;
2749+
2750+ g_signal_handlers_disconnect_by_func (pad, (gpointer) pad_properties_sync_title, NULL);
2751+ pad->priv->properties = NULL;
2752+}
2753+
2754+static void
2755+prop_notify_font (XpadPad *pad)
2756+{
2757+ XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties);
2758+
2759+ gboolean follow_font_style;
2760+ g_object_get (prop, "follow-font-style", &follow_font_style, NULL);
2761+ g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", follow_font_style, NULL);
2762+
2763+ if (!follow_font_style)
2764+ {
2765+ const gchar *font;
2766+ g_object_get (prop, "fontname", &font, NULL);
2767+ PangoFontDescription *fontdesc;
2768+
2769+ fontdesc = font ? pango_font_description_from_string (font) : NULL;
2770+ gtk_widget_override_font (pad->priv->textview, fontdesc);
2771+ if (fontdesc)
2772+ pango_font_description_free (fontdesc);
2773+ }
2774+
2775+ xpad_pad_save_info_delayed (pad);
2776+}
2777+
2778+static void
2779+prop_notify_colors (XpadPad *pad)
2780+{
2781+ XpadPadProperties *prop = XPAD_PAD_PROPERTIES (pad->priv->properties);
2782+
2783+ gboolean follow_color_style;
2784+ const GdkRGBA *text_color, *back_color;
2785+
2786+ g_object_get (prop, "follow-color-style", &follow_color_style, NULL);
2787+ g_object_set (XPAD_TEXT_VIEW (pad->priv->textview), "follow-color-style", follow_color_style, NULL);
2788+
2789+ if (follow_color_style)
2790+ /* Set the colors to the global preferences colors */
2791+ g_object_get (pad->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL);
2792+ else
2793+ /* Set the color to the individual pad properties colors */
2794+ g_object_get (prop, "text-color", &text_color, "back-color", &back_color, NULL);
2795+
2796+ gtk_widget_override_cursor (pad->priv->textview, text_color, text_color);
2797+ gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, text_color);
2798+ gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_NORMAL, back_color);
2799+
2800+ /* Inverse the text and background colors for selected text, so it is likely to be visible by any choice of the colors. */
2801+ gtk_widget_override_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, back_color);
2802+ gtk_widget_override_background_color (pad->priv->textview, GTK_STATE_FLAG_SELECTED, text_color);
2803+
2804+ xpad_pad_save_info_delayed (pad);
2805+}
2806+
2807+static void
2808+xpad_pad_open_properties (XpadPad *pad)
2809+{
2810+ gboolean follow_font_style, follow_color_style;
2811+ GtkStyleContext *style = NULL;
2812+ PangoFontDescription *font;
2813+ GdkRGBA widget_text_color = {0, 0, 0, 0};
2814+ GdkRGBA widget_background_color = {0, 0, 0, 0};
2815+
2816+ if (pad->priv->properties)
2817+ {
2818+ gtk_window_present (GTK_WINDOW (pad->priv->properties));
2819+ return;
2820+ }
2821+
2822+ pad->priv->properties = xpad_pad_properties_new ();
2823+
2824+ gtk_window_set_transient_for (GTK_WINDOW (pad->priv->properties), GTK_WINDOW (pad));
2825+ gtk_window_set_resizable (GTK_WINDOW (pad->priv->properties), FALSE);
2826+
2827+ g_signal_connect_swapped (pad->priv->properties, "destroy", G_CALLBACK (pad_properties_destroyed), pad);
2828+ g_signal_connect (pad, "notify::title", G_CALLBACK (pad_properties_sync_title), NULL);
2829+
2830+ style = gtk_widget_get_style_context (pad->priv->textview);
2831+ gtk_style_context_get(style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL);
2832+ gtk_style_context_get_color (style, GTK_STATE_FLAG_NORMAL, &widget_text_color);
2833+ gtk_style_context_get_background_color (style, GTK_STATE_FLAG_NORMAL, &widget_background_color);
2834+
2835+ g_object_get (XPAD_TEXT_VIEW (pad->priv->textview), "follow-font-style", &follow_font_style, "follow-color-style", &follow_color_style, NULL);
2836+ g_object_set (G_OBJECT (pad->priv->properties),
2837+ "follow-font-style", follow_font_style,
2838+ "follow-color-style", follow_color_style,
2839+ "text-color", &widget_text_color,
2840+ "back-color", &widget_background_color,
2841+ "fontname", pango_font_description_to_string(font),
2842+ NULL);
2843+ pango_font_description_free (font);
2844+
2845+ g_signal_connect_swapped (pad->priv->properties, "notify::follow-font-style", G_CALLBACK (prop_notify_font), pad);
2846+ g_signal_connect_swapped (pad->priv->properties, "notify::follow-color-style", G_CALLBACK (prop_notify_colors), pad);
2847+ g_signal_connect_swapped (pad->priv->properties, "notify::text-color", G_CALLBACK (prop_notify_colors), pad);
2848+ g_signal_connect_swapped (pad->priv->properties, "notify::back-color", G_CALLBACK (prop_notify_colors), pad);
2849+ g_signal_connect_swapped (pad->priv->properties, "notify::fontname", G_CALLBACK (prop_notify_font), pad);
2850+
2851+ pad_properties_sync_title (pad);
2852+
2853+ gtk_widget_show (pad->priv->properties);
2854+}
2855+
2856+static void
2857+xpad_pad_open_preferences (XpadPad *pad)
2858+{
2859+ xpad_preferences_open (pad->priv->settings);
2860+}
2861+
2862+static void
2863+menu_toggle_tag (XpadPad *pad,
2864+ const gchar *name)
2865 {
2866 g_return_if_fail (pad->priv->textview);
2867 XpadTextBuffer *buffer = NULL;
2868@@ -1541,7 +900,8 @@
2869 * because this function has been probably been called, because of a menu toggle.
2870 */
2871 static void
2872-menu_sticky (GtkCheckMenuItem *check, XpadPad *pad)
2873+menu_sticky (GtkCheckMenuItem *check,
2874+ XpadPad *pad)
2875 {
2876 pad->priv->sticky = gtk_check_menu_item_get_active (check);
2877 if (pad->priv->sticky)
2878@@ -1552,31 +912,36 @@
2879 }
2880
2881 static void
2882-menu_toolbar (GtkCheckMenuItem *check, XpadPad *pad)
2883+menu_toolbar (GtkCheckMenuItem *check,
2884+ XpadPad *pad)
2885 {
2886 g_object_set (pad->priv->settings, "has-toolbar", gtk_check_menu_item_get_active (check), NULL);
2887 }
2888
2889 static void
2890-menu_scrollbar (GtkCheckMenuItem *check, XpadPad *pad)
2891+menu_scrollbar (GtkCheckMenuItem *check,
2892+ XpadPad *pad)
2893 {
2894 g_object_set (pad->priv->settings, "has-scrollbar", gtk_check_menu_item_get_active (check), NULL);
2895 }
2896
2897 static void
2898-menu_autohide (GtkCheckMenuItem *check, XpadPad *pad)
2899+menu_autohide (GtkCheckMenuItem *check,
2900+ XpadPad *pad)
2901 {
2902 g_object_set (pad->priv->settings, "autohide-toolbar", gtk_check_menu_item_get_active (check), NULL);
2903 }
2904
2905 static void
2906-menu_decorated (GtkCheckMenuItem *check, XpadPad *pad)
2907+menu_decorated (GtkCheckMenuItem *check,
2908+ XpadPad *pad)
2909 {
2910 g_object_set (pad->priv->settings, "has-decorations", gtk_check_menu_item_get_active (check), NULL);
2911 }
2912
2913 static gint
2914-menu_title_compare (GtkWindow *a, GtkWindow *b)
2915+menu_title_compare (GtkWindow *a,
2916+ GtkWindow *b)
2917 {
2918 gchar *title_a = g_utf8_casefold (gtk_window_get_title (a), -1);
2919 gchar *title_b = g_utf8_casefold (gtk_window_get_title (b), -1);
2920@@ -1589,6 +954,31 @@
2921 return rv;
2922 }
2923
2924+static void
2925+menu_about (XpadPad *pad)
2926+{
2927+ const gchar *artists[] = {"Michael Terry <mike@mterry.name>", NULL};
2928+ const gchar *authors[] = {"Arthur Borsboom <arthurborsboom@gmail.com>", "Jeroen Vermeulen <jtv@xs4all.nl>", "Michael Terry <mike@mterry.name>", "Paul Ivanov <pivanov@berkeley.edu>", "Sachin Raut <great.sachin@gmail.com>", NULL};
2929+ const gchar *comments = _("Sticky notes");
2930+ const gchar *copyright = "© 2001-2014 Michael Terry";
2931+ /* Translators: please translate this as your own name and optionally email
2932+ like so: "Your Name <your@email.com>" */
2933+ const gchar *translator_credits = _("translator-credits");
2934+ const gchar *website = "https://launchpad.net/xpad";
2935+
2936+ gtk_show_about_dialog (GTK_WINDOW (pad),
2937+ "artists", artists,
2938+ "authors", authors,
2939+ "comments", comments,
2940+ "copyright", copyright,
2941+ "license-type", GTK_LICENSE_GPL_3_0,
2942+ "logo-icon-name", PACKAGE,
2943+ "translator-credits", translator_credits,
2944+ "version", VERSION,
2945+ "website", website,
2946+ NULL);
2947+}
2948+
2949 /* FIXME: Accelerators are working but not visible for menu items with an image (icon). */
2950 #define MENU_ADD(mnemonic, image, key, mask, callback) {\
2951 if (image) {\
2952@@ -1621,7 +1011,32 @@
2953 }
2954
2955 static GtkWidget *
2956-menu_get_popup_no_highlight (XpadPad *pad, GtkAccelGroup *accel_group)
2957+menu_get_popup_highlight (XpadPad *pad,
2958+ GtkAccelGroup *accel_group)
2959+{
2960+ GtkWidget *menu, *item;
2961+
2962+ menu = gtk_menu_new ();
2963+ gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
2964+
2965+ MENU_ADD (_("Cu_t"), "edit-cut", 0, 0, xpad_pad_cut);
2966+ MENU_ADD (_("_Copy"), "edit-copy", 0, 0, xpad_pad_copy);
2967+ MENU_ADD (_("_Paste"), "edit-paste", 0, 0, xpad_pad_paste);
2968+ g_object_set_data (G_OBJECT (menu), "paste", item);
2969+ MENU_ADD_SEP ();
2970+ MENU_ADD (_("_Bold"), "format-text-bold", GDK_KEY_b, GDK_CONTROL_MASK, menu_bold);
2971+ MENU_ADD (_("_Italic"), "format-text-italic", GDK_KEY_i, GDK_CONTROL_MASK, menu_italic);
2972+ MENU_ADD (_("_Underline"), "format-text-underline", GDK_KEY_u, GDK_CONTROL_MASK, menu_underline);
2973+ MENU_ADD (_("_Strikethrough"), "format-text-strikethrough", 0, 0, menu_strikethrough);
2974+
2975+ gtk_widget_show_all (menu);
2976+
2977+ return menu;
2978+}
2979+
2980+static GtkWidget *
2981+menu_get_popup_no_highlight (XpadPad *pad,
2982+ GtkAccelGroup *accel_group)
2983 {
2984 GtkWidget *uppermenu, *menu, *item;
2985 gboolean has_toolbar, autohide_toolbar, has_scrollbar, decorations;
2986@@ -1693,7 +1108,7 @@
2987 gtk_container_add (GTK_CONTAINER (uppermenu), item);
2988 menu = gtk_menu_new ();
2989 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
2990- MENU_ADD (_("_Help"), "help-browser", GDK_KEY_F1, 0, show_help);
2991+ MENU_ADD (_("_Help"), "help-browser", GDK_KEY_F1, 0, show_help);
2992 MENU_ADD (_("_About"), "help-about", 0, 0, menu_about);
2993
2994 gtk_widget_show_all (uppermenu);
2995@@ -1702,7 +1117,139 @@
2996 }
2997
2998 static void
2999-menu_prep_popup_no_highlight (XpadPad *pad, GtkWidget *uppermenu)
3000+xpad_pad_show (XpadPad *pad)
3001+{
3002+ /*
3003+ * Some wm's might not acknowledge our request for a specific
3004+ * location before we are shown. What we do here is a little gimpy
3005+ * and not very respectful of wms' sovereignty, but it has the effect
3006+ * of making pads' locations very dependable. We just move the pad
3007+ * again here after being shown. This may create a visual effect if
3008+ * the wm did ignore us, but is better than being in the wrong
3009+ * place, I guess.
3010+ */
3011+ if (pad->priv->location_valid)
3012+ gtk_window_move (GTK_WINDOW (pad), pad->priv->x, pad->priv->y);
3013+
3014+ if (pad->priv->sticky)
3015+ gtk_window_stick (GTK_WINDOW (pad));
3016+ else
3017+ gtk_window_unstick (GTK_WINDOW (pad));
3018+}
3019+
3020+static gboolean toolbar_timeout (XpadPad *pad)
3021+{
3022+ if (!pad || !pad->priv || !pad->priv->toolbar_timeout)
3023+ return FALSE;
3024+
3025+ gboolean has_toolbar, autohide_toolbar;
3026+ g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
3027+
3028+ if (pad->priv->toolbar_timeout && autohide_toolbar && has_toolbar)
3029+ xpad_pad_hide_toolbar (pad);
3030+
3031+ pad->priv->toolbar_timeout = 0;
3032+
3033+ return FALSE;
3034+}
3035+
3036+static gboolean
3037+xpad_pad_configure_event (XpadPad *pad,
3038+ GdkEventConfigure *event)
3039+{
3040+ if (!gtk_widget_get_visible (GTK_WIDGET(pad)))
3041+ return FALSE;
3042+
3043+ int eWidth = event->width;
3044+ int eHeight = event->height;
3045+
3046+ /* safe cast from gint to guint */
3047+ if (eWidth >= 0 && eHeight >=0 ) {
3048+ if (pad->priv->width != (guint) eWidth || pad->priv->height != (guint) eHeight)
3049+ pad->priv->toolbar_pad_resized = TRUE;
3050+
3051+ pad->priv->width = (guint) event->width;
3052+ pad->priv->height = (guint) event->height;
3053+ }
3054+ else {
3055+ g_warning("There is a problem in the program Xpad. In function 'xpad_pad_configure_event' the variable 'event->width' or 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
3056+ }
3057+
3058+ pad->priv->x = event->x;
3059+ pad->priv->y = event->y;
3060+ pad->priv->location_valid = TRUE;
3061+
3062+ xpad_pad_save_info_delayed(pad);
3063+
3064+ /*
3065+ * Sometimes when moving, if the toolbar tries to hide itself,
3066+ * the window manager will not resize it correctly. So, we make
3067+ * sure not to end the timeout while moving.
3068+ */
3069+ if (pad->priv->toolbar_timeout)
3070+ {
3071+ g_source_remove (pad->priv->toolbar_timeout);
3072+ pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
3073+ }
3074+
3075+ return FALSE;
3076+}
3077+
3078+static gboolean
3079+xpad_pad_toolbar_size_allocate (XpadPad *pad,
3080+ GtkAllocation *event)
3081+{
3082+ /* safe cast from gint to guint */
3083+ if (event->height >= 0) {
3084+ pad->priv->toolbar_height = (guint) event->height;
3085+ }
3086+ else {
3087+ g_warning("There is a problem in the program Xpad. In function 'xpad_pad_toolbar_size_allocate' the variable 'event->height' is not a postive number. Please send a bugreport to https://bugs.launchpad.net/xpad/+filebug to help improve Xpad.");
3088+ pad->priv->toolbar_height = 0;
3089+ }
3090+ return FALSE;
3091+}
3092+
3093+static gboolean
3094+xpad_pad_delete_event (XpadPad *pad,
3095+ GdkEvent *event)
3096+{
3097+ /* A dirty way to silence the compiler for these unused variables. */
3098+ (void) event;
3099+
3100+ xpad_pad_close (pad);
3101+
3102+ return TRUE;
3103+}
3104+
3105+static gboolean
3106+xpad_pad_leave_notify_event (GtkWidget *pad,
3107+ GdkEventCrossing *event)
3108+{
3109+ gboolean has_toolbar, autohide_toolbar;
3110+ g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
3111+
3112+ if (has_toolbar && autohide_toolbar &&
3113+ event->detail != GDK_NOTIFY_INFERIOR &&
3114+ event->mode == GDK_CROSSING_NORMAL)
3115+ {
3116+ if (!XPAD_PAD (pad)->priv->toolbar_timeout)
3117+ XPAD_PAD (pad)->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
3118+ }
3119+
3120+ return FALSE;
3121+}
3122+
3123+static void
3124+menu_popup (XpadPad *pad)
3125+{
3126+ g_signal_handlers_block_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL);
3127+ pad->priv->toolbar_timeout = 0;
3128+}
3129+
3130+static void
3131+menu_prep_popup_no_highlight (XpadPad *pad,
3132+ GtkWidget *uppermenu)
3133 {
3134 GtkWidget *menu, *item;
3135
3136@@ -1747,6 +1294,495 @@
3137 gtk_widget_show_all (menu);
3138 }
3139
3140+static void
3141+menu_prep_popup_highlight (XpadPad *pad,
3142+ GtkWidget *menu)
3143+{
3144+ /* A dirty way to silence the compiler for these unused variables. */
3145+ (void) pad;
3146+
3147+ GtkWidget *item;
3148+ GtkClipboard *clipboard;
3149+
3150+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3151+
3152+ item = g_object_get_data (G_OBJECT (menu), "paste");
3153+ if (item)
3154+ gtk_widget_set_sensitive (item, gtk_clipboard_wait_is_text_available (clipboard));
3155+}
3156+
3157+static void
3158+xpad_pad_popup (XpadPad *pad,
3159+ GdkEventButton *event)
3160+{
3161+ GtkTextBuffer *buffer;
3162+ GtkWidget *menu;
3163+
3164+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
3165+
3166+ if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
3167+ {
3168+ menu = pad->priv->highlight_menu;
3169+ menu_prep_popup_highlight (pad, menu);
3170+ }
3171+ else
3172+ {
3173+ menu = pad->priv->menu;
3174+ menu_prep_popup_no_highlight (pad, menu);
3175+ }
3176+
3177+ if (!menu)
3178+ return;
3179+
3180+ menu_popup (pad);
3181+
3182+ if (event)
3183+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
3184+ else
3185+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
3186+}
3187+
3188+static gboolean
3189+xpad_pad_popup_menu (XpadPad *pad)
3190+{
3191+ xpad_pad_popup (pad, NULL);
3192+
3193+ return TRUE;
3194+}
3195+
3196+static void
3197+menu_popdown (XpadPad *pad)
3198+{
3199+ cairo_rectangle_int_t rect;
3200+
3201+ /* We must check if we disabled off of pad and start the timeout if so. */
3202+ rect.x = 10;
3203+ rect.y = 10;
3204+ rect.width = 1;
3205+ rect.height = 1;
3206+
3207+ if (!pad->priv->toolbar_timeout && !gtk_widget_intersect (GTK_WIDGET (pad), &rect, NULL))
3208+ pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
3209+
3210+ g_signal_handlers_unblock_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL);
3211+}
3212+
3213+static gboolean
3214+xpad_pad_button_press_event (XpadPad *pad,
3215+ GdkEventButton *event)
3216+{
3217+ if (event->type == GDK_BUTTON_PRESS)
3218+ {
3219+ switch (event->button)
3220+ {
3221+ case 1:
3222+ if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK)
3223+ {
3224+ gtk_window_begin_move_drag (GTK_WINDOW (pad), (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time);
3225+ return TRUE;
3226+ }
3227+ break;
3228+
3229+ case 3:
3230+ if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_CONTROL_MASK)
3231+ {
3232+ GdkWindowEdge edge;
3233+
3234+ if (gtk_widget_get_direction (GTK_WIDGET (pad)) == GTK_TEXT_DIR_LTR)
3235+ edge = GDK_WINDOW_EDGE_SOUTH_EAST;
3236+ else
3237+ edge = GDK_WINDOW_EDGE_SOUTH_WEST;
3238+
3239+ gtk_window_begin_resize_drag (GTK_WINDOW (pad), edge, (gint) event->button, (gint) event->x_root, (gint) event->y_root, event->time);
3240+ }
3241+ else
3242+ {
3243+ xpad_pad_popup (pad, event);
3244+ }
3245+ return TRUE;
3246+ }
3247+ }
3248+
3249+ return FALSE;
3250+}
3251+
3252+static void
3253+xpad_pad_notify_has_scrollbar (XpadPad *pad)
3254+{
3255+ gboolean has_scrollbar;
3256+ g_object_get (pad->priv->settings, "has-scrollbar", &has_scrollbar, NULL);
3257+
3258+ /* Update pad menu with the new status */
3259+ GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-scrollbar");
3260+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_scrollbar);
3261+
3262+ if (has_scrollbar)
3263+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar),
3264+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3265+ else
3266+ {
3267+ GtkAdjustment *v, *h;
3268+
3269+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pad->priv->scrollbar),
3270+ GTK_POLICY_NEVER, GTK_POLICY_NEVER);
3271+
3272+ /* now we need to adjust view so that user can see whole pad */
3273+ h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar));
3274+ v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (pad->priv->scrollbar));
3275+
3276+ gtk_adjustment_set_value (h, 0);
3277+ gtk_adjustment_set_value (v, 0);
3278+ }
3279+}
3280+
3281+static void
3282+xpad_pad_notify_has_decorations (XpadPad *pad)
3283+{
3284+ GtkWidget *pad_widget = GTK_WIDGET (pad);
3285+ GtkWindow *pad_window = GTK_WINDOW (pad);
3286+ gboolean decorations;
3287+ g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL);
3288+
3289+ /* Update pad menu with the new status */
3290+ GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-decorations");
3291+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), decorations);
3292+
3293+ /*
3294+ * There are two modes of operation: a normal mode and a 'stealth' mode.
3295+ * If decorations are disabled, we also don't show up in the taskbar or pager.
3296+ */
3297+ gtk_window_set_decorated (pad_window, decorations);
3298+ gtk_window_set_skip_taskbar_hint (pad_window, !decorations);
3299+ gtk_window_set_skip_pager_hint (pad_window, !decorations);
3300+
3301+ /*
3302+ * reshow_with_initial_size() seems to set the window back to a never-shown state.
3303+ * This is good, as some WMs don't like us changing the above parameters mid-run,
3304+ * even if we do a hide/show cycle.
3305+ */
3306+ gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height);
3307+ gtk_widget_hide (pad_widget);
3308+ gtk_widget_unrealize (pad_widget);
3309+ gtk_widget_show (pad_widget);
3310+}
3311+
3312+static void
3313+xpad_pad_notify_has_toolbar (XpadPad *pad)
3314+{
3315+ gboolean has_toolbar, autohide_toolbar;
3316+ g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
3317+
3318+ /* Update pad menu with the new status */
3319+ GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-toolbar");
3320+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), has_toolbar);
3321+ menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar");
3322+ gtk_widget_set_sensitive (menu_item, has_toolbar);
3323+
3324+ if (has_toolbar && !autohide_toolbar)
3325+ xpad_pad_show_toolbar (pad);
3326+ else
3327+ xpad_pad_hide_toolbar (pad);
3328+}
3329+
3330+static void
3331+xpad_pad_notify_autohide_toolbar (XpadPad *pad)
3332+{
3333+ gboolean autohide_toolbar;
3334+ g_object_get (pad->priv->settings, "autohide-toolbar", &autohide_toolbar, NULL);
3335+
3336+ /* Update pad menu with the new status */
3337+ GtkWidget *menu_item = g_object_get_data (G_OBJECT (pad->priv->menu), "has-autohide-toolbar");
3338+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), autohide_toolbar);
3339+
3340+ if (autohide_toolbar)
3341+ {
3342+ /* Likely not to be in pad when turning setting on */
3343+ if (!pad->priv->toolbar_timeout)
3344+ pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
3345+ }
3346+ else
3347+ {
3348+ gboolean has_toolbar;
3349+ g_object_get (pad->priv->settings, "has-toolbar", &has_toolbar, NULL);
3350+
3351+ if (has_toolbar)
3352+ xpad_pad_show_toolbar(pad);
3353+ }
3354+}
3355+
3356+static void
3357+xpad_pad_clear (XpadPad *pad)
3358+{
3359+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
3360+ gtk_text_buffer_set_text (buffer, "", -1);
3361+}
3362+
3363+static gboolean
3364+xpad_pad_enter_notify_event (GtkWidget *pad,
3365+ GdkEventCrossing *event)
3366+{
3367+ gboolean has_toolbar, autohide_toolbar;
3368+ g_object_get (XPAD_PAD (pad)->priv->settings, "has-toolbar", &has_toolbar, "autohide-toolbar", &autohide_toolbar, NULL);
3369+
3370+ if (has_toolbar && autohide_toolbar &&
3371+ event->detail != GDK_NOTIFY_INFERIOR &&
3372+ event->mode == GDK_CROSSING_NORMAL)
3373+ {
3374+ XPAD_PAD (pad)->priv->toolbar_timeout = 0;
3375+ xpad_pad_show_toolbar (XPAD_PAD (pad));
3376+ }
3377+
3378+ return FALSE;
3379+}
3380+
3381+static void xpad_pad_constructed (GObject *object)
3382+{
3383+ XpadPad *pad = XPAD_PAD (object);
3384+
3385+ gboolean decorations;
3386+ GtkBox *vbox;
3387+
3388+ g_object_get (pad->priv->settings,
3389+ "width", &pad->priv->width,
3390+ "height", &pad->priv->height,
3391+ "autostart-sticky", &pad->priv->sticky, NULL);
3392+
3393+ GtkWindow *pad_window = GTK_WINDOW (pad);
3394+
3395+ pad->priv->textview = GTK_WIDGET (XPAD_TEXT_VIEW (xpad_text_view_new (pad->priv->settings, pad)));
3396+
3397+ pad->priv->scrollbar = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,
3398+ "hadjustment", NULL,
3399+ "hscrollbar-policy", GTK_POLICY_NEVER,
3400+ "shadow-type", GTK_SHADOW_NONE,
3401+ "vadjustment", NULL,
3402+ "vscrollbar-policy", GTK_POLICY_NEVER,
3403+ "child", pad->priv->textview,
3404+ NULL));
3405+
3406+ pad->priv->toolbar = GTK_WIDGET (xpad_toolbar_new (pad));
3407+
3408+ pad->priv->accel_group = gtk_accel_group_new ();
3409+ gtk_window_add_accel_group (pad_window, pad->priv->accel_group);
3410+ pad->priv->menu = menu_get_popup_no_highlight (pad, pad->priv->accel_group);
3411+ pad->priv->highlight_menu = menu_get_popup_highlight (pad, pad->priv->accel_group);
3412+ gtk_accel_group_connect (pad->priv->accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0, g_cclosure_new_swap (G_CALLBACK (xpad_app_quit), pad, NULL));
3413+
3414+ vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 0));
3415+ gtk_box_set_homogeneous (vbox, FALSE);
3416+ gtk_box_pack_start (vbox, pad->priv->scrollbar, TRUE, TRUE, 0);
3417+ gtk_box_pack_start (vbox, pad->priv->toolbar, FALSE, FALSE, 0);
3418+
3419+ gtk_container_child_set (GTK_CONTAINER (vbox), pad->priv->toolbar, "expand", FALSE, NULL);
3420+
3421+ g_object_get (pad->priv->settings, "has-decorations", &decorations, NULL);
3422+ gtk_window_set_decorated (pad_window, decorations);
3423+ gtk_window_set_default_size (pad_window, (gint) pad->priv->width, (gint) pad->priv->height);
3424+ gtk_window_set_gravity (pad_window, GDK_GRAVITY_STATIC); /* static gravity makes saving pad x,y work */
3425+ gtk_window_set_skip_pager_hint (pad_window, decorations);
3426+ gtk_window_set_skip_taskbar_hint (pad_window, !decorations);
3427+ gtk_window_set_position (pad_window, GTK_WIN_POS_MOUSE);
3428+
3429+ g_object_set (G_OBJECT (pad), "child", vbox, NULL);
3430+
3431+ xpad_pad_notify_has_scrollbar (pad);
3432+ xpad_pad_notify_has_selection (pad);
3433+ xpad_pad_notify_clipboard_owner_changed (pad);
3434+ xpad_pad_notify_undo_redo_changed (pad);
3435+
3436+ pad->priv->clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3437+
3438+ if (pad->priv->sticky)
3439+ gtk_window_stick (pad_window);
3440+ else
3441+ gtk_window_unstick (pad_window);
3442+
3443+ xpad_pad_sync_title (pad);
3444+
3445+ gtk_widget_show_all (GTK_WIDGET (vbox));
3446+
3447+ gtk_widget_hide (pad->priv->toolbar);
3448+ xpad_pad_notify_has_toolbar (pad);
3449+
3450+ /* Set up signals */
3451+ gtk_widget_add_events (GTK_WIDGET (pad), GDK_BUTTON_PRESS_MASK | GDK_PROPERTY_CHANGE_MASK);
3452+ gtk_widget_add_events (pad->priv->toolbar, GDK_ALL_EVENTS_MASK);
3453+ g_signal_connect_swapped (pad->priv->textview, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), pad);
3454+ g_signal_connect_swapped (pad->priv->textview, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), pad);
3455+ g_signal_connect_swapped (pad->priv->toolbar, "size-allocate", G_CALLBACK (xpad_pad_toolbar_size_allocate), pad);
3456+ g_signal_connect (pad, "button-press-event", G_CALLBACK (xpad_pad_button_press_event), NULL);
3457+ g_signal_connect (pad, "configure-event", G_CALLBACK (xpad_pad_configure_event), NULL);
3458+ g_signal_connect (pad, "delete-event", G_CALLBACK (xpad_pad_delete_event), NULL);
3459+ g_signal_connect (pad, "popup-menu", G_CALLBACK (xpad_pad_popup_menu), NULL);
3460+ g_signal_connect (pad, "show", G_CALLBACK (xpad_pad_show), NULL);
3461+ g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "changed", G_CALLBACK (xpad_pad_text_changed), pad);
3462+
3463+ g_signal_connect (pad, "enter-notify-event", G_CALLBACK (xpad_pad_enter_notify_event), NULL);
3464+ g_signal_connect (pad, "leave-notify-event", G_CALLBACK (xpad_pad_leave_notify_event), NULL);
3465+
3466+ g_signal_connect_swapped (pad->priv->settings, "notify::has-decorations", G_CALLBACK (xpad_pad_notify_has_decorations), pad);
3467+ g_signal_connect_swapped (pad->priv->settings, "notify::has-toolbar", G_CALLBACK (xpad_pad_notify_has_toolbar), pad);
3468+ g_signal_connect_swapped (pad->priv->settings, "notify::autohide-toolbar", G_CALLBACK (xpad_pad_notify_autohide_toolbar), pad);
3469+ g_signal_connect_swapped (pad->priv->settings, "notify::has-scrollbar", G_CALLBACK (xpad_pad_notify_has_scrollbar), pad);
3470+ g_signal_connect_swapped (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)), "notify::has-selection", G_CALLBACK (xpad_pad_notify_has_selection), pad);
3471+ g_signal_connect_swapped (pad->priv->clipboard, "owner-change", G_CALLBACK (xpad_pad_notify_clipboard_owner_changed), pad);
3472+
3473+ g_signal_connect_swapped (pad->priv->toolbar, "activate-new", G_CALLBACK (xpad_pad_spawn), pad);
3474+ g_signal_connect_swapped (pad->priv->toolbar, "activate-clear", G_CALLBACK (xpad_pad_clear), pad);
3475+ g_signal_connect_swapped (pad->priv->toolbar, "activate-close", G_CALLBACK (xpad_pad_close), pad);
3476+ g_signal_connect_swapped (pad->priv->toolbar, "activate-undo", G_CALLBACK (xpad_pad_undo), pad);
3477+ g_signal_connect_swapped (pad->priv->toolbar, "activate-redo", G_CALLBACK (xpad_pad_redo), pad);
3478+ g_signal_connect_swapped (pad->priv->toolbar, "activate-cut", G_CALLBACK (xpad_pad_cut), pad);
3479+ g_signal_connect_swapped (pad->priv->toolbar, "activate-copy", G_CALLBACK (xpad_pad_copy), pad);
3480+ g_signal_connect_swapped (pad->priv->toolbar, "activate-paste", G_CALLBACK (xpad_pad_paste), pad);
3481+ g_signal_connect_swapped (pad->priv->toolbar, "activate-delete", G_CALLBACK (xpad_pad_delete), pad);
3482+ g_signal_connect_swapped (pad->priv->toolbar, "activate-properties", G_CALLBACK (xpad_pad_open_properties), pad);
3483+ g_signal_connect_swapped (pad->priv->toolbar, "activate-preferences", G_CALLBACK (xpad_pad_open_preferences), pad);
3484+ g_signal_connect_swapped (pad->priv->toolbar, "activate-quit", G_CALLBACK (xpad_pad_close_all), pad);
3485+
3486+ g_signal_connect_swapped (pad->priv->toolbar, "popup", G_CALLBACK (menu_popup), pad);
3487+ g_signal_connect_swapped (pad->priv->toolbar, "popdown", G_CALLBACK (menu_popdown), pad);
3488+
3489+ g_signal_connect_swapped (pad->priv->menu, "deactivate", G_CALLBACK (menu_popdown), pad);
3490+ g_signal_connect_swapped (pad->priv->highlight_menu, "deactivate", G_CALLBACK (menu_popdown), pad);
3491+}
3492+
3493+static void
3494+xpad_pad_dispose (GObject *object)
3495+{
3496+ XpadPad *pad = XPAD_PAD (object);
3497+
3498+ if (pad->priv->group) {
3499+ g_object_unref(pad->priv->group);
3500+ pad->priv->group = NULL;
3501+ }
3502+
3503+ if (GTK_IS_WIDGET(pad->priv->menu)) {
3504+ gtk_widget_destroy (pad->priv->menu);
3505+ pad->priv->menu = NULL;
3506+ }
3507+
3508+ if (GTK_IS_WIDGET(pad->priv->highlight_menu)) {
3509+ gtk_widget_destroy (pad->priv->highlight_menu);
3510+ pad->priv->highlight_menu = NULL;
3511+ }
3512+
3513+ if (XPAD_IS_PAD_PROPERTIES (pad->priv->properties)) {
3514+ gtk_widget_destroy (pad->priv->properties);
3515+ pad->priv->properties = NULL;
3516+ }
3517+
3518+ gtk_clipboard_clear (pad->priv->clipboard);
3519+
3520+ /* For some reason the toolbar handler does not get automatically disconnected (or not at the right moment), leading to errors after deleting a pad. This manual disconnect prevents this error. */
3521+ if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) {
3522+ g_signal_handlers_disconnect_matched (pad->priv->toolbar, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad);
3523+ gtk_widget_destroy(pad->priv->toolbar);
3524+ pad->priv->toolbar = NULL;
3525+ }
3526+
3527+ G_OBJECT_CLASS (xpad_pad_parent_class)->dispose (object);
3528+}
3529+
3530+static void
3531+xpad_pad_finalize (GObject *object)
3532+{
3533+ XpadPad *pad = XPAD_PAD (object);
3534+
3535+ if (pad->priv->settings) {
3536+ g_signal_handlers_disconnect_matched (pad->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pad);
3537+ g_object_unref(pad->priv->settings);
3538+ pad->priv->settings = NULL;
3539+ }
3540+
3541+ g_free (pad->priv->infoname);
3542+ g_free (pad->priv->contentname);
3543+
3544+ G_OBJECT_CLASS (xpad_pad_parent_class)->finalize (object);
3545+}
3546+
3547+void
3548+xpad_pad_notify_has_selection (XpadPad *pad)
3549+{
3550+ g_return_if_fail (pad);
3551+
3552+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
3553+ gboolean has_selection = gtk_text_buffer_get_has_selection (buffer);
3554+
3555+ XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
3556+ if (toolbar == NULL)
3557+ return;
3558+
3559+ xpad_toolbar_enable_cut_button (toolbar, has_selection);
3560+ xpad_toolbar_enable_copy_button (toolbar, has_selection);
3561+}
3562+
3563+void
3564+xpad_pad_notify_clipboard_owner_changed (XpadPad *pad)
3565+{
3566+ g_return_if_fail (pad);
3567+
3568+ /* safe cast to toolbar */
3569+ if (XPAD_IS_TOOLBAR (pad->priv->toolbar)) {
3570+ XpadToolbar *toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
3571+ g_return_if_fail (toolbar);
3572+
3573+ GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3574+ xpad_toolbar_enable_paste_button (toolbar, gtk_clipboard_wait_is_text_available (clipboard));
3575+ }
3576+}
3577+
3578+void
3579+xpad_pad_notify_undo_redo_changed (XpadPad *pad)
3580+{
3581+ g_return_if_fail (pad);
3582+
3583+ XpadTextBuffer *buffer = NULL;
3584+ buffer = XPAD_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview)));
3585+ g_return_if_fail (buffer);
3586+
3587+ XpadToolbar *toolbar = NULL;
3588+ toolbar = XPAD_TOOLBAR (pad->priv->toolbar);
3589+ g_return_if_fail (toolbar);
3590+
3591+ xpad_toolbar_enable_undo_button (toolbar, xpad_text_buffer_undo_available (buffer));
3592+ xpad_toolbar_enable_redo_button (toolbar, xpad_text_buffer_redo_available (buffer));
3593+}
3594+
3595+void
3596+xpad_pad_close (XpadPad *pad)
3597+{
3598+ gtk_widget_hide (GTK_WIDGET (pad));
3599+
3600+ /*
3601+ * If no tray and this is the last pad, we don't want to record this
3602+ * pad as closed, we want to start with just this pad next open. So
3603+ * quit before we record.
3604+ */
3605+ if (!xpad_tray_is_open () &&
3606+ xpad_pad_group_num_visible_pads (pad->priv->group) == 0)
3607+ {
3608+ xpad_app_quit ();
3609+ return;
3610+ }
3611+
3612+ if (pad->priv->properties)
3613+ gtk_widget_destroy (pad->priv->properties);
3614+
3615+ xpad_pad_save_info (pad);
3616+
3617+ g_signal_emit (pad, signals[CLOSED], 0);
3618+}
3619+
3620+void
3621+xpad_pad_toggle(XpadPad *pad)
3622+{
3623+ if (gtk_widget_get_visible (GTK_WIDGET(pad)))
3624+ xpad_pad_close (pad);
3625+ else
3626+ gtk_widget_show (GTK_WIDGET (pad));
3627+}
3628+
3629 void xpad_pad_append_pad_titles_to_menu (GtkWidget *menu)
3630 {
3631 GSList *pads, *l;
3632@@ -1782,114 +1818,75 @@
3633 g_slist_free (pads);
3634 }
3635
3636-static GtkWidget *
3637-menu_get_popup_highlight (XpadPad *pad, GtkAccelGroup *accel_group)
3638-{
3639- GtkWidget *menu, *item;
3640-
3641- menu = gtk_menu_new ();
3642- gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
3643-
3644- MENU_ADD (_("Cu_t"), "edit-cut", 0, 0, xpad_pad_cut);
3645- MENU_ADD (_("_Copy"), "edit-copy", 0, 0, xpad_pad_copy);
3646- MENU_ADD (_("_Paste"), "edit-paste", 0, 0, xpad_pad_paste);
3647- g_object_set_data (G_OBJECT (menu), "paste", item);
3648- MENU_ADD_SEP ();
3649- MENU_ADD (_("_Bold"), "format-text-bold", GDK_KEY_b, GDK_CONTROL_MASK, menu_bold);
3650- MENU_ADD (_("_Italic"), "format-text-italic", GDK_KEY_i, GDK_CONTROL_MASK, menu_italic);
3651- MENU_ADD (_("_Underline"), "format-text-underline", GDK_KEY_u, GDK_CONTROL_MASK, menu_underline);
3652- MENU_ADD (_("_Strikethrough"), "format-text-strikethrough", 0, 0, menu_strikethrough);
3653-
3654- gtk_widget_show_all (menu);
3655-
3656- return menu;
3657-}
3658-
3659-static void
3660-menu_prep_popup_highlight (XpadPad *pad, GtkWidget *menu)
3661-{
3662- /* A dirty way to silence the compiler for these unused variables. */
3663- (void) pad;
3664-
3665- GtkWidget *item;
3666- GtkClipboard *clipboard;
3667-
3668- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3669-
3670- item = g_object_get_data (G_OBJECT (menu), "paste");
3671- if (item)
3672- gtk_widget_set_sensitive (item, gtk_clipboard_wait_is_text_available (clipboard));
3673-}
3674-
3675-static void
3676-menu_popup (XpadPad *pad)
3677-{
3678- g_signal_handlers_block_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL);
3679- pad->priv->toolbar_timeout = 0;
3680-}
3681-
3682-static void
3683-menu_popdown (XpadPad *pad)
3684-{
3685- cairo_rectangle_int_t rect;
3686-
3687- /* We must check if we disabled off of pad and start the timeout if so. */
3688- rect.x = 10;
3689- rect.y = 10;
3690- rect.width = 1;
3691- rect.height = 1;
3692-
3693- if (!pad->priv->toolbar_timeout && !gtk_widget_intersect (GTK_WIDGET (pad), &rect, NULL))
3694- pad->priv->toolbar_timeout = g_timeout_add (1000, (GSourceFunc) toolbar_timeout, pad);
3695-
3696- g_signal_handlers_unblock_matched (pad, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer) xpad_pad_leave_notify_event, NULL);
3697-}
3698-
3699-static void
3700-xpad_pad_popup (XpadPad *pad, GdkEventButton *event)
3701-{
3702- GtkTextBuffer *buffer;
3703- GtkWidget *menu;
3704-
3705- buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pad->priv->textview));
3706-
3707- if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
3708- {
3709- menu = pad->priv->highlight_menu;
3710- menu_prep_popup_highlight (pad, menu);
3711- }
3712- else
3713- {
3714- menu = pad->priv->menu;
3715- menu_prep_popup_no_highlight (pad, menu);
3716- }
3717-
3718- if (!menu)
3719- return;
3720-
3721- menu_popup (pad);
3722-
3723- if (event)
3724- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
3725- else
3726- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
3727-}
3728-
3729 /* These functions below are used to reduce the amounts of writes, hence improve the performance. */
3730 void xpad_pad_save_content_delayed (XpadPad *pad)
3731 {
3732- pad->priv->unsaved_content = TRUE;
3733- xpad_periodic_save_content_delayed (pad);
3734+ pad->priv->unsaved_content = TRUE;
3735+ xpad_periodic_save_content_delayed (pad);
3736 }
3737+
3738 void xpad_pad_save_info_delayed (XpadPad *pad)
3739 {
3740- pad->priv->unsaved_info = TRUE;
3741- xpad_periodic_save_info_delayed (pad);
3742+ pad->priv->unsaved_info = TRUE;
3743+ xpad_periodic_save_info_delayed (pad);
3744 }
3745+
3746 void xpad_pad_save_unsaved (XpadPad *pad)
3747 {
3748- if (pad->priv->unsaved_content)
3749- xpad_pad_save_content (pad);
3750- if (pad->priv->unsaved_info)
3751- xpad_pad_save_info (pad);
3752+ if (pad->priv->unsaved_content)
3753+ xpad_pad_save_content (pad);
3754+ if (pad->priv->unsaved_info)
3755+ xpad_pad_save_info (pad);
3756+}
3757+
3758+/* Class pad - constructor */
3759+static void
3760+xpad_pad_class_init (XpadPadClass *klass)
3761+{
3762+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
3763+
3764+ gobject_class->constructed = xpad_pad_constructed;
3765+ gobject_class->set_property = xpad_pad_set_property;
3766+ gobject_class->get_property = xpad_pad_get_property;
3767+ gobject_class->dispose = xpad_pad_dispose;
3768+ gobject_class->finalize = xpad_pad_finalize;
3769+
3770+ signals[CLOSED] =
3771+ g_signal_new ("closed",
3772+ G_OBJECT_CLASS_TYPE (gobject_class),
3773+ G_SIGNAL_RUN_FIRST,
3774+ G_STRUCT_OFFSET (XpadPadClass, closed),
3775+ NULL, NULL,
3776+ g_cclosure_marshal_VOID__VOID,
3777+ G_TYPE_NONE,
3778+ 0);
3779+
3780+ /* Properties */
3781+ obj_prop[PROP_GROUP] = g_param_spec_pointer ("group", "Pad group", "Pad group for this pad", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
3782+ obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
3783+
3784+ g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop);
3785+}
3786+
3787+/* Class pad - initializer */
3788+static void
3789+xpad_pad_init (XpadPad *pad)
3790+{
3791+ pad->priv = xpad_pad_get_instance_private (pad);
3792+
3793+ pad->priv->x = 0;
3794+ pad->priv->y = 0;
3795+ pad->priv->location_valid = FALSE;
3796+ pad->priv->infoname = NULL;
3797+ pad->priv->contentname = NULL;
3798+ pad->priv->textview = NULL;
3799+ pad->priv->scrollbar = NULL;
3800+ pad->priv->toolbar = NULL;
3801+ pad->priv->toolbar_timeout = 0;
3802+ pad->priv->toolbar_height = 0;
3803+ pad->priv->toolbar_expanded = FALSE;
3804+ pad->priv->toolbar_pad_resized = TRUE;
3805+ pad->priv->properties = NULL;
3806+ pad->priv->unsaved_content = FALSE;
3807+ pad->priv->unsaved_info = FALSE;
3808 }
3809
3810=== modified file 'src/xpad-periodic.c'
3811--- src/xpad-periodic.c 2014-06-19 09:08:49 +0000
3812+++ src/xpad-periodic.c 2014-09-08 13:22:52 +0000
3813@@ -20,246 +20,269 @@
3814 */
3815
3816 #include "../config.h"
3817+
3818 #include "xpad-periodic.h"
3819-#include <glib/gi18n.h>
3820+
3821 #include <stdlib.h>
3822 #include <string.h>
3823
3824+#include <glib/gi18n.h>
3825+
3826 #ifdef SHOW_DEBUG
3827 # define G_PRINT_DBG g_print
3828 #else
3829 # define G_PRINT_DBG gprint_ignore
3830 #endif
3831
3832-#define TIMEOUT_SECONDS 4
3833+#define TIMEOUT_SECONDS 4
3834
3835 struct sigref_ {
3836- const char * signame;
3837- XpadPeriodicFunc func_ptr;
3838- gpointer data;
3839+ const char *signame;
3840+ XpadPeriodicFunc func_ptr;
3841+ gpointer data;
3842 };
3843
3844 typedef struct sigref_ Xpadsigref;
3845
3846 typedef struct {
3847- /************************
3848- count = a clock tick count
3849- after_id = the timeout id
3850- ************************/
3851- int count;
3852- int after_id;
3853+ /************************
3854+ count = a clock tick count
3855+ after_id = the timeout id
3856+ ************************/
3857+ int count;
3858+ int after_id;
3859
3860- /************************
3861- template = a list of signal names and function pointers
3862- template_len = the length of 'template'
3863- sigs = a list of signal names, function pointers and data
3864- sigs_len = the length of 'sigs'
3865- ************************/
3866- Xpadsigref * template;
3867- int template_len;
3868- Xpadsigref * sigs;
3869- int sigs_len;
3870+ /************************
3871+ template = a list of signal names and function pointers
3872+ template_len = the length of 'template'
3873+ sigs = a list of signal names, function pointers and data
3874+ sigs_len = the length of 'sigs'
3875+ ************************/
3876+ Xpadsigref *template;
3877+ int template_len;
3878+ Xpadsigref *sigs;
3879+ int sigs_len;
3880 } XpadPeriodic;
3881
3882-
3883-/* prototypes */
3884-static gint xppd_intercept (gpointer);
3885 static gint gprint_ignore(const char *, ...);
3886-static void xpad_periodic_signal (const char * cbname, void * xpad_pad);
3887-static void xpad_periodic_error_exit (const char *, ...);
3888-
3889-static gboolean str_equal (const char *, const char *);
3890
3891 /* global variables */
3892 static XpadPeriodic xpptr [1];
3893
3894 /* Functions start here */
3895
3896-gboolean xpad_periodic_init (void)
3897-{
3898- memset(xpptr, 0, sizeof(*xpptr));
3899- xpptr->after_id = (gint) g_timeout_add_seconds(TIMEOUT_SECONDS, xppd_intercept, xpptr);
3900-
3901- /* Allocate space for the signal references. */
3902- int tlen = xpptr->template_len = 5;
3903- int slen = xpptr->sigs_len = 20;
3904- xpptr->template = g_malloc0((gsize) tlen * sizeof(Xpadsigref));
3905- xpptr->sigs = g_malloc0((gsize) slen * sizeof(Xpadsigref));
3906-
3907- return TRUE;
3908-}
3909-
3910-void xpad_periodic_close (void)
3911-{
3912- if (xpptr->after_id) { g_source_remove((guint) xpptr->after_id); }
3913- /* Free the signal references memory. */
3914- g_free(xpptr->template);
3915- g_free(xpptr->sigs);
3916- /* Signal that this structure is now cleared. */
3917- memset(xpptr, 0, sizeof(*xpptr));
3918-}
3919-
3920-/************************
3921-xppd_intercept - intercepts a timer tick
3922-
3923- This function intercepts a timer tick and iterates
3924- over the signal references. Any signal references that
3925- are fully stocked with signal names, function pointers
3926- and data pointers are invoked.
3927-
3928- IOW (In other words), the function pointer is called with the
3929- right data pointer.
3930-************************/
3931-gint xppd_intercept (gpointer cdata)
3932+void
3933+xpad_periodic_close (void)
3934+{
3935+ if (xpptr->after_id) { g_source_remove((guint) xpptr->after_id); }
3936+ /* Free the signal references memory. */
3937+ g_free(xpptr->template);
3938+ g_free(xpptr->sigs);
3939+ /* Signal that this structure is now cleared. */
3940+ memset(xpptr, 0, sizeof(*xpptr));
3941+}
3942+
3943+ /************************
3944+ xppd_intercept - intercepts a timer tick
3945+
3946+ This function intercepts a timer tick and iterates
3947+ over the signal references. Any signal references that
3948+ are fully stocked with signal names, function pointers
3949+ and data pointers are invoked.
3950+
3951+ IOW (In other words), the function pointer is called with the
3952+ right data pointer.
3953+ ************************/
3954+gint
3955+xppd_intercept (gpointer cdata)
3956 {
3957 /* A dirty way to silence the compiler for these unused variables. */
3958 (void) cdata;
3959
3960- int cnt=0;
3961- XpadPeriodicFunc fnptr=0;
3962- xpptr->count++; /* increment tick count */
3963-
3964- G_PRINT_DBG("xppd tick: %4d\n", xpptr->count);
3965-
3966- for (cnt = 0; cnt < xpptr->sigs_len; ++cnt) {
3967- Xpadsigref * sig_item = xpptr->sigs + cnt;
3968- if (sig_item->signame && sig_item->func_ptr && sig_item->data) {
3969- fnptr = sig_item->func_ptr;
3970- (*fnptr)(sig_item->data);
3971- G_PRINT_DBG("invoked %s : %p : %p\n", sig_item->signame,
3972- sig_item->func_ptr, sig_item->data);
3973- memset(sig_item, 0, sizeof(*sig_item));
3974- }
3975- }
3976-
3977- return TRUE;
3978-}
3979-
3980-/************************
3981- Xpad_periodic_set_callback():
3982- This function prepares a callback function to be invoked
3983- for an event name such as "save-content" or "save-info".
3984-
3985- cbname : event name (or callback function name)
3986- func : function address
3987-
3988- Returns true if a callback was registered.
3989-************************/
3990-gboolean xpad_periodic_set_callback (
3991- const char * cbname,
3992- XpadPeriodicFunc func)
3993-{
3994- int index = 0;
3995- gboolean isdone=FALSE;
3996- if (0 == func) { return FALSE; }
3997- if (0 == cbname || 0==*cbname) { return FALSE; }
3998-
3999- /* Find an open slot for signal (callback) references and
4000- insert this one. */
4001- for (index = 0; index < xpptr->template_len; ++index) {
4002- /* Store a pointer to the current signal item. */
4003- Xpadsigref * sig_item = xpptr->template + index;
4004-
4005- /* If it's empty, set it. */
4006- if (0 == sig_item->signame) {
4007- sig_item->signame = cbname;
4008- sig_item->func_ptr = func;
4009- isdone = TRUE;
4010- break;
4011- }
4012- }
4013-
4014- if (! isdone) {
4015- g_print("Failed to install signal callback: %s\n", cbname);
4016- exit(1);
4017- }
4018-
4019- return isdone;
4020-}
4021-
4022-void xpad_periodic_save_info_delayed (void * xpad_pad)
4023-{
4024- xpad_periodic_signal("save-info", xpad_pad);
4025-}
4026-
4027-void xpad_periodic_save_content_delayed (void * xpad_pad)
4028-{
4029- xpad_periodic_signal("save-content", xpad_pad);
4030-}
4031-
4032-static void xpad_periodic_signal (const char * cbname, void * xpad_pad) {
4033- int isdone = 0;
4034- int tnx=0, snx=0;
4035- XpadPeriodicFunc func_ptr = 0;
4036- Xpadsigref * sig_item = 0;
4037-
4038- if (0 == cbname || 0==*cbname) { return; }
4039- if (0 == xpad_pad) { return; }
4040-
4041- /* Get the callback function address */
4042- for (tnx = 0; tnx < xpptr->template_len; ++tnx) {
4043- if (str_equal(xpptr->template[tnx].signame, cbname)) {
4044- func_ptr = xpptr->template[tnx].func_ptr;
4045- break;
4046- }
4047- }
4048-
4049- /* If there is no callback address, we can't continue. */
4050- if (! func_ptr) {
4051- xpad_periodic_error_exit("Can't find signal function address: %s\n", cbname);
4052- }
4053-
4054- /* Check that this event is not already present.
4055- If it is present, don't do anything more. */
4056- for (snx = 0; snx < xpptr->sigs_len; ++snx) {
4057- sig_item = xpptr->sigs + snx;
4058- if (str_equal(sig_item->signame,cbname) &&
4059- (xpad_pad == sig_item->data)) {
4060- G_PRINT_DBG("Already got signal: %s\n", cbname);
4061- return;
4062- }
4063- }
4064-
4065- /* Find a suitable slot for the signal reference and set it. */
4066- for (snx = 0; snx < xpptr->sigs_len; ++snx) {
4067- gint doadd = 0;
4068- sig_item = xpptr->sigs + snx;
4069-
4070- doadd += (str_equal(sig_item->signame, cbname));
4071- doadd += (0 == sig_item->signame);
4072-
4073- if (doadd) {
4074- sig_item->signame = cbname;
4075- sig_item->func_ptr = func_ptr;
4076- sig_item->data = xpad_pad;
4077- isdone = TRUE;
4078- break;
4079- }
4080- }
4081-
4082- if (! isdone) {
4083- xpad_periodic_error_exit("Could not schedule event: %s\n", cbname);
4084- }
4085-}
4086-
4087-gboolean str_equal (const char * s1, const char * s2) {
4088- if (0 == s1 || 0==s2) { return FALSE; }
4089- if (s1 == s2) { return TRUE; }
4090- return (0 == strcmp(s1, s2));
4091-}
4092-
4093-gint gprint_ignore (const char * fmt, ...)
4094+ int cnt=0;
4095+ XpadPeriodicFunc fnptr=0;
4096+ xpptr->count++; /* increment tick count */
4097+
4098+ G_PRINT_DBG ("xppd tick: %4d\n", xpptr->count);
4099+
4100+ for (cnt = 0; cnt < xpptr->sigs_len; ++cnt)
4101+ {
4102+ Xpadsigref * sig_item = xpptr->sigs + cnt;
4103+ if (sig_item->signame && sig_item->func_ptr && sig_item->data)
4104+ {
4105+ fnptr = sig_item->func_ptr;
4106+ (*fnptr)(sig_item->data);
4107+ G_PRINT_DBG ("invoked %s : %p : %p\n", sig_item->signame,
4108+ sig_item->func_ptr, sig_item->data);
4109+ memset(sig_item, 0, sizeof(*sig_item));
4110+ }
4111+ }
4112+
4113+ return TRUE;
4114+}
4115+
4116+ /************************
4117+ Xpad_periodic_set_callback():
4118+ This function prepares a callback function to be invoked
4119+ for an event name such as "save-content" or "save-info".
4120+
4121+ cbname : event name (or callback function name)
4122+ func : function address
4123+
4124+ Returns true if a callback was registered.
4125+ ************************/
4126+gboolean
4127+xpad_periodic_set_callback (const char * cbname,
4128+ XpadPeriodicFunc func)
4129+{
4130+ int index = 0;
4131+ gboolean isdone=FALSE;
4132+ if (0 == func) { return FALSE; }
4133+ if (0 == cbname || 0==*cbname) { return FALSE; }
4134+
4135+ /* Find an open slot for signal (callback) references and
4136+ insert this one. */
4137+ for (index = 0; index < xpptr->template_len; ++index)
4138+ {
4139+ /* Store a pointer to the current signal item. */
4140+ Xpadsigref * sig_item = xpptr->template + index;
4141+
4142+ /* If it's empty, set it. */
4143+ if (0 == sig_item->signame)
4144+ {
4145+ sig_item->signame = cbname;
4146+ sig_item->func_ptr = func;
4147+ isdone = TRUE;
4148+ break;
4149+ }
4150+ }
4151+
4152+ if (! isdone)
4153+ {
4154+ g_print ("Failed to install signal callback: %s\n", cbname);
4155+ exit (1);
4156+ }
4157+
4158+ return isdone;
4159+}
4160+
4161+gboolean
4162+xpad_periodic_init (void)
4163+{
4164+ memset(xpptr, 0, sizeof(*xpptr));
4165+ xpptr->after_id = (gint) g_timeout_add_seconds(TIMEOUT_SECONDS, xppd_intercept, xpptr);
4166+
4167+ /* Allocate space for the signal references. */
4168+ int tlen = xpptr->template_len = 5;
4169+ int slen = xpptr->sigs_len = 20;
4170+ xpptr->template = g_malloc0((gsize) tlen * sizeof(Xpadsigref));
4171+ xpptr->sigs = g_malloc0((gsize) slen * sizeof(Xpadsigref));
4172+
4173+ return TRUE;
4174+}
4175+
4176+static void
4177+xpad_periodic_error_exit (const char * fmt, ...)
4178+{
4179+ va_list app;
4180+ va_start (app, fmt);
4181+ g_print (fmt, app);
4182+ va_end (app);
4183+ exit (1);
4184+}
4185+
4186+static void
4187+xpad_periodic_signal (const char * cbname,
4188+ void * xpad_pad)
4189+{
4190+ int isdone = 0;
4191+ int tnx=0, snx=0;
4192+ XpadPeriodicFunc func_ptr = 0;
4193+ Xpadsigref * sig_item = 0;
4194+
4195+ if (0 == cbname || 0==*cbname) { return; }
4196+ if (0 == xpad_pad) { return; }
4197+
4198+ /* Get the callback function address */
4199+ for (tnx = 0; tnx < xpptr->template_len; ++tnx)
4200+ {
4201+ if (str_equal (xpptr->template[tnx].signame, cbname))
4202+ {
4203+ func_ptr = xpptr->template[tnx].func_ptr;
4204+ break;
4205+ }
4206+ }
4207+
4208+ /* If there is no callback address, we can't continue. */
4209+ if (! func_ptr)
4210+ {
4211+ xpad_periodic_error_exit ("Can't find signal function address: %s\n", cbname);
4212+ }
4213+
4214+ /* Check that this event is not already present.
4215+ If it is present, don't do anything more. */
4216+ for (snx = 0; snx < xpptr->sigs_len; ++snx)
4217+ {
4218+ sig_item = xpptr->sigs + snx;
4219+ if (str_equal(sig_item->signame,cbname) &&
4220+ (xpad_pad == sig_item->data))
4221+ {
4222+ G_PRINT_DBG ("Already got signal: %s\n", cbname);
4223+ return;
4224+ }
4225+ }
4226+
4227+ /* Find a suitable slot for the signal reference and set it. */
4228+ for (snx = 0; snx < xpptr->sigs_len; ++snx)
4229+ {
4230+ gint doadd = 0;
4231+ sig_item = xpptr->sigs + snx;
4232+
4233+ doadd += (str_equal (sig_item->signame, cbname));
4234+ doadd += (0 == sig_item->signame);
4235+
4236+ if (doadd)
4237+ {
4238+ sig_item->signame = cbname;
4239+ sig_item->func_ptr = func_ptr;
4240+ sig_item->data = xpad_pad;
4241+ isdone = TRUE;
4242+ break;
4243+ }
4244+ }
4245+
4246+ if (! isdone)
4247+ {
4248+ xpad_periodic_error_exit ("Could not schedule event: %s\n", cbname);
4249+ }
4250+}
4251+
4252+void
4253+xpad_periodic_save_info_delayed (void * xpad_pad)
4254+{
4255+ xpad_periodic_signal ("save-info", xpad_pad);
4256+}
4257+
4258+void
4259+xpad_periodic_save_content_delayed (void * xpad_pad)
4260+{
4261+ xpad_periodic_signal ("save-content", xpad_pad);
4262+}
4263+
4264+gboolean
4265+str_equal (const char * s1,
4266+ const char * s2)
4267+{
4268+ if (0 == s1 || 0==s2) { return FALSE; }
4269+ if (s1 == s2) { return TRUE; }
4270+ return (0 == strcmp(s1, s2));
4271+}
4272+
4273+gint
4274+gprint_ignore (const char * fmt, ...)
4275 {
4276 /* A dirty way to silence the compiler for these unused variables. */
4277 (void) fmt;
4278
4279- return 0;
4280-}
4281-
4282-static void xpad_periodic_error_exit (const char * fmt, ...) {
4283- va_list app;
4284- va_start(app, fmt);
4285- g_print(fmt, app);
4286- va_end(app);
4287- exit(1);
4288+ return 0;
4289 }
4290
4291=== modified file 'src/xpad-periodic.h'
4292--- src/xpad-periodic.h 2014-06-19 09:08:49 +0000
4293+++ src/xpad-periodic.h 2014-09-08 13:22:52 +0000
4294@@ -19,11 +19,13 @@
4295
4296 */
4297
4298-#ifndef XPAD_PERIODIC_H
4299-#define XPAD_PERIODIC_H
4300+#ifndef __XPAD_PERIODIC_H__
4301+#define __XPAD_PERIODIC_H__
4302
4303 #include <glib.h>
4304
4305+G_BEGIN_DECLS
4306+
4307 typedef void (*XpadPeriodicFunc)(void *);
4308
4309 /* Callback function codes: save-content, save-info */
4310@@ -51,4 +53,6 @@
4311 void xpad_periodic_save_content_delayed (void * xpad_pad);
4312 void xpad_periodic_save_info_delayed (void * xpad_pad);
4313
4314-#endif /* XPAD_PERIODIC_H */
4315+G_END_DECLS
4316+
4317+#endif /* __XPAD_PERIODIC_H__ */
4318
4319=== modified file 'src/xpad-preferences.c'
4320--- src/xpad-preferences.c 2014-07-20 16:36:07 +0000
4321+++ src/xpad-preferences.c 2014-09-08 13:22:52 +0000
4322@@ -20,10 +20,12 @@
4323 */
4324
4325 #include "../config.h"
4326+
4327 #include "xpad-preferences.h"
4328+#include "xpad-app.h"
4329+
4330 #include <glib/gi18n.h>
4331 #include <gtk/gtk.h>
4332-#include "xpad-app.h"
4333
4334 struct XpadPreferencesPrivate
4335 {
4336@@ -36,12 +38,12 @@
4337 GtkWidget *fontbutton;
4338 GtkWidget *colorcheck;
4339 GtkWidget *anticolorcheck;
4340- GtkWidget *colorbox;
4341+ GtkWidget *colorbox;
4342 GtkWidget *textbutton;
4343 GtkWidget *backbutton;
4344 GtkWidget *autostart_xpad;
4345 GtkWidget *autostart_wait_systray;
4346- GtkWidget *autostart_delay;
4347+ GtkWidget *autostart_delay;
4348 GtkWidget *autostart_new_pad;
4349 GtkWidget *autostart_sticky;
4350 GtkWidget *autostart_display_pads;
4351@@ -50,7 +52,7 @@
4352 GtkWidget *editcheck;
4353 GtkWidget *confirmcheck;
4354
4355- gulong fontcheck_handler;
4356+ gulong fontcheck_handler;
4357 gulong font_handler;
4358 gulong colorcheck_handler;
4359 gulong text_handler;
4360@@ -60,7 +62,7 @@
4361 gulong autostart_delay_handler;
4362 gulong autostart_new_pad_handler;
4363 gulong autostart_sticky_handler;
4364- gulong autostart_display_pads_handler;
4365+ gulong autostart_display_pads_handler;
4366 gulong tray_enabled_handler;
4367 gulong tray_click_handler;
4368 gulong editcheck_handler;
4369@@ -83,51 +85,13 @@
4370
4371 G_DEFINE_TYPE_WITH_PRIVATE (XpadPreferences, xpad_preferences, GTK_TYPE_DIALOG)
4372
4373-static void xpad_preferences_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
4374-static void xpad_preferences_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
4375-static void xpad_preferences_constructed (GObject *object);
4376-static void xpad_preferences_finalize (GObject *object);
4377-static void xpad_preferences_response (GtkDialog *dialog, gint response);
4378-
4379-static void change_font_check (GtkToggleButton *button, XpadPreferences *pref);
4380-static void change_font_face (GtkFontButton *button, XpadPreferences *pref);
4381-static void change_color_check (GtkToggleButton *button, XpadPreferences *pref);
4382-static void change_text_color (GtkColorChooser *chooser, XpadPreferences *pref);
4383-static void change_back_color (GtkColorChooser *chooser, XpadPreferences *pref);
4384-static void change_autostart_xpad (GtkToggleButton *button, XpadPreferences *pref);
4385-static void change_autostart_wait_systray (GtkToggleButton *button, XpadPreferences *pref);
4386-static void change_autostart_delay (GtkComboBox *box, XpadPreferences *pref);
4387-static void change_autostart_new_pad (GtkToggleButton *button, XpadPreferences *pref);
4388-static void change_autostart_sticky (GtkToggleButton *button, XpadPreferences *pref);
4389-static void change_autostart_display_pads (GtkComboBox *box, XpadPreferences *pref);
4390-static void change_tray_enabled (GtkToggleButton *button, XpadPreferences *pref);
4391-static void change_tray_click (GtkComboBox *box, XpadPreferences *pref);
4392-static void change_edit_check (GtkToggleButton *button, XpadPreferences *pref);
4393-static void change_confirm_check (GtkToggleButton *button, XpadPreferences *pref);
4394-
4395-static void notify_fontname (XpadPreferences *pref);
4396-static void notify_text_color (XpadPreferences *pref);
4397-static void notify_back_color (XpadPreferences *pref);
4398-static void notify_autostart_xpad (XpadPreferences *pref);
4399-static void notify_autostart_wait_systray (XpadPreferences *pref);
4400-static void notify_autostart_delay (XpadPreferences *pref);
4401-static void notify_autostart_new_pad (XpadPreferences *pref);
4402-static void notify_autostart_sticky (XpadPreferences *pref);
4403-static void notify_autostart_display_pads (XpadPreferences *pref);
4404-static void notify_tray_enabled (XpadPreferences *pref);
4405-static void notify_tray_click (XpadPreferences *pref);
4406-static void notify_edit (XpadPreferences *pref);
4407-static void notify_confirm (XpadPreferences *pref);
4408-
4409-static GtkWidget * create_label (const gchar *label_text);
4410-
4411 static GtkWidget *_xpad_preferences = NULL;
4412
4413 enum
4414 {
4415- PROP_0,
4416- PROP_SETTINGS,
4417- N_PROPERTIES
4418+ PROP_0,
4419+ PROP_SETTINGS,
4420+ N_PROPERTIES
4421 };
4422
4423 static GParamSpec *obj_prop[N_PROPERTIES] = { NULL, };
4424@@ -144,25 +108,447 @@
4425 gtk_window_present (GTK_WINDOW (_xpad_preferences));
4426 }
4427
4428-static void
4429-xpad_preferences_class_init (XpadPreferencesClass *klass)
4430-{
4431- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
4432-
4433- gobject_class->constructed = xpad_preferences_constructed;
4434- gobject_class->set_property = xpad_preferences_set_property;
4435- gobject_class->get_property = xpad_preferences_get_property;
4436- gobject_class->finalize = xpad_preferences_finalize;
4437-
4438- obj_prop[PROP_SETTINGS] = g_param_spec_pointer ("settings", "Xpad settings", "Xpad global settings", G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
4439-
4440- g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_prop);
4441-}
4442-
4443-static void
4444-xpad_preferences_init (XpadPreferences *pref)
4445-{
4446- pref->priv = xpad_preferences_get_instance_private (pref);
4447+static GtkWidget * create_label (const gchar *label_text)
4448+{
4449+ GtkWidget *label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL,
4450+ "label", g_strconcat ("<b>", label_text, "</b>", NULL),
4451+ "use-markup", TRUE,
4452+ "xalign", 0.0,
4453+ NULL));
4454+ return label;
4455+}
4456+
4457+static void
4458+xpad_preferences_set_property (GObject *object,
4459+ guint prop_id,
4460+ const GValue *value,
4461+ GParamSpec *pspec)
4462+{
4463+ XpadPreferences *pref = XPAD_PREFERENCES (object);
4464+
4465+ switch (prop_id)
4466+ {
4467+ case PROP_SETTINGS:
4468+ pref->priv->settings = g_value_get_pointer (value);
4469+ g_object_ref (pref->priv->settings);
4470+ break;
4471+
4472+ default:
4473+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4474+ break;
4475+ }
4476+}
4477+
4478+static void
4479+xpad_preferences_get_property (GObject *object,
4480+ guint prop_id,
4481+ GValue *value,
4482+ GParamSpec *pspec)
4483+{
4484+ XpadPreferences *pref = XPAD_PREFERENCES (object);
4485+
4486+ switch (prop_id)
4487+ {
4488+ case PROP_SETTINGS:
4489+ g_value_set_pointer (value, pref->priv->settings);
4490+ break;
4491+
4492+ default:
4493+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4494+ break;
4495+ }
4496+}
4497+
4498+static void
4499+xpad_preferences_finalize (GObject *object)
4500+{
4501+ XpadPreferences *pref = XPAD_PREFERENCES (object);
4502+
4503+ if (pref->priv->settings)
4504+ g_signal_handlers_disconnect_matched (pref->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pref);
4505+
4506+ G_OBJECT_CLASS (xpad_preferences_parent_class)->finalize (object);
4507+}
4508+
4509+static void
4510+xpad_preferences_response (GtkDialog *dialog,
4511+ gint response)
4512+{
4513+ if (response == GTK_RESPONSE_CLOSE)
4514+ gtk_widget_destroy (GTK_WIDGET (dialog));
4515+}
4516+
4517+static void
4518+change_font_check (GtkToggleButton *button,
4519+ XpadPreferences *pref)
4520+{
4521+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_font_handler);
4522+ if (!gtk_toggle_button_get_active (button))
4523+ g_object_set (pref->priv->settings, "fontname", NULL, NULL);
4524+ else
4525+ g_object_set (pref->priv->settings, "fontname", gtk_font_button_get_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton)), NULL);
4526+ gtk_widget_set_sensitive (pref->priv->fontbutton, gtk_toggle_button_get_active (button));
4527+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_font_handler);
4528+}
4529+
4530+static void
4531+change_font_face (GtkFontButton *button,
4532+ XpadPreferences *pref)
4533+{
4534+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_font_handler);
4535+ g_object_set (pref->priv->settings, "fontname", gtk_font_button_get_font_name (button), NULL);
4536+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_font_handler);
4537+}
4538+
4539+static void
4540+change_color_check (GtkToggleButton *button,
4541+ XpadPreferences *pref)
4542+{
4543+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_text_handler);
4544+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_back_handler);
4545+
4546+ if (!gtk_toggle_button_get_active (button))
4547+ g_object_set (pref->priv->settings, "text-color", NULL, "back-color", NULL, NULL);
4548+ else
4549+ {
4550+ GdkRGBA text_color, back_color;
4551+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (pref->priv->textbutton), &text_color);
4552+ gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), &back_color);
4553+ g_object_set (pref->priv->settings, "text-color", &text_color, "back-color", &back_color, NULL);
4554+ }
4555+
4556+ gtk_widget_set_sensitive (pref->priv->colorbox, gtk_toggle_button_get_active (button));
4557+
4558+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_text_handler);
4559+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_back_handler);
4560+}
4561+
4562+static void
4563+change_text_color (GtkColorChooser *chooser,
4564+ XpadPreferences *pref)
4565+{
4566+ GdkRGBA text_color = {0, 0, 0, 0};
4567+ gtk_color_chooser_get_rgba (chooser, &text_color);
4568+
4569+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_text_handler);
4570+ g_object_set (pref->priv->settings, "text-color", &text_color, NULL);
4571+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_text_handler);
4572+}
4573+
4574+static void
4575+change_back_color (GtkColorChooser *chooser,
4576+ XpadPreferences *pref)
4577+{
4578+ GdkRGBA back_color = {0, 0, 0, 0};
4579+ gtk_color_chooser_get_rgba (chooser, &back_color);
4580+
4581+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_back_handler);
4582+ g_object_set (pref->priv->settings, "back-color", &back_color, NULL);
4583+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_back_handler);
4584+}
4585+
4586+static void
4587+change_autostart_xpad (GtkToggleButton *button,
4588+ XpadPreferences *pref)
4589+{
4590+ g_object_set (pref->priv->settings, "autostart-xpad", gtk_toggle_button_get_active (button), NULL);
4591+}
4592+
4593+static void
4594+change_autostart_wait_systray (GtkToggleButton *button,
4595+ XpadPreferences *pref)
4596+{
4597+ GKeyFile *keyfile;
4598+ GKeyFileFlags flags;
4599+ GError *error = NULL;
4600+ char *filename;
4601+ gboolean wait_systray;
4602+
4603+ wait_systray = gtk_toggle_button_get_active (button);
4604+
4605+ /* Create a new GKeyFile object and a bitwise list of flags. */
4606+ keyfile = g_key_file_new ();
4607+ filename = g_strdup_printf ("%s/.config/autostart/xpad.desktop", g_get_home_dir());
4608+ flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
4609+
4610+ /* Load the GKeyFile from xpad.desktop or show an error message. */
4611+ if (!g_key_file_load_from_file (keyfile, filename, flags, &error)) {
4612+ gchar *errtext;
4613+ errtext = g_strdup_printf (_("Could not load %s\n%s"), filename, error->message);
4614+ xpad_app_error (NULL, _("Error changing wait for systray setting"), errtext);
4615+ g_free (errtext);
4616+
4617+ gtk_toggle_button_set_active (button, !wait_systray);
4618+ return;
4619+ }
4620+
4621+ g_key_file_set_boolean (keyfile, "Desktop Entry", "X-LXQt-Need-Tray", wait_systray);
4622+
4623+ if (!g_key_file_save_to_file (keyfile, filename, &error)) {
4624+ gchar *errtext;
4625+ errtext = g_strdup_printf (_("Could not save %s\n%s"), filename, error->message);
4626+ xpad_app_error (NULL, _("Error changing wait for systray setting"), errtext);
4627+ g_free (errtext);
4628+
4629+ gtk_toggle_button_set_active (button, !wait_systray);
4630+ return;
4631+ }
4632+
4633+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_wait_systray_handler);
4634+ g_object_set (pref->priv->settings, "autostart-wait-systray", wait_systray, NULL);
4635+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_wait_systray_handler);
4636+}
4637+
4638+static void
4639+change_autostart_new_pad (GtkToggleButton *button,
4640+ XpadPreferences *pref)
4641+{
4642+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_new_pad_handler);
4643+ g_object_set (pref->priv->settings, "autostart-new-pad", gtk_toggle_button_get_active (button), NULL);
4644+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_new_pad_handler);
4645+}
4646+
4647+static void
4648+change_autostart_sticky (GtkToggleButton *button,
4649+ XpadPreferences *pref)
4650+{
4651+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_sticky_handler);
4652+ g_object_set (pref->priv->settings, "autostart-sticky", gtk_toggle_button_get_active (button), NULL);
4653+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_sticky_handler);
4654+}
4655+
4656+static void
4657+change_autostart_delay (GtkComboBox *box,
4658+ XpadPreferences *pref)
4659+{
4660+ g_signal_handler_block(pref->priv->settings, pref->priv->notify_autostart_delay_handler);
4661+ g_object_set (pref->priv->settings, "autostart-delay", (guint) gtk_combo_box_get_active (box), NULL);
4662+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_autostart_delay_handler);
4663+}
4664+
4665+static void
4666+change_autostart_display_pads (GtkComboBox *box,
4667+ XpadPreferences *pref)
4668+{
4669+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_autostart_display_pads_handler);
4670+ g_object_set (pref->priv->settings, "autostart-display-pads", (guint) gtk_combo_box_get_active (box), NULL);
4671+ g_signal_handler_unblock(pref->priv->settings, pref->priv->notify_autostart_display_pads_handler);
4672+}
4673+
4674+static void
4675+change_tray_enabled (GtkToggleButton *button,
4676+ XpadPreferences *pref)
4677+{
4678+ g_object_set (pref->priv->settings, "tray-enabled", gtk_toggle_button_get_active (button), NULL);
4679+}
4680+
4681+static void
4682+change_tray_click (GtkComboBox *box,
4683+ XpadPreferences *pref)
4684+{
4685+ g_signal_handler_block(pref->priv->settings, pref->priv->notify_tray_click_handler);
4686+ g_object_set (pref->priv->settings, "tray-click-configuration", (guint) gtk_combo_box_get_active (box), NULL);
4687+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_tray_click_handler);
4688+}
4689+
4690+static void
4691+change_edit_check (GtkToggleButton *button, XpadPreferences *pref)
4692+{
4693+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_edit_handler);
4694+ g_object_set (pref->priv->settings, "edit-lock", gtk_toggle_button_get_active (button), NULL);
4695+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_edit_handler);
4696+}
4697+
4698+static void
4699+change_confirm_check (GtkToggleButton *button,
4700+ XpadPreferences *pref)
4701+{
4702+ g_signal_handler_block (pref->priv->settings, pref->priv->notify_confirm_handler);
4703+ g_object_set (pref->priv->settings, "confirm-destroy", gtk_toggle_button_get_active (button), NULL);
4704+ g_signal_handler_unblock (pref->priv->settings, pref->priv->notify_confirm_handler);
4705+}
4706+
4707+static void
4708+notify_fontname (XpadPreferences *pref)
4709+{
4710+ const gchar *fontname;
4711+ g_object_get (pref->priv->settings, "fontname", &fontname, NULL);
4712+
4713+ g_signal_handler_block (pref->priv->fontbutton, pref->priv->font_handler);
4714+ g_signal_handler_block (pref->priv->fontcheck, pref->priv->fontcheck_handler);
4715+
4716+ if (fontname)
4717+ {
4718+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->fontcheck), TRUE);
4719+ gtk_widget_set_sensitive (pref->priv->fontbutton, TRUE);
4720+ gtk_font_button_set_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton), fontname);
4721+ }
4722+ else
4723+ {
4724+ gtk_widget_set_sensitive (pref->priv->fontbutton, FALSE);
4725+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->antifontcheck), TRUE);
4726+ }
4727+
4728+ g_signal_handler_unblock (pref->priv->fontcheck, pref->priv->fontcheck_handler);
4729+ g_signal_handler_unblock (pref->priv->fontbutton, pref->priv->font_handler);
4730+}
4731+
4732+static void
4733+notify_text_color (XpadPreferences *pref)
4734+{
4735+ const GdkRGBA *text_color;
4736+ g_object_get (pref->priv->settings, "text-color", &text_color, NULL);
4737+
4738+ g_signal_handler_block (pref->priv->textbutton, pref->priv->text_handler);
4739+ g_signal_handler_block (pref->priv->colorcheck, pref->priv->colorcheck_handler);
4740+
4741+ if (text_color)
4742+ {
4743+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->colorcheck), TRUE);
4744+ gtk_widget_set_sensitive (pref->priv->colorbox, TRUE);
4745+ gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->textbutton), text_color);
4746+
4747+ }
4748+ else
4749+ {
4750+ gtk_widget_set_sensitive (pref->priv->colorbox, FALSE);
4751+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->anticolorcheck), TRUE);
4752+ }
4753+
4754+ g_signal_handler_unblock (pref->priv->colorcheck, pref->priv->colorcheck_handler);
4755+ g_signal_handler_unblock (pref->priv->textbutton, pref->priv->text_handler);
4756+}
4757+
4758+static void
4759+notify_back_color (XpadPreferences *pref)
4760+{
4761+ const GdkRGBA *back_color;
4762+ g_object_get (pref->priv->settings, "back-color", &back_color, NULL);
4763+
4764+ g_signal_handler_block (pref->priv->backbutton, pref->priv->back_handler);
4765+ g_signal_handler_block (pref->priv->colorcheck, pref->priv->colorcheck_handler);
4766+
4767+ if (back_color)
4768+ {
4769+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->colorcheck), TRUE);
4770+ gtk_widget_set_sensitive (pref->priv->colorbox, TRUE);
4771+ gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), back_color);
4772+ }
4773+ else
4774+ {
4775+ gtk_widget_set_sensitive (pref->priv->colorbox, FALSE);
4776+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->anticolorcheck), TRUE);
4777+ }
4778+
4779+ g_signal_handler_unblock (pref->priv->colorcheck, pref->priv->colorcheck_handler);
4780+ g_signal_handler_unblock (pref->priv->backbutton, pref->priv->back_handler);
4781+}
4782+
4783+static void
4784+notify_autostart_xpad (XpadPreferences *pref)
4785+{
4786+ gboolean value;
4787+ g_object_get (pref->priv->settings, "autostart-xpad", &value, NULL);
4788+ g_signal_handler_block (pref->priv->autostart_xpad, pref->priv->autostart_xpad_handler);
4789+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_xpad), value);
4790+ gtk_widget_set_sensitive (pref->priv->autostart_wait_systray, value);
4791+ if (value)
4792+ change_autostart_wait_systray (GTK_TOGGLE_BUTTON (pref->priv->autostart_wait_systray), pref);
4793+ g_signal_handler_unblock (pref->priv->autostart_xpad, pref->priv->autostart_xpad_handler);
4794+}
4795+
4796+static void
4797+notify_autostart_wait_systray (XpadPreferences *pref)
4798+{
4799+ gboolean value;
4800+ g_object_get (pref->priv->settings, "autostart-wait-systray", &value, NULL);
4801+ g_signal_handler_block (pref->priv->autostart_wait_systray, pref->priv->autostart_wait_systray_handler);
4802+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_wait_systray), value);
4803+ g_signal_handler_unblock (pref->priv->autostart_wait_systray, pref->priv->autostart_wait_systray_handler);
4804+}
4805+
4806+static void
4807+notify_autostart_new_pad (XpadPreferences *pref)
4808+{
4809+ gboolean value;
4810+ g_object_get (pref->priv->settings, "autostart-new-pad", &value, NULL);
4811+ g_signal_handler_block (pref->priv->autostart_new_pad, pref->priv->autostart_new_pad_handler);
4812+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_new_pad), value);
4813+ g_signal_handler_unblock (pref->priv->autostart_new_pad, pref->priv->autostart_new_pad_handler);
4814+}
4815+
4816+static void
4817+notify_autostart_sticky (XpadPreferences *pref)
4818+{
4819+ gboolean value;
4820+ g_object_get (pref->priv->settings, "autostart-sticky", &value, NULL);
4821+ g_signal_handler_block (pref->priv->autostart_sticky, pref->priv->autostart_sticky_handler);
4822+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_sticky), value);
4823+ g_signal_handler_unblock (pref->priv->autostart_sticky, pref->priv->autostart_sticky_handler);
4824+}
4825+
4826+static void
4827+notify_autostart_delay (XpadPreferences *pref)
4828+{
4829+ guint value;
4830+ g_object_get (pref->priv->settings, "autostart-delay", &value, NULL);
4831+ g_signal_handler_block (pref->priv->autostart_delay, pref->priv->autostart_delay_handler);
4832+ gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->autostart_delay), value);
4833+ g_signal_handler_unblock (pref->priv->autostart_delay, pref->priv->autostart_delay_handler);
4834+}
4835+
4836+static void
4837+notify_autostart_display_pads (XpadPreferences *pref)
4838+{
4839+ guint value;
4840+ g_object_get (pref->priv->settings, "autostart-display-pads", &value, NULL);
4841+ g_signal_handler_block (pref->priv->autostart_display_pads, pref->priv->autostart_display_pads_handler);
4842+ gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->autostart_display_pads), value);
4843+ g_signal_handler_unblock (pref->priv->autostart_display_pads, pref->priv->autostart_display_pads_handler);
4844+}
4845+
4846+static void
4847+notify_tray_enabled (XpadPreferences *pref)
4848+{
4849+ gboolean value;
4850+ g_object_get (pref->priv->settings, "tray-enabled", &value, NULL);
4851+ g_signal_handler_block (pref->priv->tray_enabled, pref->priv->tray_enabled_handler);
4852+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->tray_enabled), value);
4853+ gtk_widget_set_sensitive (pref->priv->tray_click_configuration, value);
4854+ gtk_widget_set_sensitive (pref->priv->autostart_display_pads, value);
4855+ if (!value)
4856+ g_object_set (pref->priv->settings, "autostart-display-pads", 0, NULL);
4857+ g_signal_handler_unblock (pref->priv->tray_enabled, pref->priv->tray_enabled_handler);
4858+}
4859+
4860+static void
4861+notify_tray_click (XpadPreferences *pref)
4862+{
4863+ guint value;
4864+ g_object_get (pref->priv->settings, "tray-click-configuration", &value, NULL);
4865+ g_signal_handler_block (pref->priv->tray_click_configuration, pref->priv->tray_click_handler);
4866+ gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->tray_click_configuration), value);
4867+ g_signal_handler_unblock (pref->priv->tray_click_configuration, pref->priv->tray_click_handler);
4868+}
4869+
4870+static void
4871+notify_edit (XpadPreferences *pref)
4872+{
4873+ gboolean value;
4874+ g_object_get (pref->priv->settings, "edit-lock", &value, NULL);
4875+ g_signal_handler_block (pref->priv->editcheck, pref->priv->editcheck_handler);
4876+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->editcheck), value);
4877+ g_signal_handler_unblock (pref->priv->editcheck, pref->priv->editcheck_handler);
4878+}
4879+
4880+static void
4881+notify_confirm (XpadPreferences *pref)
4882+{
4883+ gboolean value;
4884+ g_object_get (pref->priv->settings, "confirm-destroy", &value, NULL);
4885+ g_signal_handler_block (pref->priv->confirmcheck, pref->priv->confirmcheck_handler);
4886+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->confirmcheck), value);
4887+ g_signal_handler_unblock (pref->priv->confirmcheck, pref->priv->confirmcheck_handler);
4888 }
4889
4890 static void xpad_preferences_constructed (GObject *object)
4891@@ -263,10 +649,10 @@
4892 else
4893 {
4894 PangoFontDescription *font;
4895-
4896+
4897 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->antifontcheck), TRUE);
4898 gtk_widget_set_sensitive (pref->priv->fontbutton, FALSE);
4899-
4900+
4901 gtk_style_context_get (style, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font, NULL);
4902 gtk_font_button_set_font_name (GTK_FONT_BUTTON (pref->priv->fontbutton), pango_font_description_to_string(font));
4903 pango_font_description_free (font);
4904@@ -288,17 +674,17 @@
4905 gtk_widget_set_sensitive (pref->priv->colorbox, FALSE);
4906 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (pref->priv->backbutton), &theme_background_color);
4907 }
4908-
4909+
4910 alignment = gtk_alignment_new (1, 1, 1, 1);
4911 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
4912 gtk_container_add (GTK_CONTAINER (alignment), pref->priv->colorbox);
4913-
4914+
4915 vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6));
4916
4917 gtk_box_pack_start (vbox, pref->priv->antifontcheck, FALSE, FALSE, 0);
4918 gtk_box_pack_start (vbox, GTK_WIDGET (font_hbox), FALSE, FALSE, 0);
4919 gtk_box_pack_start (appearance_vbox, GTK_WIDGET (vbox), FALSE, FALSE, 0);
4920-
4921+
4922 vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 6));
4923
4924 gtk_box_pack_start (vbox, pref->priv->anticolorcheck, FALSE, FALSE, 0);
4925@@ -358,7 +744,7 @@
4926 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pref->priv->autostart_sticky), autostart_sticky);
4927
4928 label = gtk_label_new (_("Delay in seconds"));
4929- pref->priv->autostart_delay = gtk_combo_box_text_new();
4930+ pref->priv->autostart_delay = gtk_combo_box_text_new();
4931 guint i;
4932 for (i=0; i<15; i++)
4933 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pref->priv->autostart_delay), g_strdup_printf ("%i", i));
4934@@ -482,7 +868,7 @@
4935 pref->priv->notify_confirm_handler = g_signal_connect_swapped (pref->priv->settings, "notify::confirm-destroy", G_CALLBACK (notify_confirm), pref);
4936 pref->priv->notify_tray_enabled_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-enabled", G_CALLBACK (notify_tray_enabled), pref);
4937 pref->priv->notify_tray_click_handler = g_signal_connect_swapped (pref->priv->settings, "notify::tray-click-configuration", G_CALLBACK(notify_tray_click), pref);
4938-
4939+
4940 g_object_unref (size_group_labels);
4941
4942 /* Initiliaze the GUI logic */
4943@@ -498,423 +884,23 @@
4944 g_object_set (G_OBJECT (pref), "default-width", (gint) (req.height * 0.8), NULL);
4945 }
4946
4947-static GtkWidget * create_label (const gchar *label_text) {
4948- GtkWidget *label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL,
4949- "label", g_strconcat ("<b>", label_text, "</b>", NULL),
4950- "use-markup", TRUE,
4951- "xalign", 0.0,
4952- NULL));
4953- return label;
4954-}
4955-
4956-static void
4957-xpad_preferences_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
4958-{
4959- XpadPreferences *pref = XPAD_PREFERENCES (object);
4960-
4961- switch (prop_id)
4962- {
4963- case PROP_SETTINGS:
4964- pref->priv->settings = g_value_get_pointer (value);
4965- g_object_ref (pref->priv->settings);
4966- break;
4967-
4968- default:
4969- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4970- break;
4971- }
4972-}
4973-
4974-static void
4975-xpad_preferences_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
4976-{
4977- XpadPreferences *pref = XPAD_PREFERENCES (object);
4978-
4979- switch (prop_id)
4980- {
4981- case PROP_SETTINGS:
4982- g_value_set_pointer (value, pref->priv->settings);
4983- break;
4984-
4985- default:
4986- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4987- break;
4988- }
4989-}
4990-
4991-static void
4992-xpad_preferences_finalize (GObject *object)
4993-{
4994- XpadPreferences *pref = XPAD_PREFERENCES (object);
4995-
4996- if (pref->priv->settings)
4997- g_signal_handlers_disconnect_matched (pref->priv->settings, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, pref);
4998-
4999- G_OBJECT_CLASS (xpad_preferences_parent_class)->finalize (object);
5000-}
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches