1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Johannes Schmid 2007 <jhs@gnome.org>
6 * file-manager is free software.
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)
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>
41 # include <gtk/gtktooltip.h>
44 #include <libanjuta/anjuta-debug.h>
46 typedef struct _AnjutaFileViewPrivate AnjutaFileViewPrivate
;
48 struct _AnjutaFileViewPrivate
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
);
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;
81 file_view_on_file_clicked (GtkTreeViewColumn
* column
, AnjutaFileView
* view
)
87 file_view_save_expanded_row (GtkTreeView
* tree_view
, GtkTreePath
* path
,
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
));
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
,
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
);
126 g_list_free (priv
->saved_paths
);
127 priv
->saved_paths
= NULL
;
128 priv
->refresh_idle_id
= 0;
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
);
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
);
152 priv
->refresh_idle_id
= g_idle_add (file_view_expand_row_idle
, view
);
157 file_view_get_selected (AnjutaFileView
* view
)
159 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
160 GtkTreeSelection
* selection
=
161 gtk_tree_view_get_selection (GTK_TREE_VIEW (view
));
162 GtkTreeIter selected
;
163 if (gtk_tree_selection_get_selected (selection
, NULL
, &selected
))
165 gchar
* uri
= file_model_get_uri (priv
->model
, &selected
);
173 file_view_button_press_event (GtkWidget
* widget
, GdkEventButton
* event
)
175 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
176 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
177 GtkTreeIter selected
;
180 GtkTreePath
* path
= NULL
;
182 GtkTreeSelection
* selection
=
183 gtk_tree_view_get_selection (GTK_TREE_VIEW (view
));
185 if (gtk_tree_selection_get_selected (selection
, NULL
, &selected
))
187 path
= gtk_tree_model_get_path (GTK_TREE_MODEL(priv
->model
), &selected
);
188 gtk_tree_model_get (GTK_TREE_MODEL(priv
->model
), &selected
,
190 COLUMN_IS_DIR
, &is_dir
,
199 switch (event
->button
)
201 case 1: /* Left mouse button */
203 if (event
->type
== GDK_2BUTTON_PRESS
)
207 if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (view
),
210 gtk_tree_view_expand_row (GTK_TREE_VIEW (view
),
216 gtk_tree_view_collapse_row (GTK_TREE_VIEW (view
),
222 g_signal_emit_by_name (G_OBJECT (view
),
229 case 3: /* Right mouse button */
231 g_signal_emit_by_name (G_OBJECT (view
),
240 gtk_tree_path_free (path
);
243 GTK_WIDGET_CLASS (file_view_parent_class
)->button_press_event (widget
,
248 file_view_selection_changed (GtkTreeSelection
* selection
, AnjutaFileView
* view
)
250 GtkTreeIter selected
;
252 if (gtk_tree_selection_get_selected (selection
, &model
, &selected
))
254 gchar
* uri
= file_model_get_uri (FILE_MODEL(model
), &selected
);
255 g_signal_emit_by_name (G_OBJECT (view
), "current-uri-changed",
261 g_signal_emit_by_name (G_OBJECT (view
), "current-uri-changed",
268 file_view_query_tooltip (GtkWidget
* widget
, gint x
, gint y
, gboolean keyboard
,
271 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
272 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
273 GtkTreeModel
* model
= GTK_TREE_MODEL (priv
->model
);
277 gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(view
),
278 x
, y
, &path
, NULL
, NULL
, NULL
);
281 if (gtk_tree_model_get_iter (model
, &iter
, path
))
283 gchar
* filename
= file_model_get_filename (priv
->model
, &iter
);
284 gtk_tooltip_set_markup (tooltip
, filename
);
286 gtk_tree_path_free (path
);
289 gtk_tree_path_free (path
);
296 file_view_init (AnjutaFileView
*object
)
298 GtkCellRenderer
* renderer_text
;
299 GtkCellRenderer
* renderer_pixbuf
;
300 GtkTreeViewColumn
* column
;
301 GtkTreeSelection
* selection
;
303 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
305 priv
->model
= file_model_new (GTK_TREE_VIEW(object
), NULL
);
307 gtk_tree_view_set_model (GTK_TREE_VIEW (object
), GTK_TREE_MODEL(priv
->model
));
309 renderer_pixbuf
= gtk_cell_renderer_pixbuf_new ();
310 renderer_text
= gtk_cell_renderer_text_new ();
312 column
= gtk_tree_view_column_new ();
313 gtk_tree_view_column_set_title (column
, _("Filename"));
314 gtk_tree_view_column_pack_start (column
, renderer_pixbuf
, FALSE
);
315 gtk_tree_view_column_pack_start (column
, renderer_text
, FALSE
);
316 gtk_tree_view_column_set_attributes (column
, renderer_pixbuf
,
317 "pixbuf", COLUMN_PIXBUF
, NULL
);
318 gtk_tree_view_column_set_attributes (column
, renderer_text
,
319 "text", COLUMN_FILENAME
, NULL
);
320 gtk_tree_view_append_column (GTK_TREE_VIEW (object
), column
);
322 g_signal_connect (G_OBJECT (column
), "clicked",
323 G_CALLBACK (file_view_on_file_clicked
), object
);
326 gtk_tree_view_get_selection (GTK_TREE_VIEW (object
));
327 g_signal_connect (selection
, "changed",
328 G_CALLBACK (file_view_selection_changed
), object
);
330 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (object
), FALSE
);
333 g_object_set (object
, "has-tooltip", TRUE
, NULL
);
338 file_view_get_property (GObject
*object
, guint prop_id
, GValue
*value
,
341 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
347 g_object_get (G_OBJECT(priv
->model
), "base_uri", &uri
, NULL
);
348 g_value_set_string (value
, uri
);
351 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
357 file_view_set_property (GObject
*object
, guint prop_id
, const GValue
*value
,
360 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
365 g_object_set (G_OBJECT (priv
->model
), "base_uri", g_value_get_string (value
),
369 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
375 file_view_finalize (GObject
*object
)
377 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (object
);
378 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
380 G_OBJECT_CLASS (file_view_parent_class
)->finalize (object
);
384 file_view_class_init (AnjutaFileViewClass
*klass
)
386 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
387 GtkTreeViewClass
* parent_class
= GTK_TREE_VIEW_CLASS (klass
);
388 GtkWidgetClass
* widget_class
= GTK_WIDGET_CLASS (klass
);
390 g_type_class_add_private (klass
, sizeof (AnjutaFileViewPrivate
));
392 object_class
->finalize
= file_view_finalize
;
393 object_class
->set_property
= file_view_set_property
;
394 object_class
->get_property
= file_view_get_property
;
396 g_object_class_install_property (object_class
,
398 g_param_spec_string ("base_uri",
400 _("Uri of the top-most path displayed"),
405 g_signal_new ("file-open",
406 ANJUTA_TYPE_FILE_VIEW
,
408 G_STRUCT_OFFSET (AnjutaFileViewClass
, file_open
),
410 g_cclosure_marshal_VOID__STRING
,
416 g_signal_new ("current-uri-changed",
417 ANJUTA_TYPE_FILE_VIEW
,
419 G_STRUCT_OFFSET (AnjutaFileViewClass
, current_uri_changed
),
421 g_cclosure_marshal_VOID__STRING
,
427 g_signal_new ("show-popup-menu",
428 ANJUTA_TYPE_FILE_VIEW
,
430 G_STRUCT_OFFSET (AnjutaFileViewClass
, show_popup_menu
),
432 file_view_cclosure_marshal_VOID__STRING_BOOLEAN_INT_INT
,
441 widget_class
->button_press_event
= file_view_button_press_event
;
445 widget_class
->query_tooltip
= file_view_query_tooltip
;
453 return g_object_new (ANJUTA_TYPE_FILE_VIEW
, NULL
);