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 <gdk/gdkkeysyms.h>
36 #define HAVE_TOOLTIP_API (GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 12))
37 #include <glib/gi18n.h>
38 #include <glib/gprintf.h>
39 #include <glib/gstdio.h>
41 #include <libanjuta/anjuta-utils.h>
42 #include <libanjuta/anjuta-debug.h>
43 #include <libanjuta/anjuta-vcs-status.h>
45 typedef struct _AnjutaFileViewPrivate AnjutaFileViewPrivate
;
47 struct _AnjutaFileViewPrivate
52 GtkTreeRowReference
* current_selection
;
54 GFile
* pending_selected_file
;
57 GtkTargetEntry uri_targets
[] =
67 #define ANJUTA_FILE_VIEW_GET_PRIVATE(o) \
68 (G_TYPE_INSTANCE_GET_PRIVATE((o), ANJUTA_TYPE_FILE_VIEW, AnjutaFileViewPrivate))
70 G_DEFINE_TYPE (AnjutaFileView
, file_view
, GTK_TYPE_TREE_VIEW
);
73 get_status_string(AnjutaVcsStatus status
)
77 case ANJUTA_VCS_STATUS_NONE
:
79 case ANJUTA_VCS_STATUS_MODIFIED
:
81 case ANJUTA_VCS_STATUS_DELETED
:
83 case ANJUTA_VCS_STATUS_ADDED
:
85 case ANJUTA_VCS_STATUS_CONFLICTED
:
86 return _("Conflicted");
87 case ANJUTA_VCS_STATUS_UPTODATE
:
88 return _("Up-to-date");
89 case ANJUTA_VCS_STATUS_LOCKED
:
91 case ANJUTA_VCS_STATUS_MISSING
:
93 case ANJUTA_VCS_STATUS_UNVERSIONED
:
94 return _("Unversioned");
95 case ANJUTA_VCS_STATUS_IGNORED
:
111 file_view_refresh (AnjutaFileView
* view
)
113 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
114 GtkTreePath
* tree_path
;
116 file_model_refresh (priv
->model
);
118 tree_path
= gtk_tree_path_new_first ();
119 gtk_tree_view_expand_row (GTK_TREE_VIEW (view
), tree_path
, FALSE
);
120 gtk_tree_path_free (tree_path
);
125 file_view_rename_edit_finish (GtkCellRendererText
*renderer
,
128 gpointer user_data
) {
129 AnjutaFileView
* view
= (AnjutaFileView
*) user_data
;
130 GFile
* file
= file_view_get_selected (view
);
133 gchar
* newFilename
;
134 gchar
* oldFilename
;
136 gchar
* fileBasename
;
137 GFile
* parent
= NULL
;
138 if(!g_file_has_parent(file
, NULL
)) {/* You try to rename "/" */
139 anjuta_util_dialog_error(NULL
, _("You can't rename \"/\"!"), NULL
);
143 fileBasename
= g_file_get_basename(file
) ;
144 parent
= g_file_get_parent(file
) ;
145 oldPath
= g_file_get_path (parent
) ;
147 /* Creating the new filename */
148 newFilename
= g_strconcat(oldPath
, G_DIR_SEPARATOR_S
, new_text
, NULL
);
149 oldFilename
= g_strconcat(oldPath
, G_DIR_SEPARATOR_S
, fileBasename
, NULL
);
151 if(g_rename(oldFilename
, newFilename
))
152 anjuta_util_dialog_error(NULL
,
153 _("An error has occurred!\n\
154 Maybe your permissions are insufficient or the filename is wrong")
157 g_object_unref(parent
) ;
158 g_free(newFilename
) ;
159 g_free(oldFilename
) ;
161 g_free(fileBasename
) ;
165 file_view_rename_edit_start (GtkCellRenderer
*cell
,
166 GtkCellEditable
*editable
,
170 if (GTK_IS_ENTRY (editable
)) {
171 GtkEntry
*entry
= GTK_ENTRY (editable
);
173 AnjutaFileView
* view
= (AnjutaFileView
*) data
;
174 GFile
* file
= file_view_get_selected (view
);
176 gchar
* fileBasename
;
177 fileBasename
= g_file_get_basename(file
) ;
178 gtk_entry_set_text(entry
, fileBasename
);
179 g_free(fileBasename
) ;
183 void file_view_rename (AnjutaFileView
* view
)
186 GtkTreeSelection
* selection
= gtk_tree_view_get_selection(
187 GTK_TREE_VIEW(view
));
189 GtkTreeModel
* model
= NULL
;
190 gtk_tree_selection_get_selected(selection
, &model
, &iter
);
192 GtkTreePath
* path
= gtk_tree_model_get_path(model
, &iter
);
193 GtkTreeViewColumn
* column
= gtk_tree_view_get_column(GTK_TREE_VIEW(view
),
196 gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(view
)
199 gtk_tree_path_free(path
) ;
202 gboolean
file_view_can_rename (AnjutaFileView
* view
)
205 * Maybe it can be use for windows (look if file is already open)
211 file_view_get_selected (AnjutaFileView
* view
)
213 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
214 GtkTreeSelection
* selection
=
215 gtk_tree_view_get_selection (GTK_TREE_VIEW (view
));
216 GtkTreeIter selected
;
217 if (gtk_tree_selection_get_selected (selection
, NULL
, &selected
))
220 GtkTreeIter real_iter
;
221 GtkTreeModel
* sort_model
= gtk_tree_view_get_model (GTK_TREE_VIEW(view
));
223 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model
),
224 &real_iter
, &selected
);
226 file
= file_model_get_file (priv
->model
, &real_iter
);
234 file_view_select_iter (AnjutaFileView
* view
, GtkTreeIter iter
)
236 GtkTreeModelSort
* model_sort
;
237 GtkTreeIter sort_iter
;
238 GtkTreeSelection
* selection
;
241 model_sort
= GTK_TREE_MODEL_SORT (gtk_tree_view_get_model (GTK_TREE_VIEW (view
)));
243 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (view
));
244 gtk_tree_model_sort_convert_child_iter_to_iter (model_sort
, &sort_iter
, &iter
);
245 path
= gtk_tree_model_get_path (GTK_TREE_MODEL (model_sort
), &sort_iter
);
247 gtk_tree_selection_select_iter (selection
, &sort_iter
);
248 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view
), path
, NULL
, TRUE
, 0.5, 0.0);
252 file_view_select_from_iter (AnjutaFileView
* view
, GtkTreeIter iter
)
254 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
256 GtkTreeModelSort
* model_sort
;
258 GtkTreeIter sort_iter
;
261 model_sort
= GTK_TREE_MODEL_SORT (gtk_tree_view_get_model (GTK_TREE_VIEW (view
)));
265 gboolean is_dummy
, is_dir
;
267 gtk_tree_model_get (GTK_TREE_MODEL (priv
->model
), &iter
,
268 COLUMN_FILE
, &file
, COLUMN_DUMMY
, &is_dummy
,
269 COLUMN_IS_DIR
, &is_dir
, -1);
274 if (g_file_equal (priv
->pending_selected_file
, file
))
276 file_view_select_iter (view
, iter
);
280 else if (g_file_has_prefix (priv
->pending_selected_file
, file
))
284 GtkTreePath
*path
= NULL
;
286 gtk_tree_model_sort_convert_child_iter_to_iter (model_sort
, &sort_iter
, &iter
);
287 path
= gtk_tree_model_get_path (GTK_TREE_MODEL (model_sort
), &sort_iter
);
289 if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view
), path
))
291 GtkTreeIter parent
= iter
;
292 valid
= gtk_tree_model_iter_children (GTK_TREE_MODEL (priv
->model
), &iter
, &parent
);
293 gtk_tree_path_free (path
);
297 gtk_tree_view_expand_row (GTK_TREE_VIEW (view
), path
, FALSE
);
298 gtk_tree_path_free (path
);
304 file_view_select_iter (view
, iter
);
309 valid
= gtk_tree_model_iter_next (GTK_TREE_MODEL (priv
->model
), &iter
);
311 g_clear_object (&file
);
316 g_object_unref (file
);
320 file_view_directory_expanded (FileModel
* model
, GtkTreeIter
* iter
, GtkTreePath
* path
,
323 AnjutaFileView
* view
= user_data
;
324 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
326 if (priv
->pending_selected_file
)
330 gtk_tree_model_get (GTK_TREE_MODEL (priv
->model
), iter
,
331 COLUMN_FILE
, &dir
, -1);
333 if (g_file_has_prefix (priv
->pending_selected_file
, dir
))
334 file_view_select_from_iter (view
, *iter
);
336 g_object_unref (dir
);
341 file_view_set_selected (AnjutaFileView
* view
, GFile
*selected
)
343 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
348 g_clear_object (&priv
->pending_selected_file
);
349 priv
->pending_selected_file
= g_object_ref (selected
);
351 valid
= gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv
->model
), &iter
);
353 file_view_select_from_iter (view
, iter
);
357 file_view_drag_data_get (GtkWidget
* widget
,
358 GdkDragContext
*drag_context
,
359 GtkSelectionData
*data
,
363 AnjutaFileView
* view
= ANJUTA_FILE_VIEW(widget
);
364 GFile
* selected
= file_view_get_selected (view
);
369 uris
[0] = g_file_get_uri (selected
);
371 gtk_selection_data_set_uris (data
, uris
);
377 file_view_row_activated (GtkTreeView
* widget
, GtkTreePath
* sort_path
,
378 GtkTreeViewColumn
* column
)
380 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
381 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
382 GtkTreeIter selected
;
383 GtkTreePath
* path
= NULL
;
387 GtkTreeIter select_iter
;
388 GtkTreeModel
* sort_model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
389 gtk_tree_model_get_iter (sort_model
, &selected
, sort_path
);
390 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model
),
391 &select_iter
, &selected
);
392 gtk_tree_model_get (GTK_TREE_MODEL(priv
->model
), &select_iter
,
393 COLUMN_IS_DIR
, &is_dir
,
395 file
= file_model_get_file (priv
->model
, &select_iter
);
397 path
= gtk_tree_model_get_path(sort_model
, &selected
);
401 if (!gtk_tree_view_row_expanded (GTK_TREE_VIEW (view
),
404 gtk_tree_view_expand_row (GTK_TREE_VIEW (view
),
410 gtk_tree_view_collapse_row (GTK_TREE_VIEW (view
),
416 g_signal_emit_by_name (G_OBJECT (view
),
421 g_object_unref (file
);
423 gtk_tree_path_free(path
);
427 file_view_key_press_event (GtkWidget
* widget
, GdkEventKey
* event
)
429 if (event
->keyval
== GDK_KEY_Return
|| event
->keyval
== GDK_KEY_KP_Enter
)
431 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
432 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
433 GtkTreeIter selected
;
435 GtkTreeSelection
* selection
=
436 gtk_tree_view_get_selection (GTK_TREE_VIEW (view
));
438 if (gtk_tree_selection_get_selected (selection
, NULL
, &selected
))
441 GtkTreeIter select_iter
;
442 GtkTreeModel
* sort_model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
443 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model
),
444 &select_iter
, &selected
);
445 file
= file_model_get_file (priv
->model
, &select_iter
);
448 g_signal_emit_by_name (G_OBJECT (view
),
451 g_object_unref (file
);
456 GTK_WIDGET_CLASS (file_view_parent_class
)->key_press_event (widget
,
461 file_view_do_popup_menu (GtkWidget
* widget
, GdkEventButton
* event
)
463 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
464 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
465 GtkTreeSelection
* selection
=
466 gtk_tree_view_get_selection (GTK_TREE_VIEW (widget
));
468 gboolean is_dir
= FALSE
;
469 GtkTreeIter selected
;
470 gint button
, event_time
;
472 if (gtk_tree_selection_get_selected (selection
, NULL
, &selected
))
474 GtkTreeIter select_iter
;
475 GtkTreeModel
* sort_model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
476 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sort_model
),
477 &select_iter
, &selected
);
478 gtk_tree_model_get (GTK_TREE_MODEL(priv
->model
), &select_iter
,
479 COLUMN_IS_DIR
, &is_dir
,
481 file
= file_model_get_file (priv
->model
, &select_iter
);
486 button
= event
->button
;
487 event_time
= event
->time
;
492 event_time
= gtk_get_current_event_time ();
495 g_signal_emit_by_name (G_OBJECT(widget
), "show-popup-menu",
496 file
, is_dir
, button
, event_time
);
498 g_object_unref (file
);
502 file_view_button_press_event (GtkWidget
*widget
, GdkEventButton
*event
)
505 GTK_WIDGET_CLASS (file_view_parent_class
)->button_press_event (widget
,
507 /* Ignore double-clicks and triple-clicks */
508 if (event
->button
== 3 && event
->type
== GDK_BUTTON_PRESS
)
512 /* Select file under cursor if not selected */
513 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget
),
514 event
->x
,event
->y
, &path
, NULL
, NULL
, NULL
))
516 GtkTreeSelection
*selection
;
518 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW (widget
));
519 if (!gtk_tree_selection_path_is_selected(selection
, path
))
521 gtk_tree_selection_unselect_all(selection
);
522 gtk_tree_selection_select_path(selection
, path
);
523 gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget
),
526 gtk_tree_path_free (path
);
528 file_view_do_popup_menu (widget
, event
);
539 file_view_popup_menu (GtkWidget
* widget
)
541 file_view_do_popup_menu(widget
, NULL
);
546 file_view_show_extended_data (AnjutaFileView
* view
, GtkTreeIter
* iter
)
548 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
550 GtkTreeModel
* file_model
= GTK_TREE_MODEL (priv
->model
);
551 gboolean is_dummy
, is_dir
;
553 GFileInfo
* file_info
;
557 AnjutaVcsStatus status
;
559 gtk_tree_model_get (file_model
, iter
, COLUMN_DUMMY
, &is_dummy
,
560 COLUMN_IS_DIR
, &is_dir
, -1);
561 if (is_dummy
|| is_dir
)
565 gtk_tree_model_get (file_model
, iter
, COLUMN_FILE
, &file
,
566 COLUMN_STATUS
, &status
, -1);
568 file_info
= g_file_query_info (file
,
569 "standard::*,time::changed",
570 G_FILE_QUERY_INFO_NONE
,
572 g_object_unref (file
);
576 time
= g_file_info_get_attribute_uint64(file_info
, "time::changed");
577 strftime(time_str
, 127, "%x %X", localtime(&time
));
578 if (get_status_string(status
))
580 display
= g_markup_printf_escaped("%s\n"
581 "<small><tt>%s</tt></small>\n"
583 g_file_info_get_display_name(file_info
),
585 get_status_string(status
));
589 display
= g_markup_printf_escaped("%s\n"
590 "<small><tt>%s</tt></small>",
591 g_file_info_get_display_name(file_info
),
594 gtk_tree_store_set (GTK_TREE_STORE(file_model
), iter
,
595 COLUMN_DISPLAY
, display
,
598 g_object_unref (file_info
);
603 file_view_selection_changed (GtkTreeSelection
* selection
, AnjutaFileView
* view
)
605 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
606 GtkTreeModel
* file_model
= GTK_TREE_MODEL(priv
->model
);
607 GtkTreeIter selected
;
608 GtkTreeModel
* model
= gtk_tree_view_get_model (GTK_TREE_VIEW(view
));
610 if (priv
->current_selection
)
613 GtkTreePath
* path
= gtk_tree_row_reference_get_path (priv
->current_selection
);
614 if (path
&& gtk_tree_model_get_iter (file_model
, &iter
, path
))
617 gtk_tree_model_get (file_model
, &iter
, COLUMN_FILENAME
, &filename
, -1);
618 gtk_tree_store_set (GTK_TREE_STORE (file_model
), &iter
,
619 COLUMN_DISPLAY
, filename
, -1);
621 gtk_tree_path_free(path
);
623 gtk_tree_row_reference_free(priv
->current_selection
);
624 priv
->current_selection
= NULL
;
627 if (gtk_tree_selection_get_selected (selection
, &model
, &selected
))
629 GtkTreeIter real_selection
;
632 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model
),
633 &real_selection
, &selected
);
635 path
= gtk_tree_model_get_path(file_model
, &real_selection
);
636 priv
->current_selection
= gtk_tree_row_reference_new (file_model
, path
);
637 gtk_tree_path_free(path
);
639 file_view_show_extended_data (view
, &real_selection
);
641 file
= file_model_get_file(FILE_MODEL(file_model
), &real_selection
);
642 g_signal_emit_by_name (G_OBJECT (view
), "current-file-changed",
644 g_object_unref (file
);
648 g_signal_emit_by_name (G_OBJECT (view
), "current-file-changed",
652 /* The pending selection is now either done or if the user changed the
653 * selection before it was finished we cancel it. */
654 g_clear_object (&priv
->pending_selected_file
);
656 DEBUG_PRINT ("%s", "selection_changed");
660 file_view_query_tooltip (GtkWidget
* widget
, gint x
, gint y
, gboolean keyboard
,
663 AnjutaFileView
* view
= ANJUTA_FILE_VIEW (widget
);
664 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
665 GtkTreeModel
* model_sort
;
666 GtkTreeModel
* file_model
= GTK_TREE_MODEL (priv
->model
);
669 GtkTreeIter real_iter
;
671 gboolean result
= TRUE
;
672 GdkRectangle visible_rect
, column_rect
;
673 GdkScreen
*screen
= gdk_screen_get_default ();
674 PangoContext
*context
;
678 if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (view
),
685 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (model_sort
),
688 filename
= file_model_get_filename (FILE_MODEL (file_model
), &real_iter
);
690 context
= gdk_pango_context_get_for_screen (screen
);
691 layout
= pango_layout_new (context
);
693 pango_layout_set_text (layout
, filename
, -1);
694 pango_layout_get_pixel_size (layout
, &width
, &height
);
696 gtk_tree_view_get_visible_rect (GTK_TREE_VIEW (view
), &visible_rect
);
697 gtk_tree_view_get_cell_area (GTK_TREE_VIEW (view
), path
,
698 gtk_tree_view_get_column (GTK_TREE_VIEW (view
), 0), &column_rect
);
700 if (column_rect
.x
+ width
> visible_rect
.x
+ visible_rect
.width
||
701 column_rect
.x
< visible_rect
.x
)
703 gtk_tooltip_set_text (tooltip
, filename
);
704 gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (view
),
713 gtk_tree_path_free (path
);
714 g_object_unref (layout
);
715 g_object_unref (context
);
721 file_view_sort_model(GtkTreeModel
* model
,
727 gchar
*filename1
= NULL
, *filename2
= NULL
;
728 gboolean is_dir1
, is_dir2
;
731 gtk_tree_model_get (model
, iter1
,
732 COLUMN_FILENAME
, &filename1
,
734 COLUMN_IS_DIR
, &is_dir1
, -1);
735 gtk_tree_model_get (model
, iter2
,
736 COLUMN_FILENAME
, &filename2
,
738 COLUMN_IS_DIR
, &is_dir2
, -1);
742 retval
= sort2
- sort1
;
744 else if (is_dir1
!= is_dir2
)
746 retval
= is_dir1
? -1 : 1;
748 else if (filename1
&& filename2
)
750 retval
= strcasecmp(filename1
, filename2
);
758 #define EMBLEM_ADDED "vcs-added.png"
759 #define EMBLEM_CONFLICT "vcs-conflict.png"
760 #define EMBLEM_DELETED "vcs-deleted.png"
761 #define EMBLEM_IGNORED "vcs-ignored.png"
762 #define EMBLEM_LOCKED "vcs-locked.png"
763 #define EMBLEM_UNVERSIONED "vcs-unversioned.png"
764 #define EMBLEM_UPTODATE "vcs-updated.png"
765 #define EMBLEM_MODIFIED "vcs-modified.png"
767 #define COMPOSITE_ALPHA 225
770 get_vcs_emblem (AnjutaVcsStatus status
)
775 case ANJUTA_VCS_STATUS_ADDED
:
776 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_ADDED
, NULL
);
778 case ANJUTA_VCS_STATUS_MODIFIED
:
779 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_MODIFIED
, NULL
);
781 case ANJUTA_VCS_STATUS_DELETED
:
782 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_DELETED
, NULL
);
784 case ANJUTA_VCS_STATUS_CONFLICTED
:
785 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_CONFLICT
, NULL
);
787 case ANJUTA_VCS_STATUS_LOCKED
:
788 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_LOCKED
, NULL
);
790 case ANJUTA_VCS_STATUS_UNVERSIONED
:
791 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_UNVERSIONED
, NULL
);
793 case ANJUTA_VCS_STATUS_UPTODATE
:
794 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_UPTODATE
, NULL
);
796 case ANJUTA_VCS_STATUS_IGNORED
:
797 emblem
= gdk_pixbuf_new_from_file (PACKAGE_PIXMAPS_DIR
"/"EMBLEM_IGNORED
, NULL
);
806 file_view_render_pixbuf_with_emblem (GtkTreeViewColumn
* tree_column
,
807 GtkCellRenderer
* cell
,
808 GtkTreeModel
* tree_model
,
812 GdkPixbuf
* file_icon
= NULL
;
813 GdkPixbuf
* emblem
= NULL
;
815 AnjutaVcsStatus status
;
817 gtk_tree_model_get (tree_model
, iter
,
818 COLUMN_STATUS
, &status
,
819 COLUMN_PIXBUF
, &file_icon
, -1);
823 emblem
= get_vcs_emblem (status
);
828 new_icon
= gdk_pixbuf_copy (file_icon
);
829 gdk_pixbuf_composite (emblem
,
832 gdk_pixbuf_get_width (file_icon
),
833 gdk_pixbuf_get_height (file_icon
),
839 g_object_set (cell
, "pixbuf", new_icon
, NULL
);
841 g_object_unref (new_icon
);
842 g_object_unref (emblem
);
846 g_object_set (cell
, "pixbuf", file_icon
, NULL
);
848 g_object_unref (file_icon
);
853 file_view_init (AnjutaFileView
*object
)
855 GtkCellRenderer
* renderer_pixbuf
;
856 GtkCellRenderer
* renderer_display
;
857 GtkTreeViewColumn
* column
;
858 GtkTreeSelection
* selection
;
859 GtkTreeModel
* sort_model
;
861 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
863 priv
->current_selection
= NULL
;
865 priv
->model
= file_model_new (GTK_TREE_VIEW(object
), NULL
);
866 g_signal_connect_object (priv
->model
, "directory-expanded",
867 G_CALLBACK (file_view_directory_expanded
), object
, 0);
869 sort_model
= gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(priv
->model
));
871 gtk_tree_view_set_model (GTK_TREE_VIEW(object
), sort_model
);
872 /* set_model takes a reference so we can release the reference we got when
873 * the sort_model was created. */
874 g_object_unref (sort_model
);
875 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(sort_model
),
876 file_view_sort_model
,
880 renderer_pixbuf
= gtk_cell_renderer_pixbuf_new ();
881 renderer_display
= gtk_cell_renderer_text_new ();
883 g_object_set(renderer_display
,
884 "mode", GTK_CELL_RENDERER_MODE_EDITABLE
,
885 "editable", TRUE
, NULL
);
886 g_object_connect(renderer_display
, "signal::edited",
887 file_view_rename_edit_finish
, object
, NULL
);
888 g_object_connect(renderer_display
, "signal::editing-started",
889 file_view_rename_edit_start
, object
, NULL
);
891 column
= gtk_tree_view_column_new ();
892 gtk_tree_view_column_set_title (column
, _("Filename"));
893 gtk_tree_view_column_pack_start (column
, renderer_pixbuf
, FALSE
);
894 gtk_tree_view_column_pack_start (column
, renderer_display
, FALSE
);
895 gtk_tree_view_column_set_cell_data_func(column
,
897 file_view_render_pixbuf_with_emblem
,
899 gtk_tree_view_column_set_attributes (column
, renderer_display
,
900 "markup", COLUMN_DISPLAY
,
902 gtk_tree_view_append_column (GTK_TREE_VIEW (object
), column
);
905 gtk_tree_view_get_selection (GTK_TREE_VIEW (object
));
906 g_signal_connect (selection
, "changed",
907 G_CALLBACK (file_view_selection_changed
), object
);
910 gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW(object
),
916 /* Typeahead search */
917 gtk_tree_view_set_search_column (GTK_TREE_VIEW (object
), COLUMN_FILENAME
);
921 file_view_get_property (GObject
*object
, guint prop_id
, GValue
*value
,
924 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
929 g_object_get_property (G_OBJECT(priv
->model
), "base-path", value
);
932 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
938 file_view_set_property (GObject
*object
, guint prop_id
, const GValue
*value
,
941 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
946 g_object_set_property (G_OBJECT (priv
->model
), "base-path", value
);
949 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
955 file_view_finalize (GObject
*object
)
957 AnjutaFileViewPrivate
*priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (object
);
959 g_object_unref (priv
->model
);
961 G_OBJECT_CLASS (file_view_parent_class
)->finalize (object
);
965 file_view_class_init (AnjutaFileViewClass
*klass
)
967 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
968 GtkWidgetClass
* widget_class
= GTK_WIDGET_CLASS (klass
);
969 GtkTreeViewClass
* tree_class
= GTK_TREE_VIEW_CLASS(klass
);
971 g_type_class_add_private (klass
, sizeof (AnjutaFileViewPrivate
));
973 object_class
->finalize
= file_view_finalize
;
974 object_class
->set_property
= file_view_set_property
;
975 object_class
->get_property
= file_view_get_property
;
977 g_object_class_install_property (object_class
,
979 g_param_spec_object ("base-path",
981 _("GFile representing the top-most path displayed"),
983 G_PARAM_READABLE
| G_PARAM_WRITABLE
| G_PARAM_CONSTRUCT
));
984 g_signal_new ("file-open",
985 ANJUTA_TYPE_FILE_VIEW
,
987 G_STRUCT_OFFSET (AnjutaFileViewClass
, file_open
),
989 g_cclosure_marshal_VOID__OBJECT
,
995 g_signal_new ("current-file-changed",
996 ANJUTA_TYPE_FILE_VIEW
,
998 G_STRUCT_OFFSET (AnjutaFileViewClass
, current_uri_changed
),
1000 g_cclosure_marshal_VOID__OBJECT
,
1006 g_signal_new ("show-popup-menu",
1007 ANJUTA_TYPE_FILE_VIEW
,
1009 G_STRUCT_OFFSET (AnjutaFileViewClass
, show_popup_menu
),
1011 file_view_cclosure_marshal_VOID__OBJECT_BOOLEAN_INT_INT
,
1020 tree_class
->row_activated
= file_view_row_activated
;
1021 widget_class
->key_press_event
= file_view_key_press_event
;
1022 widget_class
->popup_menu
= file_view_popup_menu
;
1023 widget_class
->button_press_event
= file_view_button_press_event
;
1026 widget_class
->query_tooltip
= file_view_query_tooltip
;
1029 widget_class
->drag_data_get
= file_view_drag_data_get
;
1033 file_view_refresh_vcs (AnjutaFileView
* view
)
1035 AnjutaFileViewPrivate
* priv
= ANJUTA_FILE_VIEW_GET_PRIVATE (view
);
1036 file_model_update_vcs_status(priv
->model
);
1041 file_view_new (void)
1043 return g_object_new (ANJUTA_TYPE_FILE_VIEW
,
1044 "headers-visible", FALSE
,
1045 "has-tooltip", TRUE
,
1046 "enable-search", TRUE
,