Merged older cs.po file with newest pot file.
[gliv/czech_localization.git] / src / tree_browser.c
bloba7ef9161dd8353d12619589384051e58c8c041eb
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /*****************************************
22 * The thumbnails browser in a tree view *
23 *****************************************/
25 #include <string.h> /* memset() */
27 #include "gliv.h"
28 #include "tree_browser.h"
29 #include "tree.h"
30 #include "thumbnails.h"
31 #include "images_menus.h"
32 #include "next_image.h"
33 #include "messages.h"
34 #include "loading.h"
35 #include "rendering.h"
37 extern GlivImage *current_image;
39 static GtkTreeStore *tree_store;
40 static GtkTreeView *tree_view;
43 * Association between a directory and a GtkTreePath
44 * Used when adding filenames.
46 static GHashTable *dir_path_hash = NULL;
48 /* Avoid reentrance */
49 static gint disable_tree = 0;
52 * If a row is selected when we cannot load an image, we
53 * record the filename to load it when possible.
55 static const gchar *next_filename;
57 /* The tree columns (they are not all displayed) */
58 enum {
59 PIXBUF_COLUMN,
60 NAME_COLUMN,
61 PATH_COLUMN,
62 N_COLUMNS
65 static tree_item *make_tree_rec(GtkTreeIter * where, GNode * node)
67 static const gchar *browser = NULL;
68 static gint percent = 0, number = 0;
69 tree_item *item, *first_item;
70 GNode *child;
72 if (where == NULL) {
73 /* First time for this browser */
74 number = 0;
75 percent = 0;
76 set_progress(NULL, NULL, -1);
78 if (browser == NULL)
79 /* First time */
80 browser = _("Browser");
81 return NULL;
84 item = node->data;
86 if (G_NODE_IS_LEAF(node)) {
87 fill_thumbnail(item);
88 gtk_tree_store_set(tree_store, where,
89 PIXBUF_COLUMN, item->thumb,
90 NAME_COLUMN, item->name,
91 PATH_COLUMN, item->path, -1);
92 set_progress(browser, &percent, number);
93 number++;
94 return item;
97 g_hash_table_insert(dir_path_hash, item->path,
98 gtk_tree_model_get_path(GTK_TREE_MODEL(tree_store),
99 where));
101 first_item = NULL;
102 for (child = g_node_first_child(node); child; child = child->next) {
103 GtkTreeIter iter;
104 gtk_tree_store_append(tree_store, &iter, where);
105 item = make_tree_rec(&iter, child);
106 if (first_item == NULL && item != NULL && item->thumb != NULL)
107 first_item = item;
110 item = node->data;
111 gtk_tree_store_set(tree_store, where,
112 PIXBUF_COLUMN, first_item ? first_item->thumb : NULL,
113 NAME_COLUMN, item->path,
114 PATH_COLUMN, first_item ? first_item->path : NULL, -1);
116 return first_item;
119 void load_later(void)
121 if (next_filename != NULL && !currently_loading() && current_image->node) {
122 menu_load(next_filename);
123 if (current_image->node->data == next_filename)
124 next_filename = NULL;
128 static void activate_row(GtkTreeSelection * selection)
130 GtkTreeIter iter;
131 GtkTreeModel *model;
132 gchar *path;
134 if (!gtk_tree_selection_get_selected(selection, &model, &iter))
135 return;
137 gtk_tree_model_get(model, &iter, PATH_COLUMN, &path, -1);
138 next_filename = path;
139 do_later(G_PRIORITY_DEFAULT, load_later);
142 static gboolean build_tree_browser(void)
144 GtkTreeIter iter;
145 GNode *tree;
147 tree = get_tree();
148 if (tree == NULL)
149 return FALSE;
151 if (dir_path_hash != NULL)
152 g_hash_table_destroy(dir_path_hash);
154 dir_path_hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
155 (GDestroyNotify) gtk_tree_path_free);
157 if (tree_store == NULL)
158 /* First time */
159 tree_store = gtk_tree_store_new(N_COLUMNS,
160 GDK_TYPE_PIXBUF, G_TYPE_STRING,
161 G_TYPE_POINTER);
162 else
163 gtk_tree_store_clear(tree_store);
165 gtk_tree_store_append(tree_store, &iter, NULL);
166 make_tree_rec(NULL, NULL);
167 make_tree_rec(&iter, tree);
169 set_progress(NULL, NULL, 0);
170 end_using_tree();
171 return TRUE;
174 static void destroy_tree_view(GtkWindow * window)
176 gtk_widget_destroy(GTK_WIDGET(window));
177 tree_view = NULL;
180 void show_tree_browser(void)
182 GtkCellRenderer *name_renderer;
183 GtkTreeViewColumn *col;
184 GtkTreeSelection *selection;
185 GtkScrolledWindow *scroll;
186 GtkWindow *window;
188 if (tree_view != NULL)
189 /* Currently displayed */
190 return;
192 if (tree_store == NULL && !build_tree_browser())
193 return;
195 tree_view =
196 GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_store)));
198 gtk_tree_view_set_enable_search(tree_view, TRUE);
200 col =
201 gtk_tree_view_column_new_with_attributes(_("Thumb"),
202 gtk_cell_renderer_pixbuf_new(),
203 "pixbuf", PIXBUF_COLUMN, NULL);
204 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
206 name_renderer = gtk_cell_renderer_text_new();
207 g_object_set(name_renderer,
208 "ellipsize-set", TRUE,
209 "ellipsize", PANGO_ELLIPSIZE_START, NULL);
210 col =
211 gtk_tree_view_column_new_with_attributes(_("Name"), name_renderer,
212 "text", NAME_COLUMN, NULL);
213 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), col);
214 gtk_widget_show_all(GTK_WIDGET(tree_view));
216 scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
217 gtk_scrolled_window_set_policy(scroll,
218 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
219 gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(tree_view));
220 gtk_widget_show_all(GTK_WIDGET(scroll));
222 window = new_window(_("Thumbnails browser"));
223 gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(scroll));
224 gtk_window_set_default_size(window, 300, 600);
225 gtk_widget_show_all(GTK_WIDGET(window));
227 selection = gtk_tree_view_get_selection(tree_view);
228 g_signal_connect(selection, "changed", G_CALLBACK(activate_row), NULL);
230 g_signal_connect(window, "delete-event", G_CALLBACK(destroy_tree_view),
231 NULL);
233 highlight_current_image();
236 void highlight_current_image(void)
238 gchar *path;
239 GtkTreePath *tree_path;
240 GtkTreeIter iter, child;
242 if (tree_view == NULL || !GTK_WIDGET_VISIBLE(tree_view) ||
243 current_image->node == NULL)
244 return;
246 if (next_filename) {
247 do_later(G_PRIORITY_DEFAULT, load_later);
248 return;
251 path = g_strdup(current_image->node->data);
252 do {
253 gchar *new_path = g_path_get_dirname(path);
255 g_free(path);
256 path = new_path;
258 tree_path = g_hash_table_lookup(dir_path_hash, path);
259 } while (!tree_path && !g_str_equal(path, "/") && !g_str_equal(path, "."));
261 g_free(path);
263 if (tree_path == NULL)
264 return;
266 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_store), &iter, tree_path))
267 return;
269 if (!gtk_tree_model_iter_children
270 (GTK_TREE_MODEL(tree_store), &child, &iter))
271 return;
273 do {
274 GValue tree_filename;
275 memset(&tree_filename, 0, sizeof(tree_filename));
277 gtk_tree_model_get_value(GTK_TREE_MODEL(tree_store), &child,
278 PATH_COLUMN, &tree_filename);
280 if (g_value_peek_pointer(&tree_filename) == current_image->node->data) {
281 tree_path =
282 gtk_tree_model_get_path(GTK_TREE_MODEL(tree_store), &child);
284 disable_tree++;
285 gtk_tree_view_expand_to_path(tree_view, tree_path);
286 gtk_tree_view_expand_row(tree_view, tree_path, FALSE);
287 gtk_tree_view_scroll_to_cell(tree_view, tree_path,
288 NULL, FALSE, 0.0, 0.0);
289 gtk_tree_view_set_cursor(tree_view, tree_path, NULL, FALSE);
290 disable_tree--;
292 gtk_tree_path_free(tree_path);
293 break;
296 g_value_unset(&tree_filename);
297 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(tree_store), &child));
300 void cond_rebuild_tree_browser(void)
302 if (dir_path_hash != NULL)
303 build_tree_browser();