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
);
150 gtk_tree_path_free (tree_path
);
153 priv
->refresh_idle_id
= g_idle_add (file_view_expand_row_idle
, view
);
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
);
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
;
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
,
191 COLUMN_IS_DIR
, &is_dir
,
200 switch (event
->button
)
202 case 1: /* Left mouse button */
204 if (event
->type
== GDK_2BUTTON_PRESS
)
208 if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (view
),
211 gtk_tree_view_expand_row (GTK_TREE_VIEW (view
),
217 gtk_tree_view_collapse_row (GTK_TREE_VIEW (view
),
223 g_signal_emit_by_name (G_OBJECT (view
),
230 case 3: /* Right mouse button */
232 g_signal_emit_by_name (G_OBJECT (view
),
241 gtk_tree_path_free (path
);
244 GTK_WIDGET_CLASS (file_view_parent_class
)->button_press_event (widget
,
249 file_view_selection_changed (GtkTreeSelection
* selection
, AnjutaFileView
* view
)
251 GtkTreeIter selected
;
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",
262 g_signal_emit_by_name (G_OBJECT (view
), "current-uri-changed",
269 file_view_query_tooltip (GtkWidget
* widget
, gint x
, gint y
, gboolean keyboard
,
272 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
273 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
274 GtkTreeModel
* model
= GTK_TREE_MODEL (priv
->model
);
278 gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW(view
),
279 x
, y
, &path
, NULL
, NULL
, NULL
);
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
);
287 gtk_tree_path_free (path
);
290 gtk_tree_path_free (path
);
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
);
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
);
334 g_object_set (object
, "has-tooltip", TRUE
, NULL
);
339 file_view_get_property (GObject
*object
, guint prop_id
, GValue
*value
,
342 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
348 g_object_get (G_OBJECT(priv
->model
), "base_uri", &uri
, NULL
);
349 g_value_set_string (value
, uri
);
352 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
358 file_view_set_property (GObject
*object
, guint prop_id
, const GValue
*value
,
361 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
366 g_object_set (G_OBJECT (priv
->model
), "base_uri", g_value_get_string (value
),
370 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
376 file_view_finalize (GObject
*object
)
378 G_OBJECT_CLASS (file_view_parent_class
)->finalize (object
);
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
,
395 g_param_spec_string ("base_uri",
397 _("Uri of the top-most path displayed"),
402 g_signal_new ("file-open",
403 ANJUTA_TYPE_FILE_VIEW
,
405 G_STRUCT_OFFSET (AnjutaFileViewClass
, file_open
),
407 g_cclosure_marshal_VOID__STRING
,
413 g_signal_new ("current-uri-changed",
414 ANJUTA_TYPE_FILE_VIEW
,
416 G_STRUCT_OFFSET (AnjutaFileViewClass
, current_uri_changed
),
418 g_cclosure_marshal_VOID__STRING
,
424 g_signal_new ("show-popup-menu",
425 ANJUTA_TYPE_FILE_VIEW
,
427 G_STRUCT_OFFSET (AnjutaFileViewClass
, show_popup_menu
),
429 file_view_cclosure_marshal_VOID__STRING_BOOLEAN_INT_INT
,
438 widget_class
->button_press_event
= file_view_button_press_event
;
442 widget_class
->query_tooltip
= file_view_query_tooltip
;
450 return g_object_new (ANJUTA_TYPE_FILE_VIEW
, NULL
);