13 G_DEFINE_TYPE(Prefs, prefs, G_TYPE_OBJECT);
26 static Prefs *_prefs = NULL;
28 static const pref1 prefs_list[] =
30 {G_TYPE_INT, "headword.maxhits", {50}},
31 {G_TYPE_INT, "dictbar.word_hist", {30}},
32 {G_TYPE_INT, "selection.maxchar", {32}},
33 {G_TYPE_INT, "selection.lookup_started", {0}},
34 {G_TYPE_INT, "hotkeys.ignore_locks", {1}},
35 {G_TYPE_INT, "popupwnd.w", {350}},
36 {G_TYPE_INT, "popupwnd.h", {450}},
37 {G_TYPE_INT, "popupwnd.x", {300}},
38 {G_TYPE_INT, "popupwnd.y", {300}},
39 {G_TYPE_INT, "popupwnd.remember_pos", {0}},
40 {G_TYPE_INT, "popupwnd.lock", {0}},
41 {G_TYPE_INT, "popupwnd.jap_only", {0}},
42 {G_TYPE_INT, "popupwnd.timeout", {2000}},
43 {G_TYPE_INT, "popupwnd.maxhits", {5}},
44 {G_TYPE_INT, "popupwnd.search_method", {0}},
45 {G_TYPE_INT, "mainwnd.x", {300}},
46 {G_TYPE_INT, "mainwnd.y", {300}},
47 {G_TYPE_INT, "mainwnd.w", {500}},
48 {G_TYPE_INT, "mainwnd.h", {400}},
49 {G_TYPE_INT, "mainwnd.remember_pos", {1}},
50 {G_TYPE_INT, "mainwnd.search", {0}},
51 {G_TYPE_INT, "mainwnd.custom_font", {0}},
52 {G_TYPE_INT, "paned.tree_width", {150}},
53 {G_TYPE_INT, "highlight_all_keywords", {1}},
54 {G_TYPE_INT, "prepend_title", {1}},
55 {G_TYPE_INT, "prepend_len", {1}},
56 {G_TYPE_INT, "headword.use_tree", {0}},
57 {G_TYPE_STRING, "mainwnd.font", {.s = ""}},
58 {G_TYPE_STRING, "color.link", {.s = "#0000c0"}},
59 {G_TYPE_STRING, "color.keyword", {.s = "#c00000"}},
60 {G_TYPE_STRING, "color.title", {.s = "#306090"}}
63 static void prefs_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
65 Prefs *prefs = PREFS(object);
70 prefs->builder = BUILDER(g_value_get_pointer(value));
73 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
79 static void prefs_class_init(PrefsClass *klass)
81 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
82 gobject_class->set_property = prefs_set_property;
83 g_object_class_install_property(gobject_class, 1, g_param_spec_pointer("builder", _("Builder"), _("Builder"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
86 static void prefs_init(Prefs *self)
93 //GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass);
94 //gst_element_class_add_pad_template(gstelement_class, gst_static_pad_template_get(&prefs_template));
96 g_datalist_init(&(self->data));
98 gchar *home_dir = getenv("HOME");
99 gchar *userdir = g_strdup_printf("%s%s.%s", home_dir, G_DIR_SEPARATOR_S, PACKAGE_NAME);
100 prefs_set_str(self, "userdir", userdir);
103 if((dir = g_dir_open(userdir, 0, NULL)) == NULL)
105 if(g_mkdir_with_parents(userdir, 493))
107 LOG(LOG_CRITICAL, "Failed to create directory: %s\n", userdir);
122 static void prefs_selection_changed_cb(GtkTreeSelection *selection, gpointer data)
126 if(!gtk_tree_selection_get_selected(selection, &model, &iter)) return;
128 GtkNotebook *notebook = GTK_NOTEBOOK(data);
130 gtk_tree_model_get(model, &iter, 1, &n, -1);
132 gtk_notebook_set_current_page(notebook, n);
135 static const pref1* prefs_get1(Prefs *p, const gchar *str)
138 for(i = 0; i < SZ(prefs_list); i++)
140 const pref1 *p1 = &(prefs_list[i]);
141 if(!g_strcmp0(p1->name, str))
147 static void prefs_set_widget_data(Prefs *p, Builder *b, const gchar *str)
149 const pref1 *p1 = prefs_get1(p, str);
150 if(p1->type == G_TYPE_INT)
152 gint value = prefs_get_int(p, str);
153 builder_set_int(b, str, value);
155 if(p1->type == G_TYPE_STRING)
157 const gchar *value = prefs_get_str(p, str);
158 builder_set_str(b, str, value);
162 static void prefs_get_widget_data(Prefs *p, Builder *b, const gchar *str)
164 const pref1 *p1 = prefs_get1(p, str);
165 if(p1->type == G_TYPE_INT)
167 gint value = builder_get_int(b, str);
168 prefs_set_int(p, str, value);
170 if(p1->type == G_TYPE_STRING)
172 const gchar *value = builder_get_str(b, str);
173 prefs_set_str(p, str, value);
177 gboolean preferences_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
179 gtk_widget_hide(widget);
183 void prefs_ok_btn_clicked_cb(GtkWidget *widget, gpointer data)
185 Mainwnd *mw = MAINWND(data);
186 GtkWidget *wnd = gtk_widget_get_toplevel(widget);
187 gtk_widget_hide(wnd);
189 for(i = 0; i < SZ(prefs_list); i++)
191 const pref1 *p1 = &(prefs_list[i]);
192 prefs_get_widget_data(mw->prefs, mw->builder, p1->name);
194 prefs_save(mw->prefs);
195 mainwnd_reset_font(mw);
196 mainwnd_reset_headwords(mw);
197 GtkBox *vbox = GTK_BOX(gtk_builder_get_object(GTK_BUILDER(mw->builder), "hotkeys_vbox"));
198 hotkeys_reload(mw->hotkeys, vbox);
199 hotkeys_local_install(mw->hotkeys);
200 hotkeys_global_install(mw->hotkeys);
201 hotkeys_save(mw->hotkeys);
204 void prefs_close_wnd(Prefs *prefs)
206 GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(prefs->builder), "preferences"));
210 void prefs_cancel_btn_clicked_cb(GtkWidget *widget, gpointer data)
212 Mainwnd *mw = MAINWND(data);
213 prefs_close_wnd(mw->prefs);
216 void prefs_btn_clicked_cb(GtkWidget *widget, gpointer data)
218 Mainwnd *mw = MAINWND(data);
219 Prefs *prefs = mw->prefs;
221 GtkWidget *wnd = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "preferences"));
222 gtk_widget_hide_on_delete(wnd);
224 GtkTreeView *prefs_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(mw->builder), "prefs_tree"));
225 GtkTreeStore *prefs_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(mw->builder), "prefs_store"));
226 GtkTreeSelection *select = gtk_tree_view_get_selection(prefs_tree);
227 GtkTreeIter iter1, iter2;
228 static gboolean preparewnd = True;
231 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
232 gtk_tree_view_insert_column_with_attributes(prefs_tree, -1, _("Items"), renderer, "text", 0, NULL);
234 GtkNotebook *notebook = GTK_NOTEBOOK(gtk_builder_get_object(GTK_BUILDER(mw->builder), "notebook1"));
235 gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
236 g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(prefs_selection_changed_cb), notebook);
238 gint n = gtk_notebook_get_n_pages(notebook);
240 for(i = 0; i < n; i++)
242 GtkWidget *p = gtk_notebook_get_nth_page(notebook, i);
243 GtkWidget *l = gtk_notebook_get_tab_label(notebook, p);
244 const gchar *text = gtk_label_get_text(GTK_LABEL(l));
247 gtk_tree_store_append(prefs_store, &iter1, NULL);
248 gtk_tree_store_set(prefs_store, &iter1, 0, _(text), 1, i, -1);
252 gtk_tree_store_append(prefs_store, &iter2, &iter1);
253 gtk_tree_store_set(prefs_store, &iter2, 0, _(&(text[1])), 1, i, -1);
256 builder_install_text_cellrenderer(mw->builder, "popupwnd.search_method");
257 for(i = 0; i < SZ(prefs_list); i++)
259 const pref1 *p1 = &(prefs_list[i]);
260 prefs_set_widget_data(prefs, mw->builder, p1->name);
262 GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "mainwnd.font"));
263 gtk_widget_set_sensitive(w, prefs_get_int(mw->prefs, "mainwnd.custom_font"));
265 Hotkeys *hotkeys = mw->hotkeys;
266 GtkBox *vbox = GTK_BOX(gtk_builder_get_object(GTK_BUILDER(mw->builder), "hotkeys_vbox"));
267 for(i = 0; (w = hotkeys_edit_nth(hotkeys, i)); i++)
269 gtk_box_pack_start(vbox, w, FALSE, FALSE, 0);
273 if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_store), &iter1))
275 gtk_tree_selection_select_iter(select, &iter1);
277 gtk_tree_view_expand_all(prefs_tree);
278 gtk_widget_show_all(wnd);
281 void prefs_save(Prefs *self)
283 printf("prefs_save\n");
285 gchar filename[PATH_MAX], buff[128];
287 xmlDocPtr doc = xmlNewDoc((xmlChar*)"1.0");
288 doc->children = xmlNewDocRawNode(doc, NULL, (xmlChar*)"Prefs", NULL);
290 const gchar *userdir = prefs_get_str(self, "userdir");
291 sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_PREFS);
293 for(i = 0 ; i < SZ(prefs_list); i++)
295 const pref1 *p = &(prefs_list[i]);
296 switch(prefs_list[i].type)
300 j = prefs_get_int(self, p->name);
301 sprintf(buff, "%d", j);
306 str = prefs_get_str(self, p->name);
308 sprintf(buff, "%s", str);
311 xmlNodePtr node = xmlAddChild(doc->children, xmlNewNode(NULL, (xmlChar*)prefs_list[i].name));
312 xmlNewProp(node, (xmlChar*)"value", (xmlChar*)buff);
314 xmlSaveFormatFileEnc(filename, doc, "utf8", 0);
318 void prefs_load_elem(void *ctx, const xmlChar *name, const xmlChar **atts)
321 xmlParserCtxt *ctxt = (xmlParserCtxt*)ctx;
322 xmlSAXHandler *cb = ctxt->sax;
323 Prefs *prefs = PREFS(cb->_private);
324 for(i = 0; i < SZ(prefs_list); i++)
326 if(!g_strcmp0((gchar*)name, prefs_list[i].name))
328 switch(prefs_list[i].type){
331 prefs_set_int(prefs, (const gchar*)name, atoi((gchar*)atts[1]));
334 prefs_set_str(prefs, (const gchar*)name, strdup((gchar*)atts[1]));
343 void prefs_load(Prefs *self)
345 gchar filename[PATH_MAX];
347 const gchar *userdir = prefs_get_str(self, "userdir");
348 sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_PREFS);
349 if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
351 memset(&cb, 0, sizeof(xmlSAXHandler));
352 cb.startElement = &prefs_load_elem;
354 xmlDocPtr doc = xmlSAXParseFile(&cb, filename, 0);
358 gint prefs_get_int(Prefs *self, const gchar *name)
360 gpointer ptr = g_datalist_get_data(&self->data, name);
364 void prefs_set_int(Prefs *self, const gchar *name, gint value)
366 g_datalist_set_data(&self->data, name, (gpointer)value);
369 const gchar* prefs_get_str(Prefs *self, const gchar *name)
371 gpointer ptr = g_datalist_get_data(&self->data, name);
372 return (const gchar*)ptr;
375 void prefs_set_str(Prefs *self, const gchar *name, const gchar *value)
377 g_datalist_set_data(&self->data, name, (gpointer)value);
380 const gchar* prefs_get_userdir()
382 return prefs_get_str(_prefs, "userdir");
385 void prefs_custom_font_toggled_cb(GtkToggleButton *btn, gpointer data)
387 Mainwnd *mw = MAINWND(data);
388 GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "mainwnd.font"));
389 gtk_widget_set_sensitive(w, gtk_toggle_button_get_active(btn));