Commit eed94367 authored by Alexander Larsson's avatar Alexander Larsson Committed by Alexander Larsson

Add hover expansion

2005-06-15  Alexander Larsson  <alexl@redhat.com>

	* libnautilus-private/nautilus-tree-view-drag-dest.c:
	Add hover expansion

	* src/file-manager/fm-directory-view.[ch]:
	Add support for adding/removing subdirectories.

	* src/file-manager/fm-list-model.[ch]:
	Add support for subdirectories making this a tree view.

	* src/file-manager/fm-list-view.c:
	Turn listview into a treeview.

	Patch from Jürg Billeter <j@bitron.ch>
parent 2b62737f
2005-06-15 Alexander Larsson <alexl@redhat.com>
* libnautilus-private/nautilus-tree-view-drag-dest.c:
Add hover expansion
* src/file-manager/fm-directory-view.[ch]:
Add support for adding/removing subdirectories.
* src/file-manager/fm-list-model.[ch]:
Add support for subdirectories making this a tree view.
* src/file-manager/fm-list-view.c:
Turn listview into a treeview.
Patch from Jürg Billeter <j@bitron.ch>
2005-06-15 Alexander Larsson <alexl@redhat.com>
* src/nautilus-spatial-window.c:
......
......@@ -54,6 +54,7 @@ struct _NautilusTreeViewDragDestDetails {
guint highlight_id;
guint scroll_id;
guint expand_id;
};
enum {
......@@ -133,6 +134,33 @@ remove_scroll_timeout (NautilusTreeViewDragDest *dest)
}
}
static int
expand_timeout (gpointer data)
{
GtkTreeView *tree_view;
GtkTreePath *drop_path;
tree_view = GTK_TREE_VIEW (data);
gtk_tree_view_get_drag_dest_row (tree_view, &drop_path, NULL);
if (drop_path) {
gtk_tree_view_expand_row (tree_view, drop_path, FALSE);
gtk_tree_path_free (drop_path);
}
return FALSE;
}
static void
remove_expand_timeout (NautilusTreeViewDragDest *dest)
{
if (dest->details->expand_id) {
g_source_remove (dest->details->expand_id);
dest->details->expand_id = 0;
}
}
static gboolean
highlight_expose (GtkWidget *widget,
GdkEventExpose *event,
......@@ -369,7 +397,9 @@ drag_motion_callback (GtkWidget *widget,
{
NautilusTreeViewDragDest *dest;
GtkTreePath *path;
GtkTreePath *drop_path;
GtkTreePath *drop_path, *old_drop_path;
GtkTreeModel *model;
GtkTreeIter drop_iter;
GtkTreeViewDropPosition pos;
guint action;
......@@ -386,10 +416,27 @@ drag_motion_callback (GtkWidget *widget,
action = get_drop_action (dest, context, drop_path);
gtk_tree_view_get_drag_dest_row (GTK_TREE_VIEW (widget), &old_drop_path,
NULL);
if (action) {
set_drag_dest_row (dest, drop_path);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
if (drop_path == NULL || (old_drop_path != NULL &&
gtk_tree_path_compare (old_drop_path, drop_path) != 0)) {
remove_expand_timeout (dest);
}
if (dest->details->expand_id == 0 && drop_path != NULL) {
gtk_tree_model_get_iter (model, &drop_iter, drop_path);
if (gtk_tree_model_iter_has_child (model, &drop_iter)) {
dest->details->expand_id = g_timeout_add (500,
expand_timeout,
dest->details->tree_view);
}
}
} else {
clear_drag_dest_row (dest);
remove_expand_timeout (dest);
}
if (path) {
......@@ -400,6 +447,10 @@ drag_motion_callback (GtkWidget *widget,
gtk_tree_path_free (drop_path);
}
if (old_drop_path) {
gtk_tree_path_free (old_drop_path);
}
if (dest->details->scroll_id == 0) {
dest->details->scroll_id =
g_timeout_add (150,
......@@ -427,6 +478,7 @@ drag_leave_callback (GtkWidget *widget,
free_drag_data (dest);
remove_scroll_timeout (dest);
remove_expand_timeout (dest);
}
static void
......@@ -612,6 +664,7 @@ drag_drop_callback (GtkWidget *widget,
get_drag_data (dest, context, time);
remove_scroll_timeout (dest);
remove_expand_timeout (dest);
clear_drag_dest_row (dest);
return TRUE;
......@@ -626,6 +679,7 @@ tree_view_weak_notify (gpointer user_data,
dest = NAUTILUS_TREE_VIEW_DRAG_DEST (user_data);
remove_scroll_timeout (dest);
remove_expand_timeout (dest);
dest->details->tree_view = NULL;
}
......@@ -644,6 +698,7 @@ nautilus_tree_view_drag_dest_dispose (GObject *object)
}
remove_scroll_timeout (dest);
remove_expand_timeout (dest);
EEL_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}
......
......@@ -249,6 +249,8 @@ struct FMDirectoryViewDetails
NautilusFile *file_monitored_for_open_with;
GtkActionGroup *open_with_action_group;
guint open_with_merge_id;
GList *subdirectory_list;
};
typedef enum {
......@@ -2080,6 +2082,7 @@ done_loading (FMDirectoryView *view)
view->details->loading = FALSE;
}
typedef struct {
GHashTable *debuting_uris;
GList *added_files;
......@@ -2276,7 +2279,20 @@ copy_move_done_callback (GHashTable *debuting_uris, gpointer data)
static gboolean
real_file_still_belongs (FMDirectoryView *view, NautilusFile *file)
{
return nautilus_directory_contains_file (view->details->model, file);
GList *node;
if (nautilus_directory_contains_file (view->details->model, file)) {
return TRUE;
}
for (node = view->details->subdirectory_list; node != NULL; node = node->next) {
if (nautilus_directory_contains_file (NAUTILUS_DIRECTORY (node->data),
file)) {
return TRUE;
}
}
return FALSE;
}
static gboolean
......@@ -2739,6 +2755,88 @@ fm_directory_view_queue_file_change (FMDirectoryView *view, NautilusFile *file)
queue_pending_files (view, &singleton_list, &view->details->new_changed_files);
}
void
fm_directory_view_add_subdirectory (FMDirectoryView *view,
NautilusDirectory*directory)
{
NautilusFileAttributes attributes;
if (g_list_find (view->details->subdirectory_list, directory) == NULL) {
nautilus_directory_ref (directory);
attributes = nautilus_icon_factory_get_required_file_attributes ();
attributes |= NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
NAUTILUS_FILE_ATTRIBUTE_METADATA |
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME |
NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
nautilus_directory_file_monitor_add (directory,
&view->details->model,
view->details->show_hidden_files,
view->details->show_backup_files,
attributes,
files_added_callback, view);
g_signal_connect
(directory, "files_added",
G_CALLBACK (files_added_callback), view);
g_signal_connect
(directory, "files_changed",
G_CALLBACK (files_changed_callback), view);
view->details->subdirectory_list = g_list_prepend (
view->details->subdirectory_list, directory);
}
}
static void
real_remove_subdirectory (FMDirectoryView *view,
NautilusDirectory*directory)
{
view->details->subdirectory_list = g_list_remove (
view->details->subdirectory_list, directory);
g_signal_handlers_disconnect_by_func (directory,
G_CALLBACK (files_added_callback),
view);
g_signal_handlers_disconnect_by_func (directory,
G_CALLBACK (files_changed_callback),
view);
nautilus_directory_file_monitor_remove (directory, &view->details->model);
nautilus_directory_unref (directory);
}
void
fm_directory_view_remove_subdirectory (FMDirectoryView *view,
NautilusDirectory*directory)
{
GList *node;
NautilusFile *parent, *file1, *file2;
NautilusDirectory *subdir;
parent = nautilus_directory_get_corresponding_file (directory);
for (node = view->details->subdirectory_list; node != NULL;) {
file1 = nautilus_directory_get_corresponding_file (node->data);
while (file1 != parent && file1 != NULL) {
file2 = nautilus_file_get_parent (file1);
nautilus_file_unref (file1);
file1 = file2;
}
subdir = NAUTILUS_DIRECTORY (node->data);
node = node->next;
if (file1 == parent) {
real_remove_subdirectory (view, subdir);
}
if (file1 != NULL) {
nautilus_file_unref (file1);
}
}
}
/**
* fm_directory_view_clear:
*
......@@ -7369,6 +7467,11 @@ load_directory (FMDirectoryView *view,
* of old selection.
*/
schedule_update_menus (view);
while (view->details->subdirectory_list != NULL) {
real_remove_subdirectory (view,
view->details->subdirectory_list->data);
}
disconnect_model_handlers (view);
......
......@@ -392,5 +392,9 @@ void fm_directory_view_handle_uri_list_drop (FMDirect
int y);
void fm_directory_view_freeze_updates (FMDirectoryView *view);
void fm_directory_view_unfreeze_updates (FMDirectoryView *view);
void fm_directory_view_add_subdirectory (FMDirectoryView *view,
NautilusDirectory*directory);
void fm_directory_view_remove_subdirectory (FMDirectoryView *view,
NautilusDirectory*directory);
#endif /* FM_DIRECTORY_VIEW_H */
This diff is collapsed.
......@@ -26,6 +26,7 @@
#include <gtk/gtktreeview.h>
#include <gdk/gdkdnd.h>
#include <libnautilus-private/nautilus-file.h>
#include <libnautilus-private/nautilus-directory.h>
#include <libnautilus-private/nautilus-icon-factory.h>
#include <libnautilus-extension/nautilus-column.h>
......@@ -70,7 +71,7 @@ typedef struct {
} FMListModelClass;
GType fm_list_model_get_type (void);
void fm_list_model_add_file (FMListModel *model,
gboolean fm_list_model_add_file (FMListModel *model,
NautilusFile *file);
void fm_list_model_file_changed (FMListModel *model,
NautilusFile *file);
......@@ -115,4 +116,8 @@ int fm_list_model_add_column (FMListModel *model,
NautilusColumn *column);
int fm_list_model_get_column_number (FMListModel *model,
const char *column_name);
void fm_list_model_subdirectory_done_loading (FMListModel *model,
NautilusDirectory *directory);
#endif /* FM_LIST_MODEL_H */
......@@ -430,8 +430,10 @@ motion_notify_callback (GtkWidget *widget,
gtk_drag_set_icon_default (context);
}
}
return TRUE;
}
return TRUE;
return FALSE;
}
static void
......@@ -458,6 +460,8 @@ button_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer callba
static gint64 last_click_time = 0;
static int click_count = 0;
int double_click_time;
int expander_size, horizontal_separator;
NautilusFile *file;
view = FM_LIST_VIEW (callback_data);
tree_view = GTK_TREE_VIEW (widget);
......@@ -543,12 +547,25 @@ button_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer callba
call_parent = FALSE;
}
file = fm_list_model_file_for_path (view->details->model, path);
if (file == NULL) {
/* this is the dummy loading node */
call_parent = FALSE;
} else {
nautilus_file_unref (file);
}
if ((event->button == 1 || event->button == 2) &&
((event->state & GDK_CONTROL_MASK) != 0 ||
(event->state & GDK_SHIFT_MASK) == 0)) {
view->details->row_selected_on_button_down = gtk_tree_selection_path_is_selected (selection, path);
if (view->details->row_selected_on_button_down) {
call_parent = FALSE;
gtk_widget_style_get (widget,
"expander-size", &expander_size,
"horizontal-separator", &horizontal_separator,
NULL);
call_parent = (event->x <= horizontal_separator / 2 +
gtk_tree_path_get_depth (path) * expander_size);
} else if ((event->state & GDK_CONTROL_MASK) != 0) {
call_parent = FALSE;
gtk_tree_selection_select_path (selection, path);
......@@ -611,7 +628,6 @@ button_release_callback (GtkWidget *widget,
stop_drag_check (view);
if (!view->details->drag_started) {
fm_list_view_did_not_drag (view, event);
return TRUE;
}
}
return FALSE;
......@@ -739,6 +755,38 @@ popup_menu_callback (GtkWidget *widget, gpointer callback_data)
return TRUE;
}
static void
subdirectory_done_loading_callback (NautilusDirectory *directory, FMListView *view)
{
fm_list_model_subdirectory_done_loading (view->details->model, directory);
}
static void
row_expanded_callback (GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer callback_data)
{
FMListView *view;
NautilusFile *file;
NautilusDirectory *directory;
view = FM_LIST_VIEW (callback_data);
file = fm_list_model_file_for_path (view->details->model, path);
directory = nautilus_directory_get_for_file (file);
fm_directory_view_add_subdirectory (FM_DIRECTORY_VIEW (view), directory);
if (nautilus_directory_are_all_files_seen (directory)) {
fm_list_model_subdirectory_done_loading (view->details->model,
directory);
} else {
g_signal_connect_object (directory, "done_loading",
G_CALLBACK (subdirectory_done_loading_callback),
view, 0);
}
nautilus_directory_unref (directory);
}
static gboolean
key_press_callback (GtkWidget *widget, GdkEventKey *event, gpointer callback_data)
{
......@@ -1069,6 +1117,8 @@ create_and_set_up_tree_view (FMListView *view)
G_CALLBACK (key_press_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "popup_menu",
G_CALLBACK (popup_menu_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "row_expanded",
G_CALLBACK (row_expanded_callback), view, 0);
view->details->model = g_object_new (FM_TYPE_LIST_MODEL, NULL);
gtk_tree_view_set_model (view->details->tree_view, GTK_TREE_MODEL (view->details->model));
......@@ -1180,7 +1230,15 @@ create_and_set_up_tree_view (FMListView *view)
static void
fm_list_view_add_file (FMDirectoryView *view, NautilusFile *file)
{
fm_list_model_add_file (FM_LIST_VIEW (view)->details->model, file);
FMListModel *model;
model = FM_LIST_VIEW (view)->details->model;
if (!fm_list_model_add_file (model, file)) {
fm_directory_view_remove_subdirectory (view,
nautilus_directory_get_for_file (file));
fm_list_model_remove_file (model, file);
fm_list_model_add_file (model, file);
}
}
static GList *
......@@ -1374,8 +1432,10 @@ fm_list_view_get_selection_foreach_func (GtkTreeModel *model, GtkTreePath *path,
FM_LIST_MODEL_FILE_COLUMN, &file,
-1);
nautilus_file_ref (file);
(* list) = g_list_prepend ((* list), file);
if (file != NULL) {
nautilus_file_ref (file);
(* list) = g_list_prepend ((* list), file);
}
}
static GList *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment