1 /*
2 * config.c - Part of the Geany Markdown plugin
3 *
4 * Copyright 2012 Matthew Brush <mbrush@codebrainz.ca>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 *
22 */
23
24 #include "config.h"
25 #include <string.h>
26 #include <gtk/gtk.h>
27 #include <geanyplugin.h>
28 #include "conf.h"
29 #include "markdown-gtk-compat.h"
30
31 #define FONT_NAME_MAX 256
32 #define COLOR_CODE_MAX 8
33 #define DEFAULT_CONF \
34 "[general]\n" \
35 "template=\n" \
36 "\n" \
37 "[view]\n" \
38 "position=0\n" \
39 "font_name=Serif\n" \
40 "code_font_name=Mono\n" \
41 "font_point_size=12\n" \
42 "code_font_point_size=12\n" \
43 "bg_color=#fff\n" \
44 "fg_color=#000\n"
45
46 #define MARKDOWN_HTML_TEMPLATE \
47 "<html>\n" \
48 " <head>\n" \
49 " <style type=\"text/css\">\n" \
50 " body {\n" \
51 " font-family: @@font_name@@;\n" \
52 " font-size: @@font_point_size@@pt;\n" \
53 " background-color: @@bg_color@@;\n" \
54 " color: @@fg_color@@;\n" \
55 " }\n" \
56 " code {\n" \
57 " font-family: @@code_font_name@@;\n" \
58 " font-size: @@code_font_point_size@@pt;\n" \
59 " }\n" \
60 " </style>\n" \
61 " </head>\n" \
62 " <body>\n" \
63 " @@markdown@@\n" \
64 " </body>\n" \
65 "</html>\n"
66
67 enum
68 {
69 PROP_0 = 0,
70 PROP_TEMPLATE_FILE,
71 PROP_FONT_NAME,
72 PROP_CODE_FONT_NAME,
73 PROP_FONT_POINT_SIZE,
74 PROP_CODE_FONT_POINT_SIZE,
75 PROP_BG_COLOR,
76 PROP_FG_COLOR,
77 PROP_VIEW_POS,
78 PROP_LAST
79 };
80
81 static GParamSpec *md_props[PROP_LAST] = { NULL };
82
83 struct _MarkdownConfigPrivate
84 {
85 gchar *filename;
86 GKeyFile *kf;
87 guint handle;
88 gulong dlg_handle;
89 gboolean initialized;
90 gchar *tmpl_text;
91 gsize tmpl_text_len;
92 struct {
93 GtkWidget *table;
94 GtkWidget *pos_sb_radio;
95 GtkWidget *pos_mw_radio;
96 GtkWidget *font_button;
97 GtkWidget *code_font_button;
98 GtkWidget *bg_color_button;
99 GtkWidget *fg_color_button;
100 GtkWidget *tmpl_file_button;
101 } widgets;
102 };
103
104 static void markdown_config_finalize(GObject *object);
105
G_DEFINE_TYPE(MarkdownConfig,markdown_config,G_TYPE_OBJECT)106 G_DEFINE_TYPE(MarkdownConfig, markdown_config, G_TYPE_OBJECT)
107
108 static gboolean on_idle_timeout(MarkdownConfig *conf)
109 {
110 markdown_config_save(conf);
111 conf->priv->handle = 0;
112 return FALSE;
113 }
114
115 static void
init_conf_file(MarkdownConfig * conf)116 init_conf_file(MarkdownConfig *conf)
117 {
118 GError *error = NULL;
119 gchar *def_tmpl, *dirn;
120
121 dirn = g_path_get_dirname(conf->priv->filename);
122 if (!g_file_test(dirn, G_FILE_TEST_IS_DIR)) {
123 g_mkdir_with_parents(dirn, 0755);
124 }
125
126 if (!g_file_test(conf->priv->filename, G_FILE_TEST_EXISTS)) {
127 if (!g_file_set_contents(conf->priv->filename, DEFAULT_CONF, -1, &error)) {
128 g_warning("Unable to write default configuration file: %s", error->message);
129 g_error_free(error); error = NULL;
130 }
131 }
132
133 def_tmpl = g_build_filename(dirn, "template.html", NULL);
134
135 if (!g_file_test(def_tmpl, G_FILE_TEST_EXISTS)) {
136 if (!g_file_set_contents(def_tmpl, MARKDOWN_HTML_TEMPLATE, -1, &error)) {
137 g_warning("Unable to write default template file: %s", error->message);
138 g_error_free(error); error = NULL;
139 }
140 }
141
142 g_free(dirn);
143 g_free(def_tmpl);
144 }
145
146 static void
markdown_config_load_template_text(MarkdownConfig * conf)147 markdown_config_load_template_text(MarkdownConfig *conf)
148 {
149 GError *error = NULL;
150 gchar *tmpl_file = NULL;
151
152 g_object_get(conf, "template-file", &tmpl_file, NULL);
153
154 g_free(conf->priv->tmpl_text);
155 conf->priv->tmpl_text = NULL;
156 conf->priv->tmpl_text_len = 0;
157
158 if (!g_file_get_contents(tmpl_file, &(conf->priv->tmpl_text),
159 &(conf->priv->tmpl_text_len), &error))
160 {
161 g_warning("Error reading template file: %s", error->message);
162 g_error_free(error); error = NULL;
163 }
164 }
165
166 static void
markdown_config_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)167 markdown_config_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec)
168 {
169 gboolean save_later = FALSE;
170 MarkdownConfig *conf = MARKDOWN_CONFIG(obj);
171
172 /* FIXME: Prevent writing to keyfile until it's ready */
173 if (!conf->priv->initialized)
174 return;
175
176 switch (prop_id) {
177 case PROP_TEMPLATE_FILE:
178 g_key_file_set_string(conf->priv->kf, "general", "template",
179 g_value_get_string(value));
180 /*markdown_config_load_template_text(conf);*/
181 save_later = TRUE;
182 break;
183 case PROP_FONT_NAME:
184 g_key_file_set_string(conf->priv->kf, "view", "font_name",
185 g_value_get_string(value));
186 save_later = TRUE;
187 break;
188 case PROP_CODE_FONT_NAME:
189 g_key_file_set_string(conf->priv->kf, "view", "code_font_name",
190 g_value_get_string(value));
191 save_later = TRUE;
192 break;
193 case PROP_FONT_POINT_SIZE:
194 g_key_file_set_integer(conf->priv->kf, "view", "font_point_size",
195 (gint) g_value_get_uint(value));
196 save_later = TRUE;
197 break;
198 case PROP_CODE_FONT_POINT_SIZE:
199 g_key_file_set_integer(conf->priv->kf, "view", "code_font_point_size",
200 (gint) g_value_get_uint(value));
201 save_later = TRUE;
202 break;
203 case PROP_BG_COLOR:
204 g_key_file_set_string(conf->priv->kf, "view", "bg_color",
205 g_value_get_string(value));
206 save_later = TRUE;
207 break;
208 case PROP_FG_COLOR:
209 g_key_file_set_string(conf->priv->kf, "view", "fg_color",
210 g_value_get_string(value));
211 save_later = TRUE;
212 break;
213 case PROP_VIEW_POS:
214 g_key_file_set_integer(conf->priv->kf, "view", "position",
215 (gint) g_value_get_uint(value));
216 save_later = TRUE;
217 break;
218 default:
219 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
220 break;
221 }
222
223 if (save_later && conf->priv->handle == 0) {
224 conf->priv->handle = g_idle_add((GSourceFunc) on_idle_timeout, conf);
225 }
226 }
227
228 static gchar *
markdown_config_get_string_key(MarkdownConfig * conf,const gchar * group,const gchar * key,const gchar * default_value)229 markdown_config_get_string_key(MarkdownConfig *conf, const gchar *group,
230 const gchar *key, const gchar *default_value)
231 {
232 gchar *out_str;
233 GError *error = NULL;
234
235 out_str = g_key_file_get_string(conf->priv->kf, group, key, &error);
236 if (error) {
237 g_debug("Config read failed: %s", error->message);
238 g_error_free(error); error = NULL;
239 out_str = g_strdup(default_value);
240 }
241
242 return out_str;
243 }
244
245 static guint
markdown_config_get_uint_key(MarkdownConfig * conf,const gchar * group,const gchar * key,guint default_value)246 markdown_config_get_uint_key(MarkdownConfig *conf, const gchar *group,
247 const gchar *key, guint default_value)
248 {
249 guint out_uint;
250 GError *error = NULL;
251
252 out_uint = (guint) g_key_file_get_integer(conf->priv->kf, group, key, &error);
253 if (error) {
254 g_debug("Config read failed: %s", error->message);
255 g_error_free(error); error = NULL;
256 out_uint = default_value;
257 }
258
259 return out_uint;
260 }
261
262 static void
markdown_config_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)263 markdown_config_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec)
264 {
265 MarkdownConfig *conf = MARKDOWN_CONFIG(obj);
266
267 switch (prop_id) {
268 case PROP_TEMPLATE_FILE:
269 {
270 gchar *tmpl_file;
271 tmpl_file = markdown_config_get_string_key(conf, "general", "template", "");
272 /* If empty, use default template.html file. */
273 if (!tmpl_file || !tmpl_file[0]) {
274 gchar *dn;
275 g_free(tmpl_file);
276 dn = g_path_get_dirname(conf->priv->filename);
277 tmpl_file = g_build_filename(dn, "template.html", NULL);
278 g_free(dn);
279 }
280 g_value_set_string(value, tmpl_file);
281 g_free(tmpl_file);
282 break;
283 }
284 case PROP_FONT_NAME:
285 {
286 gchar *font_name;
287 font_name = markdown_config_get_string_key(conf, "view", "font_name", "Serif");
288 g_value_set_string(value, font_name);
289 g_free(font_name);
290 break;
291 }
292 case PROP_CODE_FONT_NAME:
293 {
294 gchar *font_name;
295 font_name = markdown_config_get_string_key(conf, "view", "code_font_name", "Monospace");
296 g_value_set_string(value, font_name);
297 g_free(font_name);
298 break;
299 }
300 case PROP_FONT_POINT_SIZE:
301 {
302 guint font_size;
303 font_size = markdown_config_get_uint_key(conf, "view", "font_point_size", 12);
304 g_value_set_uint(value, font_size);
305 break;
306 }
307 case PROP_CODE_FONT_POINT_SIZE:
308 {
309 guint font_size;
310 font_size = markdown_config_get_uint_key(conf, "view", "code_font_point_size", 12);
311 g_value_set_uint(value, font_size);
312 break;
313 }
314 case PROP_BG_COLOR:
315 {
316 gchar *bg_color;
317 bg_color = markdown_config_get_string_key(conf, "view", "bg_color", "#ffffff");
318 g_value_set_string(value, bg_color);
319 g_free(bg_color);
320 break;
321 }
322 case PROP_FG_COLOR:
323 {
324 gchar *fg_color;
325 fg_color = markdown_config_get_string_key(conf, "view", "fg_color", "#000000");
326 g_value_set_string(value, fg_color);
327 g_free(fg_color);
328 break;
329 }
330 case PROP_VIEW_POS:
331 {
332 guint view_pos;
333 view_pos = markdown_config_get_uint_key(conf, "view", "position", 0);
334 g_value_set_uint(value, view_pos);
335 break;
336 }
337 default:
338 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
339 break;
340 }
341 }
342
343 static void
markdown_install_class_properties(GObjectClass * gclass,guint n_pspecs,GParamSpec ** pspecs)344 markdown_install_class_properties(GObjectClass *gclass, guint n_pspecs,
345 GParamSpec **pspecs)
346 {
347 #if GLIB_CHECK_VERSION(2, 26, 0)
348 g_object_class_install_properties(gclass, n_pspecs, pspecs);
349 #else
350 guint i;
351 for (i = 1; i < n_pspecs; i++)
352 g_object_class_install_property(gclass, i, pspecs[i]);
353 #endif
354 }
355
356 static void
markdown_config_class_init(MarkdownConfigClass * klass)357 markdown_config_class_init(MarkdownConfigClass *klass)
358 {
359 GObjectClass *g_object_class;
360
361 g_object_class = G_OBJECT_CLASS(klass);
362 g_object_class->finalize = markdown_config_finalize;
363 g_object_class->set_property = markdown_config_set_property;
364 g_object_class->get_property = markdown_config_get_property;
365 g_type_class_add_private((gpointer)klass, sizeof(MarkdownConfigPrivate));
366
367 md_props[PROP_TEMPLATE_FILE] = g_param_spec_string("template-file", "TemplateFile",
368 "HTML template file for preview", "", G_PARAM_READWRITE);
369 md_props[PROP_FONT_NAME] = g_param_spec_string("font-name", "FontName",
370 "Font family name", "Serif", G_PARAM_READWRITE);
371 md_props[PROP_CODE_FONT_NAME] = g_param_spec_string("code-font-name", "CodeFontName",
372 "Font family for code blocks", "Monospace", G_PARAM_READWRITE);
373 md_props[PROP_FONT_POINT_SIZE] = g_param_spec_uint("font-point-size", "FontPointSize",
374 "Size in points of the font", 2, 100, 12, G_PARAM_READWRITE);
375 md_props[PROP_CODE_FONT_POINT_SIZE] = g_param_spec_uint("code-font-point-size",
376 "CodeFontPointSize", "Size in points of the font for code blocks", 2, 100, 12,
377 G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
378 md_props[PROP_BG_COLOR] = g_param_spec_string("bg-color", "BackgroundColor",
379 "Background colour of the page", "#ffffff", G_PARAM_READWRITE);
380 md_props[PROP_FG_COLOR] = g_param_spec_string("fg-color", "ForegroundColor",
381 "Foreground colour of the page", "#000000", G_PARAM_READWRITE);
382 md_props[PROP_VIEW_POS] = g_param_spec_uint("view-pos", "ViewPosition",
383 "Notebook where the view will be positioned", 0,
384 MARKDOWN_CONFIG_VIEW_POS_MAX-1, (guint) MARKDOWN_CONFIG_VIEW_POS_SIDEBAR,
385 G_PARAM_READWRITE);
386
387 markdown_install_class_properties(g_object_class, PROP_LAST, md_props);
388 }
389
390
391 static void
markdown_config_finalize(GObject * object)392 markdown_config_finalize(GObject *object)
393 {
394 MarkdownConfig *self;
395
396 g_return_if_fail(MARKDOWN_IS_CONFIG(object));
397
398 self = MARKDOWN_CONFIG(object);
399
400 if (self->priv->handle != 0) {
401 g_source_remove(self->priv->handle);
402 markdown_config_save(self);
403 }
404
405 g_free(self->priv->filename);
406 g_key_file_free(self->priv->kf);
407
408 G_OBJECT_CLASS(markdown_config_parent_class)->finalize (object);
409 }
410
411
412 static void
markdown_config_init(MarkdownConfig * self)413 markdown_config_init(MarkdownConfig *self)
414 {
415 self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MARKDOWN_TYPE_CONFIG, MarkdownConfigPrivate);
416 }
417
418
419 MarkdownConfig *
markdown_config_new(const gchar * filename)420 markdown_config_new(const gchar *filename)
421 {
422 MarkdownConfig *conf = g_object_new(MARKDOWN_TYPE_CONFIG, NULL);
423 GError *error = NULL;
424
425 g_return_val_if_fail(filename, conf);
426
427 conf->priv->filename = g_strdup(filename);
428 init_conf_file(conf);
429 conf->priv->kf = g_key_file_new();
430 if (!g_key_file_load_from_file(conf->priv->kf, conf->priv->filename,
431 G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error))
432 {
433 g_warning("Error loading configuration file: %s", error->message);
434 g_error_free(error); error = NULL;
435 }
436
437 conf->priv->initialized = TRUE;
438
439 return conf;
440 }
441
442 gboolean
markdown_config_save(MarkdownConfig * conf)443 markdown_config_save(MarkdownConfig *conf)
444 {
445 gchar *contents;
446 gsize len;
447 gboolean success = FALSE;
448 GError *error = NULL;
449
450 contents = g_key_file_to_data(conf->priv->kf, &len, &error);
451
452 /*g_debug("Saving: %s\n%s", conf->priv->filename, contents);*/
453
454 if (error) {
455 g_warning("Error getting config data as string: %s", error->message);
456 g_error_free(error); error = NULL;
457 return success;
458 }
459
460 success = g_file_set_contents(conf->priv->filename, contents, len, &error);
461 g_free(contents);
462
463 if (!success) {
464 g_warning("Error writing config data to disk: %s", error->message);
465 g_error_free(error); error = NULL;
466 }
467
468 return success;
469 }
470
471 static gchar *
color_button_get_color(GtkColorButton * color_button)472 color_button_get_color(GtkColorButton *color_button)
473 {
474 MarkdownColor color;
475
476 markdown_gtk_color_button_get_color(color_button, &color);
477
478 return g_strdup_printf("#%02x%02x%02x", color.red, color.green, color.blue);
479 }
480
481 static gboolean
get_font_info(const gchar * font_desc,gchar ** font_name,guint * font_size)482 get_font_info(const gchar *font_desc, gchar **font_name, guint *font_size)
483 {
484 gboolean success = FALSE;
485 PangoFontDescription *pfd;
486
487 pfd = pango_font_description_from_string(font_desc);
488 if (pfd) {
489 *font_name = g_strdup(pango_font_description_get_family(pfd));
490 *font_size = (guint) (pango_font_description_get_size(pfd) / PANGO_SCALE);
491 success = TRUE;
492 pango_font_description_free(pfd);
493 }
494
495 return success;
496 }
497
498 static void
on_dialog_response(MarkdownConfig * conf,gint response_id,GtkDialog * dialog)499 on_dialog_response(MarkdownConfig *conf, gint response_id, GtkDialog *dialog)
500 {
501 if (response_id == GTK_RESPONSE_APPLY || response_id == GTK_RESPONSE_OK) {
502 GtkWidget *wid = conf->priv->widgets.pos_sb_radio;
503 gboolean pos_sidebar = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wid));
504 gchar *bg_color, *fg_color;
505 gchar *tmpl_file = NULL, *fnt = NULL, *code_fnt = NULL;
506 guint fnt_size = 0, code_fnt_size = 0;
507 const gchar *font_desc;
508 MarkdownConfigViewPos view_pos;
509
510 view_pos = pos_sidebar ? MARKDOWN_CONFIG_VIEW_POS_SIDEBAR : MARKDOWN_CONFIG_VIEW_POS_MSGWIN;
511
512 bg_color = color_button_get_color(GTK_COLOR_BUTTON(conf->priv->widgets.bg_color_button));
513 fg_color = color_button_get_color(GTK_COLOR_BUTTON(conf->priv->widgets.fg_color_button));
514
515 font_desc = gtk_font_button_get_font_name(GTK_FONT_BUTTON(conf->priv->widgets.font_button));
516 get_font_info(font_desc, &fnt, &fnt_size);
517
518 font_desc = gtk_font_button_get_font_name(GTK_FONT_BUTTON(conf->priv->widgets.code_font_button));
519 get_font_info(font_desc, &code_fnt, &code_fnt_size);
520
521 tmpl_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(conf->priv->widgets.tmpl_file_button));
522
523 g_object_set(conf,
524 "font-name", fnt,
525 "font-point-size", fnt_size,
526 "code-font-name", code_fnt,
527 "code-font-point-size", code_fnt_size,
528 "view-pos", view_pos,
529 "bg-color", bg_color,
530 "fg-color", fg_color,
531 "template-file", tmpl_file,
532 NULL);
533
534 g_free(fnt);
535 g_free(code_fnt);
536 g_free(bg_color);
537 g_free(fg_color);
538 g_free(tmpl_file);
539 }
540 }
541
markdown_config_gui(MarkdownConfig * conf,GtkDialog * dialog)542 GtkWidget *markdown_config_gui(MarkdownConfig *conf, GtkDialog *dialog)
543 {
544 GSList *grp = NULL;
545 GtkWidget *table, *label, *hbox, *wid;
546 gchar *tmpl_file=NULL, *fnt=NULL, *code_fnt=NULL, *bg=NULL, *fg=NULL;
547 guint view_pos=0, fnt_sz=0, code_fnt_sz=0;
548
549 g_object_get(conf,
550 "view-pos", &view_pos,
551 "font-name", &fnt,
552 "code-font-name", &code_fnt,
553 "font-point-size", &fnt_sz,
554 "code-font-point-size", &code_fnt_sz,
555 "bg-color", &bg,
556 "fg-color", &fg,
557 "template-file", &tmpl_file,
558 NULL);
559
560 table = markdown_gtk_table_new(6, 2, FALSE);
561 markdown_gtk_table_set_col_spacing(MARKDOWN_GTK_TABLE(table), 6);
562 markdown_gtk_table_set_row_spacing(MARKDOWN_GTK_TABLE(table), 6);
563
564 conf->priv->widgets.table = table;
565
566 { /* POSITION OF VIEW */
567 label = gtk_label_new(_("Position:"));
568 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
569 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL);
570
571 hbox = gtk_hbox_new(FALSE, 6);
572
573 wid = gtk_radio_button_new_with_label(grp, _("Sidebar"));
574 grp = gtk_radio_button_get_group(GTK_RADIO_BUTTON(wid));
575 gtk_box_pack_start(GTK_BOX(hbox), wid, FALSE, TRUE, 0);
576 conf->priv->widgets.pos_sb_radio = wid;
577 if (((MarkdownConfigViewPos) view_pos) == MARKDOWN_CONFIG_VIEW_POS_SIDEBAR) {
578 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wid), TRUE);
579 }
580
581 wid = gtk_radio_button_new_with_label(grp, _("Message Window"));
582 grp = gtk_radio_button_get_group(GTK_RADIO_BUTTON(wid));
583 gtk_box_pack_start(GTK_BOX(hbox), wid, FALSE, TRUE, 0);
584 conf->priv->widgets.pos_mw_radio = wid;
585 if (((MarkdownConfigViewPos) view_pos) == MARKDOWN_CONFIG_VIEW_POS_MSGWIN) {
586 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wid), TRUE);
587 }
588
589 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), hbox, 1, 2, 0, 1, GTK_FILL, GTK_FILL);
590 }
591
592 { /* FONT BUTTON */
593 gchar *font_desc;
594
595 label = gtk_label_new(_("Font:"));
596 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
597 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL);
598
599 font_desc = g_strdup_printf("%s %d", fnt, fnt_sz);
600 wid = gtk_font_button_new_with_font(font_desc);
601 conf->priv->widgets.font_button = wid;
602 g_free(font_desc);
603
604 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), wid, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL);
605
606 g_free(fnt);
607 }
608
609 { /* CODE FONT BUTTON */
610 gchar *font_desc;
611
612 label = gtk_label_new(_("Code Font:"));
613 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
614 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL);
615
616 font_desc = g_strdup_printf("%s %d", code_fnt, code_fnt_sz);
617 wid = gtk_font_button_new_with_font(font_desc);
618 conf->priv->widgets.code_font_button = wid;
619 g_free(font_desc);
620
621 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), wid, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL);
622
623 g_free(code_fnt);
624 }
625
626 { /* BG COLOR */
627 MarkdownColor bgclr;
628
629 label = gtk_label_new(_("BG Color:"));
630 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
631 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL);
632
633 markdown_color_parse(bg, &bgclr);
634
635 wid = markdown_gtk_color_button_new_with_color(&bgclr);
636 conf->priv->widgets.bg_color_button = wid;
637 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), wid, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, GTK_FILL);
638
639 g_free(bg);
640 }
641
642 { /* FG COLOR */
643 MarkdownColor fgclr;
644
645 label = gtk_label_new(_("FG Color:"));
646 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
647 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL);
648
649 markdown_color_parse(fg, &fgclr);
650
651 wid = markdown_gtk_color_button_new_with_color(&fgclr);
652 conf->priv->widgets.fg_color_button = wid;
653 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), wid, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, GTK_FILL);
654
655 g_free(fg);
656 }
657
658 { /* TEMPLATE FILE */
659 label = gtk_label_new(_("Template:"));
660 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
661 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), label, 0, 1, 5, 6, GTK_FILL, GTK_FILL);
662
663 wid = gtk_file_chooser_button_new(_("Select Template File"),
664 GTK_FILE_CHOOSER_ACTION_OPEN);
665 conf->priv->widgets.tmpl_file_button = wid;
666 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(wid), g_get_home_dir());
667 if (tmpl_file && tmpl_file[0]) {
668 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(wid), tmpl_file);
669 }
670 markdown_gtk_table_attach(MARKDOWN_GTK_TABLE(table), wid, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, GTK_FILL);
671
672 g_free(tmpl_file);
673 }
674
675 conf->priv->dlg_handle = g_signal_connect_swapped(dialog, "response",
676 G_CALLBACK(on_dialog_response), conf);
677
678 gtk_widget_show_all(table);
679
680 return table;
681 }
682
683 const gchar *
markdown_config_get_template_text(MarkdownConfig * conf)684 markdown_config_get_template_text(MarkdownConfig *conf)
685 {
686 g_return_val_if_fail(conf, NULL);
687 if (!conf->priv->tmpl_text) {
688 markdown_config_load_template_text(conf);
689 }
690 return (const gchar *) conf->priv->tmpl_text;
691 }
692
693 gchar *
markdown_config_get_dirname(MarkdownConfig * conf)694 markdown_config_get_dirname(MarkdownConfig *conf)
695 {
696 g_return_val_if_fail(conf, NULL);
697 return g_path_get_dirname(conf->priv->filename);
698 }
699
markdown_config_get_view_pos(MarkdownConfig * conf)700 MarkdownConfigViewPos markdown_config_get_view_pos(MarkdownConfig *conf)
701 {
702 guint view_pos;
703 g_return_val_if_fail(MARKDOWN_IS_CONFIG(conf), MARKDOWN_CONFIG_VIEW_POS_SIDEBAR);
704 g_object_get(conf, "view-pos", &view_pos, NULL);
705 return (MarkdownConfigViewPos) view_pos;
706 }
707
markdown_config_set_view_pos(MarkdownConfig * conf,MarkdownConfigViewPos view_pos)708 void markdown_config_set_view_pos(MarkdownConfig *conf, MarkdownConfigViewPos view_pos)
709 {
710 g_return_if_fail(MARKDOWN_IS_CONFIG(conf));
711 g_object_set(conf, "view-pos", view_pos, NULL);
712 }
713