Updated Spanish translation
[anjuta-git-plugin.git] / plugins / file-manager / file-view.c
blob48ef99e4f237b5650329bb884f547ae7fe6a091c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * file-manager
4 * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
5 *
6 * file-manager is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
13 * file-manager is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with file-manager. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
25 #include "file-view.h"
26 #include "file-model.h"
27 #include "file-view-marshal.h"
29 #include <gtk/gtkcellrenderertext.h>
30 #include <gtk/gtkcellrendererpixbuf.h>
31 #include <gtk/gtkcellrendererprogress.h>
32 #include <gtk/gtktreestore.h>
33 #include <gtk/gtktreeselection.h>
34 #include <gtk/gtktreemodelsort.h>
35 #include <gtk/gtkversion.h>
37 #define HAVE_TOOLTIP_API (GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 12))
38 #include <glib/gi18n.h>
40 #if HAVE_TOOLTIP_API
41 # include <gtk/gtktooltip.h>
42 #endif
44 #include <libanjuta/anjuta-debug.h>
46 typedef struct _AnjutaFileViewPrivate AnjutaFileViewPrivate;
48 struct _AnjutaFileViewPrivate
50 FileModel* model;
52 GList* saved_paths;
53 guint refresh_idle_id;
56 #define ANJUTA_FILE_VIEW_GET_PRIVATE(o) \
57 (G_TYPE_INSTANCE_GET_PRIVATE((o), ANJUTA_TYPE_FILE_VIEW, AnjutaFileViewPrivate))
59 G_DEFINE_TYPE (AnjutaFileView, file_view, GTK_TYPE_TREE_VIEW);
61 enum
63 PROP_BASE_URI = 1,
64 PROP_END
67 static void
68 file_view_cancel_refresh(AnjutaFileView* view)
70 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE(view);
71 if (priv->refresh_idle_id)
73 GSource* source = g_main_context_find_source_by_id (g_main_context_default(),
74 priv->refresh_idle_id);
75 g_source_destroy (source);
76 priv->refresh_idle_id = 0;
80 static void
81 file_view_on_file_clicked (GtkTreeViewColumn* column, AnjutaFileView* view)
86 static void
87 file_view_save_expanded_row (GtkTreeView* tree_view, GtkTreePath* path,
88 gpointer user_data)
90 AnjutaFileView* view = ANJUTA_FILE_VIEW (tree_view);
91 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
92 priv->saved_paths = g_list_append (priv->saved_paths,
93 gtk_tree_path_to_string (path));
96 static void
97 file_view_get_expanded_rows (AnjutaFileView* view)
99 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
101 priv->saved_paths = NULL;
102 gtk_tree_view_map_expanded_rows (GTK_TREE_VIEW (view),
103 file_view_save_expanded_row,
104 priv->saved_paths);
107 static gboolean
108 file_view_expand_row_idle (gpointer user_data)
110 AnjutaFileView* view = ANJUTA_FILE_VIEW (user_data);
111 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
113 if (priv->saved_paths)
115 gchar* path_string = (gchar*) priv->saved_paths->data;
116 GtkTreePath* path = gtk_tree_path_new_from_string (path_string);
118 gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
119 gtk_tree_path_free (path);
120 g_free (path_string);
121 priv->saved_paths = g_list_next (priv->saved_paths);
122 return TRUE;
124 else
126 g_list_free (priv->saved_paths);
127 priv->saved_paths = NULL;
128 priv->refresh_idle_id = 0;
129 return FALSE;
133 void
134 file_view_refresh (AnjutaFileView* view, gboolean remember_open)
136 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
137 GtkTreePath* tree_path;
139 file_view_cancel_refresh(view);
141 if (remember_open)
143 file_view_get_expanded_rows (view);
146 file_model_refresh (priv->model);
148 tree_path = gtk_tree_path_new_first ();
149 gtk_tree_view_expand_row (GTK_TREE_VIEW (view), tree_path, FALSE);
150 gtk_tree_path_free (tree_path);
151 if (remember_open)
153 priv->refresh_idle_id = g_idle_add (file_view_expand_row_idle, view);
157 gchar*
158 file_view_get_selected (AnjutaFileView* view)
160 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
161 GtkTreeSelection* selection =
162 gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
163 GtkTreeIter selected;
164 if (gtk_tree_selection_get_selected (selection, NULL, &selected))
166 gchar* uri = file_model_get_uri (priv->model, &selected);
167 return uri;
169 else
170 return NULL;
173 static gboolean
174 file_view_button_press_event (GtkWidget* widget, GdkEventButton* event)
176 AnjutaFileView* view = ANJUTA_FILE_VIEW (widget);
177 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
178 GtkTreeIter selected;
179 gchar* uri;
180 gboolean is_dir;
181 GtkTreePath* path = NULL;
183 GtkTreeSelection* selection =
184 gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
186 if (gtk_tree_selection_get_selected (selection, NULL, &selected))
188 path = gtk_tree_model_get_path (GTK_TREE_MODEL(priv->model), &selected);
189 gtk_tree_model_get (GTK_TREE_MODEL(priv->model), &selected,
190 COLUMN_URI, &uri,
191 COLUMN_IS_DIR, &is_dir,
192 -1);
194 else
196 uri = NULL;
197 is_dir = FALSE;
200 switch (event->button)
202 case 1: /* Left mouse button */
204 if (event->type == GDK_2BUTTON_PRESS)
206 if (is_dir)
208 if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (view),
209 path))
211 gtk_tree_view_expand_row (GTK_TREE_VIEW (view),
212 path,
213 FALSE);
215 else
217 gtk_tree_view_collapse_row (GTK_TREE_VIEW (view),
218 path);
221 else
223 g_signal_emit_by_name (G_OBJECT (view),
224 "file-open",
225 uri);
228 break;
230 case 3: /* Right mouse button */
232 g_signal_emit_by_name (G_OBJECT (view),
233 "show-popup-menu",
234 uri,
235 is_dir,
236 event->button,
237 event->time);
240 if (path != NULL)
241 gtk_tree_path_free (path);
242 g_free (uri);
243 return
244 GTK_WIDGET_CLASS (file_view_parent_class)->button_press_event (widget,
245 event);
248 static void
249 file_view_selection_changed (GtkTreeSelection* selection, AnjutaFileView* view)
251 GtkTreeIter selected;
252 GtkTreeModel* model;
253 if (gtk_tree_selection_get_selected (selection, &model, &selected))
255 gchar* uri = file_model_get_uri (FILE_MODEL(model), &selected);
256 g_signal_emit_by_name (G_OBJECT (view), "current-uri-changed",
257 uri, NULL);
258 g_free(uri);
260 else
262 g_signal_emit_by_name (G_OBJECT (view), "current-uri-changed",
263 NULL, NULL);
267 #if HAVE_TOOLTIP_API
268 static gboolean
269 file_view_query_tooltip (GtkWidget* widget, gint x, gint y, gboolean keyboard,
270 GtkTooltip* tooltip)
272 AnjutaFileView* view = ANJUTA_FILE_VIEW (widget);
273 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (view);
274 GtkTreeModel* model = GTK_TREE_MODEL (priv->model);
275 GtkTreePath* path;
276 GtkTreeIter iter;
278 gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(view),
279 x, y, &path, NULL, NULL, NULL);
280 if (path)
282 if (gtk_tree_model_get_iter (model, &iter, path))
284 gchar* filename = file_model_get_filename (priv->model, &iter);
285 gtk_tooltip_set_markup (tooltip, filename);
286 g_free(filename);
287 gtk_tree_path_free (path);
288 return TRUE;
290 gtk_tree_path_free (path);
292 return FALSE;
294 #endif
296 static void
297 file_view_init (AnjutaFileView *object)
299 GtkCellRenderer* renderer_text;
300 GtkCellRenderer* renderer_pixbuf;
301 GtkTreeViewColumn* column;
302 GtkTreeSelection* selection;
304 AnjutaFileViewPrivate* priv = ANJUTA_FILE_VIEW_GET_PRIVATE (object);
306 priv->model = file_model_new (GTK_TREE_VIEW(object), NULL);
308 gtk_tree_view_set_model (GTK_TREE_VIEW (object), GTK_TREE_MODEL(priv->model));
310 renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
311 renderer_text = gtk_cell_renderer_text_new ();
313 column = gtk_tree_view_column_new ();
314 gtk_tree_view_column_set_title (column, _("Filename"));
315 gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
316 gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
317 gtk_tree_view_column_set_attributes (column, renderer_pixbuf,
318 "pixbuf", COLUMN_PIXBUF, NULL);
319 gtk_tree_view_column_set_attributes (column, renderer_text,
320 "text", COLUMN_FILENAME, NULL);
321 gtk_tree_view_append_column (GTK_TREE_VIEW (object), column);
323 g_signal_connect (G_OBJECT (column), "clicked",
324 G_CALLBACK (file_view_on_file_clicked), object);
326 selection =
327 gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
328 g_signal_connect (selection, "changed",
329 G_CALLBACK (file_view_selection_changed), object);
331 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (object), FALSE);
333 #if HAVE_TOOLTIP_API
334 g_object_set (object, "has-tooltip", TRUE, NULL);
335 #endif
338 static void
339 file_view_get_property (GObject *object, guint prop_id, GValue *value,
340 GParamSpec *pspec)
342 AnjutaFileViewPrivate *priv = ANJUTA_FILE_VIEW_GET_PRIVATE (object);
343 gchar* uri;
345 switch (prop_id)
347 case PROP_BASE_URI:
348 g_object_get (G_OBJECT(priv->model), "base_uri", &uri, NULL);
349 g_value_set_string (value, uri);
350 break;
351 default:
352 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
353 break;
357 static void
358 file_view_set_property (GObject *object, guint prop_id, const GValue *value,
359 GParamSpec *pspec)
361 AnjutaFileViewPrivate *priv = ANJUTA_FILE_VIEW_GET_PRIVATE (object);
363 switch (prop_id)
365 case PROP_BASE_URI:
366 g_object_set (G_OBJECT (priv->model), "base_uri", g_value_get_string (value),
367 NULL);
368 break;
369 default:
370 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
371 break;
375 static void
376 file_view_finalize (GObject *object)
378 G_OBJECT_CLASS (file_view_parent_class)->finalize (object);
381 static void
382 file_view_class_init (AnjutaFileViewClass *klass)
384 GObjectClass* object_class = G_OBJECT_CLASS (klass);
385 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
387 g_type_class_add_private (klass, sizeof (AnjutaFileViewPrivate));
389 object_class->finalize = file_view_finalize;
390 object_class->set_property = file_view_set_property;
391 object_class->get_property = file_view_get_property;
393 g_object_class_install_property (object_class,
394 PROP_BASE_URI,
395 g_param_spec_string ("base_uri",
396 _("Base uri"),
397 _("Uri of the top-most path displayed"),
398 NULL,
399 G_PARAM_READABLE |
400 G_PARAM_WRITABLE |
401 G_PARAM_CONSTRUCT));
402 g_signal_new ("file-open",
403 ANJUTA_TYPE_FILE_VIEW,
404 G_SIGNAL_RUN_LAST,
405 G_STRUCT_OFFSET (AnjutaFileViewClass, file_open),
406 NULL, NULL,
407 g_cclosure_marshal_VOID__STRING,
408 G_TYPE_NONE,
410 G_TYPE_STRING,
411 NULL);
413 g_signal_new ("current-uri-changed",
414 ANJUTA_TYPE_FILE_VIEW,
415 G_SIGNAL_RUN_LAST,
416 G_STRUCT_OFFSET (AnjutaFileViewClass, current_uri_changed),
417 NULL, NULL,
418 g_cclosure_marshal_VOID__STRING,
419 G_TYPE_NONE,
421 G_TYPE_STRING,
422 NULL);
424 g_signal_new ("show-popup-menu",
425 ANJUTA_TYPE_FILE_VIEW,
426 G_SIGNAL_RUN_LAST,
427 G_STRUCT_OFFSET (AnjutaFileViewClass, show_popup_menu),
428 NULL, NULL,
429 file_view_cclosure_marshal_VOID__STRING_BOOLEAN_INT_INT,
430 G_TYPE_NONE,
432 G_TYPE_STRING,
433 G_TYPE_BOOLEAN,
434 G_TYPE_INT,
435 G_TYPE_INT,
436 NULL);
438 widget_class->button_press_event = file_view_button_press_event;
440 /* Tooltips */
441 #if HAVE_TOOLTIP_API
442 widget_class->query_tooltip = file_view_query_tooltip;
443 #endif
447 GtkWidget*
448 file_view_new (void)
450 return g_object_new (ANJUTA_TYPE_FILE_VIEW, NULL);