Merge lp:~ghugesss/xpad/code_refactor into lp:xpad
- code_refactor
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Arthur Borsboom | code review no testing | Needs Fixing | |
Review via email:
|
Commit message
Description of the change
https:/
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 : | # |
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.
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 */ class_init (XpadUndoClass *klass)
static void
xpad_undo_
/* bad */ class_init (XpadUndoClass *klass)
static void xpad_undo_
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.