hooksets_init();
- //history_load_words();
//hotkeys_load();
mainwnd_prepare(mainwnd);
<object class="GtkComboBox" id="mainwnd_search">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="model">mainwnd_search_store</property>
+ <property name="active">0</property>
<property name="has_entry">True</property>
+ <property name="entry_text_column">0</property>
</object>
<packing>
<property name="expand">True</property>
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="model">mainwnd_search_store</property>
+ <property name="model">mainwnd_search_method_store</property>
</object>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="button3">
+ <object class="GtkButton" id="mainwnd_prev">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="relief">none</property>
+ <signal name="clicked" handler="mainwnd_prev_clicked_cb" swapped="no"/>
<child>
<object class="GtkImage" id="image7">
<property name="visible">True</property>
<column type="gpointer"/>
</columns>
</object>
- <object class="GtkListStore" id="mainwnd_search_store">
+ <object class="GtkListStore" id="mainwnd_search_method_store">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkListStore" id="mainwnd_search_store">
+ <columns>
+ <!-- column-name history -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
<object class="GtkWindow" id="popupwnd">
<property name="can_focus">False</property>
<property name="type">popup</property>
<object class="GtkComboBox" id="popupwnd.search_method">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="model">mainwnd_search_store</property>
+ <property name="model">mainwnd_search_method_store</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
- <placeholder/>
+ <object class="GtkHBox" id="hbox9">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkVBox" id="hotkeys_vbox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">10</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton1">
+ <property name="label" translatable="yes">Ignore locks</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
</child>
</object>
</child>
extern Builder *_builder;
extern Prefs *_prefs;
-void history_prev()
+G_DEFINE_TYPE(History, history, G_TYPE_OBJECT);
+
+static gint history_selection_depth = -1;
+
+static void history_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+ History *history = HISTORY(object);
+ switch(param_id)
+ {
+ case 1:
+ history->builder = BUILDER(g_value_get_pointer(value));
+ break;
+ case 2:
+ history->prefs = PREFS(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void history_class_init(HistoryClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->set_property = history_set_property;
+ g_object_class_install_property(gobject_class, 1, g_param_spec_pointer("builder", _("Builder"), _("Builder"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property(gobject_class, 2, g_param_spec_pointer("prefs", _("Prefs"), _("Prefs"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+}
+
+static void history_init(History *self)
+{
+}
+
+void history_prev(History *self)
{
GList *hist, *hist1;
RESULT *res;
- hist = g_list_last(history.list);
+ hist = g_list_last(self->list);
if(!hist)
return;
return;
result_free((RESULT *)hist->data);
- history.list = g_list_delete_link(history.list, hist);
+ self->list = g_list_delete_link(self->list, hist);
res = (RESULT *)(hist1->data);
- //mainwnd_open(res);
+ mainwnd_open(MAINWND(mainwnd_get_wnd()), res);
}
-void history_next(RESULT *res)
+void history_insert_res(History *self, RESULT *res)
{
- GList *hist = g_list_last(history.list);
+ GList *hist = g_list_last(self->list);
if(hist)
{
RESULT *res1 = (RESULT*)hist->data;
if((res1->binfo == res->binfo) && (res1->pos.page == res->pos.page) && (res1->pos.offset == res->pos.offset))
return;
}
- history.list = g_list_append(history.list, result_duplicate(res));
+ self->list = g_list_append(self->list, result_duplicate(res));
}
-RESULT *history_last_result()
+RESULT *history_last_result(History *self)
{
- GList *hist = g_list_last(history.list);
+ GList *hist = g_list_last(self->list);
if(hist)
return (RESULT*)hist->data;
return NULL;
return FALSE;
}
-void history_insert_word(const gchar *word)
+void history_insert_word(History *self, const gchar *word)
{
gboolean b;
GtkTreeIter iter;
gtk_tree_model_foreach(model, history_remove_word, (gpointer)word);
gtk_tree_model_foreach(model, history_remove_word, (gpointer)word);
-#if 0
- while(gtk_tree_model_iter_n_children(model, NULL) > dictbar.word_hist)
+ gint n = prefs_get_int(self->prefs, "dictbar.word_hist");
+#if 1
+ while(gtk_tree_model_iter_n_children(model, NULL) > n)
{
- path = gtk_tree_path_new_from_indices(dictbar.word_hist - 1, -1);
+ path = gtk_tree_path_new_from_indices(n - 1, -1);
b = gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_path_free(path);
if(!b) break;
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
}
- gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(mainwnd_search), word);
- gtk_combo_box_set_active(mainwnd_search, 0);
+ gtk_list_store_prepend(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, word, -1);
+ //gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(mainwnd_search), word);
+ //gtk_combo_box_set_active(mainwnd_search, 0);
#endif
return;
}
return FALSE;
}
-void history_save_words()
+void history_save_words(History *self)
{
gchar filename[PATH_MAX];
- GtkComboBox *mainwnd_search = GTK_COMBO_BOX(gtk_builder_get_object(GTK_BUILDER(_builder), "mainwnd_search"));
+ GtkComboBox *mainwnd_search = GTK_COMBO_BOX(gtk_builder_get_object(GTK_BUILDER(self->builder), "mainwnd_search"));
GtkTreeModel *model = gtk_combo_box_get_model(mainwnd_search);
xmlDocPtr doc = xmlNewDoc((xmlChar*)"1.0");
doc->children = xmlNewDocRawNode(doc, NULL, (xmlChar*)"History", NULL);
void history_load_word(void *ctx, const xmlChar *name, const xmlChar **atts)
{
+ xmlParserCtxt *ctxt = (xmlParserCtxt*)ctx;
+ xmlSAXHandler *cb = ctxt->sax;
+ History *self = HISTORY(cb->_private);
if(!g_strcmp0((gchar*)name, "word"))
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(mainwnd_search), (gchar*)atts[1]);
+ {
+ GtkComboBox *mainwnd_search = GTK_COMBO_BOX(gtk_builder_get_object(GTK_BUILDER(self->builder), "mainwnd_search"));
+ GtkTreeModel *model = gtk_combo_box_get_model(mainwnd_search);
+ GtkTreeIter iter;
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, (gchar*)atts[1], -1);
+ }
}
-void history_load_words()
+void history_load_words(History *self)
{
gchar filename[PATH_MAX];
xmlSAXHandler cb;
return;
memset(&cb, 0, sizeof(xmlSAXHandler));
cb.startElement = &history_load_word;
- xmlDocPtr doc = xmlSAXParseFile(&cb, filename, 0);
+ cb._private = self;
+ xmlDocPtr doc = xmlSAXParseFile(&cb, filename, NULL);
xmlFreeDoc(doc);
}
#ifndef __HISTORY_H_
#define __HISTORY_H_
-void history_prev();
-void history_next(RESULT *res);
+#include "builder.h"
+#include "prefs.h"
+
+G_BEGIN_DECLS
+
+#define TYPE_HISTORY (history_get_type ())
+#define HISTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_HISTORY, History))
+#define HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_HISTORY, HistoryClass))
+#define IS_HISTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_HISTORY))
+#define IS_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_HISTORY))
+#define HISTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_HISTORY, HistoryClass))
+
+typedef struct _History History;
+typedef struct _HistoryClass HistoryClass;
+
+struct _History {
+ GObject parent_instance;
+ GList *list;
+ Builder *builder;
+ Prefs *prefs;
+};
+
+struct _HistoryClass {
+ GObjectClass parent_class;
+};
+
+void history_insert_word(History *self, const gchar *word);
+void history_insert_res(History *self, RESULT *res);
+void history_prev(History *self);
+
+void history_save_words(History *self);
+void history_load_words(History *self);
+
+GType history_get_type (void);
+
+G_END_DECLS
+
RESULT* history_last_result();
void history_free_data(RESULT *res);
-void history_insert_word(const gchar *word);
-void history_save_words();
-void history_load_words();
RESULT* result_new(BOOK_INFO *binfo, EB_Position *pos);
RESULT* result_duplicate(RESULT *res);
void result_clear_all();
gboolean result_compare(RESULT *res1, RESULT *res2);
-struct _history
-{
- GList *list;
-} history;
-
#endif /* __HISTORY_H_ */
#include "mainwnd.h"
#include "prefs.h"
+typedef struct
+{
+ gchar *name;
+ void (* func)();
+ gboolean global;
+} HOTKEY_COMMAND;
+
+typedef struct
+{
+ guint32 mask, keyval;
+ gboolean enabled;
+} HOTKEY_EVENT;
+
const HOTKEY_COMMAND hotkeys_list[] = {
{ _("Search"), mainwnd_search_, FALSE},
{ _("Go back"), history_prev, FALSE},
-// { _("Clear search field"), mainwnd_clear_combo, FALSE},
+ { _("Clear search field"), mainwnd_clear_combo, FALSE},
// { _("Next hit"), headword_next, FALSE},
// { _("Previous hit"), headword_prev, FALSE},
// { _("Select all dictionaries"), dictbar_all_select, FALSE},
// { _("Unselect all dictionaries"), dictbar_all_unselect, FALSE},
// { _("Select next group"), dictbar_group_next, FALSE},
// { _("Select previous group"), dictbar_group_prev, FALSE},
- { _("Quit program"), mainwnd_exit, FALSE},
- { _("Iconify/restore main window"), mainwnd_iconify_restore, TRUE},
// { _("Search in main window"), selection_search_in_mainwnd, TRUE},
// { _("Search in popup window"), selection_search_in_popupwnd, TRUE},
- {NULL, NULL, FALSE}
+ { _("Iconify/restore main window"), mainwnd_iconify_restore, TRUE},
+ { _("Quit program"), mainwnd_exit, FALSE}
};
-void hotkeys_list_init()
+G_DEFINE_TYPE(Hotkeys, hotkeys, G_TYPE_OBJECT);
+
+static Hotkeys *_hotkeys = NULL;
+
+#if 0
+static void hotkeys_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+ Hotkeys *hotkeys = HOTKEYS(object);
+ switch(param_id)
+ {
+ case 1:
+ hotkeys->builder = BUILDER(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+#endif
+
+static void hotkeys_class_init(HotkeysClass *klass)
+{
+ //GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ //gobject_class->set_property = hotkeys_set_property;
+ //g_object_class_install_property(gobject_class, 1, g_param_spec_pointer("builder", _("Builder"), _("Builder"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+}
+
+static void hotkeys_init(Hotkeys *self)
{
+ if(!_hotkeys)
+ _hotkeys = self;
+ else
+ g_assert(1);
gint i;
HOTKEY_EVENT *events = g_try_new0(HOTKEY_EVENT, sizeof(hotkeys_list));
if(!events) return;
- hotkeys.list = NULL;
- for(i = 0; hotkeys_list[i].name; i++)
- hotkeys.list = g_list_append(hotkeys.list, (gpointer)&(events[i]));
+ self->list = NULL;
+ g_printf("hotkeys list size = %d\n", SZ(hotkeys_list));
+ for(i = 0; i < SZ(hotkeys_list); i++)
+ self->list = g_list_append(self->list, (gpointer)&(events[i]));
}
-static gboolean hotkeys_local_activated_cb(GtkAccelGroup *accelgroup, GObject *arg1, guint arg2, GdkModifierType arg3, gpointer user_data)
+static gboolean hotkeys_local_activated_cb(GtkAccelGroup *accelgroup, GObject *arg1, guint arg2, GdkModifierType arg3, gpointer data)
{
gint i;
guint cmp;
HOTKEY_EVENT *evt;
+ Hotkeys *self = HOTKEYS(data);
- gulong keyval = (gulong)user_data;
+ gulong keyval = (gulong)arg2;
gulong mask = arg3;
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
if(!keyval) continue;
if(evt->keyval != keyval) continue;
cmp = (evt->mask ^ mask);
- if(hotkeys.ignore_locks)
+ if(self->ignore_locks)
cmp = cmp & !(GDK_MOD2_MASK | GDK_LOCK_MASK);
if(!cmp)
{
return FALSE;
}
-void hotkeys_local_install()
+void hotkeys_local_install(Hotkeys *self)
{
static GtkAccelGroup *accel_group = NULL;
GClosure *closure;
}
accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(mainwnd_get_wnd(), accel_group);
- g_signal_connect(G_OBJECT(accel_group), "accel-activate", G_CALLBACK(hotkeys_local_activated_cb), NULL);
+ g_signal_connect(G_OBJECT(accel_group), "accel-activate", G_CALLBACK(hotkeys_local_activated_cb), self);
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
gulong keyval = evt->keyval;
if(!evt->enabled || hotkeys_list[i].global) continue;
const guint mods = LockMask | Mod2Mask;
guint i;
HOTKEY_EVENT *evt;
+ Hotkeys *self = HOTKEYS(self);
switch(xevent->type)
{
case KeyPress:
{
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
if(!hotkeys_list[i].global) continue;
gboolean mask_cmp;
- if(hotkeys.ignore_locks)
+ if(self->ignore_locks)
mask_cmp = ((xevent->xkey.state | mods) == (evt->mask | mods));
else
mask_cmp = (xevent->xkey.state == evt->mask);
return GDK_FILTER_CONTINUE;
}
-void hotkeys_global_install()
+void hotkeys_global_install(Hotkeys *self)
{
static gboolean cb_added = FALSE;
GdkWindow *rootwin = gdk_get_default_root_window();
if(!cb_added)
{
- gdk_window_add_filter(rootwin, hotkeys_global_cb, NULL);
+ gdk_window_add_filter(rootwin, hotkeys_global_cb, self);
cb_added = TRUE;
}
const guint mod_masks [] = {
LockMask | Mod2Mask
};
// remove all hotkeys
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
if(!hotkeys_list[i].global) continue;
for(j = 0; j < G_N_ELEMENTS(mod_masks); j++)
XUngrabKey(d, XKeysymToKeycode(d, evt->keyval), evt->mask | mod_masks[j], DefaultRootWindow(d));
}
// install currently assigned hotkeys
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
if(!hotkeys_list[i].global) continue;
- if(hotkeys.ignore_locks)
+ if(self->ignore_locks)
{
for(j = 0; j < G_N_ELEMENTS(mod_masks); j++)
XGrabKey(d, XKeysymToKeycode(d, evt->keyval), evt->mask | mod_masks[j], DefaultRootWindow(d), True, GrabModeAsync, GrabModeAsync);
}
}
-HOTKEY_EVENT* hotkeys_find(const gchar *name)
+HOTKEY_EVENT* hotkeys_find(Hotkeys *self, const gchar *name)
{
gint i;
- for(i = 0; hotkeys_list[i].name; i++)
+ for(i = 0; i < SZ(hotkeys_list); i++)
{
if(!g_strcmp0(hotkeys_list[i].name, name))
- return (HOTKEY_EVENT*)g_list_nth_data(hotkeys.list, i);
+ return (HOTKEY_EVENT*)g_list_nth_data(self->list, i);
}
return NULL;
}
-void hotkeys_save()
+void hotkeys_save(Hotkeys *self)
{
gchar filename[PATH_MAX], buff[16];
gint i;
doc->children = xmlNewDocRawNode(doc, NULL, (xmlChar*)"hotkeys", NULL);
gchar *userdir = prefs_get_userdir();
sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_HOTKEYS);
- for(i = 0; (evt = g_list_nth_data(hotkeys.list, i)); i++)
+ for(i = 0; (evt = g_list_nth_data(self->list, i)); i++)
{
if(!evt->enabled) continue;
xmlNodePtr node1 = xmlAddChild((xmlNodePtr)doc->children, xmlNewNode(NULL, (xmlChar*)"hotkeys"));
void hotkeys_load_item(void *ctx, const xmlChar *name, const xmlChar **atts)
{
if(!atts) return;
- HOTKEY_EVENT *evt = hotkeys_find((gchar*)atts[1]);
+
+ xmlParserCtxt *ctxt = (xmlParserCtxt*)ctx;
+ xmlSAXHandler *cb = ctxt->sax;
+ Hotkeys *self = HOTKEYS(cb->_private);
+ HOTKEY_EVENT *evt = hotkeys_find(self, (gchar*)atts[1]);
if(!evt) return;
+
evt->mask = strtol((gchar*)atts[3], NULL, 16);
evt->keyval = strtol((gchar*)atts[5], NULL, 16);
evt->enabled = (evt->keyval != 0);
}
/* Add local some default hotkeys */
-void hotkeys_add_defaults()
+void hotkeys_add_defaults(Hotkeys *self)
{
gint i;
for(i = 0; hotkeys_list[i].name; i++)
{
if(hotkeys_list[i].func == mainwnd_exit)
{
- HOTKEY_EVENT *evt = (HOTKEY_EVENT*)g_list_nth_data(hotkeys.list, i);
+ HOTKEY_EVENT *evt = (HOTKEY_EVENT*)g_list_nth_data(self->list, i);
evt->mask = 0x4;
evt->keyval = 0x71;
evt->enabled = TRUE;
#endif
else if(hotkeys_list[i].func == mainwnd_iconify_restore)
{
- HOTKEY_EVENT *evt = (HOTKEY_EVENT*)g_list_nth_data(hotkeys.list, i);
+ HOTKEY_EVENT *evt = (HOTKEY_EVENT*)g_list_nth_data(self->list, i);
evt->mask = 0x4;
evt->keyval = 0x69;
evt->enabled = TRUE;
}
}
-void hotkeys_load()
+void hotkeys_load(Hotkeys *self)
{
gchar filename[PATH_MAX];
xmlSAXHandler cb;
sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_HOTKEYS);
if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
{
- hotkeys_add_defaults();
+ hotkeys_add_defaults(self);
return;
}
memset(&cb, 0, sizeof(xmlSAXHandler));
cb.startElement = &hotkeys_load_item;
+ cb._private = self;
xmlDocPtr doc = xmlSAXParseFile(&cb, filename, 0);
xmlFreeDoc(doc);
}
strcat(key, gdk_keyval_name(keyval));
}
+GtkEntry* hotkeys_hbox_get_entry(GtkHBox *hbox)
+{
+ GList *list = gtk_container_get_children(GTK_CONTAINER(hbox));
+ return GTK_ENTRY(list->next->data);
+}
+
+static gboolean hotkeys_grab_key_cb(GtkDialog *dlg, GdkEventKey *evt, GtkHBox *hbox)
+{
+ gchar key[256];
+
+ switch (evt->keyval){
+ case GDK_Shift_L:
+ case GDK_Shift_R:
+ case GDK_Control_L:
+ case GDK_Control_R:
+ case GDK_Meta_L:
+ case GDK_Meta_R:
+ case GDK_Alt_L:
+ case GDK_Alt_R:
+ case GDK_Caps_Lock:
+ case GDK_Shift_Lock:
+ case GDK_Scroll_Lock:
+ case GDK_Num_Lock:
+ case GDK_Kana_Lock:
+ return(FALSE);
+ break;
+ }
+
+ if(evt->keyval == GDK_Escape)
+ {
+ gtk_dialog_response(dlg, GTK_RESPONSE_NO);
+ return TRUE;
+ }
+
+ if(_hotkeys->ignore_locks)
+ evt->state = evt->state & (~GDK_LOCK_MASK) & (~GDK_MOD2_MASK);
+ hotkey_to_string(evt->state, evt->keyval, key);
+
+ gtk_entry_set_text(hotkeys_hbox_get_entry(hbox), key);
+ gtk_dialog_response(dlg, GTK_RESPONSE_OK);
+
+ return TRUE;
+}
+
+static void hotkeys_edit_cb(GtkWidget *widget, GtkHBox *hbox)
+{
+ GtkWidget* dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE,
+ _("Press a key (or a key combination) to setup hotkey,\n"
+ "\"Clear\" button or \"Esc\" key to remove current hotkey,\n"
+ "\"Cancel\" to close this message."));
+ gtk_dialog_add_buttons(GTK_DIALOG(dlg), GTK_STOCK_CLEAR, GTK_RESPONSE_NO, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+ gtk_window_set_title(GTK_WINDOW(dlg), _("Grabbing a key."));
+ g_signal_connect(G_OBJECT(dlg), "key-press-event", G_CALLBACK(hotkeys_grab_key_cb), hbox);
+
+ if(gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_NO)
+ gtk_entry_set_text(hotkeys_hbox_get_entry(hbox), "");
+ gtk_widget_destroy(dlg);
+}
+
+GtkWidget* hotkeys_edit_nth(Hotkeys *self, gint n)
+{
+ if(n >= SZ(hotkeys_list))
+ return NULL;
+
+ GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
+ if(hotkeys_list[n].global)
+ gtk_widget_set_tooltip_text(hbox, _("Global hotkey"));
+
+ GtkWidget *label = gtk_label_new(hotkeys_list[n].name);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ GtkWidget *btn = gtk_button_new_with_label(_("Edit..."));
+ gtk_box_pack_end(GTK_BOX(hbox), btn, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(btn), "clicked", G_CALLBACK(hotkeys_edit_cb), hbox);
+
+ GtkWidget *entry = gtk_entry_new();
+ gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
+ gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
+
+ HOTKEY_EVENT *evt = (HOTKEY_EVENT*)g_list_nth_data(self->list, n);
+ gchar keystr[64];
+ if(evt ? evt->enabled : FALSE)
+ {
+ hotkey_to_string(evt->mask, evt->keyval, keystr);
+ gtk_entry_set_text(GTK_ENTRY(entry), keystr);
+ }
+ return hbox;
+}
+
#ifndef __HOTKEYS_H__
#define __HOTKEYS_H__
-struct _hotkeys
-{
- gboolean ignore_locks;
- GList *list;
-} hotkeys;
-
-typedef struct
-{
- gchar *name;
- void (* func)();
- gboolean global;
-} HOTKEY_COMMAND;
-
-typedef struct
-{
- guint32 mask, keyval;
- gboolean enabled;
-} HOTKEY_EVENT;
-
-void hotkeys_list_init();
+#include "builder.h"
+
+G_BEGIN_DECLS
+
+#define TYPE_HOTKEYS (hotkeys_get_type ())
+#define HOTKEYS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_HOTKEYS, Hotkeys))
+#define HOTKEYS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_HOTKEYS, HotkeysClass))
+#define IS_HOTKEYS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_HOTKEYS))
+#define IS_HOTKEYS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_HOTKEYS))
+#define HOTKEYS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_HOTKEYS, HotkeysClass))
+
+typedef struct _Hotkeys Hotkeys;
+typedef struct _HotkeysClass HotkeysClass;
+
+struct _Hotkeys {
+ GObject parent_instance;
+ GList *list;
+ gboolean ignore_locks;
+};
+
+struct _HotkeysClass {
+ GObjectClass parent_class;
+};
+
+void hotkeys_load(Hotkeys *self);
+void hotkeys_save(Hotkeys *self);
+GtkWidget* hotkeys_edit_nth(Hotkeys *self, gint n);
+
+GType hotkeys_get_type (void);
+
+G_END_DECLS
+
void hotkeys_local_install();
void hotkeys_global_install();
-HOTKEY_EVENT* hotkeys_find(const gchar *name);
-void hotkeys_save();
-void hotkeys_load();
void hotkey_to_string(guint mask, guint keyval, gchar *key);
#endif /* __HOTKEYS_H__ */
self->builder = g_object_new(TYPE_BUILDER, NULL);
self->prefs = g_object_new(TYPE_PREFS, "builder", self->builder, NULL);
self->dicts = g_object_new(TYPE_DICTS, "builder", self->builder, NULL);
+ self->history = g_object_new(TYPE_HISTORY, "builder", self->builder, "prefs", self->prefs, NULL);
+ self->hotkeys = g_object_new(TYPE_HOTKEYS, NULL);
self->results = g_sequence_new(result_free);
gtk_builder_connect_signals(GTK_BUILDER(self->builder), self);
GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(self->builder), "vbox1"));
gtk_widget_reparent(vbox, GTK_WIDGET(self));
GtkContainer *scroll = GTK_CONTAINER(gtk_builder_get_object(GTK_BUILDER(self->builder), "scrolledwindow2"));
- self->text = g_object_new(TYPE_TEXTVIEW, "prefs", self->prefs, NULL);
+ self->text = g_object_new(TYPE_TEXTVIEW, "prefs", self->prefs, "history", self->history, NULL);
gtk_container_add(scroll, GTK_WIDGET(self->text));
self->popupwnd = g_object_new(TYPE_POPUPWND, "mainwnd", self, "type", GTK_WINDOW_POPUP, NULL);
self->word = NULL;
w = gtk_paned_get_position(p);
prefs_set_int(prefs, "paned.tree_width", w);
- //history_save_words();
+ history_save_words(mw->history);
prefs_save(prefs);
dicts_save(mw->dicts);
//hotkeys_save();
if(method == -1)
method = builder_get_int(self->builder, "mainwnd_search_method");
- //history_insert_word(word);
+ history_insert_word(self->history, word);
gint maxhits = prefs_get_int(self->prefs, "headword.maxhits");
ebook_search(word, method, self->results, maxhits, False);
mainwnd_update_results(self);
history_prev();
}
+#endif
+
void mainwnd_clear_combo()
{
+ //GtkWidget *combo = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(_mainwnd->builder), "mainwnd_search"));
+ //GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)));
builder_set_str(_mainwnd->builder, "mainwnd_search", "");
}
-#endif
gboolean mainwnd_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
void mainwnd_scan_toggled_cb(GtkToggleButton *btn, gpointer data)
{
Mainwnd *mw = MAINWND(data);
+ if(!gtk_widget_get_visible(GTK_WIDGET(mw))) return;
gint scan = gtk_toggle_button_get_active(btn);
mainwnd_scan_start_stop(mw, scan);
}
void mainwnd_prepare(Mainwnd *self)
{
-#if 0
- hotkeys_local_install();
- hotkeys_global_install();
-#endif
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)icon_xpm);
gtk_window_set_default_icon(pixbuf);
g_object_unref(pixbuf);
gtk_widget_hide_on_delete(GTK_WIDGET(self));
prefs_load(self->prefs);
+ history_load_words(self->history);
+ hotkeys_load(self->hotkeys);
+ hotkeys_local_install(self->hotkeys);
+ hotkeys_global_install(self->hotkeys);
builder_install_text_cellrenderer(self->builder, "mainwnd_search_method");
builder_install_text_cellrenderer(self->builder, "mainwnd_dict_group");
+ builder_install_text_cellrenderer(self->builder, "mainwnd_search");
GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "mainwnd_results"));
GtkTreeSelection *select = gtk_tree_view_get_selection(tree);
builder_set_int(self->builder, "mainwnd_dict_group", active);
builder_set_int(self->builder, "mainwnd_search", 0);
- gboolean b = prefs_get_int(self->prefs, "selection.lookup_started");
- builder_set_int(self->builder, "mainwnd_scan", b);
-
gint i;
GtkTreeIter iter;
- GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(GTK_BUILDER(self->builder), "mainwnd_search_store"));
+ GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(GTK_BUILDER(self->builder), "mainwnd_search_method_store"));
for(i = 0; i < 4; i++)
{
const gchar *name = ebook_index_to_method_name(i);
gtk_window_move(GTK_WINDOW(self), x, y);
}
mainwnd_reset_font(self);
+ gboolean b = prefs_get_int(self->prefs, "selection.lookup_started");
+ builder_set_int(self->builder, "mainwnd_scan", b);
builder_grab_focus(self->builder, "mainwnd_search");
}
mainwnd_dict_buttons_update(mw);
}
+void mainwnd_prev_clicked_cb(GtkWidget *widget, gpointer data)
+{
+ Mainwnd *mw = MAINWND(data);
+ history_prev(mw->history);
+}
+
#include "builder.h"
#include "dicts.h"
#include "prefs.h"
+#include "history.h"
+#include "hotkeys.h"
#include "textview.h"
#include "popupwnd.h"
Builder *builder;
Dicts *dicts;
Prefs *prefs;
+ History *history;
+ Hotkeys *hotkeys;
GSequence *results;
TextView *text;
Popupwnd *popupwnd;
G_END_DECLS
+void mainwnd_clear_combo();
void mainwnd_iconify_restore();
void mainwnd_search_();
-void mainwnd_clear_combo();
GtkWidget* mainwnd_search_method_combo();
#endif /* __MAINWND_H__ */
g_datalist_init(&(self->data));
- hotkeys_list_init();
-
gchar *home_dir = getenv("HOME");
gchar *userdir = g_strdup_printf("%s%s.%s", home_dir, G_DIR_SEPARATOR_S, PACKAGE_NAME);
prefs_set_str(self, "userdir", userdir);
}
GtkWidget *w = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "mainwnd.font"));
gtk_widget_set_sensitive(w, prefs_get_int(mw->prefs, "mainwnd.custom_font"));
+
+ Hotkeys *hotkeys = mw->hotkeys;
+ GtkBox *vbox = GTK_BOX(gtk_builder_get_object(GTK_BUILDER(mw->builder), "hotkeys_vbox"));
+ for(i = 0; w = hotkeys_edit_nth(hotkeys, i); i++)
+ {
+ gtk_box_pack_start(vbox, w, FALSE, FALSE, 0);
+ }
preparewnd = False;
}
if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_store), &iter1))
break;
case G_TYPE_STRING:
str = prefs_get_str(self, p->name);
- sprintf(buff, "%s", str);
+ if(str)
+ sprintf(buff, "%s", str);
break;
}
xmlNodePtr node = xmlAddChild(doc->children, xmlNewNode(NULL, (xmlChar*)prefs_list[i].name));
render_content(res->binfo, self, text, self->prefs);
g_free(text);
- TextViewClass *klass = TEXTVIEW_GET_CLASS(self);
- if(klass->history_next)
- klass->history_next(res);
+ if(self->history)
+ history_insert_res(self->history, res);
if(word && prefs_get_int(self->prefs, "highlight_all_keywords"))
textview_highlight_word(self, word);
}
text->prefs = PREFS(g_value_get_pointer(value));
g_signal_connect(G_OBJECT(text), "populate_popup", G_CALLBACK(textview_populate_popup_cb), text);
break;
+ case 2:
+ text->history = HISTORY(g_value_get_pointer(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
static void textview_class_init(TextViewClass *klass)
{
- klass->history_next = NULL;
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = textview_set_property;
g_object_class_install_property(gobject_class, 1, g_param_spec_pointer("prefs", _("Prefs"), _("Prefs"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property(gobject_class, 2, g_param_spec_pointer("history", _("History"), _("History"), G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
}
static void textview_init(TextView *self)
gtk_text_view_set_right_margin(GTK_TEXT_VIEW(self), 10);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(self), GTK_WRAP_WORD);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(self), FALSE);
+ self->history = NULL;
}
void textview_clear_textbuf(TextView *self)
GtkTextView parent_instance;
GtkTextTag *tag;
Prefs *prefs;
+ History *history;
};
struct _TextViewClass {
GtkTextViewClass parent_class;
- void (*history_next)(RESULT *res);
};
void textview_open(TextView *self, RESULT *res, gboolean clear, const gchar *word);