OSDN Git Service

up/down in dicts dialog, various ui fixes
authoriev <iev@land.ru>
Tue, 23 Aug 2011 15:28:48 +0000 (19:28 +0400)
committeriev <iev@land.ru>
Tue, 23 Aug 2011 15:28:48 +0000 (19:28 +0400)
12 files changed:
src/builder.c
src/builder.h
src/dicts.c
src/dicts.h
src/eb123.glade
src/ebook.c
src/mainwnd.c
src/mainwnd.h
src/popupwnd.c
src/prefs.c
src/textview.c
src/textview.h

index 9641e0a..86524b3 100644 (file)
@@ -133,6 +133,10 @@ const gchar* builder_get_str(Builder *self, const gchar *name)
        gtk_color_button_get_color(GTK_COLOR_BUTTON(w), &color);
        return gtk_color_selection_palette_to_string(&color, 1);
     }
+    if(GTK_IS_LABEL(w))
+    {
+       return gtk_label_get_text(GTK_LABEL(w));
+    }
     return NULL;
 }
 
@@ -149,6 +153,10 @@ void builder_set_str(Builder *self, const gchar *name, const gchar *value)
        gdk_color_parse(value, &color);
        gtk_color_button_set_color(GTK_COLOR_BUTTON(w), &color);
     }
+    if(GTK_IS_LABEL(w))
+    {
+       gtk_label_set_text(GTK_LABEL(w), value);
+    }
 }
 
 void builder_install_text_cellrenderer(Builder *self, gchar *box)
index 177d860..5933b45 100644 (file)
@@ -5,7 +5,7 @@
 G_BEGIN_DECLS
 
 #define TYPE_BUILDER (builder_get_type ())
-#define BUILDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BUILDER, BUILDER))
+#define BUILDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_BUILDER, Builder))
 #define BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_BUILDER, BuilderClass))
 #define IS_BUILDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_BUILDER))
 #define IS_BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_BUILDER))
index 765d93b..090d087 100644 (file)
 
 G_DEFINE_TYPE(Dicts, dicts, G_TYPE_OBJECT);
 
-static Dicts *_dicts = NULL;
-extern Builder *_builder;
+static gint dicts_selection_depth = -1;
+
+static void dicts_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+    Dicts *dicts = DICTS(object);
+    switch(param_id)
+    {
+       case 1:
+           dicts->builder = BUILDER(g_value_get_pointer(value));
+           dicts->store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(dicts->builder), "dicts_store"));
+           break;
+       default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+           break;
+    }
+}
 
 static void dicts_class_init(DictsClass *klass)
 {
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+    gobject_class->set_property = dicts_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 dicts_init(Dicts *self)
 {
-    if(!_dicts)
-       _dicts = self;
-    else
-       g_assert(1);
-    self->store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_store"));
 }
 
-#if 0
-static void dicts_cell_edited(GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text, gpointer data)
+static void dicts_cell_edited_cb(GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text, gpointer data)
 {
+    Dicts *dicts = DICTS(data);
     gchar *old_text;
     gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column"));
     GtkTreeIter iter;
     GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
-    gtk_tree_model_get_iter(GTK_TREE_MODEL(dicts.store), &iter, path);
-    gtk_tree_model_get(GTK_TREE_MODEL(dicts.store), &iter, column, &old_text, -1);
+    gtk_tree_model_get_iter(GTK_TREE_MODEL(dicts->store), &iter, path);
+    gtk_tree_model_get(GTK_TREE_MODEL(dicts->store), &iter, column, &old_text, -1);
     g_free(old_text);
-    gtk_tree_store_set(GTK_TREE_STORE(dicts.store), &iter, column, new_text, -1);
+    gtk_tree_store_set(dicts->store, &iter, column, new_text, -1);
     gtk_tree_path_free(path);
 }
-#endif
 
-#if 0
 static gboolean dicts_row_drop_possible(GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
 {
-    GtkTreeSelection *selection;
-    GtkTreeIter iter;
-    GtkTreePath *src;
-
     if(!dest) return FALSE;
-
-    if(GTK_TREE_STORE(drag_dest) == GTK_TREE_STORE(dicts.store))
-       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dicts.view));
-    else
-       return FALSE;
-
-    if(!gtk_tree_selection_get_selected(selection, NULL, &iter))
-       return FALSE;
-
-    src = gtk_tree_model_get_path(GTK_TREE_MODEL(drag_dest), &iter);
-    return (gtk_tree_path_get_depth(src) == gtk_tree_path_get_depth(dest));
+    return (gtk_tree_path_get_depth(dest) == dicts_selection_depth);
 }
-#endif
 
-#if 0
-static void dicts_item_move(GtkWidget *w, gpointer data, gboolean up)
+static void dicts_item_move(Dicts *self, gboolean up)
 {
     GtkTreeIter iter, iter2;
     GtkTreeSelection *selection;
     GtkTreePath *path, *path_orig;
 
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dicts.view));
-    if(gtk_tree_selection_get_selected(selection, NULL, &iter) == FALSE)
+    GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_tree"));
+    selection = gtk_tree_view_get_selection(tree);
+    if(!gtk_tree_selection_get_selected(selection, NULL, &iter))
     {
        LOG(LOG_WARNING, _("No dictionary selected"));
        return;
     }
-    path = gtk_tree_model_get_path(GTK_TREE_MODEL(dicts.store), &iter);
+    path = gtk_tree_model_get_path(GTK_TREE_MODEL(self->store), &iter);
     path_orig = gtk_tree_path_copy(path);
 
     up ? gtk_tree_path_prev(path) : gtk_tree_path_next(path);
-    if((gtk_tree_path_compare(path, path_orig) != 0) && gtk_tree_model_get_iter(GTK_TREE_MODEL(dicts.store), &iter2, path))
+    g_printf("compare path, path_orig = %d\n", gtk_tree_path_compare(path, path_orig));
+    if(gtk_tree_path_compare(path, path_orig) && gtk_tree_model_get_iter(GTK_TREE_MODEL(self->store), &iter2, path)) 
     {
-       my_gtk_tree_store_swap(dicts.store, &iter, &iter2);
-       gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(dicts.view)), &iter);
+       gtk_tree_store_swap(self->store, &iter, &iter2);
+       gtk_tree_selection_select_iter(selection, &iter);
     }
     else if(gtk_tree_path_get_depth(path) > 1)
     {
        gtk_tree_path_up(path);
+       gtk_tree_path_free(path_orig);
+       path_orig = gtk_tree_path_copy(path);
+       up ? gtk_tree_path_prev(path) : gtk_tree_path_next(path);
        if(gtk_tree_path_compare(path, path_orig))
        {
-           gtk_tree_path_free(path_orig);
-           path_orig = gtk_tree_path_copy(path);
-           up ? gtk_tree_path_prev(path) : gtk_tree_path_next(path);
-           if(gtk_tree_path_compare(path, path_orig))
+           GtkTreeIter parent;
+           if(gtk_tree_model_get_iter(GTK_TREE_MODEL(self->store), &parent, path))
            {
-               GtkTreeIter parent;
-               if(gtk_tree_model_get_iter(GTK_TREE_MODEL(dicts.store), &parent, path))
-               {
-                   GtkTreeIter new_iter;
-                   gchar *title;
-                   gboolean editable;
-                   BOOK_INFO *binfo;
-
-                   gtk_tree_store_append(GTK_TREE_STORE(dicts.store), &new_iter, &parent);
-
-                   gtk_tree_model_get(GTK_TREE_MODEL(dicts.store), 
-                           &iter, 
-                           DICT_ALIAS, &title,
-                           DICT_BINFO, &binfo,
-                           DICT_EDITABLE, &editable,
-                           -1);
+               if(up)
+                   gtk_tree_store_append(self->store, &iter2, &parent);
+               else
+                   gtk_tree_store_prepend(self->store, &iter2, &parent);
 
-                   gtk_tree_store_set(dicts.store, &new_iter,
-                           DICT_ALIAS, title,
-                           DICT_BINFO, binfo,
-                           DICT_EDITABLE, editable,
-                           -1);
-                   g_free(title);
-
-                   gtk_tree_store_remove(GTK_TREE_STORE(dicts.store), &iter);
-
-                   gtk_tree_view_expand_row(GTK_TREE_VIEW(dicts.view), path, TRUE);
-                   gtk_tree_selection_select_iter(gtk_tree_view_get_selection(GTK_TREE_VIEW(dicts.view)), &new_iter);
-
-               }
+               gchar *title;
+               gboolean editable;
+               BOOK_INFO *binfo;
+               gtk_tree_model_get(GTK_TREE_MODEL(self->store), 
+                       &iter, 
+                       DICT_ALIAS, &title,
+                       DICT_BINFO, &binfo,
+                       DICT_EDITABLE, &editable,
+                       -1);
+               gtk_tree_store_set(self->store, &iter2,
+                       DICT_ALIAS, title,
+                       DICT_BINFO, binfo,
+                       DICT_EDITABLE, editable,
+                       -1);
+               g_free(title);
+
+               gtk_tree_store_remove(self->store, &iter);
+               gtk_tree_view_expand_row(tree, path, TRUE);
+               gtk_tree_selection_select_iter(gtk_tree_view_get_selection(tree), &iter2);
            }
        }
     }
     gtk_tree_path_free(path);
     gtk_tree_path_free(path_orig);
 }
-#endif
-
-#if 0
-static void dicts_item_up_cb(GtkWidget *w, gpointer data)
-{
-    dicts_item_move(w, data, TRUE);
-}
 
-static void dicts_item_down_cb(GtkWidget *w, gpointer data)
+void dicts_scroll_down(Dicts *self)
 {
-    dicts_item_move(w, data, FALSE);
+    while(gtk_events_pending())
+       gtk_main_iteration();
+    GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_tree"));
+    GtkTreeSelection *sel = gtk_tree_view_get_selection(tree);
+    GtkTreeIter iter;
+    gtk_tree_selection_get_selected(sel, NULL, &iter);
+    GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(self->store), &iter);
+    gtk_tree_view_scroll_to_cell(tree, path, NULL, True, .5, .5);
+    gtk_tree_path_free(path);
 }
-#endif
 
 void dicts_add_btn_clicked_cb(GtkWidget *w, gpointer data)
 {
@@ -160,158 +151,14 @@ void dicts_add_btn_clicked_cb(GtkWidget *w, gpointer data)
     GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_tree"));
     GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
     gtk_tree_selection_select_iter(selection, &iter);
-    gtk_widget_grab_focus(tree);
+    gtk_widget_grab_focus(GTK_WIDGET(tree));
     dicts_scroll_down(self);
 }
 
-#if 0
-static gboolean dicts_drag_data_received(GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData  *selection_data)
+static gboolean dicts_drag_data_received_cb(GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData  *selection_data)
 {
     return FALSE;
 }
-#endif
-
-#define G_NODE(node) ((GNode *)node)
-#define VALID_ITER(iter, tree_store) (iter!= NULL && iter->user_data != NULL && tree_store->stamp == iter->stamp)
-
-// gtk_tree_store_swap: copied from GTK+-2.2
-void my_gtk_tree_store_swap(GtkTreeStore *tree_store, GtkTreeIter *a, GtkTreeIter *b)
-{
-    GNode *tmp, *node_a, *node_b, *parent_node, *a_prev, *a_next, *b_prev, *b_next;
-    gint i, a_count, b_count, length, *order;
-    GtkTreePath *path_a, *path_b;
-    GtkTreeIter parent;
-
-    g_return_if_fail(GTK_IS_TREE_STORE (tree_store));
-    g_return_if_fail(VALID_ITER (a, tree_store));
-    g_return_if_fail(VALID_ITER (b, tree_store));
-
-    node_a = G_NODE (a->user_data);
-    node_b = G_NODE (b->user_data);
-
-    // basic sanity checking
-    g_return_if_fail(node_a != node_b);
-
-    path_a = gtk_tree_model_get_path(GTK_TREE_MODEL (tree_store), a);
-    path_b = gtk_tree_model_get_path(GTK_TREE_MODEL (tree_store), b);
-
-    g_return_if_fail(path_a && path_b);
-
-    gtk_tree_path_up(path_a);
-    gtk_tree_path_up(path_b);
-
-    if((gtk_tree_path_get_depth(path_a) != 0) || (gtk_tree_path_get_depth(path_b) != 0))
-    {
-       if (gtk_tree_path_compare (path_a, path_b))
-       {
-           gtk_tree_path_free (path_a);
-           gtk_tree_path_free (path_b);
-           g_warning ("Given childs are not in the same level\n");
-           return;
-       }
-    }
-
-    if(gtk_tree_path_get_depth(path_a) == 0)
-    {
-       parent_node = G_NODE (tree_store->root);
-    }
-    else
-    {
-       gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_store), &parent, path_a);
-       parent_node = G_NODE (parent.user_data);
-    }
-
-    gtk_tree_path_free (path_b);
-
-    // old links which we have to keep around
-    a_prev = node_a->prev;
-    a_next = node_a->next;
-
-    b_prev = node_b->prev;
-    b_next = node_b->next;
-
-    // fix up links if the nodes are next to eachother
-    if(a_prev == node_b)    a_prev = node_a;
-    if(a_next == node_b)    a_next = node_a;
-
-    if(b_prev == node_a)    b_prev = node_b;
-    if(b_next == node_a)    b_next = node_b;
-
-    // counting nodes
-    tmp = parent_node->children;
-    i = a_count = b_count = 0;
-    while (tmp)
-    {
-       if(tmp == node_a)   a_count = i;
-       if(tmp == node_b)   b_count = i;
-       tmp = tmp->next;
-       i++;
-    }
-    length = i;
-
-    // hacking the tree
-    a_prev ? (a_prev->next = node_b) : (parent_node->children = node_b);
-    if(a_next) a_next->prev = node_b;
-    b_prev ? (b_prev->next = node_a) : (parent_node->children = node_a);
-    if(b_next)  b_next->prev = node_a;
-
-    node_a->prev = b_prev;
-    node_a->next = b_next;
-    node_b->prev = a_prev;
-    node_b->next = a_next;
-
-    // emit signal
-    order = g_new (gint, length);
-    for (i = 0; i < length; i++)
-    {
-       if(i == a_count)
-           order[i] = b_count;
-       else if(i == b_count)
-           order[i] = a_count;
-       else
-           order[i] = i;
-    }
-
-    gtk_tree_model_rows_reordered(GTK_TREE_MODEL (tree_store), path_a, (gtk_tree_path_get_depth(path_a) == 0) ? NULL : &parent, order);
-    gtk_tree_path_free(path_a);
-    g_free(order);
-}
-
-#if 0
-void my_gtk_combo_box_set_active_text(GtkComboBox *combo, const gchar *text)
-{
-    if(!text) return;
-    gchar *str;
-    gint i = 0;
-    GtkTreeIter iter;
-    GtkTreeModel *model = gtk_combo_box_get_model(combo);
-
-    if(!gtk_tree_model_get_iter_first(model, &iter)) return;
-    do {
-       gtk_tree_model_get(model, &iter, 0, &str, -1);
-       if(!g_ascii_strcasecmp(str, text))
-       {
-           g_free(str);
-           gtk_combo_box_set_active(combo, i);
-           break;
-       }
-       g_free(str);
-       i++;
-    } while(gtk_tree_model_iter_next(model, &iter));
-    if(gtk_combo_box_get_active(combo) < 0)
-       gtk_combo_box_set_active(combo, 0);
-}
-#endif
-
-void dicts_scroll_down(Dicts *dicts)
-{
-    while(gtk_events_pending())
-       gtk_main_iteration();
-    GdkScreen *screen = gdk_screen_get_default();
-    gint h = gdk_screen_get_height(screen);
-    GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(dicts->builder), "dicts_tree"));
-    gtk_tree_view_scroll_to_point((tree), 0, h);
-}
 
 void dicts_info_update_search_cb(GtkWidget *w, gpointer data)
 {
@@ -328,40 +175,7 @@ void dicts_info_update_search_cb(GtkWidget *w, gpointer data)
     }
 }
 
-static void dicts_info_update()
-{
-    //dicts_info(FALSE);
-}
-
-void dicts_info_activate(GtkExpander *w, gpointer data)
-{
-    dicts_info_update();
-}
-
-#if 0
-static void dicts_selection_changed_cb(GtkTreeSelection *selection, gpointer data)
-{
-    dicts_info_update();
-}
-
-static gboolean dicts_key_release_cb(GtkWidget *w, GdkEventKey *evt, gpointer data)
-{
-    if(evt->keyval == GDK_Delete)
-    {
-       dicts_item_remove_cb(w, data);
-    }
-    return TRUE;
-}
-#endif
-
-#if 0
-void dicts_path_search(GtkEntry *entry, gpointer data)
-{
-    dicts_search_disk(NULL, NULL);
-}
-#endif
-
-static void dicts_find_recursive(gchar *path, gint depth)
+static void dicts_find_recursive(Dicts *self, gchar *path, gint depth)
 {
     static gboolean group_exists = FALSE;
     static gchar *dirname = NULL;
@@ -395,15 +209,15 @@ static void dicts_find_recursive(gchar *path, gint depth)
            dirname = g_strdup(_("Results"));
        group_exists = FALSE;
     }
-    GtkTreeView *dicts_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_tree"));
-    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_store"));
+    GtkTreeView *dicts_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_tree"));
+    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_store"));
     while((name = g_dir_read_name(dir)))
     {
        sprintf(fullpath, "%s%s%s", path, G_DIR_SEPARATOR_S, name);
        if(g_file_test(fullpath, G_FILE_TEST_IS_DIR))
        {
-           if(depth < builder_get_int(_builder, "dicts_search_depth"))
-               dicts_find_recursive(fullpath, depth + 1);
+           if(depth < builder_get_int(self->builder, "dicts_search_depth"))
+               dicts_find_recursive(self, fullpath, depth + 1);
        }
        if(g_file_test(fullpath, G_FILE_TEST_IS_REGULAR))
        {
@@ -449,26 +263,29 @@ gboolean dictionaries_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpoint
 
 void dicts_browse_btn_clicked_cb(GtkWidget *widget, gpointer data)
 {
+    Mainwnd *mw = MAINWND(data);
     static gchar *path = NULL;
     path = app_browse_disk("Select directory", GTK_WINDOW(gtk_widget_get_toplevel(widget)), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_OPEN, path);
     if(path)
     {
-       builder_set_str(_builder, "dicts_search_path", path);
-       builder_grab_focus(_builder, "dicts_search_path");
+       builder_set_str(mw->builder, "dicts_search_path", path);
+       builder_grab_focus(mw->builder, "dicts_search_path");
     }
 }
 
 void dicts_find_btn_clicked_cb(GtkWidget *widget, gpointer data)
 {
-    GtkEntry *path = GTK_ENTRY(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_search_path"));
+    Mainwnd *mw = MAINWND(data);
+    Dicts *self = mw->dicts;
+    GtkEntry *path = GTK_ENTRY(gtk_builder_get_object(GTK_BUILDER(mw->builder), "dicts_search_path"));
     if(!gtk_entry_get_text_length(path))
        return;
     gchar *dirname = (gchar*)gtk_entry_get_text(path);
     dirname = g_strdup(dirname);
-    dicts_find_recursive(dirname, 0);
+    dicts_find_recursive(self, dirname, 0);
     g_free(dirname);
     gtk_entry_set_text(path, "");
-    //dicts_view_scroll_down();
+    dicts_scroll_down(self);
 }
 
 void dicts_close_btn_clicked_cb(GtkWidget *widget, gpointer data)
@@ -492,11 +309,14 @@ static void dicts_selection_changed_cb(GtkTreeSelection *selection, gpointer dat
     if(gtk_tree_selection_get_selected(selection, &store, &iter))
     {
        path = gtk_tree_model_get_path(store, &iter);
+       dicts_selection_depth = gtk_tree_path_get_depth(path);
        n = gtk_tree_path_get_depth(path);
        gtk_tree_path_free(path);
        if(n == 2)
            gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, DICT_BINFO, &binfo, -1);
     }
+    else
+       dicts_selection_depth = -1;
     builder_set_str(mw->builder, "dicts_book_title", binfo ? binfo->title : "");
     builder_set_str(mw->builder, "dicts_book_path", binfo ? binfo->path : "");
     builder_set_int(mw->builder, "dicts_subbook_no", binfo ? binfo->subbook_no : -1);
@@ -513,63 +333,39 @@ void dicts_btn_clicked_cb(GtkWidget *widget, gpointer data)
     GtkWidget *wnd = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "dictionaries"));
     gtk_widget_hide_on_delete(wnd);
     GtkTreeIter iter1;
-    GtkTreeView *dicts_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(mw->builder), "dicts_tree"));
-    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(mw->builder), "dicts_store"));
-    GtkTreeSelection *select = gtk_tree_view_get_selection(dicts_tree);
-    GtkBox *box = GTK_BOX(gtk_builder_get_object(GTK_BUILDER(mw->builder), "dicts_search_methods"));
+    GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_tree"));
+    GtkTreeSelection *select = gtk_tree_view_get_selection(tree);
+    GtkBox *box = GTK_BOX(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_search_methods"));
     static gboolean preparewnd = True;
     if(preparewnd)
     {
-       self->builder = mw->builder;
        GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
-       gtk_tree_view_insert_column_with_attributes(dicts_tree, -1, _("Name"), renderer, "text", DICT_ALIAS, "editable", DICT_EDITABLE, NULL);
+       gtk_tree_view_insert_column_with_attributes(tree, -1, _("Name"), renderer, "text", DICT_ALIAS, "editable", DICT_EDITABLE, NULL);
+       g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(dicts_cell_edited_cb), self);
        gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
        g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(dicts_selection_changed_cb), data);
        gint i;
-#if 1
        const gchar *name;
        for(i = 0; (name = ebook_index_to_method_name(i)); i++)
            gtk_box_pack_start(box, gtk_label_new(name), False, False, 2);
-#endif
+
+       GtkTreeDragDestIface *iface = GTK_TREE_DRAG_DEST_GET_IFACE(self->store);
+       iface->row_drop_possible = dicts_row_drop_possible;
+       g_signal_connect(G_OBJECT(tree), "drag_data_received", G_CALLBACK(dicts_drag_data_received_cb), self);
+       gtk_tree_view_set_reorderable(tree, TRUE);
        preparewnd = False;
     }
-    if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dicts_store), &iter1))
+    if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(self->store), &iter1))
     {   
         gtk_tree_selection_select_iter(select, &iter1);
     }
-    builder_set_int(_builder, "dicts_search_depth", 1);
-    builder_set_str(_builder, "dicts_search_path", "");
-    builder_grab_focus(_builder, "dicts_search_path");
+    builder_set_int(self->builder, "dicts_search_depth", 1);
+    builder_set_str(self->builder, "dicts_search_path", "");
+    builder_grab_focus(self->builder, "dicts_search_path");
     gtk_widget_show_all(wnd);
     gtk_container_foreach(GTK_CONTAINER(box), dicts_info_update_search_cb, NULL);
 }
 
-gboolean dicts_check_binfo(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-    gint n = gtk_tree_path_get_depth(path);
-    gpointer *q = (gpointer*)data;
-    if(n == 2)
-    {
-       BOOK_INFO *binfo = NULL;
-       gtk_tree_model_get(GTK_TREE_MODEL(model), iter, DICT_BINFO, &binfo, -1);
-       if(*q == (gpointer)binfo->book)
-       {
-           *q = (gpointer*)gtk_tree_model_get_path(GTK_TREE_MODEL(model), iter);
-           return TRUE;
-       }
-    }
-    return FALSE;
-}
-
-GtkTreePath* dicts_find_path(EB_Book *book)
-{
-    gpointer q = (gpointer)book;
-    //gtk_tree_model_foreach(GTK_TREE_MODEL(dicts.store), dicts_check_binfo, &q);
-    if(q == (gpointer)book)
-       return NULL;
-    return (GtkTreePath*)q;
-}
-
 gboolean dicts_save_item(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
 {
     guchar *title;
@@ -588,7 +384,7 @@ gboolean dicts_save_item(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *it
        gchar buf[16];
        xmlNodePtr node = xmlAddChild(group, xmlNewNode(NULL, (xmlChar*)"dict"));
        BOOK_INFO *binfo;
-       GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_store"));
+       GtkTreeStore *dicts_store = GTK_TREE_STORE(model);
        gtk_tree_model_get(GTK_TREE_MODEL(dicts_store), iter, DICT_ALIAS, &title, DICT_BINFO, &binfo, -1);
        xmlNewProp(node, (xmlChar*)"name", (xmlChar*)title);
        xmlNewProp(node, (xmlChar*)"path", (xmlChar*)binfo->path);
@@ -610,11 +406,11 @@ void dicts_save(Dicts *self)
     gchar filename[PATH_MAX], buf[16];
     xmlDocPtr doc = xmlNewDoc((xmlChar*)"1.0");
     doc->children = xmlNewDocRawNode(doc, NULL, (xmlChar*)"Dictionaries", NULL);
-    sprintf(buf, "%d", builder_get_int(_builder, "mainwnd_dict_group"));
+    sprintf(buf, "%d", builder_get_int(self->builder, "mainwnd_dict_group"));
     xmlNewProp(doc->children, (xmlChar*)"active", (xmlChar*)buf);
     gchar *userdir = prefs_get_userdir();
     sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_DICTS);
-    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_store"));
+    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_store"));
     gtk_tree_model_foreach(GTK_TREE_MODEL(dicts_store), dicts_save_item, doc->children);
     xmlSaveFormatFileEnc(filename, doc, "utf8", 0);
     xmlFreeDoc(doc);
@@ -656,13 +452,12 @@ void dicts_startElement(void *ctx, const xmlChar *name, const xmlChar **atts)
     static GtkTreeIter iter;
     xmlParserCtxt *ctxt = (xmlParserCtxt*)ctx;
     xmlSAXHandler *cb = ctxt->sax;
+    Dicts *dicts = DICTS(cb->_private);
     if(!g_strcmp0((gchar*)name, "Dictionaries"))
     {
-       gint *active = (gint*)cb->_private;
-       *active = atoi((gchar*)atts[1]);
-       //dictbar.group = g_strdup((gchar*)atts[1]);
+       dicts->active_group = atoi((gchar*)atts[1]);
     }
-    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_store"));
+    GtkTreeStore *dicts_store = GTK_TREE_STORE(gtk_builder_get_object(GTK_BUILDER(dicts->builder), "dicts_store"));
     if(!g_strcmp0((gchar*)name, "group"))
     {
        gtk_tree_store_append(dicts_store, &iter, NULL);
@@ -684,17 +479,16 @@ gint dicts_load(Dicts *self)
 {
     gchar filename[PATH_MAX];
     xmlSAXHandler cb;
-    gint active = 0;
     gchar *userdir = prefs_get_userdir();
     sprintf(filename, "%s%s%s", userdir, G_DIR_SEPARATOR_S, FILENAME_DICTS);
     if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
        return 0;
     memset(&cb, 0, sizeof(xmlSAXHandler));
     cb.startElement = &dicts_startElement;
-    cb._private = &active;
+    cb._private = self;
     xmlDocPtr doc = xmlSAXParseFile(&cb, filename, 0);
     xmlFreeDoc(doc);
-    return active;
+    return self->active_group;
 }
 
 gboolean dicts_get_nth(Dicts *self, gint n, GtkTreeIter *iter)
@@ -716,7 +510,7 @@ void dicts_delete_btn_clicked_cb(GtkWidget *widget, gpointer data)
     Mainwnd *mw = MAINWND(data);
     Dicts *dicts = mw->dicts;
 
-    GtkTreeView *dicts_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(_builder), "dicts_tree"));
+    GtkTreeView *dicts_tree = GTK_TREE_VIEW(gtk_builder_get_object(GTK_BUILDER(dicts->builder), "dicts_tree"));
     GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dicts_tree));
     if(!gtk_tree_selection_get_selected(selection, NULL, &iter))
        return;
@@ -737,3 +531,23 @@ void dicts_delete_btn_clicked_cb(GtkWidget *widget, gpointer data)
     gtk_tree_path_free(path);
 }
 
+gboolean dicts_tree_key_release_event_cb(GtkWidget *w, GdkEventKey *evt, gpointer data)
+{
+    if(evt->keyval == GDK_Delete)
+    {
+       dicts_delete_btn_clicked_cb(w, data);
+    }
+    return TRUE;
+}
+
+void dicts_up_btn_clicked_cb(GtkWidget *widget, gpointer data)
+{
+    Mainwnd *mw = MAINWND(data);
+    dicts_item_move(mw->dicts, True);
+}
+
+void dicts_down_btn_clicked_cb(GtkWidget *widget, gpointer data)
+{
+    Mainwnd *mw = MAINWND(data);
+    dicts_item_move(mw->dicts, False);
+}
index 0ad88c1..6067dc3 100644 (file)
@@ -7,7 +7,7 @@
 G_BEGIN_DECLS
 
 #define TYPE_DICTS (dicts_get_type ())
-#define DICTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DICTS, DICTS))
+#define DICTS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DICTS, Dicts))
 #define DICTS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DICTS, DictsClass))
 #define IS_DICTS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DICTS))
 #define IS_DICTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DICTS))
@@ -21,6 +21,7 @@ struct _Dicts {
     GData          *data;
     GtkTreeStore    *store;
     Builder        *builder;
+    gint           active_group;
 };
 
 struct _DictsClass {
@@ -37,13 +38,3 @@ G_END_DECLS
 
 #endif /* __DICTS_H__ */
 
-#ifndef __PREF_DICTGROUP_H__
-#define __PREF_DICTGROUP_H__
-
-void            dicts_show(GtkWidget *w, gpointer data);
-GtkWidget*     dicts_info(gboolean create);
-GtkTreePath*    dicts_find_path(EB_Book *book);
-
-void            my_gtk_tree_store_swap(GtkTreeStore *tree_store, GtkTreeIter *a, GtkTreeIter *b);
-
-#endif /* __PREF_DICTGROUP_H__ */
index 5174c38..9efed65 100644 (file)
@@ -85,6 +85,7 @@
           <object class="GtkHBox" id="hbox12">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="spacing">5</property>
             <child>
               <object class="GtkLabel" id="label5">
                 <property name="visible">True</property>
                         <property name="shadow_type">etched-in</property>
                         <child>
                           <object class="GtkTreeView" id="dicts_tree">
+                            <property name="height_request">200</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="model">dicts_store</property>
                             <property name="headers_visible">False</property>
+                            <signal name="key-release-event" handler="dicts_tree_key_release_event_cb" swapped="no"/>
                           </object>
                         </child>
                       </object>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkButton" id="button12">
+                  <object class="GtkButton" id="dicts_down_btn">
                     <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="dicts_down_btn_clicked_cb" swapped="no"/>
                     <child>
                       <object class="GtkImage" id="image10">
                         <property name="visible">True</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkButton" id="button13">
+                  <object class="GtkButton" id="dicts_up_btn">
                     <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="dicts_up_btn_clicked_cb" swapped="no"/>
                     <child>
                       <object class="GtkImage" id="image11">
                         <property name="visible">True</property>
               <object class="GtkVBox" id="vbox6">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="spacing">5</property>
                 <child>
                   <object class="GtkHBox" id="hbox13">
                     <property name="visible">True</property>
               <object class="GtkLabel" id="label12">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="label" translatable="yes">expander</property>
+                <property name="label" translatable="yes">Book info</property>
               </object>
             </child>
           </object>
           </packing>
         </child>
         <child>
-          <object class="GtkHPaned" id="hpaned1">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow1">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">automatic</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <property name="shadow_type">in</property>
-                <child>
-                  <object class="GtkTreeView" id="mainwnd_results">
-                    <property name="width_request">150</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="model">mainwnd_results_store</property>
-                    <property name="headers_visible">False</property>
-                    <property name="headers_clickable">False</property>
-                    <property name="enable_search">False</property>
-                    <property name="show_expanders">False</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">False</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkVBox" id="vbox8">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="shadow_type">in</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="mainwnd_next">
-                    <property name="can_focus">False</property>
-                    <property name="no_show_all">True</property>
-                    <child>
-                      <object class="GtkButton" id="button6">
-                        <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>
-                        <child>
-                          <object class="GtkImage" id="image12">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="stock">gtk-close</property>
-                            <property name="icon-size">2</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="entry1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="invisible_char">●</property>
-                        <property name="primary_icon_activatable">False</property>
-                        <property name="secondary_icon_activatable">False</property>
-                        <property name="primary_icon_sensitive">True</property>
-                        <property name="secondary_icon_sensitive">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="button8">
-                        <property name="label">gtk-media-next</property>
-                        <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>
-                        <property name="use_stock">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkHBox" id="hbox2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="position">3</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkHPaned" id="hpaned1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hscrollbar_policy">automatic</property>
+                <property name="vscrollbar_policy">automatic</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTreeView" id="mainwnd_results">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">mainwnd_results_store</property>
+                    <property name="headers_visible">False</property>
+                    <property name="headers_clickable">False</property>
+                    <property name="enable_search">False</property>
+                    <property name="show_expanders">False</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">False</property>
+                <property name="shrink">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox8">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkScrolledWindow" id="scrolledwindow2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">automatic</property>
+                    <property name="vscrollbar_policy">automatic</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="mainwnd_next">
+                    <property name="can_focus">False</property>
+                    <property name="no_show_all">True</property>
+                    <child>
+                      <object class="GtkButton" id="button6">
+                        <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>
+                        <child>
+                          <object class="GtkImage" id="image12">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="stock">gtk-close</property>
+                            <property name="icon-size">2</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="primary_icon_activatable">False</property>
+                        <property name="secondary_icon_activatable">False</property>
+                        <property name="primary_icon_sensitive">True</property>
+                        <property name="secondary_icon_sensitive">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="button8">
+                        <property name="label">gtk-media-next</property>
+                        <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>
+                        <property name="use_stock">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">False</property>
+                <property name="shrink">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">150</property>
+          </packing>
+        </child>
       </object>
     </child>
   </object>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="tab_pos">left</property>
+                <property name="show_tabs">False</property>
+                <property name="show_border">False</property>
                 <child>
                   <object class="GtkFrame" id="frame3">
                     <property name="visible">True</property>
                           <object class="GtkTable" id="table1">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="n_rows">3</property>
+                            <property name="n_rows">4</property>
                             <property name="n_columns">2</property>
                             <property name="column_spacing">10</property>
                             <property name="row_spacing">10</property>
                                 <property name="label" translatable="yes">Dictionary title</property>
                               </object>
                               <packing>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
                               </packing>
                             </child>
                             <child>
                               <packing>
                                 <property name="left_attach">1</property>
                                 <property name="right_attach">2</property>
-                                <property name="top_attach">2</property>
-                                <property name="bottom_attach">3</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
                               </packing>
                             </child>
                             <child>
                                 <property name="label" translatable="yes">Link</property>
                               </object>
                             </child>
+                            <child>
+                              <object class="GtkCheckButton" id="highlight_all_keywords">
+                                <property name="label" translatable="yes">Highlight all keywords</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="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
index 01b4ec2..61ee296 100644 (file)
@@ -30,12 +30,12 @@ typedef struct
 
 static const SEARCH_METHOD methods[] =
 {
-    {SEARCH_FORWARD,       eb_have_word_search,        eb_search_word},
-    {SEARCH_BACKWARD,      eb_have_endword_search,     eb_search_endword},
-    {SEARCH_EXACTWORD,     eb_have_exactword_search,   eb_search_exactword},
-    {SEARCH_KEYWORD,       eb_have_keyword_search,     ebook_search_keyword},
-    {SEARCH_MENU,          eb_have_menu,               NULL},
-    {SEARCH_COPYRIGHT,     eb_have_copyright,          NULL},
+    {_("Forward"),         eb_have_word_search,        eb_search_word},
+    {_("Backward"),        eb_have_endword_search,     eb_search_endword},
+    {_("Exactword"),       eb_have_exactword_search,   eb_search_exactword},
+    {_("Keyword"),         eb_have_keyword_search,     ebook_search_keyword},
+    {_("Menu"),                    eb_have_menu,               NULL},
+    {_("Copyright"),       eb_have_copyright,          NULL},
 };
 
 const gchar* ebook_index_to_method_name(gint index)
index cbca314..cf0a434 100644 (file)
@@ -28,8 +28,8 @@ static void mainwnd_init(Mainwnd *self)
         g_assert(1);
 
     self->builder = g_object_new(TYPE_BUILDER, NULL);
-    self->prefs = g_object_new(TYPE_PREFS, NULL);
-    self->dicts = g_object_new(TYPE_DICTS, NULL);
+    self->prefs = g_object_new(TYPE_PREFS, "builder", self->builder, NULL);
+    self->dicts = g_object_new(TYPE_DICTS, "builder", self->builder, 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"));
@@ -38,6 +38,7 @@ static void mainwnd_init(Mainwnd *self)
     self->text = g_object_new(TYPE_TEXTVIEW, "prefs", self->prefs, 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;
 }
 
 void mainwnd_headword_append(gpointer data, gpointer user_data)
@@ -100,11 +101,9 @@ void mainwnd_exit()
     prefs_set_int(prefs, "mainwnd.w", w);
     prefs_set_int(prefs, "mainwnd.h", h);
 
-    GtkWidget *tree = GTK_WIDGET(gtk_builder_get_object(GTK_BUILDER(mw->builder), "mainwnd_results"));
-    w = tree->allocation.width;
-    h = tree->allocation.height;
+    GtkPaned *p = GTK_PANED(gtk_builder_get_object(GTK_BUILDER(mw->builder), "hpaned1"));
+    w = gtk_paned_get_position(p);
     prefs_set_int(prefs, "paned.tree_width", w);
-    prefs_set_int(prefs, "paned.tree_height", h);
 
     //history_save_words();
     prefs_save(prefs);
@@ -135,6 +134,13 @@ void mainwnd_search_clear_clicked_cb(GtkWidget *widget, gpointer data)
 
 void mainwnd_search(Mainwnd *self, const gchar *word, gint method)
 {
+    if(self->word)
+    {
+       g_free(self->word);
+       self->word = NULL;
+    }
+    if(word)
+       self->word = g_strdup(word);
     if(method == -1)
        method = builder_get_int(self->builder, "mainwnd_search_method");
 
@@ -257,7 +263,7 @@ void mainwnd_iconify_restore(Mainwnd *mw)
        gtk_widget_hide(GTK_WIDGET(mw));
     }
     else
-       gtk_window_present(mw);
+       gtk_window_present(GTK_WINDOW(mw));
 }
 
 void mainwnd_iconify_cb(GtkWidget *widget, gpointer data)
@@ -414,18 +420,17 @@ void mainwnd_prepare(Mainwnd *self)
     }
     builder_set_int(self->builder, "mainwnd_search_method", 0);
 
-    gint remember_pos = prefs_get_int(self->prefs, "mainwnd.remember_pos");
-    if(remember_pos)
+    gint w = prefs_get_int(self->prefs, "mainwnd.w");
+    gint h = prefs_get_int(self->prefs, "mainwnd.h");
+    gtk_window_resize(GTK_WINDOW(self), w, h);
+    w = prefs_get_int(self->prefs, "paned.tree_width");
+    GtkPaned *p = GTK_PANED(gtk_builder_get_object(GTK_BUILDER(self->builder), "hpaned1"));
+    gtk_paned_set_position(p, w);
+    if(prefs_get_int(self->prefs, "mainwnd.remember_pos"))
     {
        gint x = prefs_get_int(self->prefs, "mainwnd.x");
        gint y = prefs_get_int(self->prefs, "mainwnd.y");
-       gint w = prefs_get_int(self->prefs, "mainwnd.w");
-       gint h = prefs_get_int(self->prefs, "mainwnd.h");
-       gtk_window_set_default_size(GTK_WINDOW(self), w, h);
         gtk_window_move(GTK_WINDOW(self), x, y);
-       w = prefs_get_int(self->prefs, "paned.tree_width");
-       h = prefs_get_int(self->prefs, "paned.tree_height");
-       gtk_widget_set_size_request(GTK_WIDGET(tree), w, h);
     }
     builder_grab_focus(self->builder, "mainwnd_search");
 }
@@ -465,11 +470,6 @@ void mainwnd_insert_text(gchar *txt, gboolean clear)
     textview_insert_message(text, txt, clear);
 }
 
-void mainwnd_clear_text()
-{
-    g_printf("TODO: clear text\n");
-}
-
 gint mainwnd_get_search_method()
 {
     return builder_get_int(_mainwnd->builder, "mainwnd_search_method");
@@ -477,8 +477,8 @@ gint mainwnd_get_search_method()
 
 void mainwnd_open(Mainwnd *self, RESULT *res)
 {
-    textview_open(self->text, res, self->prefs, TRUE, 0);
-    gtk_widget_show_all(GTK_WIDGET(mainwnd_get_wnd()));
+    textview_open(self->text, res, TRUE, self->word);
+    gtk_widget_show_all(GTK_WIDGET(self));
 }
 
 void mainwnd_menu_btn_clicked_cb(GtkWidget *widget, gpointer data)
index 5bce9fb..21dc44a 100644 (file)
@@ -28,6 +28,7 @@ struct _Mainwnd {
     GSequence  *results;
     TextView   *text;
     Popupwnd   *popupwnd;
+    gchar      *word;
 };
 
 struct _MainwndClass {
@@ -42,7 +43,6 @@ GSequence*    mainwnd_get_results();
 gint           mainwnd_get_search_method();
 gboolean        mainwnd_get_dicts(GtkTreeModel **store, GtkTreeIter *iter);
 void           mainwnd_insert_text(gchar *txt, gboolean clear);
-void           mainwnd_clear_text();
 void            mainwnd_search(Mainwnd *self, const gchar *word, gint method);
 void            mainwnd_open(Mainwnd *self, RESULT *res);
 void           mainwnd_exit();
index 30789f1..c8ae1ba 100644 (file)
@@ -46,7 +46,7 @@ static gboolean popuwnd_hide_timeout_cb(gpointer data)
     return False;
 }
 
-static void popupwnd_start_stop_timer(Popupwnd *self, gboolean start)
+static void popupwnd_timer(Popupwnd *self, gboolean start)
 {
     static gint timeout_id = 0;
     if(timeout_id != 0)
@@ -59,12 +59,12 @@ static void popupwnd_start_stop_timer(Popupwnd *self, gboolean start)
 
 void popupwnd_leave_notify_event_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
 {
-    popupwnd_start_stop_timer(POPUPWND(widget), (event->detail == GDK_NOTIFY_NONLINEAR) || (event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL));
+    popupwnd_timer(POPUPWND(widget), (event->detail == GDK_NOTIFY_NONLINEAR) || (event->detail == GDK_NOTIFY_NONLINEAR_VIRTUAL));
 }
 
 void popupwnd_enter_notify_event_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
 {
-    popupwnd_start_stop_timer(POPUPWND(widget), False);
+    popupwnd_timer(POPUPWND(widget), False);
 }
 
 static void popupwnd_class_init(PopupwndClass *klass)
@@ -202,11 +202,6 @@ static void popupwnd_dict_menu_create(Popupwnd *self, gboolean newmenu)
         popupwnd_dict_menu_append(NULL, NULL, NULL, self);
        GtkTreeModel *store = GTK_TREE_MODEL(gtk_builder_get_object(GTK_BUILDER(self->builder), "dicts_store"));
         gtk_tree_model_foreach(GTK_TREE_MODEL(store), popupwnd_dict_menu_append, self);
-       if(self->binfo)
-       {
-           if(!dicts_find_path(self->binfo->book))
-               self->binfo = NULL;
-       }
     }
 }
 
@@ -220,9 +215,43 @@ void popupwnd_dict_btn_clicked_cb(GtkWidget *widget, gpointer data)
 
 void popupwnd_render(gpointer data, gpointer user_data)
 {
-    Popupwnd *w = POPUPWND(user_data);
+    Popupwnd *pw = POPUPWND(user_data);
+    const gchar *word = prefs_get_str(pw->prefs, "popupwnd_label");
     RESULT *res = (RESULT*)data;
-    textview_open(w->text, res, w->prefs, FALSE, 0);
+    textview_open(pw->text, res, FALSE, word);
+}
+
+static void popupwnd_calculate_coordinates(Popupwnd *self, gint *x, gint *y, gint *w, gint *h)
+{
+    GdkModifierType mask;
+    gint pointer_x, pointer_y, root_x, root_y;
+
+    *w = prefs_get_int(self->prefs, "popupwnd.w");
+    *h = prefs_get_int(self->prefs, "popupwnd.h");
+    *w = (*w > 100) ? *w : 100;
+    *h = (*h > 100) ? *h : 100;
+    gboolean remember_pos = prefs_get_int(self->prefs, "popupwnd.remember_pos");
+    if(remember_pos && (self->x >= 0) && (self->y >= 0))
+    {
+       *x = self->x;
+       *y = self->y;
+    }
+    else
+    {
+       GdkWindow *root_win = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), GDK_ROOT_WINDOW());
+       root_x = gdk_window_get_width(root_win);
+       root_y = gdk_window_get_height(root_win);
+       gdk_window_get_pointer(root_win, &pointer_x, &pointer_y, &mask);
+       *x = pointer_x + 10;
+       *y = pointer_y + 10;
+
+       if(*x + *w > root_x)
+           *x = root_x - *w;
+
+       if(*y + *h > root_y)
+           *y = root_y - *h;
+    }
+    g_printf("%d, %d, %d, %d\n", *x, *y, *w, *h);
 }
 
 void popupwnd_search(Popupwnd *self, const gchar *str)
@@ -250,16 +279,16 @@ void popupwnd_search(Popupwnd *self, const gchar *str)
        g_sequence_foreach(self->results, popupwnd_render, self);
     else
        textview_insert_message(self->text, "<No hits>", TRUE);
-    gtk_window_present(GTK_WINDOW(self));
-    if((self->x > 0) && (self->y > 0))
-       gtk_window_move(GTK_WINDOW(_popupwnd), self->x, self->y);
 
-    gint w = prefs_get_int(self->prefs, "popupwnd.w");
-    gint h = prefs_get_int(self->prefs, "popupwnd.h");
-    w = (w > 100) ? w : 100;
-    h = (h > 100) ? h : 100;
-    gtk_widget_set_size_request(GTK_WIDGET(self), w, h);
+    if(!self->lock)
+    {
+       gint x, y, w, h;
+       popupwnd_calculate_coordinates(self, &x, &y, &w, &h);
+       gtk_window_move(GTK_WINDOW(_popupwnd), x, y);
+       gtk_widget_set_size_request(GTK_WIDGET(self), w, h);
+    }
 
+    popupwnd_timer(self, False);
     gtk_widget_show_all(GTK_WIDGET(self));
 }
 
index b2be199..d6e32a9 100644 (file)
@@ -49,17 +49,34 @@ static const pref1 prefs_list[] =
     {G_TYPE_INT, "mainwnd.remember_pos", {1}},
     {G_TYPE_INT, "mainwnd.search", {0}},
     {G_TYPE_INT, "mainwnd.custom_font", {0}},
-    {G_TYPE_INT, "paned.tree_width", {185}},
-    {G_TYPE_INT, "paned.tree_height", {210}},
+    {G_TYPE_INT, "paned.tree_width", {150}},
+    {G_TYPE_INT, "highlight_all_keywords", {1}},
     {G_TYPE_STRING, "color.link", {.s = "#0000c0"}},
     {G_TYPE_STRING, "color.keyword", {.s = "#c00000"}},
     {G_TYPE_STRING, "color.title", {.s = "#306090"}}
 };
 
-//static GParamSpec *obj_properties[SZ(prefs_list) + 2] = { NULL, };
+static void prefs_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
+{
+    Prefs *prefs = PREFS(object);
+
+    switch(param_id)
+    {
+       case 1:
+           prefs->builder = BUILDER(g_value_get_pointer(value));
+           break;
+       default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+           break;
+    }
+}
+
 
 static void prefs_class_init(PrefsClass *klass)
 {
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+    gobject_class->set_property = prefs_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 prefs_init(Prefs *self)
@@ -68,6 +85,7 @@ static void prefs_init(Prefs *self)
        _prefs = self;
     else
        g_assert(1);
+
     //GstElementClass *gstelement_class = GST_ELEMENT_CLASS(klass);
     //gst_element_class_add_pad_template(gstelement_class, gst_static_pad_template_get(&prefs_template));
 
@@ -201,7 +219,6 @@ void prefs_btn_clicked_cb(GtkWidget *widget, gpointer data)
     static gboolean preparewnd = True;
     if(preparewnd)
     {
-       prefs->builder = mw->builder;
        GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
        GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("Items"), renderer, "text", 0, NULL);
        gtk_tree_view_append_column(prefs_tree, column);
index bbeb205..8ff52c9 100644 (file)
@@ -131,36 +131,29 @@ gint textview_button_press_cb(GtkWidget *widget, GdkEventButton *event, gpointer
         {
             RESULT *res = (RESULT*)g_object_get_data(G_OBJECT(tag), "link");
            if(res)
-               textview_open(text, res, text->prefs, TRUE, 0);
+               textview_open(text, res, TRUE, NULL);
            return TRUE;
         }
     }
     return FALSE;
 }
 
-void textview_open(TextView *self, RESULT *res, Prefs *prefs, gboolean clear, gint mark)
+void textview_open(TextView *self, RESULT *res, gboolean clear, const gchar *word)
 {
     if(!res)
         return;
-    gchar *text = ebook_get_text(res);
     if(clear)
        textview_clear_textbuf(self);
-    else
-    {
-       gchar str[16];
-       GtkTextIter iter;
-       GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self));
-       gtk_text_buffer_get_end_iter(buf, &iter);
-       if(gtk_text_buffer_get_char_count(buf))
-           gtk_text_buffer_insert(buf, &iter, "\n", -1);
-       g_sprintf(str, "%d", mark);
-       gtk_text_buffer_create_mark(buf, str, &iter, TRUE);
-    }
+
+    gchar *text = ebook_get_text(res);
     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(word && prefs_get_int(self->prefs, "highlight_all_keywords"))
+       textview_highlight_word(self, word);
 }
 
 static void textview_set_property(GObject *object, guint param_id, const GValue *value, GParamSpec *pspec)
@@ -219,3 +212,20 @@ void textview_insert_message(TextView *self, gchar *msg, gboolean clear)
     gtk_text_buffer_insert(buf, &iter, msg, -1);
 }
 
+void textview_highlight_word(TextView *self, const gchar *word)
+{
+    GtkTextIter iter, start, end;
+    GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self));
+    const gchar *color = prefs_get_str(self->prefs, "color.keyword");
+    GtkTextTag *tag = gtk_text_buffer_create_tag(buf, NULL, "foreground", color, NULL);
+    gtk_text_buffer_get_start_iter(buf, &iter);
+    for(;;)
+    {
+       gboolean b = gtk_text_iter_forward_search(&iter, word, GTK_TEXT_SEARCH_VISIBLE_ONLY, &start, &end, NULL);
+       if(!b)
+           break;
+       gtk_text_buffer_apply_tag(buf, tag, &start, &end);
+       gtk_text_iter_set_offset(&iter, gtk_text_iter_get_offset(&end));
+    }
+}
+
index 8e5bd8f..23f83e2 100644 (file)
@@ -27,14 +27,10 @@ struct _TextViewClass {
     void               (*history_next)(RESULT *res);
 };
 
-void       textview_open(TextView *self, RESULT *res, Prefs *prefs, gboolean clear, gint mark);
-void        textview_push_message(TextView *self, gchar *msg);
-void        textview_set_pixels(TextView *self, gint n);
+void       textview_open(TextView *self, RESULT *res, gboolean clear, const gchar *word);
 void        textview_clear_textbuf(TextView *self);
 void        textview_insert_message(TextView *self, gchar *msg, gboolean clear);
-void        textview_underline_lnk(GtkWidget *widget, GdkEventMotion *event, GtkTextTag **tag_lnk);
-gint        textview_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data);
-//void     textview_populate_popup(GtkTextView *tview, GtkMenu *menu, gpointer user_data);
+void       textview_highlight_word(TextView *self, const gchar *word);
 
 GType      textview_get_type (void);