diff options
author | Ramiro Estrugo <ramiro@src.gnome.org> | 2001-04-04 15:51:58 +0000 |
---|---|---|
committer | Ramiro Estrugo <ramiro@src.gnome.org> | 2001-04-04 15:51:58 +0000 |
commit | 3d2a9e54d508a93cc4c06297a434bb489ed57d6c (patch) | |
tree | 7b43f6bfe76350bf3655047fb9ac434cff84b8ca | |
parent | 0e104cc00f42574cc6b0c806802babdbf6c12528 (diff) | |
download | nautilus-3d2a9e54d508a93cc4c06297a434bb489ed57d6c.tar.gz |
Remove nautilusclist cut-n-paste code.
* configure.in:
Remove nautilusclist cut-n-paste code.
* cut-n-paste-code/widgets/Makefile.am:
* cut-n-paste-code/widgets/nautilusclist/.cvsignore:
* cut-n-paste-code/widgets/nautilusclist/Makefile.am:
* cut-n-paste-code/widgets/nautilusclist/nautilusclist.c:
* cut-n-paste-code/widgets/nautilusclist/nautilusclist.h:
Remove nautilusclist cut-n-paste code.
* libnautilus-extensions/nautilus-file-dnd.h:
* libnautilus-extensions/nautilus-file-dnd.c:
New file with Drag and Drop code that operated on NautilusFile
objects.
* libnautilus-extensions/Makefile.am:
* libnautilus-extensions/nautilus-list-column-title.c:
* libnautilus-extensions/nautilus-list-column-title.h:
* libnautilus-extensions/nautilus-list.c:
* libnautilus-extensions/nautilus-list.h:
* libnautilus-extensions/nautilus-ctree.c:
* libnautilus-extensions/nautilus-ctree.h:
* libnautilus-extensions/nautilus-drag.c:
* libnautilus-extensions/nautilus-drag.h:
Move these widget into eel.
* libnautilus-extensions/nautilus-icon-dnd.h:
* libnautilus-extensions/nautilus-icon-dnd.c:
Update for eel dnd code move.
* nautilus-installer/install-lib/Makefile.am:
* nautilus-installer/libtrilobite/Makefile.am:
Remove some voodoo that was needed for cut-n-paste code in
trilobite that no longer is among us.
* components/help/hyperbola-nav-tree.c:
* components/music/nautilus-music-view.c:
* components/rpmview/nautilus-rpm-verify-window.c:
* components/rpmview/nautilus-rpm-view-private.h:
* components/rpmview/nautilus-rpm-view.c:
* components/tree/nautilus-tree-view-dnd.c:
* components/tree/nautilus-tree-view-dnd.h:
* components/tree/nautilus-tree-view-private.h:
* components/tree/nautilus-tree-view.c:
* src/file-manager/fm-directory-view.c:
* src/file-manager/fm-list-view.c: (fm_list_view_initialize),
* src/nautilus-sidebar.c:
Update for clist, ctree, list and dnd code that now lives in eel.
Also do more #include cleanup.
50 files changed, 892 insertions, 33895 deletions
@@ -1,5 +1,57 @@ 2001-04-04 Ramiro Estrugo <ramiro@eazel.com> + * configure.in: + Remove nautilusclist cut-n-paste code. + + * cut-n-paste-code/widgets/Makefile.am: + * cut-n-paste-code/widgets/nautilusclist/.cvsignore: + * cut-n-paste-code/widgets/nautilusclist/Makefile.am: + * cut-n-paste-code/widgets/nautilusclist/nautilusclist.c: + * cut-n-paste-code/widgets/nautilusclist/nautilusclist.h: + Remove nautilusclist cut-n-paste code. + + * libnautilus-extensions/nautilus-file-dnd.h: + * libnautilus-extensions/nautilus-file-dnd.c: + New file with Drag and Drop code that operated on NautilusFile + objects. + + * libnautilus-extensions/Makefile.am: + * libnautilus-extensions/nautilus-list-column-title.c: + * libnautilus-extensions/nautilus-list-column-title.h: + * libnautilus-extensions/nautilus-list.c: + * libnautilus-extensions/nautilus-list.h: + * libnautilus-extensions/nautilus-ctree.c: + * libnautilus-extensions/nautilus-ctree.h: + * libnautilus-extensions/nautilus-drag.c: + * libnautilus-extensions/nautilus-drag.h: + Move these widget into eel. + + * libnautilus-extensions/nautilus-icon-dnd.h: + * libnautilus-extensions/nautilus-icon-dnd.c: + Update for eel dnd code move. + + * nautilus-installer/install-lib/Makefile.am: + * nautilus-installer/libtrilobite/Makefile.am: + Remove some voodoo that was needed for cut-n-paste code in + trilobite that no longer is among us. + + * components/help/hyperbola-nav-tree.c: + * components/music/nautilus-music-view.c: + * components/rpmview/nautilus-rpm-verify-window.c: + * components/rpmview/nautilus-rpm-view-private.h: + * components/rpmview/nautilus-rpm-view.c: + * components/tree/nautilus-tree-view-dnd.c: + * components/tree/nautilus-tree-view-dnd.h: + * components/tree/nautilus-tree-view-private.h: + * components/tree/nautilus-tree-view.c: + * src/file-manager/fm-directory-view.c: + * src/file-manager/fm-list-view.c: (fm_list_view_initialize), + * src/nautilus-sidebar.c: + Update for clist, ctree, list and dnd code that now lives in eel. + Also do more #include cleanup. + +2001-04-04 Ramiro Estrugo <ramiro@eazel.com> + * components/mozilla/Makefile.am: * components/mozilla/nautilus-mozilla-content-view.c: * components/services/clone/Makefile.am: diff --git a/components/help/hyperbola-nav-tree.c b/components/help/hyperbola-nav-tree.c index 0fcc8fa80..39728a3c3 100644 --- a/components/help/hyperbola-nav-tree.c +++ b/components/help/hyperbola-nav-tree.c @@ -1,12 +1,12 @@ #include <config.h> -#include <libnautilus/libnautilus.h> + #include "hyperbola-filefmt.h" #include <gtk/gtk.h> +#include <gtk/gtkctree.h> #include <libgnome/gnome-defs.h> #include <libgnome/gnome-i18n.h> -#include <libnautilus-extensions/nautilus-ctree.h> #include <libnautilus-extensions/nautilus-theme.h> -#include <eel/eel-gdk-font-extensions.h> +#include <libnautilus/libnautilus.h> #include "hyperbola-nav.h" diff --git a/components/music/nautilus-music-view.c b/components/music/nautilus-music-view.c index 67cf39fd2..07ee73331 100644 --- a/components/music/nautilus-music-view.c +++ b/components/music/nautilus-music-view.c @@ -1092,7 +1092,7 @@ play_status_display (NautilusMusicView *music_view) } -/* The following are copied from gtkclist.c and nautilusclist.c */ +/* The following are copied from gtkclist.c and eel-clist.c */ #define CELL_SPACING 1 /* gives the top pixel of the given row in context of diff --git a/components/rpmview/nautilus-rpm-verify-window.c b/components/rpmview/nautilus-rpm-verify-window.c index 5c3d59654..c3e81681b 100644 --- a/components/rpmview/nautilus-rpm-verify-window.c +++ b/components/rpmview/nautilus-rpm-verify-window.c @@ -28,22 +28,19 @@ #include <config.h> #include "nautilus-rpm-verify-window.h" -#include <libgnome/gnome-defs.h> - -#include <math.h> -#include <gnome.h> -#include <gdk/gdk.h> +#include <eel/eel-gdk-extensions.h> +#include <eel/eel-glib-extensions.h> +#include <eel/eel-gtk-extensions.h> +#include <eel/eel-gtk-macros.h> +#include <eel/eel-label.h> #include <gdk-pixbuf/gdk-pixbuf.h> +#include <gdk/gdk.h> +#include <gnome.h> #include <gtk/gtksignal.h> +#include <libgnome/gnome-defs.h> #include <libgnome/gnome-util.h> #include <libgnomeui/gnome-pixmap.h> -#include <eel/eel-gdk-extensions.h> -#include <eel/eel-gtk-macros.h> -#include <eel/eel-gtk-extensions.h> -#include <eel/eel-glib-extensions.h> -#include <eel/eel-label.h> -#include <libnautilus-extensions/nautilus-file-utilities.h> -#include <libnautilus-extensions/nautilus-theme.h> +#include <math.h> struct NautilusRPMVerifyWindowDetails { GtkWidget *package_name; diff --git a/components/rpmview/nautilus-rpm-view-private.h b/components/rpmview/nautilus-rpm-view-private.h index c5e7f1704..dc015a662 100644 --- a/components/rpmview/nautilus-rpm-view-private.h +++ b/components/rpmview/nautilus-rpm-view-private.h @@ -28,7 +28,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif -#include <libnautilus-extensions/nautilus-ctree.h> +#include <eel/eel-ctree.h> #ifdef EAZEL_SERVICES #include "libeazelinstall.h" @@ -67,7 +67,7 @@ struct NautilusRPMViewDetails { GtkWidget *package_file_tree; GNode *filename_tree; - NautilusCTreeNode *selected_file; + EelCTreeNode *selected_file; gboolean package_installed; int background_connection; diff --git a/components/rpmview/nautilus-rpm-view.c b/components/rpmview/nautilus-rpm-view.c index 00bf40cf8..30962e222 100644 --- a/components/rpmview/nautilus-rpm-view.c +++ b/components/rpmview/nautilus-rpm-view.c @@ -28,24 +28,21 @@ #include "nautilus-rpm-verify-window.h" #include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gnome.h> -#include <gtk/gtklabel.h> -#include <libgnomevfs/gnome-vfs.h> #include <eel/eel-background.h> -#include <libnautilus-extensions/nautilus-ctree.h> -#include <libnautilus-extensions/nautilus-file-utilities.h> -#include <libnautilus-extensions/nautilus-file.h> #include <eel/eel-glib-extensions.h> #include <eel/eel-gtk-extensions.h> #include <eel/eel-gtk-macros.h> #include <eel/eel-image.h> -#include <libnautilus-extensions/nautilus-metadata.h> #include <eel/eel-string.h> -#include <libnautilus-extensions/nautilus-theme.h> #include <eel/eel-viewport.h> +#include <errno.h> +#include <fcntl.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gnome.h> +#include <gtk/gtklabel.h> +#include <libgnomevfs/gnome-vfs.h> +#include <eel/eel-ctree.h> +#include <libnautilus-extensions/nautilus-theme.h> #include <libnautilus/libnautilus.h> #include <limits.h> #include <stdio.h> @@ -82,7 +79,7 @@ static void rpm_view_load_location_callback (NautilusView *view, static void nautilus_rpm_view_verify_package_callback (GtkWidget *widget, NautilusRPMView *rpm_view); -static void file_activation_callback (NautilusCTree *ctree, NautilusCTreeNode *node, int column, +static void file_activation_callback (EelCTree *ctree, EelCTreeNode *node, int column, NautilusRPMView *rpm_view); EEL_DEFINE_CLASS_BOILERPLATE (NautilusRPMView, nautilus_rpm_view, GTK_TYPE_EVENT_BOX) @@ -341,11 +338,11 @@ nautilus_rpm_view_initialize (NautilusRPMView *rpm_view) /* use a tree list now */ list_headers[0] = _(list_headers[0]); - rpm_view->details->package_file_tree = nautilus_ctree_new_with_titles (1, 0, list_headers); + rpm_view->details->package_file_tree = eel_ctree_new_with_titles (1, 0, list_headers); gtk_container_add (GTK_CONTAINER (temp_widget), rpm_view->details->package_file_tree); gtk_signal_connect (GTK_OBJECT (rpm_view->details->package_file_tree), "tree-activate-row", GTK_SIGNAL_FUNC (file_activation_callback), rpm_view); - nautilus_ctree_set_line_style (NAUTILUS_CTREE (rpm_view->details->package_file_tree), NAUTILUS_CTREE_LINES_NONE); + eel_ctree_set_line_style (EEL_CTREE (rpm_view->details->package_file_tree), EEL_CTREE_LINES_NONE); gtk_widget_show (rpm_view->details->package_file_tree); /* add an hbox for buttons that operate on the package list */ @@ -427,7 +424,7 @@ nautilus_rpm_view_get_nautilus_view (NautilusRPMView *rpm_view) } static void -file_activation_callback (NautilusCTree *ctree, NautilusCTreeNode *node, int column, NautilusRPMView *rpm_view) +file_activation_callback (EelCTree *ctree, EelCTreeNode *node, int column, NautilusRPMView *rpm_view) { char *path_name; char *path_item; @@ -435,7 +432,7 @@ file_activation_callback (NautilusCTree *ctree, NautilusCTreeNode *node, int col path_name = g_strdup (""); while (1) { - nautilus_ctree_node_get_pixtext (ctree, node, + eel_ctree_node_get_pixtext (ctree, node, 0, &path_item, NULL, NULL); if (strcmp (path_item, "/") != 0) { new_name = g_strdup_printf ("/%s%s", path_item, path_name); @@ -443,10 +440,10 @@ file_activation_callback (NautilusCTree *ctree, NautilusCTreeNode *node, int col path_name = new_name; } - if (NAUTILUS_CTREE_ROW (node)->parent == NULL) { + if (EEL_CTREE_ROW (node)->parent == NULL) { break; } - node = NAUTILUS_CTREE_ROW (node)->parent; + node = EEL_CTREE_ROW (node)->parent; } nautilus_view_open_location_in_this_window (rpm_view->details->nautilus_view, path_name); @@ -485,15 +482,15 @@ add_to_filename_tree (char *name, NautilusRPMView *view) } static void -fill_filename_tree_int (GtkWidget *ctree, NautilusCTreeNode *parent, GNode *node) +fill_filename_tree_int (GtkWidget *ctree, EelCTreeNode *parent, GNode *node) { GNode *child; - NautilusCTreeNode *me; + EelCTreeNode *me; char *text[1]; for (child = g_node_first_child (node); child != NULL; child = g_node_next_sibling (child)) { text[0] = (char *) child->data; - me = nautilus_ctree_insert_node (NAUTILUS_CTREE (ctree), parent, NULL, text, + me = eel_ctree_insert_node (EEL_CTREE (ctree), parent, NULL, text, 0, NULL, NULL, (child->children == NULL) ? TRUE : FALSE, TRUE); @@ -504,10 +501,10 @@ fill_filename_tree_int (GtkWidget *ctree, NautilusCTreeNode *parent, GNode *node static void fill_filename_tree (NautilusRPMView *rpm_view) { - NautilusCTreeNode *top; + EelCTreeNode *top; char *text[] = { "/" }; - top = nautilus_ctree_insert_node (NAUTILUS_CTREE (rpm_view->details->package_file_tree), + top = eel_ctree_insert_node (EEL_CTREE (rpm_view->details->package_file_tree), NULL, NULL, text, 0, NULL, NULL, FALSE, TRUE); @@ -551,8 +548,8 @@ nautilus_rpm_view_update_from_uri (NautilusRPMView *rpm_view, const char *uri) } /* set the file tree */ - nautilus_clist_freeze (NAUTILUS_CLIST (rpm_view->details->package_file_tree)); - nautilus_clist_clear (NAUTILUS_CLIST (rpm_view->details->package_file_tree)); + eel_clist_freeze (EEL_CLIST (rpm_view->details->package_file_tree)); + eel_clist_clear (EEL_CLIST (rpm_view->details->package_file_tree)); if (rpm_view->details->filename_tree != NULL) { g_node_traverse (rpm_view->details->filename_tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1, (GNodeTraverseFunc)filename_node_free, NULL); @@ -563,9 +560,9 @@ nautilus_rpm_view_update_from_uri (NautilusRPMView *rpm_view, const char *uri) fill_filename_tree (rpm_view); temp_str = g_strdup_printf(_("Package Contents: %d files"), g_list_length (rpm_view->details->package->provides)); - nautilus_clist_set_column_title (NAUTILUS_CLIST(rpm_view->details->package_file_tree), 0, temp_str); + eel_clist_set_column_title (EEL_CLIST(rpm_view->details->package_file_tree), 0, temp_str); g_free(temp_str); - nautilus_clist_thaw(NAUTILUS_CLIST(rpm_view->details->package_file_tree)); + eel_clist_thaw(EEL_CLIST(rpm_view->details->package_file_tree)); temp_str = g_strdup_printf(_("Package \"%s\" "), rpm_view->details->package->name); gtk_label_set_text (GTK_LABEL (rpm_view->details->package_title), temp_str); diff --git a/components/tree/nautilus-tree-view-dnd.c b/components/tree/nautilus-tree-view-dnd.c index e38968cc0..4450503a1 100644 --- a/components/tree/nautilus-tree-view-dnd.c +++ b/components/tree/nautilus-tree-view-dnd.c @@ -34,7 +34,6 @@ #include <gtk/gtksignal.h> #include <libgnome/gnome-i18n.h> #include <eel/eel-background.h> -#include <libnautilus-extensions/nautilus-drag.h> #include <libnautilus-extensions/nautilus-file-operations.h> #include <libnautilus-extensions/nautilus-file.h> #include <eel/eel-glib-extensions.h> @@ -102,11 +101,11 @@ static char *nautilus_tree_view_find_drop_target (NautilusTreeView int y); static char *nautilus_tree_view_get_drag_uri (NautilusTreeView *tree_view); -static void nautilus_tree_view_expand_or_collapse_row (NautilusCTree *tree, +static void nautilus_tree_view_expand_or_collapse_row (EelCTree *tree, int row); static gboolean nautilus_tree_view_is_tree_node_directory (NautilusTreeView *tree_view, - NautilusCTreeNode *node); -static NautilusCTreeNode *nautilus_tree_view_tree_node_at (NautilusTreeView *tree_view, + EelCTreeNode *node); +static EelCTreeNode *nautilus_tree_view_tree_node_at (NautilusTreeView *tree_view, int x, int y); @@ -135,7 +134,7 @@ static void nautilus_tree_view_get_drop_action (NautilusTreeView *tree_view, int *default_action, int *non_default_action); static void nautilus_tree_view_collapse_all (NautilusTreeView *tree_view, - NautilusCTreeNode *current_node); + EelCTreeNode *current_node); static void nautilus_tree_view_set_dnd_icon (NautilusTreeView *tree_view, GdkDragContext *context); @@ -144,8 +143,8 @@ static void nautilus_tree_view_drag_destroy (NautilusTreeView *tree_view) static void nautilus_tree_view_drag_destroy_real (NautilusTreeView *tree_view); static GtkTargetEntry nautilus_tree_view_dnd_target_table[] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST } + { EEL_ICON_DND_GNOME_ICON_LIST_TYPE, 0, EEL_ICON_DND_GNOME_ICON_LIST }, + { EEL_ICON_DND_URI_LIST_TYPE, 0, EEL_ICON_DND_URI_LIST } }; static GtkTargetList *nautilus_tree_view_dnd_target_list = NULL; @@ -194,8 +193,8 @@ nautilus_tree_view_init_dnd (NautilusTreeView *view) view->details->dnd = g_new0 (NautilusTreeViewDndDetails, 1); view->details->dnd->expanded_nodes = NULL; - view->details->dnd->drag_info = g_new0 (NautilusDragInfo, 1); - nautilus_drag_init (view->details->dnd->drag_info, + view->details->dnd->drag_info = g_new0 (EelDragInfo, 1); + eel_drag_init (view->details->dnd->drag_info, nautilus_tree_view_dnd_target_table, EEL_N_ELEMENTS (nautilus_tree_view_dnd_target_table), NULL); @@ -271,7 +270,7 @@ nautilus_tree_view_free_dnd (NautilusTreeView *view) if (view->details->dnd->highlight_style != NULL) { gtk_style_unref (view->details->dnd->highlight_style); } - nautilus_drag_finalize (view->details->dnd->drag_info); + eel_drag_finalize (view->details->dnd->drag_info); g_free (view->details->dnd); } @@ -333,7 +332,7 @@ nautilus_tree_view_drag_motion (GtkWidget *widget, GdkDragContext *context, { NautilusTreeView *tree_view; NautilusTreeViewDndDetails *dnd; - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; int resulting_action, default_action, non_default_action; @@ -354,16 +353,16 @@ nautilus_tree_view_drag_motion (GtkWidget *widget, GdkDragContext *context, /* prelight depending on the type of drop. */ if (drag_info->got_drop_data_type) { switch (drag_info->data_type) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_URI_LIST: - nautilus_ctree_set_prelight (NAUTILUS_CTREE (tree_view->details->tree), + eel_ctree_set_prelight (EEL_CTREE (tree_view->details->tree), y); break; - case NAUTILUS_ICON_DND_KEYWORD: - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_KEYWORD: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: default: break; } @@ -376,7 +375,7 @@ nautilus_tree_view_drag_motion (GtkWidget *widget, GdkDragContext *context, nautilus_tree_view_get_drop_action (tree_view, context, x, y, &default_action, &non_default_action); - resulting_action = nautilus_drag_modifier_based_action (default_action, + resulting_action = eel_drag_modifier_based_action (default_action, non_default_action); gdk_drag_status (context, resulting_action, time); @@ -447,7 +446,7 @@ nautilus_tree_view_drag_data_received (GtkWidget *widget, guint info, guint time) { NautilusTreeViewDndDetails *dnd; - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; NautilusTreeView *tree_view; tree_view = NAUTILUS_TREE_VIEW (gtk_object_get_data (GTK_OBJECT (widget), "tree_view")); @@ -461,15 +460,15 @@ nautilus_tree_view_drag_data_received (GtkWidget *widget, /* save operation for drag motion events */ switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); + case EEL_ICON_DND_GNOME_ICON_LIST: + drag_info->selection_list = eel_drag_build_selection_list (data); break; - case NAUTILUS_ICON_DND_URI_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); + case EEL_ICON_DND_URI_LIST: + drag_info->selection_list = eel_drag_build_selection_list (data); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: + case EEL_ICON_DND_KEYWORD: default: /* we do not want to support any of the 3 above */ break; @@ -479,16 +478,16 @@ nautilus_tree_view_drag_data_received (GtkWidget *widget, if (drag_info->drop_occured) { /* drop occured: do actual operations on the data */ switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_URI_LIST: nautilus_tree_view_receive_dropped_icons (NAUTILUS_TREE_VIEW (tree_view), context, x, y); gtk_drag_finish (context, TRUE, FALSE, time); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: + case EEL_ICON_DND_KEYWORD: default: gtk_drag_finish (context, FALSE, FALSE, time); } @@ -554,12 +553,12 @@ static int nautilus_tree_view_button_press (GtkWidget *widget, GdkEventButton *event) { int retval; - NautilusCList *clist; + EelCList *clist; NautilusTreeView *tree_view; int press_row, press_column, on_row; - clist = NAUTILUS_CLIST (widget); + clist = EEL_CLIST (widget); retval = FALSE; if (event->window != clist->clist_window) @@ -567,7 +566,7 @@ nautilus_tree_view_button_press (GtkWidget *widget, GdkEventButton *event) tree_view = NAUTILUS_TREE_VIEW (gtk_object_get_data (GTK_OBJECT (widget), "tree_view")); - on_row = nautilus_clist_get_selection_info (clist, + on_row = eel_clist_get_selection_info (clist, event->x, event->y, &press_row, &press_column); @@ -576,9 +575,9 @@ nautilus_tree_view_button_press (GtkWidget *widget, GdkEventButton *event) return FALSE; } - if (nautilus_ctree_is_hot_spot (NAUTILUS_CTREE (widget), event->x, event->y)) { - NautilusCTreeRow *ctree_row; - NautilusCTreeNode *node; + if (eel_ctree_is_hot_spot (EEL_CTREE (widget), event->x, event->y)) { + EelCTreeRow *ctree_row; + EelCTreeNode *node; tree_view->details->dnd->press_x = event->x; tree_view->details->dnd->press_y = event->y; @@ -593,9 +592,9 @@ nautilus_tree_view_button_press (GtkWidget *widget, GdkEventButton *event) ctree_row->mouse_down = TRUE; ctree_row->in_hotspot = TRUE; - node = nautilus_ctree_find_node_ptr (NAUTILUS_CTREE (widget), ctree_row); + node = eel_ctree_find_node_ptr (EEL_CTREE (widget), ctree_row); if (node != NULL) { - nautilus_ctree_draw_node (NAUTILUS_CTREE (widget), node); + eel_ctree_draw_node (EEL_CTREE (widget), node); } } } else { @@ -623,16 +622,16 @@ static int nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) { int retval; - NautilusCList *clist; + EelCList *clist; NautilusTreeView *tree_view; int release_row, release_column, on_row; int distance_squared; gboolean is_still_hot_spot; int press_row, press_column; - NautilusCTreeRow *ctree_row; - NautilusCTreeNode *node; + EelCTreeRow *ctree_row; + EelCTreeNode *node; - clist = NAUTILUS_CLIST (widget); + clist = EEL_CLIST (widget); retval = FALSE; if (event->window != clist->clist_window) @@ -643,7 +642,7 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) /* Set state of spinner. Use saved dnd x and y as the mouse may have moved out * of the original row */ - on_row = nautilus_clist_get_selection_info (clist, + on_row = eel_clist_get_selection_info (clist, tree_view->details->dnd->press_x, tree_view->details->dnd->press_y, &press_row, &press_column); @@ -653,9 +652,9 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) ctree_row->in_hotspot = FALSE; /* Redraw spinner */ - node = nautilus_ctree_find_node_ptr (NAUTILUS_CTREE (widget), ctree_row); + node = eel_ctree_find_node_ptr (EEL_CTREE (widget), ctree_row); if (node != NULL) { - nautilus_ctree_draw_node (NAUTILUS_CTREE (widget), node); + eel_ctree_draw_node (EEL_CTREE (widget), node); } } @@ -663,10 +662,10 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) * (event->x - tree_view->details->dnd->press_x) + (event->y - tree_view->details->dnd->press_y) * (event->y - tree_view->details->dnd->press_y); - is_still_hot_spot = nautilus_ctree_is_hot_spot (NAUTILUS_CTREE(tree_view->details->tree), + is_still_hot_spot = eel_ctree_is_hot_spot (EEL_CTREE(tree_view->details->tree), event->x, event->y); - on_row = nautilus_clist_get_selection_info (clist, + on_row = eel_clist_get_selection_info (clist, event->x, event->y, &release_row, &release_column); @@ -679,7 +678,7 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) tree_view->details->dnd->pressed_hot_spot = FALSE; - nautilus_tree_view_expand_or_collapse_row (NAUTILUS_CTREE(tree_view->details->tree), + nautilus_tree_view_expand_or_collapse_row (EEL_CTREE(tree_view->details->tree), release_row); } else if (distance_squared <= RADIUS) { /* we are close from the place we clicked */ @@ -687,7 +686,7 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) /* Only button 1 triggers a selection */ if (event->button == 1) { - nautilus_clist_select_row (clist, + eel_clist_select_row (clist, release_row, release_column); } } @@ -704,10 +703,10 @@ nautilus_tree_view_button_release (GtkWidget *widget, GdkEventButton *event) static int nautilus_tree_view_motion_notify (GtkWidget *widget, GdkEventButton *event) { - NautilusCList *clist; + EelCList *clist; NautilusTreeView *tree_view; - clist = NAUTILUS_CLIST (widget); + clist = EEL_CLIST (widget); if (event->window != clist->clist_window) @@ -738,7 +737,7 @@ nautilus_tree_view_motion_notify (GtkWidget *widget, GdkEventButton *event) (GdkEvent *) event); - nautilus_ctree_set_prelight (NAUTILUS_CTREE (tree_view->details->tree), + eel_ctree_set_prelight (EEL_CTREE (tree_view->details->tree), tree_view->details->dnd->press_y); } @@ -777,7 +776,7 @@ static void nautilus_tree_view_set_dnd_icon (NautilusTreeView *tree_view, GdkDragContext *context) { GdkPixbuf *pixbuf; - NautilusCTreeNode *node; + EelCTreeNode *node; gchar *text; guint8 spacing; GdkPixbuf *pixbuf_opened; @@ -794,7 +793,7 @@ nautilus_tree_view_set_dnd_icon (NautilusTreeView *tree_view, GdkDragContext *co dnd->press_x, dnd->press_y); - nautilus_ctree_get_node_info (NAUTILUS_CTREE (tree_view->details->tree), + eel_ctree_get_node_info (EEL_CTREE (tree_view->details->tree), node, &text, &spacing, &pixbuf, &pixbuf_opened, &is_leaf, @@ -808,7 +807,7 @@ nautilus_tree_view_set_dnd_icon (NautilusTreeView *tree_view, GdkDragContext *co /* returns if it was expanded or not */ static gboolean -nautilus_tree_view_collapse_node (NautilusCTree *tree, NautilusCTreeNode *node) +nautilus_tree_view_collapse_node (EelCTree *tree, EelCTreeNode *node) { char *node_text; guint8 node_spacing; @@ -817,14 +816,14 @@ nautilus_tree_view_collapse_node (NautilusCTree *tree, NautilusCTreeNode *node) gboolean is_leaf; gboolean is_expanded; - nautilus_ctree_get_node_info (NAUTILUS_CTREE(tree), + eel_ctree_get_node_info (EEL_CTREE(tree), node, &node_text, &node_spacing, &pixbuf_closed, &pixbuf_opened, &is_leaf, &is_expanded); if (is_expanded) { /* collapse */ - nautilus_ctree_collapse (NAUTILUS_CTREE(tree), + eel_ctree_collapse (EEL_CTREE(tree), node); } @@ -833,9 +832,9 @@ nautilus_tree_view_collapse_node (NautilusCTree *tree, NautilusCTreeNode *node) static void -nautilus_tree_view_expand_or_collapse_row (NautilusCTree *tree, int row) +nautilus_tree_view_expand_or_collapse_row (EelCTree *tree, int row) { - NautilusCTreeNode *node; + EelCTreeNode *node; char *node_text; guint8 node_spacing; GdkPixbuf *pixbuf_closed; @@ -843,19 +842,19 @@ nautilus_tree_view_expand_or_collapse_row (NautilusCTree *tree, int row) gboolean is_leaf; gboolean is_expanded; - node = nautilus_ctree_node_nth (NAUTILUS_CTREE(tree), row); - nautilus_ctree_get_node_info (NAUTILUS_CTREE(tree), + node = eel_ctree_node_nth (EEL_CTREE(tree), row); + eel_ctree_get_node_info (EEL_CTREE(tree), node, &node_text, &node_spacing, &pixbuf_closed, &pixbuf_opened, &is_leaf, &is_expanded); if (!is_expanded) { /* expand */ - nautilus_ctree_expand (NAUTILUS_CTREE(tree), + eel_ctree_expand (EEL_CTREE(tree), node); } else { /* collapse */ - nautilus_ctree_collapse (NAUTILUS_CTREE(tree), + eel_ctree_collapse (EEL_CTREE(tree), node); } @@ -896,7 +895,7 @@ nautilus_tree_view_find_drop_target (NautilusTreeView *tree_view, { char *target_uri; NautilusFile *file; - NautilusCTreeNode *node; + EelCTreeNode *node; gboolean is_directory; NautilusTreeNode *current_node; @@ -924,7 +923,7 @@ nautilus_tree_view_find_drop_target (NautilusTreeView *tree_view, static gboolean nautilus_tree_view_is_tree_node_directory (NautilusTreeView *tree_view, - NautilusCTreeNode *node) + EelCTreeNode *node) { NautilusTreeNode *model_node; NautilusFile *file; @@ -941,20 +940,20 @@ nautilus_tree_view_is_tree_node_directory (NautilusTreeView *tree_view, -static NautilusCTreeNode * +static EelCTreeNode * nautilus_tree_view_tree_node_at (NautilusTreeView *tree_view, int x, int y) { int row, column, on_row; - NautilusCTreeNode *node; + EelCTreeNode *node; - on_row = nautilus_clist_get_selection_info (NAUTILUS_CLIST (tree_view->details->tree), + on_row = eel_clist_get_selection_info (EEL_CLIST (tree_view->details->tree), x, y, &row, &column); node = NULL; if (on_row == 1) { - node = nautilus_ctree_node_nth (NAUTILUS_CTREE (tree_view->details->tree), + node = eel_ctree_node_nth (EEL_CTREE (tree_view->details->tree), row); } @@ -975,7 +974,7 @@ static char * nautilus_tree_view_item_at (NautilusTreeView *tree_view, int x, int y) { - NautilusCTreeNode *node; + EelCTreeNode *node; node = nautilus_tree_view_tree_node_at (tree_view, x, y); if (node == NULL) { @@ -1006,7 +1005,7 @@ nautilus_tree_view_ensure_drag_data (NautilusTreeView *tree_view, GdkDragContext *context, guint32 time) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; drag_info = tree_view->details->dnd->drag_info; @@ -1028,7 +1027,7 @@ nautilus_tree_view_ensure_drag_data (NautilusTreeView *tree_view, static gboolean -ready_to_start_scrolling (NautilusDragInfo *drag_info, +ready_to_start_scrolling (EelDragInfo *drag_info, int y_scroll_delta) { return (y_scroll_delta != 0 && drag_info->start_auto_scroll_in < eel_get_system_time ()) || @@ -1038,7 +1037,7 @@ ready_to_start_scrolling (NautilusDragInfo *drag_info, static int auto_scroll_timeout_callback (gpointer data) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; NautilusTreeView *tree_view; float x_scroll_delta, y_scroll_delta; @@ -1046,7 +1045,7 @@ auto_scroll_timeout_callback (gpointer data) tree_view = NAUTILUS_TREE_VIEW (data); drag_info = tree_view->details->dnd->drag_info; - nautilus_drag_autoscroll_calculate_delta (tree_view->details->tree, &x_scroll_delta, &y_scroll_delta); + eel_drag_autoscroll_calculate_delta (tree_view->details->tree, &x_scroll_delta, &y_scroll_delta); if (drag_info->waiting_to_autoscroll && !ready_to_start_scrolling (drag_info, y_scroll_delta)) { @@ -1068,7 +1067,7 @@ nautilus_tree_view_start_auto_scroll (NautilusTreeView *tree_view) { g_assert (NAUTILUS_IS_TREE_VIEW (tree_view)); - nautilus_drag_autoscroll_start (tree_view->details->dnd->drag_info, + eel_drag_autoscroll_start (tree_view->details->dnd->drag_info, tree_view->details->tree, auto_scroll_timeout_callback, tree_view); @@ -1080,7 +1079,7 @@ nautilus_tree_view_stop_auto_scroll (NautilusTreeView *tree_view) { g_assert (NAUTILUS_IS_TREE_VIEW (tree_view)); - nautilus_drag_autoscroll_stop (tree_view->details->dnd->drag_info); + eel_drag_autoscroll_stop (tree_view->details->dnd->drag_info); } static void @@ -1107,7 +1106,7 @@ nautilus_tree_view_get_drop_action (NautilusTreeView *tree_view, int *default_action, int *non_default_action) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; char *drop_target; drag_info = NAUTILUS_TREE_VIEW (tree_view)->details->dnd->drag_info; @@ -1121,8 +1120,8 @@ nautilus_tree_view_get_drop_action (NautilusTreeView *tree_view, switch (drag_info->data_type) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_URI_LIST: if (drag_info->selection_list == NULL) { *default_action = 0; *non_default_action = 0; @@ -1135,14 +1134,14 @@ nautilus_tree_view_get_drop_action (NautilusTreeView *tree_view, *non_default_action = 0; return; } - nautilus_drag_default_drop_action_for_icons (context, drop_target, + eel_drag_default_drop_action_for_icons (context, drop_target, drag_info->selection_list, default_action, non_default_action); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_KEYWORD: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_KEYWORD: + case EEL_ICON_DND_BGIMAGE: /* we handle none of the above */ *default_action = context->suggested_action; *non_default_action = context->suggested_action; @@ -1155,7 +1154,7 @@ nautilus_tree_view_get_drop_action (NautilusTreeView *tree_view, static void nautilus_tree_view_collapse_all (NautilusTreeView *tree_view, - NautilusCTreeNode *current_node) + EelCTreeNode *current_node) { GSList *list, *temp_list; @@ -1163,11 +1162,11 @@ nautilus_tree_view_collapse_all (NautilusTreeView *tree_view, for (temp_list = list; temp_list != NULL; temp_list = temp_list->next) { - NautilusCTreeNode *expanded_node; - expanded_node = (NautilusCTreeNode *) temp_list->data; - if (!nautilus_ctree_is_ancestor (NAUTILUS_CTREE (tree_view->details->tree), + EelCTreeNode *expanded_node; + expanded_node = (EelCTreeNode *) temp_list->data; + if (!eel_ctree_is_ancestor (EEL_CTREE (tree_view->details->tree), expanded_node, current_node)) { - nautilus_tree_view_collapse_node (NAUTILUS_CTREE (tree_view->details->tree), + nautilus_tree_view_collapse_node (EEL_CTREE (tree_view->details->tree), expanded_node); } } @@ -1179,11 +1178,11 @@ nautilus_tree_view_receive_dropped_icons (NautilusTreeView *view, GdkDragContext *context, int x, int y) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; NautilusTreeView *tree_view; NautilusTreeViewDndDetails *dnd; char *drop_target_uri; - NautilusCTreeNode *dropped_node; + EelCTreeNode *dropped_node; g_assert (NAUTILUS_IS_TREE_VIEW (view)); @@ -1199,7 +1198,7 @@ nautilus_tree_view_receive_dropped_icons (NautilusTreeView *view, } if (context->action == GDK_ACTION_ASK) { - context->action = nautilus_drag_drop_action_ask + context->action = eel_drag_drop_action_ask (GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK); } @@ -1207,7 +1206,7 @@ nautilus_tree_view_receive_dropped_icons (NautilusTreeView *view, drop_target_uri = nautilus_tree_view_find_drop_target (tree_view, x, y); if (drop_target_uri == NULL) { - nautilus_drag_destroy_selection_list (drag_info->selection_list); + eel_drag_destroy_selection_list (drag_info->selection_list); return; } @@ -1233,7 +1232,7 @@ static void nautilus_tree_view_drag_destroy (NautilusTreeView *tree_view) { NautilusTreeViewDndDetails *dnd; - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; g_assert (NAUTILUS_IS_TREE_VIEW (tree_view)); @@ -1246,7 +1245,7 @@ nautilus_tree_view_drag_destroy (NautilusTreeView *tree_view) nautilus_tree_view_stop_auto_scroll (tree_view); /* remove prelighting */ - nautilus_ctree_set_prelight (NAUTILUS_CTREE (tree_view->details->tree), + eel_ctree_set_prelight (EEL_CTREE (tree_view->details->tree), -1); } @@ -1255,7 +1254,7 @@ static void nautilus_tree_view_drag_destroy_real (NautilusTreeView *tree_view) { NautilusTreeViewDndDetails *dnd; - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; g_assert (NAUTILUS_IS_TREE_VIEW (tree_view)); @@ -1264,7 +1263,7 @@ nautilus_tree_view_drag_destroy_real (NautilusTreeView *tree_view) /* reset booleans used during drag. */ drag_info->got_drop_data_type = FALSE; - nautilus_drag_destroy_selection_list (drag_info->selection_list); + eel_drag_destroy_selection_list (drag_info->selection_list); drag_info->drop_occured = FALSE; if (drag_info->selection_data != NULL) { diff --git a/components/tree/nautilus-tree-view-dnd.h b/components/tree/nautilus-tree-view-dnd.h index cc1f2da2c..8cd305179 100644 --- a/components/tree/nautilus-tree-view-dnd.h +++ b/components/tree/nautilus-tree-view-dnd.h @@ -25,12 +25,12 @@ #ifndef NAUTILUS_TREE_VIEW_DND_H #define NAUTILUS_TREE_VIEW_DND_H -#include <libnautilus-extensions/nautilus-drag.h> +#include <eel/eel-dnd.h> #include "nautilus-tree-view-private.h" struct NautilusTreeViewDndDetails { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; /* data setup by button_press signal for dragging */ @@ -50,7 +50,7 @@ struct NautilusTreeViewDndDetails { GSList *expanded_nodes; /* row being highlighted */ - NautilusCTreeNode *current_prelighted_node; + EelCTreeNode *current_prelighted_node; GtkStyle *normal_style; GtkStyle *highlight_style; }; diff --git a/components/tree/nautilus-tree-view-private.h b/components/tree/nautilus-tree-view-private.h index 2fdaaf7f7..baf3495ec 100644 --- a/components/tree/nautilus-tree-view-private.h +++ b/components/tree/nautilus-tree-view-private.h @@ -30,7 +30,7 @@ #include "nautilus-tree-expansion-state.h" #include "nautilus-tree-model.h" -#include <libnautilus-extensions/nautilus-ctree.h> +#include <eel/eel-ctree.h> #include <libnautilus/nautilus-view.h> typedef struct NautilusTreeViewDndDetails NautilusTreeViewDndDetails; @@ -81,10 +81,10 @@ struct NautilusTreeViewDetails { }; NautilusTreeNode *nautilus_tree_view_node_to_model_node (NautilusTreeView *view, - NautilusCTreeNode *node); + EelCTreeNode *node); NautilusFile *nautilus_tree_view_node_to_file (NautilusTreeView *view, - NautilusCTreeNode *node); -NautilusCTreeNode *nautilus_tree_view_model_node_to_view_node (NautilusTreeView *view, + EelCTreeNode *node); +EelCTreeNode *nautilus_tree_view_model_node_to_view_node (NautilusTreeView *view, NautilusTreeNode *node); void nautilus_tree_view_init_dnd (NautilusTreeView *view); void nautilus_tree_view_free_dnd (NautilusTreeView *view); diff --git a/components/tree/nautilus-tree-view.c b/components/tree/nautilus-tree-view.c index a3a6965bf..86224b589 100644 --- a/components/tree/nautilus-tree-view.c +++ b/components/tree/nautilus-tree-view.c @@ -54,8 +54,8 @@ static void notify_node_seen (NautilusTreeView *view, NautilusTreeNode *node); -static gboolean ctree_is_node_expanded (NautilusCTree *ctree, - NautilusCTreeNode *node); +static gboolean ctree_is_node_expanded (EelCTree *ctree, + EelCTreeNode *node); static void nautilus_tree_view_remove_model_node (NautilusTreeView *view, NautilusTreeNode *node); static void reload_model_node (NautilusTreeView *view, @@ -66,17 +66,17 @@ static void reload_whole_tree (NautilusTreeView *vie static void tree_load_location_callback (NautilusView *nautilus_view, const char *location, NautilusTreeView *view); -static void tree_expand_callback (NautilusCTree *tree, - NautilusCTreeNode *node, +static void tree_expand_callback (EelCTree *tree, + EelCTreeNode *node, NautilusTreeView *view); -static void tree_collapse_callback (NautilusCTree *tree, - NautilusCTreeNode *node, +static void tree_collapse_callback (EelCTree *tree, + EelCTreeNode *node, NautilusTreeView *view); -static void tree_select_row_callback (NautilusCTree *tree, - NautilusCTreeNode *node, +static void tree_select_row_callback (EelCTree *tree, + EelCTreeNode *node, gint column, NautilusTreeView *view); -static void size_allocate_callback (NautilusCTree *tree, +static void size_allocate_callback (EelCTree *tree, GtkAllocation *allocation, gpointer data); static void nautilus_tree_view_update_all_icons (NautilusTreeView *view); @@ -100,7 +100,7 @@ EEL_DEFINE_CLASS_BOILERPLATE (NautilusTreeView, static void unlink_view_node_from_uri (NautilusTreeView *view, - NautilusCTreeNode *view_node) + EelCTreeNode *view_node) { gpointer orig_key, value; @@ -114,7 +114,7 @@ unlink_view_node_from_uri (NautilusTreeView *view, /* URI will be g_free'd eventually */ static void link_view_node_with_uri (NautilusTreeView *view, - NautilusCTreeNode *view_node, + EelCTreeNode *view_node, const char *uri) { unlink_view_node_from_uri (view, view_node); @@ -125,7 +125,7 @@ link_view_node_with_uri (NautilusTreeView *view, /* Returned string is only valid until next link or unlink of VIEW-NODE */ static const char * map_view_node_to_uri (NautilusTreeView *view, - NautilusCTreeNode *view_node) + EelCTreeNode *view_node) { gpointer value = g_hash_table_lookup (view->details->view_node_to_uri_map, view_node); @@ -197,8 +197,8 @@ static void nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode *node) { NautilusTreeNode *parent_node; - NautilusCTreeNode *parent_view_node; - NautilusCTreeNode *view_node; + EelCTreeNode *parent_view_node; + EelCTreeNode *view_node; NautilusFile *file; char *text[2]; GdkPixbuf *closed_pixbuf; @@ -244,9 +244,9 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * is_anti_aliased (view)); view->details->inserting_node = TRUE; - NAUTILUS_CLIST_UNSET_FLAG (NAUTILUS_CLIST (view->details->tree), + EEL_CLIST_UNSET_FLAG (EEL_CLIST (view->details->tree), CLIST_AUTO_SORT); - view_node = nautilus_ctree_insert_node (NAUTILUS_CTREE (view->details->tree), + view_node = eel_ctree_insert_node (EEL_CTREE (view->details->tree), parent_view_node, NULL, text, @@ -254,7 +254,7 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * closed_pixbuf, open_pixbuf, ! nautilus_file_is_directory (file), FALSE); - NAUTILUS_CLIST_SET_FLAG (NAUTILUS_CLIST (view->details->tree), + EEL_CLIST_SET_FLAG (EEL_CLIST (view->details->tree), CLIST_AUTO_SORT); view->details->inserting_node = FALSE; @@ -262,7 +262,7 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * gdk_pixbuf_unref (open_pixbuf); - nautilus_ctree_node_set_row_data (NAUTILUS_CTREE (view->details->tree), + eel_ctree_node_set_row_data (EEL_CTREE (view->details->tree), view_node, node); @@ -276,21 +276,21 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * if (nautilus_file_is_directory (nautilus_tree_node_get_file (node))) { if (nautilus_tree_expansion_state_is_node_expanded (view->details->expansion_state, uri)) { - if (!ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + if (!ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)) { - nautilus_ctree_expand (NAUTILUS_CTREE (view->details->tree), + eel_ctree_expand (EEL_CTREE (view->details->tree), view_node); } } else { - if (ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + if (ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)) { - nautilus_ctree_collapse (NAUTILUS_CTREE (view->details->tree), + eel_ctree_collapse (EEL_CTREE (view->details->tree), view_node); } } } - nautilus_ctree_sort_single_node (NAUTILUS_CTREE (view->details->tree), view_node); + eel_ctree_sort_single_node (EEL_CTREE (view->details->tree), view_node); insert_unparented_nodes (view, node); } else { @@ -304,7 +304,7 @@ nautilus_tree_view_insert_model_node (NautilusTreeView *view, NautilusTreeNode * static void forget_view_node (NautilusTreeView *view, - NautilusCTreeNode *view_node) + EelCTreeNode *view_node) { NautilusFile *file; NautilusTreeNode *node; @@ -316,7 +316,7 @@ forget_view_node (NautilusTreeView *view, forget_unparented_node (view, node); - nautilus_ctree_node_set_row_data (NAUTILUS_CTREE (view->details->tree), + eel_ctree_node_set_row_data (EEL_CTREE (view->details->tree), view_node, NULL); g_hash_table_remove (view->details->file_to_node_map, file); @@ -327,13 +327,13 @@ forget_view_node (NautilusTreeView *view, static void forget_view_node_and_children (NautilusTreeView *view, - NautilusCTreeNode *view_node) + EelCTreeNode *view_node) { - NautilusCTreeNode *child; + EelCTreeNode *child; - for (child = NAUTILUS_CTREE_ROW (view_node)->children; + for (child = EEL_CTREE_ROW (view_node)->children; child != NULL; - child = NAUTILUS_CTREE_ROW (child)->sibling) { + child = EEL_CTREE_ROW (child)->sibling) { forget_view_node_and_children (view, child); } @@ -343,7 +343,7 @@ forget_view_node_and_children (NautilusTreeView *view, static void nautilus_tree_view_remove_model_node (NautilusTreeView *view, NautilusTreeNode *node) { - NautilusCTreeNode *view_node; + EelCTreeNode *view_node; NautilusFile *file; const char *uri; @@ -371,7 +371,7 @@ nautilus_tree_view_remove_model_node (NautilusTreeView *view, NautilusTreeNode * nautilus_tree_expansion_state_remove_node (view->details->expansion_state, uri); forget_view_node_and_children (view, view_node); - nautilus_ctree_remove_node (NAUTILUS_CTREE (view->details->tree), + eel_ctree_remove_node (EEL_CTREE (view->details->tree), view_node); } @@ -383,8 +383,8 @@ nautilus_tree_view_remove_model_node (NautilusTreeView *view, NautilusTreeNode * static gboolean -ctree_is_node_expanded (NautilusCTree *ctree, - NautilusCTreeNode *node) +ctree_is_node_expanded (EelCTree *ctree, + EelCTreeNode *node) { gchar *text; guint8 spacing; @@ -393,7 +393,7 @@ ctree_is_node_expanded (NautilusCTree *ctree, gboolean is_leaf; gboolean expanded; - nautilus_ctree_get_node_info (ctree, node, + eel_ctree_get_node_info (ctree, node, &text, &spacing, &pixbuf_closed, &pixbuf_opened, @@ -404,7 +404,7 @@ ctree_is_node_expanded (NautilusCTree *ctree, static void nautilus_tree_view_update_model_node (NautilusTreeView *view, NautilusTreeNode *node) { - NautilusCTreeNode *view_node; + EelCTreeNode *view_node; NautilusFile *file; char *uri; char *name; @@ -439,14 +439,14 @@ nautilus_tree_view_update_model_node (NautilusTreeView *view, NautilusTreeNode * name = nautilus_file_get_name (file); - nautilus_ctree_set_node_info (NAUTILUS_CTREE (view->details->tree), + eel_ctree_set_node_info (EEL_CTREE (view->details->tree), view_node, name, TREE_SPACING, closed_pixbuf, open_pixbuf, ! nautilus_file_is_directory (file), - ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)); g_free (name); @@ -460,15 +460,15 @@ nautilus_tree_view_update_model_node (NautilusTreeView *view, NautilusTreeNode * uri = nautilus_file_get_uri (file); if (nautilus_tree_expansion_state_is_node_expanded (view->details->expansion_state, uri)) { - if (!ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + if (!ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)) { - nautilus_ctree_expand (NAUTILUS_CTREE (view->details->tree), + eel_ctree_expand (EEL_CTREE (view->details->tree), view_node); } } else { - if (ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), + if (ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)) { - nautilus_ctree_collapse (NAUTILUS_CTREE (view->details->tree), + eel_ctree_collapse (EEL_CTREE (view->details->tree), view_node); } } @@ -582,12 +582,12 @@ notify_node_seen (NautilusTreeView *view, } static int -get_selected_row (NautilusCTree *ctree) +get_selected_row (EelCTree *ctree) { - NautilusCList *clist; - NautilusCTreeNode *node; + EelCList *clist; + EelCTreeNode *node; - clist = NAUTILUS_CLIST (ctree); + clist = EEL_CLIST (ctree); if (clist->selection == NULL) { return -1; } @@ -596,18 +596,18 @@ get_selected_row (NautilusCTree *ctree) } static int -get_selected_row_position (NautilusCTree *ctree) +get_selected_row_position (EelCTree *ctree) { - NautilusCList *clist; + EelCList *clist; int selected_row, top_row, column; - clist = NAUTILUS_CLIST (ctree); + clist = EEL_CLIST (ctree); selected_row = get_selected_row (ctree); - if (nautilus_clist_row_is_visible (clist, + if (eel_clist_row_is_visible (clist, selected_row) == GTK_VISIBILITY_NONE) { return -1; } - if (!nautilus_clist_get_selection_info (clist, 0, 0, + if (!eel_clist_get_selection_info (clist, 0, 0, &top_row, &column)) { return -1; } @@ -615,7 +615,7 @@ get_selected_row_position (NautilusCTree *ctree) } static void -set_selected_row_position (NautilusCTree *ctree, +set_selected_row_position (EelCTree *ctree, int position) { int current_position, top_row; @@ -631,7 +631,7 @@ set_selected_row_position (NautilusCTree *ctree, if (top_row < 0) { top_row = 0; } - nautilus_clist_moveto (NAUTILUS_CLIST (ctree), top_row, -1, 0, 0); + eel_clist_moveto (EEL_CLIST (ctree), top_row, -1, 0, 0); } static gboolean @@ -646,9 +646,9 @@ dequeue_pending_idle_callback (gpointer data) view = NAUTILUS_TREE_VIEW (data); done_early = FALSE; - nautilus_clist_freeze (NAUTILUS_CLIST (view->details->tree)); + eel_clist_freeze (EEL_CLIST (view->details->tree)); - position = get_selected_row_position (NAUTILUS_CTREE (view->details->tree)); + position = get_selected_row_position (EEL_CTREE (view->details->tree)); for (i = 0; i < NAUTILUS_TREE_VIEW_MAX_CHANGE_BATCH; i++) { change = nautilus_tree_change_queue_dequeue @@ -673,10 +673,10 @@ dequeue_pending_idle_callback (gpointer data) nautilus_tree_change_free (change); } - set_selected_row_position (NAUTILUS_CTREE (view->details->tree), + set_selected_row_position (EEL_CTREE (view->details->tree), position); - nautilus_clist_thaw (NAUTILUS_CLIST (view->details->tree)); + eel_clist_thaw (EEL_CLIST (view->details->tree)); if (done_early) { view->details->pending_idle_id = 0; @@ -837,7 +837,7 @@ update_smooth_graphics_mode (NautilusTreeView *view) old_aa_mode = is_anti_aliased (view); if (old_aa_mode != aa_mode) { - nautilus_list_set_anti_aliased_mode (NAUTILUS_LIST (view->details->tree), aa_mode); + eel_list_set_anti_aliased_mode (EEL_LIST (view->details->tree), aa_mode); /* FIXME: refetch icons using correct aa mode... */ } @@ -857,13 +857,13 @@ smooth_graphics_mode_changed_callback (gpointer callback_data) static gboolean is_anti_aliased (NautilusTreeView *view) { - return nautilus_list_is_anti_aliased (NAUTILUS_LIST (view->details->tree)); + return eel_list_is_anti_aliased (EEL_LIST (view->details->tree)); } static gpointer compare_cached_key, compare_cached_value; static gint -ctree_compare_rows (NautilusCList *clist, +ctree_compare_rows (EelCList *clist, gconstpointer ptr1, gconstpointer ptr2) { @@ -893,8 +893,8 @@ ctree_compare_rows (NautilusCList *clist, g_assert (view != NULL); if (!view->details->inserting_node) { - node1 = ((NautilusCTreeRow *) ptr1)->row.data; - node2 = ((NautilusCTreeRow *) ptr2)->row.data; + node1 = ((EelCTreeRow *) ptr1)->row.data; + node2 = ((EelCTreeRow *) ptr2)->row.data; file1 = node1 ? nautilus_tree_node_get_file (node1) : NULL; file2 = node2 ? nautilus_tree_node_get_file (node2) : NULL; @@ -917,14 +917,14 @@ create_tree (NautilusTreeView *view) view->details->change_queue = nautilus_tree_change_queue_new (); /* set up ctree */ - view->details->tree = nautilus_ctree_new (1, 0); + view->details->tree = eel_ctree_new (1, 0); gtk_object_set_data (GTK_OBJECT (view->details->tree), "tree_view", (gpointer) view); gtk_widget_add_events (GTK_WIDGET (view->details->tree), GDK_POINTER_MOTION_MASK); - nautilus_clist_set_selection_mode (NAUTILUS_CLIST (view->details->tree), GTK_SELECTION_SINGLE); - nautilus_clist_set_auto_sort (NAUTILUS_CLIST (view->details->tree), TRUE); - nautilus_clist_set_sort_type (NAUTILUS_CLIST (view->details->tree), GTK_SORT_ASCENDING); + eel_clist_set_selection_mode (EEL_CLIST (view->details->tree), GTK_SELECTION_SINGLE); + eel_clist_set_auto_sort (EEL_CLIST (view->details->tree), TRUE); + eel_clist_set_sort_type (EEL_CLIST (view->details->tree), GTK_SORT_ASCENDING); update_smooth_graphics_mode (view); @@ -934,17 +934,17 @@ create_tree (NautilusTreeView *view) * 1000s of files). So to fix bug 6988 we're reverting back * to using the standard clist comparison function (a strcmp) */ - nautilus_clist_set_compare_func (NAUTILUS_CLIST (view->details->tree), + eel_clist_set_compare_func (EEL_CLIST (view->details->tree), ctree_compare_rows); - nautilus_clist_set_column_auto_resize (NAUTILUS_CLIST (view->details->tree), 0, TRUE); - nautilus_clist_columns_autosize (NAUTILUS_CLIST (view->details->tree)); - nautilus_clist_set_reorderable (NAUTILUS_CLIST (view->details->tree), FALSE); - nautilus_clist_set_row_height (NAUTILUS_CLIST (view->details->tree), + eel_clist_set_column_auto_resize (EEL_CLIST (view->details->tree), 0, TRUE); + eel_clist_columns_autosize (EEL_CLIST (view->details->tree)); + eel_clist_set_reorderable (EEL_CLIST (view->details->tree), FALSE); + eel_clist_set_row_height (EEL_CLIST (view->details->tree), MAX (NAUTILUS_ICON_SIZE_FOR_MENUS, view->details->tree->style->font->ascent + view->details->tree->style->font->descent)); - nautilus_ctree_set_indent (NAUTILUS_CTREE (view->details->tree), 12); + eel_ctree_set_indent (EEL_CTREE (view->details->tree), 12); gtk_signal_connect (GTK_OBJECT (view->details->tree), "tree_expand", @@ -1160,7 +1160,7 @@ nautilus_tree_view_destroy (GtkObject *object) EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); } -static NautilusCTreeNode * +static EelCTreeNode * file_to_view_node (NautilusTreeView *view, NautilusFile *file) { @@ -1168,11 +1168,11 @@ file_to_view_node (NautilusTreeView *view, } -NautilusCTreeNode * +EelCTreeNode * nautilus_tree_view_model_node_to_view_node (NautilusTreeView *view, NautilusTreeNode *node) { - NautilusCTreeNode *view_node; + EelCTreeNode *view_node; NautilusFile *file; if (node == NULL) { @@ -1187,11 +1187,11 @@ nautilus_tree_view_model_node_to_view_node (NautilusTreeView *view, NautilusTreeNode * nautilus_tree_view_node_to_model_node (NautilusTreeView *view, - NautilusCTreeNode *node) + EelCTreeNode *node) { NautilusTreeNode *tree_node; - tree_node = (NautilusTreeNode *) nautilus_ctree_node_get_row_data (NAUTILUS_CTREE (view->details->tree), + tree_node = (NautilusTreeNode *) eel_ctree_node_get_row_data (EEL_CTREE (view->details->tree), node); return tree_node; @@ -1199,7 +1199,7 @@ nautilus_tree_view_node_to_model_node (NautilusTreeView *view, NautilusFile * nautilus_tree_view_node_to_file (NautilusTreeView *view, - NautilusCTreeNode *node) + EelCTreeNode *node) { NautilusTreeNode *tree_node; @@ -1274,8 +1274,8 @@ expand_uri_sequence_and_select_end (NautilusTreeView *view) const char *uri; GList *p; GList *old_sequence; - NautilusCTreeNode *view_node; - NautilusCTreeNode *last_valid_view_node; + EelCTreeNode *view_node; + EelCTreeNode *last_valid_view_node; NautilusFile *file; NautilusTreeNode *node; @@ -1308,14 +1308,14 @@ expand_uri_sequence_and_select_end (NautilusTreeView *view) * don't want. */ - if (!ctree_is_node_expanded (NAUTILUS_CTREE (view->details->tree), view_node)) { - nautilus_ctree_expand (NAUTILUS_CTREE (view->details->tree), + if (!ctree_is_node_expanded (EEL_CTREE (view->details->tree), view_node)) { + eel_ctree_expand (EEL_CTREE (view->details->tree), view_node); } } else { g_free (view->details->selected_uri); view->details->selected_uri = g_strdup (uri); - nautilus_ctree_select (NAUTILUS_CTREE (view->details->tree), + eel_ctree_select (EEL_CTREE (view->details->tree), view_node); } } @@ -1473,8 +1473,8 @@ expand_node_for_file (NautilusTreeView *view, } static void -tree_expand_callback (NautilusCTree *ctree, - NautilusCTreeNode *node, +tree_expand_callback (EelCTree *ctree, + EelCTreeNode *node, NautilusTreeView *view) { NautilusFile *file; @@ -1487,8 +1487,8 @@ tree_expand_callback (NautilusCTree *ctree, static void -tree_collapse_callback (NautilusCTree *ctree, - NautilusCTreeNode *node, +tree_collapse_callback (EelCTree *ctree, + EelCTreeNode *node, NautilusTreeView *view) { char *uri; @@ -1504,13 +1504,13 @@ tree_collapse_callback (NautilusCTree *ctree, } static void -ctree_show_node (NautilusCTree *tree, - NautilusCTreeNode *node) +ctree_show_node (EelCTree *tree, + EelCTreeNode *node) { - if (nautilus_ctree_node_is_visible (tree, node) != GTK_VISIBILITY_FULL) { - nautilus_ctree_node_moveto (tree, node, 0, 0.5, 0); - if (nautilus_ctree_node_is_visible (tree, node) != GTK_VISIBILITY_FULL) { - nautilus_ctree_node_moveto (tree, node, 0, 0.5, 0.5); + if (eel_ctree_node_is_visible (tree, node) != GTK_VISIBILITY_FULL) { + eel_ctree_node_moveto (tree, node, 0, 0.5, 0); + if (eel_ctree_node_is_visible (tree, node) != GTK_VISIBILITY_FULL) { + eel_ctree_node_moveto (tree, node, 0, 0.5, 0.5); } } } @@ -1536,7 +1536,7 @@ got_activation_uri_callback (NautilusFile *file, view->details->selected_uri = g_strdup (uri); } - ctree_show_node (NAUTILUS_CTREE (view->details->tree), + ctree_show_node (EEL_CTREE (view->details->tree), file_to_view_node (view, file)); g_free (uri); @@ -1561,8 +1561,8 @@ cancel_possible_activation (NautilusTreeView *view) } static void -tree_select_row_callback (NautilusCTree *tree, - NautilusCTreeNode *node, +tree_select_row_callback (EelCTree *tree, + EelCTreeNode *node, gint column, NautilusTreeView *view) { @@ -1583,18 +1583,18 @@ tree_select_row_callback (NautilusCTree *tree, } -static NautilusCTreeNode * -ctree_get_first_selected_node (NautilusCTree *tree) +static EelCTreeNode * +ctree_get_first_selected_node (EelCTree *tree) { - if (NAUTILUS_CLIST (tree)->selection == NULL) { + if (EEL_CLIST (tree)->selection == NULL) { return NULL; } - return NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (tree)->selection->data); + return EEL_CTREE_NODE (EEL_CLIST (tree)->selection->data); } static void -size_allocate_callback (NautilusCTree *tree, +size_allocate_callback (EelCTree *tree, GtkAllocation *allocation, gpointer data) { diff --git a/configure.in b/configure.in index 7624b591d..ffc1ba847 100644 --- a/configure.in +++ b/configure.in @@ -1041,7 +1041,6 @@ data/linksets/Makefile cut-n-paste-code/Makefile cut-n-paste-code/widgets/Makefile cut-n-paste-code/widgets/e-paned/Makefile -cut-n-paste-code/widgets/nautilusclist/Makefile cut-n-paste-code/widgets/gimphwrapbox/Makefile libnautilus/Makefile libnautilus-adapter/Makefile diff --git a/cut-n-paste-code/widgets/Makefile.am b/cut-n-paste-code/widgets/Makefile.am index b97e9437b..46f787a7b 100644 --- a/cut-n-paste-code/widgets/Makefile.am +++ b/cut-n-paste-code/widgets/Makefile.am @@ -1,7 +1,6 @@ NULL= SUBDIRS =\ - nautilusclist \ e-paned \ gimphwrapbox \ $(NULL) diff --git a/cut-n-paste-code/widgets/nautilusclist/.cvsignore b/cut-n-paste-code/widgets/nautilusclist/.cvsignore deleted file mode 100644 index 799fc9785..000000000 --- a/cut-n-paste-code/widgets/nautilusclist/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -*.lo -*.la -Makefile -Makefile.in diff --git a/cut-n-paste-code/widgets/nautilusclist/Makefile.am b/cut-n-paste-code/widgets/nautilusclist/Makefile.am deleted file mode 100644 index 28cbd4d32..000000000 --- a/cut-n-paste-code/widgets/nautilusclist/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -NULL= - -noinst_LTLIBRARIES = libnautilusclist.la - -INCLUDES = \ - -I$(top_srcdir)/cut-n-paste-code \ - $(GNOMEUI_CFLAGS) \ - $(NULL) - -libnautilusclist_la_LDFLAGS = -static - -libnautilusclist_la_SOURCES = \ - nautilusclist.c \ - $(NULL) - -noinst_HEADERS =\ - nautilusclist.h \ - $(NULL) diff --git a/cut-n-paste-code/widgets/nautilusclist/nautilusclist.c b/cut-n-paste-code/widgets/nautilusclist/nautilusclist.c deleted file mode 100644 index 696b3c413..000000000 --- a/cut-n-paste-code/widgets/nautilusclist/nautilusclist.c +++ /dev/null @@ -1,7609 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald, - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include <stdlib.h> -#include <string.h> -#include "config.h" -#include <gtk/gtkmain.h> -#include <nautilusclist.h> -#include <gtk/gtkbindings.h> -#include <gtk/gtkdnd.h> -#include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> - -/* length of button_actions array */ -#define MAX_BUTTON 5 - -/* the number rows memchunk expands at a time */ -#define CLIST_OPTIMUM_SIZE 64 - -/* the width of the column resize windows */ -#define DRAG_WIDTH 6 - -/* minimum allowed width of a column */ -#define COLUMN_MIN_WIDTH 5 - -/* this defigns the base grid spacing */ -#define CELL_SPACING 1 - -/* added the horizontal space at the beginning and end of a row*/ -#define COLUMN_INSET 3 - -/* used for auto-scrolling */ -#define SCROLL_TIME 100 - -/* gives the top pixel of the given row in context of - * the clist's voffset */ -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) - -/* returns the row index from a y pixel location in the - * context of the clist's voffset */ -#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ - ((clist)->row_height + CELL_SPACING)) - -/* gives the left pixel of the given column in context of - * the clist's hoffset */ -#define COLUMN_LEFT_XPIXEL(clist, colnum) ((clist)->column[(colnum)].area.x + \ - (clist)->hoffset) - -/* returns the column index from a x pixel location in the - * context of the clist's hoffset */ -static inline gint -COLUMN_FROM_XPIXEL (NautilusCList * clist, gint x) -{ - gint i, cx; - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].visible) - { - cx = clist->column[i].area.x + clist->hoffset; - - if (x >= (cx - (COLUMN_INSET + CELL_SPACING)) && - x <= (cx + clist->column[i].area.width + COLUMN_INSET)) - return i; - } - - /* no match */ - return -1; -} - -/* returns the top pixel of the given row in the context of - * the list height */ -#define ROW_TOP(clist, row) (((clist)->row_height + CELL_SPACING) * (row)) - -/* returns the left pixel of the given column in the context of - * the list width */ -#define COLUMN_LEFT(clist, colnum) ((clist)->column[(colnum)].area.x) - -/* returns the total height of the list */ -#define LIST_HEIGHT(clist) (((clist)->row_height * ((clist)->rows)) + \ - (CELL_SPACING * ((clist)->rows + 1))) - - -/* returns the total width of the list */ -static inline gint -LIST_WIDTH (NautilusCList * clist) -{ - gint last_column; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--); - - if (last_column >= 0) - return (clist->column[last_column].area.x + - clist->column[last_column].area.width + - COLUMN_INSET + CELL_SPACING); - return 0; -} - -/* returns the GList item for the nth row */ -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - - -#define NAUTILUS_CLIST_CLASS_FW(_widget_) NAUTILUS_CLIST_CLASS (((GtkObject*) (_widget_))->klass) - -/* redraw the list if it's not frozen */ -#define CLIST_UNFROZEN(clist) nautilus_clist_check_unfrozen (clist) -#define CLIST_REFRESH(clist) G_STMT_START { \ - if (CLIST_UNFROZEN (clist)) \ - NAUTILUS_CLIST_CLASS_FW (clist)->refresh ((NautilusCList *) (clist)); \ -} G_STMT_END - - -/* Signals */ -enum { - SELECT_ROW, - UNSELECT_ROW, - ROW_MOVE, - CLICK_COLUMN, - RESIZE_COLUMN, - TOGGLE_FOCUS_ROW, - SELECT_ALL, - UNSELECT_ALL, - UNDO_SELECTION, - START_SELECTION, - END_SELECTION, - TOGGLE_ADD_MODE, - EXTEND_SELECTION, - SCROLL_VERTICAL, - SCROLL_HORIZONTAL, - ABORT_COLUMN_RESIZE, - LAST_SIGNAL -}; - -enum { - SYNC_REMOVE, - SYNC_INSERT -}; - -enum { - ARG_0, - ARG_N_COLUMNS, - ARG_SHADOW_TYPE, - ARG_SELECTION_MODE, - ARG_ROW_HEIGHT, - ARG_TITLES_ACTIVE, - ARG_REORDERABLE, - ARG_USE_DRAG_ICONS, - ARG_SORT_TYPE -}; - -/* NautilusCList Methods */ -static void nautilus_clist_class_init (NautilusCListClass *klass); -static void nautilus_clist_init (NautilusCList *clist); - -/* GtkObject Methods */ -static void nautilus_clist_destroy (GtkObject *object); -static void nautilus_clist_finalize (GtkObject *object); -static void nautilus_clist_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_clist_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - -/* GtkWidget Methods */ -static void nautilus_clist_set_scroll_adjustments (NautilusCList *clist, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment); -static void nautilus_clist_realize (GtkWidget *widget); -static void nautilus_clist_unrealize (GtkWidget *widget); -static void nautilus_clist_map (GtkWidget *widget); -static void nautilus_clist_unmap (GtkWidget *widget); -static void nautilus_clist_draw (GtkWidget *widget, - GdkRectangle *area); -static gint nautilus_clist_expose (GtkWidget *widget, - GdkEventExpose *event); -static gint nautilus_clist_key_press (GtkWidget *widget, - GdkEventKey *event); -static gint nautilus_clist_button_press (GtkWidget *widget, - GdkEventButton *event); -static gint nautilus_clist_button_release (GtkWidget *widget, - GdkEventButton *event); -static gint nautilus_clist_motion (GtkWidget *widget, - GdkEventMotion *event); -static void nautilus_clist_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void nautilus_clist_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void nautilus_clist_draw_focus (GtkWidget *widget); -static gint nautilus_clist_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint nautilus_clist_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static gint nautilus_clist_focus (GtkContainer *container, - GtkDirectionType direction); -static void nautilus_clist_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void nautilus_clist_drag_begin (GtkWidget *widget, - GdkDragContext *context); -static gint nautilus_clist_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void nautilus_clist_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static void nautilus_clist_drag_end (GtkWidget *widget, - GdkDragContext *context); -static gboolean nautilus_clist_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void nautilus_clist_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time); -static void nautilus_clist_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time); - -/* GtkContainer Methods */ -static void nautilus_clist_set_focus_child (GtkContainer *container, - GtkWidget *child); -static void nautilus_clist_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); - -/* Selection */ -static void toggle_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void update_extended_selection (NautilusCList *clist, - gint row); -static GList *selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element); -static void real_select_all (NautilusCList *clist); -static void real_unselect_all (NautilusCList *clist); -static void real_undo_selection (NautilusCList *clist); -static void fake_unselect_all (NautilusCList *clist, - gint row); -static void fake_toggle_row (NautilusCList *clist, - gint row); -static void resync_selection (NautilusCList *clist, - GdkEvent *event); -static void sync_selection (NautilusCList *clist, - gint row, - gint mode); -static void set_anchor (NautilusCList *clist, - gboolean add_mode, - gint anchor, - gint undo_anchor); -static void start_selection (NautilusCList *clist); -static void end_selection (NautilusCList *clist); -static void toggle_add_mode (NautilusCList *clist); -static void toggle_focus_row (NautilusCList *clist); -static void extend_selection (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection); -static gint get_selection_info (NautilusCList *clist, - gint x, - gint y, - gint *row, - gint *column); - -/* Scrolling */ -static void move_focus_row (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position); -static void scroll_horizontal (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position); -static void scroll_vertical (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position); -static void move_horizontal (NautilusCList *clist, - gint diff); -static void move_vertical (NautilusCList *clist, - gint row, - gfloat align); -static gint horizontal_timeout (NautilusCList *clist); -static gint vertical_timeout (NautilusCList *clist); -static void remove_grab (NautilusCList *clist); - - -/* Resize Columns */ -static void draw_xor_line (NautilusCList *clist); -static gint new_column_width (NautilusCList *clist, - gint column, - gint *x); -static void column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width); -static void real_resize_column (NautilusCList *clist, - gint column, - gint width); -static void abort_column_resize (NautilusCList *clist); -static void cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition); - -/* Buttons */ -static void column_button_create (NautilusCList *clist, - gint column); -static void column_button_clicked (GtkWidget *widget, - gpointer data); - -/* Adjustments */ -static void adjust_adjustments (NautilusCList *clist, - gboolean block_resize); -static void check_exposures (NautilusCList *clist); -static void vadjustment_changed (GtkAdjustment *adjustment, - gpointer data); -static void vadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data); -static void hadjustment_changed (GtkAdjustment *adjustment, - gpointer data); -static void hadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data); - -/* Drawing */ -static void get_cell_style (NautilusCList *clist, - NautilusCListRow *clist_row, - gint state, - gint column, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc); -static void draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row); -static void draw_rows (NautilusCList *clist, - GdkRectangle *area); -static void draw_all (NautilusCList *clist); -static void clist_refresh (NautilusCList *clist); -static void draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos); - -/* Size Allocation / Requisition */ -static void size_allocate_title_buttons (NautilusCList *clist); -static void size_allocate_columns (NautilusCList *clist, - gboolean block_resize); -static gint list_requisition_width (NautilusCList *clist); - -/* Memory Allocation/Distruction Routines */ -static NautilusCListColumn *columns_new (NautilusCList *clist); -static void column_title_new (NautilusCList *clist, - gint column, - const gchar *title); -static void columns_delete (NautilusCList *clist); -static NautilusCListRow *row_new (NautilusCList *clist); -static void row_delete (NautilusCList *clist, - NautilusCListRow *clist_row); -static gboolean set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -static gint real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]); -static void real_remove_row (NautilusCList *clist, - gint row); -static void real_clear (NautilusCList *clist); - -/* Sorting */ -static gint default_compare (NautilusCList *clist, - gconstpointer row1, - gconstpointer row2); -static void real_sort_list (NautilusCList *clist); -static GList *nautilus_clist_merge (NautilusCList *clist, - GList *a, - GList *b); -static GList *nautilus_clist_mergesort (NautilusCList *clist, - GList *list, - gint num); -/* Misc */ -static gboolean title_focus (NautilusCList *clist, - gint dir); -static void real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row); -static gint column_title_passive_func (GtkWidget *widget, - GdkEvent *event, - gpointer data); -static void drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info); - - - -static GtkContainerClass *parent_class = NULL; -static guint clist_signals[LAST_SIGNAL] = {0}; - -static GtkTargetEntry clist_target_table = { "gtk-clist-drag-reorder", 0, 0}; - -GtkType -nautilus_clist_get_type (void) -{ - static GtkType clist_type = 0; - - if (!clist_type) - { - static const GtkTypeInfo clist_info = - { - "NautilusCList", - sizeof (NautilusCList), - sizeof (NautilusCListClass), - (GtkClassInitFunc) nautilus_clist_class_init, - (GtkObjectInitFunc) nautilus_clist_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - clist_type = gtk_type_unique (GTK_TYPE_CONTAINER, &clist_info); - } - - return clist_type; -} - -static void -nautilus_clist_class_init (NautilusCListClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - GtkBindingSet *binding_set; - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - container_class = (GtkContainerClass *) klass; - - parent_class = gtk_type_class (GTK_TYPE_CONTAINER); - - gtk_object_add_arg_type ("NautilusCList::n_columns", - GTK_TYPE_UINT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_N_COLUMNS); - gtk_object_add_arg_type ("NautilusCList::shadow_type", - GTK_TYPE_SHADOW_TYPE, - GTK_ARG_READWRITE, - ARG_SHADOW_TYPE); - gtk_object_add_arg_type ("NautilusCList::selection_mode", - GTK_TYPE_SELECTION_MODE, - GTK_ARG_READWRITE, - ARG_SELECTION_MODE); - gtk_object_add_arg_type ("NautilusCList::row_height", - GTK_TYPE_UINT, - GTK_ARG_READWRITE, - ARG_ROW_HEIGHT); - gtk_object_add_arg_type ("NautilusCList::reorderable", - GTK_TYPE_BOOL, - GTK_ARG_READWRITE, - ARG_REORDERABLE); - gtk_object_add_arg_type ("NautilusCList::titles_active", - GTK_TYPE_BOOL, - GTK_ARG_READWRITE, - ARG_TITLES_ACTIVE); - gtk_object_add_arg_type ("NautilusCList::use_drag_icons", - GTK_TYPE_BOOL, - GTK_ARG_READWRITE, - ARG_USE_DRAG_ICONS); - gtk_object_add_arg_type ("NautilusCList::sort_type", - GTK_TYPE_SORT_TYPE, - GTK_ARG_READWRITE, - ARG_SORT_TYPE); - object_class->set_arg = nautilus_clist_set_arg; - object_class->get_arg = nautilus_clist_get_arg; - object_class->destroy = nautilus_clist_destroy; - object_class->finalize = nautilus_clist_finalize; - - - widget_class->set_scroll_adjustments_signal = - gtk_signal_new ("set_scroll_adjustments", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, set_scroll_adjustments), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT); - - clist_signals[SELECT_ROW] = - gtk_signal_new ("select_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, select_row), - gtk_marshal_NONE__INT_INT_POINTER, - GTK_TYPE_NONE, 3, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_GDK_EVENT); - clist_signals[UNSELECT_ROW] = - gtk_signal_new ("unselect_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, unselect_row), - gtk_marshal_NONE__INT_INT_POINTER, - GTK_TYPE_NONE, 3, GTK_TYPE_INT, - GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); - clist_signals[ROW_MOVE] = - gtk_signal_new ("row_move", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, row_move), - gtk_marshal_NONE__INT_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); - clist_signals[CLICK_COLUMN] = - gtk_signal_new ("click_column", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, click_column), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, GTK_TYPE_INT); - clist_signals[RESIZE_COLUMN] = - gtk_signal_new ("resize_column", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, resize_column), - gtk_marshal_NONE__INT_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); - - clist_signals[TOGGLE_FOCUS_ROW] = - gtk_signal_new ("toggle_focus_row", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, toggle_focus_row), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[SELECT_ALL] = - gtk_signal_new ("select_all", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, select_all), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[UNSELECT_ALL] = - gtk_signal_new ("unselect_all", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, unselect_all), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[UNDO_SELECTION] = - gtk_signal_new ("undo_selection", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, undo_selection), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[START_SELECTION] = - gtk_signal_new ("start_selection", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, start_selection), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[END_SELECTION] = - gtk_signal_new ("end_selection", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, end_selection), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[TOGGLE_ADD_MODE] = - gtk_signal_new ("toggle_add_mode", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, toggle_add_mode), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - clist_signals[EXTEND_SELECTION] = - gtk_signal_new ("extend_selection", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, extend_selection), - gtk_marshal_NONE__ENUM_FLOAT_BOOL, - GTK_TYPE_NONE, 3, - GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT, GTK_TYPE_BOOL); - clist_signals[SCROLL_VERTICAL] = - gtk_signal_new ("scroll_vertical", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, scroll_vertical), - gtk_marshal_NONE__ENUM_FLOAT, - GTK_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT); - clist_signals[SCROLL_HORIZONTAL] = - gtk_signal_new ("scroll_horizontal", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, scroll_horizontal), - gtk_marshal_NONE__ENUM_FLOAT, - GTK_TYPE_NONE, 2, GTK_TYPE_SCROLL_TYPE, GTK_TYPE_FLOAT); - clist_signals[ABORT_COLUMN_RESIZE] = - gtk_signal_new ("abort_column_resize", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCListClass, abort_column_resize), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - gtk_object_class_add_signals (object_class, clist_signals, LAST_SIGNAL); - - widget_class->realize = nautilus_clist_realize; - widget_class->unrealize = nautilus_clist_unrealize; - widget_class->map = nautilus_clist_map; - widget_class->unmap = nautilus_clist_unmap; - widget_class->draw = nautilus_clist_draw; - widget_class->button_press_event = nautilus_clist_button_press; - widget_class->button_release_event = nautilus_clist_button_release; - widget_class->motion_notify_event = nautilus_clist_motion; - widget_class->expose_event = nautilus_clist_expose; - widget_class->size_request = nautilus_clist_size_request; - widget_class->size_allocate = nautilus_clist_size_allocate; - widget_class->key_press_event = nautilus_clist_key_press; - widget_class->focus_in_event = nautilus_clist_focus_in; - widget_class->focus_out_event = nautilus_clist_focus_out; - widget_class->draw_focus = nautilus_clist_draw_focus; - widget_class->style_set = nautilus_clist_style_set; - widget_class->drag_begin = nautilus_clist_drag_begin; - widget_class->drag_end = nautilus_clist_drag_end; - widget_class->drag_motion = nautilus_clist_drag_motion; - widget_class->drag_leave = nautilus_clist_drag_leave; - widget_class->drag_drop = nautilus_clist_drag_drop; - widget_class->drag_data_get = nautilus_clist_drag_data_get; - widget_class->drag_data_received = nautilus_clist_drag_data_received; - - /* container_class->add = NULL; use the default GtkContainerClass warning */ - /* container_class->remove=NULL; use the default GtkContainerClass warning */ - - container_class->forall = nautilus_clist_forall; - container_class->focus = nautilus_clist_focus; - container_class->set_focus_child = nautilus_clist_set_focus_child; - - klass->set_scroll_adjustments = nautilus_clist_set_scroll_adjustments; - klass->refresh = clist_refresh; - klass->select_row = real_select_row; - klass->unselect_row = real_unselect_row; - klass->row_move = real_row_move; - klass->undo_selection = real_undo_selection; - klass->resync_selection = resync_selection; - klass->selection_find = selection_find; - klass->click_column = NULL; - klass->resize_column = real_resize_column; - klass->draw_rows = draw_rows; - klass->draw_row = draw_row; - klass->draw_all = draw_all; - klass->draw_drag_highlight = draw_drag_highlight; - klass->insert_row = real_insert_row; - klass->remove_row = real_remove_row; - klass->clear = real_clear; - klass->sort_list = real_sort_list; - klass->select_all = real_select_all; - klass->unselect_all = real_unselect_all; - klass->fake_unselect_all = fake_unselect_all; - klass->scroll_horizontal = scroll_horizontal; - klass->scroll_vertical = scroll_vertical; - klass->extend_selection = extend_selection; - klass->toggle_focus_row = toggle_focus_row; - klass->toggle_add_mode = toggle_add_mode; - klass->start_selection = start_selection; - klass->end_selection = end_selection; - klass->abort_column_resize = abort_column_resize; - klass->set_cell_contents = set_cell_contents; - klass->cell_size_request = cell_size_request; - - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, GDK_Up, 0, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Down, 0, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK, - "scroll_vertical", 2, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 1.0); - - gtk_binding_entry_add_signal (binding_set, GDK_Up, GDK_SHIFT_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD, - GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_Down, GDK_SHIFT_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD, - GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_SHIFT_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD, - GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_SHIFT_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD, - GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_Home, - GDK_SHIFT_MASK | GDK_CONTROL_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE); - gtk_binding_entry_add_signal (binding_set, GDK_End, - GDK_SHIFT_MASK | GDK_CONTROL_MASK, - "extend_selection", 3, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE); - - gtk_binding_entry_add_signal (binding_set, GDK_Left, 0, - "scroll_horizontal", 2, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Right, 0, - "scroll_horizontal", 2, - GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_Home, 0, - "scroll_horizontal", 2, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 0.0); - gtk_binding_entry_add_signal (binding_set, GDK_End, 0, - "scroll_horizontal", 2, - GTK_TYPE_ENUM, GTK_SCROLL_JUMP, - GTK_TYPE_FLOAT, 1.0); - - gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, - "undo_selection", 0); - gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, - "abort_column_resize", 0); - gtk_binding_entry_add_signal (binding_set, GDK_space, 0, - "toggle_focus_row", 0); - gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK, - "toggle_add_mode", 0); - gtk_binding_entry_add_signal (binding_set, '/', GDK_CONTROL_MASK, - "select_all", 0); - gtk_binding_entry_add_signal (binding_set, '\\', GDK_CONTROL_MASK, - "unselect_all", 0); - gtk_binding_entry_add_signal (binding_set, GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK, - "end_selection", 0); - gtk_binding_entry_add_signal (binding_set, GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK, - "end_selection", 0); - gtk_binding_entry_add_signal (binding_set, GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | - GDK_CONTROL_MASK, - "end_selection", 0); - gtk_binding_entry_add_signal (binding_set, GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | - GDK_CONTROL_MASK, - "end_selection", 0); -} - -static void -nautilus_clist_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCList *clist; - - clist = NAUTILUS_CLIST (object); - - switch (arg_id) - { - case ARG_N_COLUMNS: /* construct-only arg, only set when !GTK_CONSTRUCTED */ - nautilus_clist_construct (clist, MAX (1, GTK_VALUE_UINT (*arg)), NULL); - break; - case ARG_SHADOW_TYPE: - nautilus_clist_set_shadow_type (clist, GTK_VALUE_ENUM (*arg)); - break; - case ARG_SELECTION_MODE: - nautilus_clist_set_selection_mode (clist, GTK_VALUE_ENUM (*arg)); - break; - case ARG_ROW_HEIGHT: - nautilus_clist_set_row_height (clist, GTK_VALUE_UINT (*arg)); - break; - case ARG_REORDERABLE: - nautilus_clist_set_reorderable (clist, GTK_VALUE_BOOL (*arg)); - break; - case ARG_TITLES_ACTIVE: - if (GTK_VALUE_BOOL (*arg)) - nautilus_clist_column_titles_active (clist); - else - nautilus_clist_column_titles_passive (clist); - break; - case ARG_USE_DRAG_ICONS: - nautilus_clist_set_use_drag_icons (clist, GTK_VALUE_BOOL (*arg)); - break; - case ARG_SORT_TYPE: - nautilus_clist_set_sort_type (clist, GTK_VALUE_ENUM (*arg)); - break; - } -} - -static void -nautilus_clist_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCList *clist; - - clist = NAUTILUS_CLIST (object); - - switch (arg_id) - { - int i; - - case ARG_N_COLUMNS: - GTK_VALUE_UINT (*arg) = clist->columns; - break; - case ARG_SHADOW_TYPE: - GTK_VALUE_ENUM (*arg) = clist->shadow_type; - break; - case ARG_SELECTION_MODE: - GTK_VALUE_ENUM (*arg) = clist->selection_mode; - break; - case ARG_ROW_HEIGHT: - GTK_VALUE_UINT (*arg) = NAUTILUS_CLIST_ROW_HEIGHT_SET(clist) ? clist->row_height : 0; - break; - case ARG_REORDERABLE: - GTK_VALUE_BOOL (*arg) = NAUTILUS_CLIST_REORDERABLE (clist); - break; - case ARG_TITLES_ACTIVE: - GTK_VALUE_BOOL (*arg) = TRUE; - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button && - !GTK_WIDGET_SENSITIVE (clist->column[i].button)) - { - GTK_VALUE_BOOL (*arg) = FALSE; - break; - } - break; - case ARG_USE_DRAG_ICONS: - GTK_VALUE_BOOL (*arg) = NAUTILUS_CLIST_USE_DRAG_ICONS (clist); - break; - case ARG_SORT_TYPE: - GTK_VALUE_ENUM (*arg) = clist->sort_type; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static void -nautilus_clist_init (NautilusCList *clist) -{ - clist->flags = 0; - - GTK_WIDGET_UNSET_FLAGS (clist, GTK_NO_WINDOW); - GTK_WIDGET_SET_FLAGS (clist, GTK_CAN_FOCUS); - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS); - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_DRAW_DRAG_LINE); - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS); - - clist->row_mem_chunk = NULL; - clist->cell_mem_chunk = NULL; - - clist->freeze_count = 0; - - clist->rows = 0; - clist->row_center_offset = 0; - clist->row_height = 0; - clist->row_list = NULL; - clist->row_list_end = NULL; - - clist->columns = 0; - - clist->title_window = NULL; - clist->column_title_area.x = 0; - clist->column_title_area.y = 0; - clist->column_title_area.width = 1; - clist->column_title_area.height = 1; - - clist->clist_window = NULL; - clist->clist_window_width = 1; - clist->clist_window_height = 1; - - clist->hoffset = 0; - clist->voffset = 0; - - clist->shadow_type = GTK_SHADOW_IN; - clist->vadjustment = NULL; - clist->hadjustment = NULL; - - clist->button_actions[0] = NAUTILUS_BUTTON_SELECTS | NAUTILUS_BUTTON_DRAGS; - clist->button_actions[1] = NAUTILUS_BUTTON_IGNORED; - clist->button_actions[2] = NAUTILUS_BUTTON_IGNORED; - clist->button_actions[3] = NAUTILUS_BUTTON_IGNORED; - clist->button_actions[4] = NAUTILUS_BUTTON_IGNORED; - - clist->cursor_drag = NULL; - clist->xor_gc = NULL; - clist->fg_gc = NULL; - clist->bg_gc = NULL; - clist->x_drag = 0; - - clist->selection_mode = GTK_SELECTION_SINGLE; - clist->selection = NULL; - clist->selection_end = NULL; - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->focus_row = -1; - clist->undo_anchor = -1; - - clist->anchor = -1; - clist->anchor_state = GTK_STATE_SELECTED; - clist->drag_pos = -1; - clist->htimer = 0; - clist->vtimer = 0; - - clist->click_cell.row = -1; - clist->click_cell.column = -1; - - clist->compare = default_compare; - clist->sort_type = GTK_SORT_ASCENDING; - clist->sort_column = 0; -} - -/* Constructors */ -void -nautilus_clist_construct (NautilusCList *clist, - gint columns, - gchar *titles[]) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - g_return_if_fail (columns > 0); - g_return_if_fail (GTK_OBJECT_CONSTRUCTED (clist) == FALSE); - - /* mark the object as constructed */ - gtk_object_constructed (GTK_OBJECT (clist)); - - /* initalize memory chunks, if this has not been done by any - * possibly derived widget - */ - if (!clist->row_mem_chunk) - clist->row_mem_chunk = g_mem_chunk_new ("clist row mem chunk", - sizeof (NautilusCListRow), - sizeof (NautilusCListRow) * - CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - if (!clist->cell_mem_chunk) - clist->cell_mem_chunk = g_mem_chunk_new ("clist cell mem chunk", - sizeof (NautilusCell) * columns, - sizeof (NautilusCell) * columns * - CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - /* set number of columns, allocate memory */ - clist->columns = columns; - clist->column = columns_new (clist); - - /* there needs to be at least one column button - * because there is alot of code that will break if it - * isn't there*/ - column_button_create (clist, 0); - - if (titles) - { - int i; - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES); - for (i = 0; i < columns; i++) - nautilus_clist_set_column_title (clist, i, titles[i]); - } - else - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_SHOW_TITLES); - } -} - -/* NAUTILUSLIST PUBLIC INTERFACE - * nautilus_clist_new - * nautilus_clist_new_with_titles - * nautilus_clist_set_hadjustment - * nautilus_clist_set_vadjustment - * nautilus_clist_get_hadjustment - * nautilus_clist_get_vadjustment - * nautilus_clist_set_shadow_type - * nautilus_clist_set_selection_mode - * nautilus_clist_freeze - * nautilus_clist_thaw - */ -GtkWidget* -nautilus_clist_new (gint columns) -{ - return nautilus_clist_new_with_titles (columns, NULL); -} - -GtkWidget* -nautilus_clist_new_with_titles (gint columns, - gchar *titles[]) -{ - GtkWidget *widget; - - widget = gtk_type_new (NAUTILUS_TYPE_CLIST); - nautilus_clist_construct (NAUTILUS_CLIST (widget), columns, titles); - - return widget; -} - -void -nautilus_clist_set_hadjustment (NautilusCList *clist, - GtkAdjustment *adjustment) -{ - GtkAdjustment *old_adjustment; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - if (adjustment) - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (clist->hadjustment == adjustment) - return; - - old_adjustment = clist->hadjustment; - - if (clist->hadjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (clist->hadjustment), clist); - gtk_object_unref (GTK_OBJECT (clist->hadjustment)); - } - - clist->hadjustment = adjustment; - - if (clist->hadjustment) - { - gtk_object_ref (GTK_OBJECT (clist->hadjustment)); - gtk_object_sink (GTK_OBJECT (clist->hadjustment)); - - gtk_signal_connect (GTK_OBJECT (clist->hadjustment), "changed", - (GtkSignalFunc) hadjustment_changed, - (gpointer) clist); - gtk_signal_connect (GTK_OBJECT (clist->hadjustment), "value_changed", - (GtkSignalFunc) hadjustment_value_changed, - (gpointer) clist); - } - - if (!clist->hadjustment || !old_adjustment) - gtk_widget_queue_resize (GTK_WIDGET (clist)); -} - -GtkAdjustment * -nautilus_clist_get_hadjustment (NautilusCList *clist) -{ - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - return clist->hadjustment; -} - -void -nautilus_clist_set_vadjustment (NautilusCList *clist, - GtkAdjustment *adjustment) -{ - GtkAdjustment *old_adjustment; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - if (adjustment) - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - - if (clist->vadjustment == adjustment) - return; - - old_adjustment = clist->vadjustment; - - if (clist->vadjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (clist->vadjustment), clist); - gtk_object_unref (GTK_OBJECT (clist->vadjustment)); - } - - clist->vadjustment = adjustment; - - if (clist->vadjustment) - { - gtk_object_ref (GTK_OBJECT (clist->vadjustment)); - gtk_object_sink (GTK_OBJECT (clist->vadjustment)); - - gtk_signal_connect (GTK_OBJECT (clist->vadjustment), "changed", - (GtkSignalFunc) vadjustment_changed, - (gpointer) clist); - gtk_signal_connect (GTK_OBJECT (clist->vadjustment), "value_changed", - (GtkSignalFunc) vadjustment_value_changed, - (gpointer) clist); - } - - if (!clist->vadjustment || !old_adjustment) - gtk_widget_queue_resize (GTK_WIDGET (clist)); -} - -GtkAdjustment * -nautilus_clist_get_vadjustment (NautilusCList *clist) -{ - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - return clist->vadjustment; -} - -static void -nautilus_clist_set_scroll_adjustments (NautilusCList *clist, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment) -{ - if (clist->hadjustment != hadjustment) - nautilus_clist_set_hadjustment (clist, hadjustment); - if (clist->vadjustment != vadjustment) - nautilus_clist_set_vadjustment (clist, vadjustment); -} - -void -nautilus_clist_set_shadow_type (NautilusCList *clist, - GtkShadowType type) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - clist->shadow_type = type; - - if (GTK_WIDGET_VISIBLE (clist)) - gtk_widget_queue_resize (GTK_WIDGET (clist)); -} - -void -nautilus_clist_set_selection_mode (NautilusCList *clist, - GtkSelectionMode mode) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (mode == clist->selection_mode) - return; - - clist->selection_mode = mode; - clist->anchor = -1; - clist->anchor_state = GTK_STATE_SELECTED; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - switch (mode) - { - case GTK_SELECTION_MULTIPLE: - case GTK_SELECTION_EXTENDED: - return; - case GTK_SELECTION_BROWSE: - case GTK_SELECTION_SINGLE: - nautilus_clist_unselect_all (clist); - break; - } -} - -void -nautilus_clist_freeze (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - clist->freeze_count++; -} - -void -nautilus_clist_thaw (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (clist->freeze_count) - { - clist->freeze_count--; - if (clist->freeze_count == 0) - { - if (clist->refresh_at_unfreeze_time) - NAUTILUS_CLIST_CLASS_FW (clist)->refresh (clist); - clist->refresh_at_unfreeze_time = FALSE; - } - } -} - -gboolean -nautilus_clist_check_unfrozen (NautilusCList *clist) -{ - if (clist->freeze_count == 0) - return TRUE; - - clist->refresh_at_unfreeze_time = TRUE; - return FALSE; -} - -/* PUBLIC COLUMN FUNCTIONS - * nautilus_clist_column_titles_show - * nautilus_clist_column_titles_hide - * nautilus_clist_column_title_active - * nautilus_clist_column_title_passive - * nautilus_clist_column_titles_active - * nautilus_clist_column_titles_passive - * nautilus_clist_set_column_title - * nautilus_clist_get_column_title - * nautilus_clist_set_column_widget - * nautilus_clist_set_column_justification - * nautilus_clist_set_column_visibility - * nautilus_clist_set_column_resizeable - * nautilus_clist_set_column_auto_resize - * nautilus_clist_optimal_column_width - * nautilus_clist_set_column_width - * nautilus_clist_set_column_min_width - * nautilus_clist_set_column_max_width - */ -void -nautilus_clist_column_titles_show (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (!NAUTILUS_CLIST_SHOW_TITLES(clist)) - { - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES); - if (clist->title_window) - gdk_window_show (clist->title_window); - gtk_widget_queue_resize (GTK_WIDGET (clist)); - } -} - -void -nautilus_clist_column_titles_hide (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (NAUTILUS_CLIST_SHOW_TITLES(clist)) - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_SHOW_TITLES); - if (clist->title_window) - gdk_window_hide (clist->title_window); - gtk_widget_queue_resize (GTK_WIDGET (clist)); - } -} - -void -nautilus_clist_column_title_active (NautilusCList *clist, - gint column) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (!clist->column[column].button || !clist->column[column].button_passive) - return; - - clist->column[column].button_passive = FALSE; - - gtk_signal_disconnect_by_func (GTK_OBJECT (clist->column[column].button), - (GtkSignalFunc) column_title_passive_func, - NULL); - - GTK_WIDGET_SET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS); - if (GTK_WIDGET_VISIBLE (clist)) - gtk_widget_queue_draw (clist->column[column].button); -} - -void -nautilus_clist_column_title_passive (NautilusCList *clist, - gint column) -{ - GtkButton *button; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (!clist->column[column].button || clist->column[column].button_passive) - return; - - button = GTK_BUTTON (clist->column[column].button); - - clist->column[column].button_passive = TRUE; - - if (button->button_down) - gtk_button_released (button); - if (button->in_button) - gtk_button_leave (button); - - gtk_signal_connect (GTK_OBJECT (clist->column[column].button), "event", - (GtkSignalFunc) column_title_passive_func, NULL); - - GTK_WIDGET_UNSET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS); - if (GTK_WIDGET_VISIBLE (clist)) - gtk_widget_queue_draw (clist->column[column].button); -} - -void -nautilus_clist_column_titles_active (NautilusCList *clist) -{ - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (!NAUTILUS_CLIST_SHOW_TITLES(clist)) - return; - - for (i = 0; i < clist->columns; i++) - nautilus_clist_column_title_active (clist, i); -} - -void -nautilus_clist_column_titles_passive (NautilusCList *clist) -{ - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (!NAUTILUS_CLIST_SHOW_TITLES(clist)) - return; - - for (i = 0; i < clist->columns; i++) - nautilus_clist_column_title_passive (clist, i); -} - -void -nautilus_clist_set_column_title (NautilusCList *clist, - gint column, - const gchar *title) -{ - gint new_button = 0; - GtkWidget *old_widget; - GtkWidget *alignment = NULL; - GtkWidget *label; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - /* if the column button doesn't currently exist, - * it has to be created first */ - if (!clist->column[column].button) - { - column_button_create (clist, column); - new_button = 1; - } - - column_title_new (clist, column, title); - - /* remove and destroy the old widget */ - old_widget = GTK_BIN (clist->column[column].button)->child; - if (old_widget) - gtk_container_remove (GTK_CONTAINER (clist->column[column].button), old_widget); - - /* create new alignment based no column justification */ - switch (clist->column[column].justification) - { - case GTK_JUSTIFY_LEFT: - alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_RIGHT: - alignment = gtk_alignment_new (1.0, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_CENTER: - alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_FILL: - alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - break; - } - - gtk_widget_push_composite_child (); - label = gtk_label_new (clist->column[column].title); - gtk_widget_pop_composite_child (); - gtk_container_add (GTK_CONTAINER (alignment), label); - gtk_container_add (GTK_CONTAINER (clist->column[column].button), alignment); - gtk_widget_show (label); - gtk_widget_show (alignment); - - /* if this button didn't previously exist, then the - * column button positions have to be re-computed */ - if (GTK_WIDGET_VISIBLE (clist) && new_button) - size_allocate_title_buttons (clist); -} - -gchar * -nautilus_clist_get_column_title (NautilusCList *clist, - gint column) -{ - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - if (column < 0 || column >= clist->columns) - return NULL; - - return clist->column[column].title; -} - -void -nautilus_clist_set_column_widget (NautilusCList *clist, - gint column, - GtkWidget *widget) -{ - gint new_button = 0; - GtkWidget *old_widget; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - /* if the column button doesn't currently exist, - * it has to be created first */ - if (!clist->column[column].button) - { - column_button_create (clist, column); - new_button = 1; - } - - column_title_new (clist, column, NULL); - - /* remove and destroy the old widget */ - old_widget = GTK_BIN (clist->column[column].button)->child; - if (old_widget) - gtk_container_remove (GTK_CONTAINER (clist->column[column].button), - old_widget); - - /* add and show the widget */ - if (widget) - { - gtk_container_add (GTK_CONTAINER (clist->column[column].button), widget); - gtk_widget_show (widget); - } - - /* if this button didn't previously exist, then the - * column button positions have to be re-computed */ - if (GTK_WIDGET_VISIBLE (clist) && new_button) - size_allocate_title_buttons (clist); -} - -GtkWidget * -nautilus_clist_get_column_widget (NautilusCList *clist, - gint column) -{ - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - if (column < 0 || column >= clist->columns) - return NULL; - - if (clist->column[column].button) - return GTK_BUTTON (clist->column[column].button)->child; - - return NULL; -} - -void -nautilus_clist_set_column_justification (NautilusCList *clist, - gint column, - GtkJustification justification) -{ - GtkWidget *alignment; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - clist->column[column].justification = justification; - - /* change the alinment of the button title if it's not a - * custom widget */ - if (clist->column[column].title) - { - alignment = GTK_BIN (clist->column[column].button)->child; - - switch (clist->column[column].justification) - { - case GTK_JUSTIFY_LEFT: - gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.0, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_RIGHT: - gtk_alignment_set (GTK_ALIGNMENT (alignment), 1.0, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_CENTER: - gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.5, 0.5, 0.0, 0.0); - break; - - case GTK_JUSTIFY_FILL: - gtk_alignment_set (GTK_ALIGNMENT (alignment), 0.5, 0.5, 0.0, 0.0); - break; - - default: - break; - } - } - - if (CLIST_UNFROZEN (clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); -} - -void -nautilus_clist_set_column_visibility (NautilusCList *clist, - gint column, - gboolean visible) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (clist->column[column].visible == visible) - return; - - /* don't hide last visible column */ - if (!visible) - { - gint i; - gint vis_columns = 0; - - for (i = 0, vis_columns = 0; i < clist->columns && vis_columns < 2; i++) - if (clist->column[i].visible) - vis_columns++; - - if (vis_columns < 2) - return; - } - - clist->column[column].visible = visible; - - if (clist->column[column].button) - { - if (visible) - gtk_widget_show (clist->column[column].button); - else - gtk_widget_hide (clist->column[column].button); - } - - gtk_widget_queue_resize (GTK_WIDGET(clist)); -} - -void -nautilus_clist_set_column_resizeable (NautilusCList *clist, - gint column, - gboolean resizeable) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (clist->column[column].resizeable == resizeable) - return; - - clist->column[column].resizeable = resizeable; - if (resizeable) - clist->column[column].auto_resize = FALSE; - - if (GTK_WIDGET_VISIBLE (clist)) - size_allocate_title_buttons (clist); -} - -void -nautilus_clist_set_column_auto_resize (NautilusCList *clist, - gint column, - gboolean auto_resize) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (clist->column[column].auto_resize == auto_resize) - return; - - clist->column[column].auto_resize = auto_resize; - if (auto_resize) - { - clist->column[column].resizeable = FALSE; - if (!NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - { - gint width; - - width = nautilus_clist_optimal_column_width (clist, column); - nautilus_clist_set_column_width (clist, column, width); - } - } - - if (GTK_WIDGET_VISIBLE (clist)) - size_allocate_title_buttons (clist); -} - -gint -nautilus_clist_columns_autosize (NautilusCList *clist) -{ - gint i; - gint width; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - nautilus_clist_freeze (clist); - width = 0; - for (i = 0; i < clist->columns; i++) - { - nautilus_clist_set_column_width (clist, i, - nautilus_clist_optimal_column_width (clist, i)); - - width += clist->column[i].width; - } - - nautilus_clist_thaw (clist); - return width; -} - -gint -nautilus_clist_optimal_column_width (NautilusCList *clist, - gint column) -{ - GtkRequisition requisition; - GList *list; - gint width; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_CLIST (clist), 0); - - if (column < 0 || column > clist->columns) - return 0; - - if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[column].button) - width = (clist->column[column].button->requisition.width) -#if 0 - + (CELL_SPACING + (2 * COLUMN_INSET)) -#endif - ; - else - width = 0; - - for (list = clist->row_list; list; list = list->next) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, NAUTILUS_CLIST_ROW (list), column, &requisition); - width = MAX (width, requisition.width); - } - - return width; -} - -void -nautilus_clist_set_column_width (NautilusCList *clist, - gint column, - gint width) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[RESIZE_COLUMN], - column, width); -} - -void -nautilus_clist_set_column_min_width (NautilusCList *clist, - gint column, - gint min_width) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (clist->column[column].min_width == min_width) - return; - - if (clist->column[column].max_width >= 0 && - clist->column[column].max_width < min_width) - clist->column[column].min_width = clist->column[column].max_width; - else - clist->column[column].min_width = min_width; - - if (clist->column[column].area.width < clist->column[column].min_width) - nautilus_clist_set_column_width (clist, column,clist->column[column].min_width); -} - -void -nautilus_clist_set_column_max_width (NautilusCList *clist, - gint column, - gint max_width) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - if (clist->column[column].max_width == max_width) - return; - - if (clist->column[column].min_width >= 0 && max_width >= 0 && - clist->column[column].min_width > max_width) - clist->column[column].max_width = clist->column[column].min_width; - else - clist->column[column].max_width = max_width; - - if (clist->column[column].area.width > clist->column[column].max_width) - nautilus_clist_set_column_width (clist, column,clist->column[column].max_width); -} - -/* PRIVATE COLUMN FUNCTIONS - * column_auto_resize - * real_resize_column - * abort_column_resize - * size_allocate_title_buttons - * size_allocate_columns - * list_requisition_width - * new_column_width - * column_button_create - * column_button_clicked - * column_title_passive_func - */ -static void -column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width) -{ - /* resize column if needed for auto_resize */ - GtkRequisition requisition; - - if (!clist->column[column].auto_resize || - NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - return; - - if (clist_row) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - else - requisition.width = 0; - - if (requisition.width > clist->column[column].width) - nautilus_clist_set_column_width (clist, column, requisition.width); - else if (requisition.width < old_width && - old_width == clist->column[column].width) - { - GList *list; - gint new_width = 0; - - /* run a "nautilus_clist_optimal_column_width" but break, if - * the column doesn't shrink */ - if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[column].button) - new_width = (clist->column[column].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - else - new_width = 0; - - for (list = clist->row_list; list; list = list->next) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, NAUTILUS_CLIST_ROW (list), column, &requisition); - new_width = MAX (new_width, requisition.width); - if (new_width == clist->column[column].width) - break; - } - if (new_width < clist->column[column].width) - nautilus_clist_set_column_width - (clist, column, MAX (new_width, clist->column[column].min_width)); - } -} - -static void -real_resize_column (NautilusCList *clist, - gint column, - gint width) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width)) - width = MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width); - if (clist->column[column].max_width >= 0 && - width > clist->column[column].max_width) - width = clist->column[column].max_width; - - if (clist->column[column].width == width - && clist->column[column].width_set) - return; - - clist->column[column].width = width; - clist->column[column].width_set = TRUE; - - /* FIXME: this is quite expensive to do if the widget hasn't - * been size_allocated yet, and pointless. Should - * a flag be kept - */ - size_allocate_columns (clist, TRUE); - size_allocate_title_buttons (clist); - - CLIST_REFRESH (clist); -} - -static void -abort_column_resize (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (!NAUTILUS_CLIST_IN_DRAG(clist)) - return; - - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG); - gtk_grab_remove (GTK_WIDGET (clist)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - clist->drag_pos = -1; - - if (clist->x_drag >= 0 && clist->x_drag <= clist->clist_window_width - 1) - draw_xor_line (clist); - - if (NAUTILUS_CLIST_ADD_MODE(clist)) - { - gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_ON_OFF_DASH, 0,0); - gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2); - } -} - -static void -size_allocate_title_buttons (NautilusCList *clist) -{ - GtkAllocation button_allocation; - gint last_column; - gint last_button = 0; - gint i; - - if (!GTK_WIDGET_REALIZED (clist)) - return; - - button_allocation.x = clist->hoffset; - button_allocation.y = 0; - button_allocation.width = 0; - button_allocation.height = clist->column_title_area.height; - - /* find last visible column */ - for (last_column = clist->columns - 1; last_column >= 0; last_column--) - if (clist->column[last_column].visible) - break; - - for (i = 0; i < last_column; i++) - { - if (!clist->column[i].visible) - { - last_button = i + 1; - gdk_window_hide (clist->column[i].window); - continue; - } - - button_allocation.width += (clist->column[i].area.width + - CELL_SPACING + 2 * COLUMN_INSET); - - if (!clist->column[i + 1].button) - { - gdk_window_hide (clist->column[i].window); - continue; - } - - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - button_allocation.x += button_allocation.width; - button_allocation.width = 0; - - if (clist->column[last_button].resizeable) - { - gdk_window_show (clist->column[last_button].window); - gdk_window_move_resize (clist->column[last_button].window, - button_allocation.x - (DRAG_WIDTH / 2), - 0, DRAG_WIDTH, - clist->column_title_area.height); - } - else - gdk_window_hide (clist->column[last_button].window); - - last_button = i + 1; - } - - button_allocation.width += (clist->column[last_column].area.width + - 2 * (CELL_SPACING + COLUMN_INSET)); - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - - if (clist->column[last_button].resizeable) - { - button_allocation.x += button_allocation.width; - - gdk_window_show (clist->column[last_button].window); - gdk_window_move_resize (clist->column[last_button].window, - button_allocation.x - (DRAG_WIDTH / 2), - 0, DRAG_WIDTH, clist->column_title_area.height); - } - else - gdk_window_hide (clist->column[last_button].window); -} - -static void -size_allocate_columns (NautilusCList *clist, - gboolean block_resize) -{ - gint xoffset = CELL_SPACING + COLUMN_INSET; - gint last_column; - gint i; - - /* find last visible column and calculate correct column width */ - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--); - - if (last_column < 0) - return; - - for (i = 0; i <= last_column; i++) - { - if (!clist->column[i].visible) - continue; - clist->column[i].area.x = xoffset; - if (clist->column[i].width_set) - { - if (!block_resize && NAUTILUS_CLIST_SHOW_TITLES(clist) && - clist->column[i].auto_resize && clist->column[i].button) - { - gint width; - - width = (clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - - if (width > clist->column[i].width) - nautilus_clist_set_column_width (clist, i, width); - } - - clist->column[i].area.width = clist->column[i].width; - xoffset += clist->column[i].width + CELL_SPACING + (2* COLUMN_INSET); - } - else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) - { - clist->column[i].area.width = - clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET)); - xoffset += clist->column[i].button->requisition.width; - } - } - - clist->column[last_column].area.width = clist->column[last_column].area.width - + MAX (0, clist->clist_window_width + COLUMN_INSET - xoffset); -} - -static gint -list_requisition_width (NautilusCList *clist) -{ - gint width = CELL_SPACING; - gint i; - - for (i = clist->columns - 1; i >= 0; i--) - { - if (!clist->column[i].visible) - continue; - - if (clist->column[i].width_set) - width += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET); - else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) - width += clist->column[i].button->requisition.width; - } - - return width; -} - -/* this function returns the new width of the column being resized given - * the column and x position of the cursor; the x cursor position is passed - * in as a pointer and automagicly corrected if it's beyond min/max limits */ -static gint -new_column_width (NautilusCList *clist, - gint column, - gint *x) -{ - gint xthickness = GTK_WIDGET (clist)->style->klass->xthickness; - gint width; - gint cx; - gint dx; - gint last_column; - - /* first translate the x position from widget->window - * to clist->clist_window */ - cx = *x - xthickness; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--); - - /* calculate new column width making sure it doesn't end up - * less than the minimum width */ - dx = (COLUMN_LEFT_XPIXEL (clist, column) + COLUMN_INSET + - (column < last_column) * CELL_SPACING); - width = cx - dx; - - if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width)) - { - width = MAX (COLUMN_MIN_WIDTH, clist->column[column].min_width); - cx = dx + width; - *x = cx + xthickness; - } - else if (clist->column[column].max_width >= COLUMN_MIN_WIDTH && - width > clist->column[column].max_width) - { - width = clist->column[column].max_width; - cx = dx + clist->column[column].max_width; - *x = cx + xthickness; - } - - if (cx < 0 || cx > clist->clist_window_width) - *x = -1; - - return width; -} - -static void -column_button_create (NautilusCList *clist, - gint column) -{ - GtkWidget *button; - - gtk_widget_push_composite_child (); - button = clist->column[column].button = gtk_button_new (); - gtk_widget_pop_composite_child (); - - if (GTK_WIDGET_REALIZED (clist) && clist->title_window) - gtk_widget_set_parent_window (clist->column[column].button, - clist->title_window); - gtk_widget_set_parent (button, GTK_WIDGET (clist)); - - gtk_signal_connect (GTK_OBJECT (button), "clicked", - (GtkSignalFunc) column_button_clicked, - (gpointer) clist); - gtk_widget_show (button); -} - -static void -column_button_clicked (GtkWidget *widget, - gpointer data) -{ - gint i; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (data)); - - clist = NAUTILUS_CLIST (data); - - /* find the column who's button was pressed */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button == widget) - break; - - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[CLICK_COLUMN], i); -} - -static gint -column_title_passive_func (GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - g_return_val_if_fail (event != NULL, FALSE); - - switch (event->type) - { - case GDK_MOTION_NOTIFY: - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - case GDK_ENTER_NOTIFY: - case GDK_LEAVE_NOTIFY: - return TRUE; - default: - break; - } - return FALSE; -} - - -/* PUBLIC CELL FUNCTIONS - * nautilus_clist_get_cell_type - * nautilus_clist_set_text - * nautilus_clist_get_text - * nautilus_clist_set_pixbuf - * nautilus_clist_get_pixbuf - * nautilus_clist_set_pixtext - * nautilus_clist_get_pixtext - * nautilus_clist_set_shift - */ -NautilusCellType -nautilus_clist_get_cell_type (NautilusCList *clist, - gint row, - gint column) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - - if (row < 0 || row >= clist->rows) - return -1; - if (column < 0 || column >= clist->columns) - return -1; - - clist_row = ROW_ELEMENT (clist, row)->data; - - return clist_row->cell[column].type; -} - -void -nautilus_clist_set_text (NautilusCList *clist, - gint row, - gint column, - const gchar *text) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < 0 || column >= clist->columns) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - /* if text is null, then the cell is empty */ - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, clist_row, column, NAUTILUS_CELL_TEXT, text, 0, NULL)) - { - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist)) - { - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } - } -} - -gint -nautilus_clist_get_text (NautilusCList *clist, - gint row, - gint column, - gchar **text) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - if (row < 0 || row >= clist->rows) - return 0; - if (column < 0 || column >= clist->columns) - return 0; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->cell[column].type != NAUTILUS_CELL_TEXT - && clist_row->cell[column].type != NAUTILUS_CELL_LINK_TEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_TEXT (clist_row->cell[column])->text; - - return 1; -} - -void -nautilus_clist_set_pixbuf (NautilusCList *clist, - gint row, - gint column, - GdkPixbuf *pixbuf) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < 0 || column >= clist->columns) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, clist_row, column, NAUTILUS_CELL_PIXBUF, NULL, 0, pixbuf)) - { - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist)) - { - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } - } -} - -gint -nautilus_clist_get_pixbuf (NautilusCList *clist, - gint row, - gint column, - GdkPixbuf **pixbuf) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - if (row < 0 || row >= clist->rows) - return 0; - if (column < 0 || column >= clist->columns) - return 0; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->cell[column].type != NAUTILUS_CELL_PIXBUF) - return 0; - - if (pixbuf) - { - *pixbuf = NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf; - } - - return 1; -} - -void -nautilus_clist_set_pixtext (NautilusCList *clist, - gint row, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < 0 || column >= clist->columns) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, clist_row, column, NAUTILUS_CELL_PIXTEXT, text, spacing, pixbuf)) - { - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist)) - { - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } - } -} - -gint -nautilus_clist_get_pixtext (NautilusCList *clist, - gint row, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - if (row < 0 || row >= clist->rows) - return 0; - if (column < 0 || column >= clist->columns) - return 0; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->cell[column].type != NAUTILUS_CELL_PIXTEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text; - if (spacing) - *spacing = NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing; - if (pixbuf) - *pixbuf = NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf; - - return 1; -} - -void -nautilus_clist_set_shift (NautilusCList *clist, - gint row, - gint column, - gint vertical, - gint horizontal) -{ - GtkRequisition requisition = { 0 }; - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < 0 || column >= clist->columns) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - - clist_row->cell[column].vertical = vertical; - clist_row->cell[column].horizontal = horizontal; - - column_auto_resize (clist, clist_row, column, requisition.width); - - if (CLIST_UNFROZEN (clist) && nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); -} - -/* PRIVATE CELL FUNCTIONS - * set_cell_contents - * cell_size_request - */ -static gboolean -set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - GtkRequisition requisition; - - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), FALSE); - g_return_val_if_fail (clist_row != NULL, FALSE); - - if (type == clist_row->cell[column].type) - { - switch (type) - { - case NAUTILUS_CELL_EMPTY: - return FALSE; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf == NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf) - return FALSE; - break; - case NAUTILUS_CELL_PIXTEXT: - if (pixbuf == NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) - { - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - } - break; - case NAUTILUS_CELL_WIDGET: - /* unimplemented */ - break; - default: - break; - } - } - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_EMPTY: - break; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - g_free (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - break; - case NAUTILUS_CELL_PIXBUF: - gdk_pixbuf_unref (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - break; - case NAUTILUS_CELL_PIXTEXT: - g_free (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text); - gdk_pixbuf_unref (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - break; - case NAUTILUS_CELL_WIDGET: - /* unimplemented */ - break; - default: - break; - } - - clist_row->cell[column].type = NAUTILUS_CELL_EMPTY; - - switch (type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (text) - { - clist_row->cell[column].type = NAUTILUS_CELL_TEXT; - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text = g_strdup (text); - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXBUF; - NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - case NAUTILUS_CELL_PIXTEXT: - if (text && pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXTEXT; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text = g_strdup (text); - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing = spacing; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - default: - break; - } - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - column_auto_resize (clist, clist_row, column, requisition.width); - - return TRUE; -} - -static void -cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition) -{ - GtkStyle *style; - gint width; - gint height; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - g_return_if_fail (requisition != NULL); - - get_cell_style (clist, clist_row, GTK_STATE_NORMAL, column, &style, - NULL, NULL); - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - requisition->width = - gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - requisition->height = style->font->ascent + style->font->descent; - break; - case NAUTILUS_CELL_PIXTEXT: - width = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - requisition->width = width + - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing + - gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - requisition->height = MAX (style->font->ascent + style->font->descent, - height); - break; - case NAUTILUS_CELL_PIXBUF: - requisition->width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - requisition->height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - break; - default: - requisition->width = 0; - requisition->height = 0; - break; - } - - requisition->width += clist_row->cell[column].horizontal; - requisition->height += clist_row->cell[column].vertical; -} - -/* PUBLIC INSERT/REMOVE ROW FUNCTIONS - * nautilus_clist_prepend - * nautilus_clist_append - * nautilus_clist_insert - * nautilus_clist_remove - * nautilus_clist_clear - */ -gint -nautilus_clist_prepend (NautilusCList *clist, - gchar *text[]) -{ - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - g_return_val_if_fail (text != NULL, -1); - - return NAUTILUS_CLIST_CLASS_FW (clist)->insert_row (clist, 0, text); -} - -gint -nautilus_clist_append (NautilusCList *clist, - gchar *text[]) -{ - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - g_return_val_if_fail (text != NULL, -1); - - return NAUTILUS_CLIST_CLASS_FW (clist)->insert_row (clist, clist->rows, text); -} - -gint -nautilus_clist_insert (NautilusCList *clist, - gint row, - gchar *text[]) -{ - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - g_return_val_if_fail (text != NULL, -1); - - if (row < 0 || row > clist->rows) - row = clist->rows; - - return NAUTILUS_CLIST_CLASS_FW (clist)->insert_row (clist, row, text); -} - -void -nautilus_clist_remove (NautilusCList *clist, - gint row) -{ - NAUTILUS_CLIST_CLASS_FW (clist)->remove_row (clist, row); -} - - -void -nautilus_clist_clear (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - NAUTILUS_CLIST_CLASS_FW (clist)->clear (clist); -} - -/* PRIVATE INSERT/REMOVE ROW FUNCTIONS - * get_ascending_sorted_list_position_for_new_row - * get_descending_sorted_list_position_for_new_row - * real_insert_row - * real_remove_row - * real_clear - * real_row_move - */ - -/* Returns a row number >= 0 */ -static gint -get_ascending_sorted_list_position_for_new_row (NautilusCList *clist, - NautilusCListRow *new_row) -{ - int current_row, high_row_bound, low_row_bound; - int compare_result; - GList *current_row_node; - - if (clist->rows == 0) { - return 0; - } - - current_row = clist->rows / 2; - high_row_bound = clist->rows; - low_row_bound = 0; - - while (TRUE) { - current_row_node = g_list_nth (clist->row_list, current_row); - compare_result = clist->compare (clist, - new_row, - NAUTILUS_CLIST_ROW (current_row_node)); - - if (compare_result == 0 || - (compare_result > 0 && high_row_bound == current_row + 1)) { - /* GList starts at 0, rows at 1 */ - return current_row + 1; - } - else if (compare_result > 0) { - g_assert (high_row_bound > current_row); - low_row_bound = current_row; - current_row = (current_row + high_row_bound) / 2; - } - else if (compare_result < 0) { - /* Check for case of new row being less than the first row */ - if (current_row == 0) { - return 0; - } - g_assert (low_row_bound < current_row); - high_row_bound = current_row; - current_row = (current_row + low_row_bound) / 2; - } - } - - g_assert_not_reached (); - return -1; -} - -/* Returns a row number >= 0 */ -static gint -get_descending_sorted_list_position_for_new_row (NautilusCList *clist, - NautilusCListRow *new_row) -{ - int current_row, high_row_bound, low_row_bound; - int compare_result; - GList *current_row_node; - - if (clist->rows == 0) { - return 0; - } - - current_row = clist->rows / 2; - high_row_bound = clist->rows; - low_row_bound = 0; - - while (TRUE) { - current_row_node = g_list_nth (clist->row_list, current_row); - compare_result = clist->compare (clist, - new_row, - NAUTILUS_CLIST_ROW (current_row_node)); - - if (compare_result == 0 || - (compare_result < 0 && high_row_bound == current_row + 1)) { - /* GList starts at 0, rows at 1 */ - return current_row + 1; - } - else if (compare_result < 0) { - g_assert (high_row_bound > current_row); - low_row_bound = current_row; - current_row = (current_row + high_row_bound) / 2; - } - else if (compare_result > 0) { - /* Check for case of new row being less than the first row */ - if (current_row == 0) { - return 0; - } - g_assert (low_row_bound < current_row); - high_row_bound = current_row; - current_row = (current_row + low_row_bound) / 2; - } - } - - g_assert_not_reached (); - return -1; -} - - - -static gint -real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]) -{ - gint i; - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - g_return_val_if_fail (text != NULL, -1); - - /* return if out of bounds */ - if (row < 0 || row > clist->rows) - return -1; - - /* create the row */ - clist_row = row_new (clist); - - /* set the text in the row's columns */ - for (i = 0; i < clist->columns; i++) - if (text[i]) - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, clist_row, i, NAUTILUS_CELL_TEXT, text[i], 0, NULL); - - if (!clist->rows) - { - clist->row_list = g_list_append (clist->row_list, clist_row); - clist->row_list_end = clist->row_list; - } - else - { - if (NAUTILUS_CLIST_AUTO_SORT(clist)) /* override insertion pos */ - { - GList *work; - - row = 0; - work = clist->row_list; - - if (clist->sort_type == GTK_SORT_ASCENDING) - { - row = get_ascending_sorted_list_position_for_new_row (clist, clist_row); - } - else - { - row = get_descending_sorted_list_position_for_new_row (clist, clist_row); - } - } - - /* reset the row end pointer if we're inserting at the end of the list */ - if (row == clist->rows) - clist->row_list_end = (g_list_append (clist->row_list_end, - clist_row))->next; - else - clist->row_list = g_list_insert (clist->row_list, clist_row, row); - - } - clist->rows++; - - if (row < ROW_FROM_YPIXEL (clist, 0)) - clist->voffset -= (clist->row_height + CELL_SPACING); - - /* syncronize the selection list */ - sync_selection (clist, row, SYNC_INSERT); - - if (clist->rows == 1) - { - clist->focus_row = 0; - if (clist->selection_mode == GTK_SELECTION_BROWSE) - nautilus_clist_select_row (clist, 0, -1); - } - - /* redraw the list if it isn't frozen */ - if (CLIST_UNFROZEN (clist)) - { - adjust_adjustments (clist, FALSE); - - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - } - - return row; -} - -static void -real_remove_row (NautilusCList *clist, - gint row) -{ - gint was_visible, was_selected; - GList *list; - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - /* return if out of bounds */ - if (row < 0 || row > (clist->rows - 1)) - return; - - was_visible = (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE); - was_selected = 0; - - /* get the row we're going to delete */ - list = ROW_ELEMENT (clist, row); - g_assert (list != NULL); - clist_row = list->data; - - /* if we're removing a selected row, we have to make sure - * it's properly unselected, and then sync up the clist->selected - * list to reflect the deincrimented indexies of rows after the - * removal */ - if (clist_row->state == GTK_STATE_SELECTED) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - row, -1, NULL); - - /* reset the row end pointer if we're removing at the end of the list */ - clist->rows--; - if (clist->row_list == list) - clist->row_list = g_list_next (list); - if (clist->row_list_end == list) - clist->row_list_end = g_list_previous (list); - g_list_remove (list, clist_row); - - /*if (clist->focus_row >=0 && - (row <= clist->focus_row || clist->focus_row >= clist->rows)) - clist->focus_row--;*/ - - if (row < ROW_FROM_YPIXEL (clist, 0)) - clist->voffset += clist->row_height + CELL_SPACING; - - sync_selection (clist, row, SYNC_REMOVE); - - if (clist->selection_mode == GTK_SELECTION_BROWSE && !clist->selection && - clist->focus_row >= 0) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - - /* toast the row */ - row_delete (clist, clist_row); - - /* redraw the row if it isn't frozen */ - if (CLIST_UNFROZEN (clist)) - { - adjust_adjustments (clist, FALSE); - - if (was_visible) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - } -} - -static void -real_clear (NautilusCList *clist) -{ - GList *list; - GList *free_list; - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - /* free up the selection list */ - g_list_free (clist->selection); - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - - clist->selection = NULL; - clist->selection_end = NULL; - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - clist->voffset = 0; - clist->focus_row = -1; - clist->anchor = -1; - clist->undo_anchor = -1; - clist->anchor_state = GTK_STATE_SELECTED; - clist->drag_pos = -1; - - /* remove all the rows */ - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - free_list = clist->row_list; - clist->row_list = NULL; - clist->row_list_end = NULL; - clist->rows = 0; - for (list = free_list; list; list = list->next) - row_delete (clist, NAUTILUS_CLIST_ROW (list)); - g_list_free (free_list); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) - nautilus_clist_set_column_width - (clist, i, (clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET)))); - else - nautilus_clist_set_column_width (clist, i, 0); - } - /* zero-out the scrollbars */ - if (clist->vadjustment) - { - gtk_adjustment_set_value (clist->vadjustment, 0.0); - CLIST_REFRESH (clist); - } - else - gtk_widget_queue_resize (GTK_WIDGET (clist)); -} - -static void -real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row) -{ - NautilusCListRow *clist_row; - GList *list; - gint first, last; - gint d; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (NAUTILUS_CLIST_AUTO_SORT(clist)) - return; - - if (source_row < 0 || source_row >= clist->rows || - dest_row < 0 || dest_row >= clist->rows || - source_row == dest_row) - return; - - /* unlink source row */ - clist_row = ROW_ELEMENT (clist, source_row)->data; - if (source_row == clist->rows - 1) - clist->row_list_end = clist->row_list_end->prev; - clist->row_list = g_list_remove (clist->row_list, clist_row); - clist->rows--; - - /* relink source row */ - clist->row_list = g_list_insert (clist->row_list, clist_row, dest_row); - if (dest_row == clist->rows) - clist->row_list_end = clist->row_list_end->next; - clist->rows++; - - /* sync selection */ - if (source_row > dest_row) - { - first = dest_row; - last = source_row; - d = 1; - } - else - { - first = source_row; - last = dest_row; - d = -1; - } - - for (list = clist->selection; list; list = list->next) - { - if (list->data == GINT_TO_POINTER (source_row)) - list->data = GINT_TO_POINTER (dest_row); - else if (first <= GPOINTER_TO_INT (list->data) && - last >= GPOINTER_TO_INT (list->data)) - list->data = GINT_TO_POINTER (GPOINTER_TO_INT (list->data) + d); - } - - if (clist->focus_row == source_row) - clist->focus_row = dest_row; - else if (clist->focus_row > first) - clist->focus_row += d; - - CLIST_REFRESH (clist); -} - -/* PUBLIC ROW FUNCTIONS - * nautilus_clist_moveto - * nautilus_clist_set_row_height - * nautilus_clist_set_row_data - * nautilus_clist_set_row_data_full - * nautilus_clist_get_row_data - * nautilus_clist_find_row_from_data - * nautilus_clist_swap_rows - * nautilus_clist_row_move - * nautilus_clist_row_is_visible - * nautilus_clist_set_foreground - * nautilus_clist_set_background - */ -void -nautilus_clist_moveto (NautilusCList *clist, - gint row, - gint column, - gfloat row_align, - gfloat col_align) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < -1 || row >= clist->rows) - return; - if (column < -1 || column >= clist->columns) - return; - - row_align = CLAMP (row_align, 0, 1); - col_align = CLAMP (col_align, 0, 1); - - /* adjust horizontal scrollbar */ - if (clist->hadjustment && column >= 0) - { - gint x; - - x = (COLUMN_LEFT (clist, column) - CELL_SPACING - COLUMN_INSET - - (col_align * (clist->clist_window_width - 2 * COLUMN_INSET - - CELL_SPACING - clist->column[column].area.width))); - if (x < 0) - gtk_adjustment_set_value (clist->hadjustment, 0.0); - else if (x > LIST_WIDTH (clist) - clist->clist_window_width) - gtk_adjustment_set_value - (clist->hadjustment, LIST_WIDTH (clist) - clist->clist_window_width); - else - gtk_adjustment_set_value (clist->hadjustment, x); - } - - /* adjust vertical scrollbar */ - if (clist->vadjustment && row >= 0) - move_vertical (clist, row, row_align); -} - -void -nautilus_clist_set_row_height (NautilusCList *clist, - guint height) -{ - GtkWidget *widget; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - widget = GTK_WIDGET (clist); - - if (height > 0) - { - clist->row_height = height; - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_ROW_HEIGHT_SET); - } - else - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_ROW_HEIGHT_SET); - clist->row_height = 0; - } - - if (GTK_WIDGET_REALIZED (clist)) - { - if (!NAUTILUS_CLIST_ROW_HEIGHT_SET(clist)) - { - clist->row_height = (widget->style->font->ascent + - widget->style->font->descent + 1); - clist->row_center_offset = widget->style->font->ascent + 1.5; - } - else - clist->row_center_offset = 1.5 + (clist->row_height + - widget->style->font->ascent - - widget->style->font->descent - 1) / 2; - } - - CLIST_REFRESH (clist); -} - -void -nautilus_clist_set_row_data (NautilusCList *clist, - gint row, - gpointer data) -{ - nautilus_clist_set_row_data_full (clist, row, data, NULL); -} - -void -nautilus_clist_set_row_data_full (NautilusCList *clist, - gint row, - gpointer data, - GtkDestroyNotify destroy) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row > (clist->rows - 1)) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->destroy) - clist_row->destroy (clist_row->data); - - clist_row->data = data; - clist_row->destroy = destroy; -} - -gpointer -nautilus_clist_get_row_data (NautilusCList *clist, - gint row) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - if (row < 0 || row > (clist->rows - 1)) - return NULL; - - clist_row = ROW_ELEMENT (clist, row)->data; - return clist_row->data; -} - -gint -nautilus_clist_find_row_from_data (NautilusCList *clist, - gpointer data) -{ - GList *list; - gint n; - - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), -1); - - for (n = 0, list = clist->row_list; list; n++, list = list->next) - if (NAUTILUS_CLIST_ROW (list)->data == data) - return n; - - return -1; -} - -void -nautilus_clist_swap_rows (NautilusCList *clist, - gint row1, - gint row2) -{ - gint first, last; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - g_return_if_fail (row1 != row2); - - if (NAUTILUS_CLIST_AUTO_SORT(clist)) - return; - - nautilus_clist_freeze (clist); - - first = MIN (row1, row2); - last = MAX (row1, row2); - - nautilus_clist_row_move (clist, last, first); - nautilus_clist_row_move (clist, first + 1, last); - - nautilus_clist_thaw (clist); -} - -void -nautilus_clist_row_move (NautilusCList *clist, - gint source_row, - gint dest_row) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (NAUTILUS_CLIST_AUTO_SORT(clist)) - return; - - if (source_row < 0 || source_row >= clist->rows || - dest_row < 0 || dest_row >= clist->rows || - source_row == dest_row) - return; - - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[ROW_MOVE], - source_row, dest_row); -} - -GtkVisibility -nautilus_clist_row_is_visible (NautilusCList *clist, - gint row) -{ - gint top; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - if (row < 0 || row >= clist->rows) - return GTK_VISIBILITY_NONE; - - if (clist->row_height == 0) - return GTK_VISIBILITY_NONE; - - if (row < ROW_FROM_YPIXEL (clist, 0)) - return GTK_VISIBILITY_NONE; - - if (row > ROW_FROM_YPIXEL (clist, clist->clist_window_height)) - return GTK_VISIBILITY_NONE; - - top = ROW_TOP_YPIXEL (clist, row); - - if ((top < 0) - || ((top + clist->row_height) >= clist->clist_window_height)) - return GTK_VISIBILITY_PARTIAL; - - return GTK_VISIBILITY_FULL; -} - -void -nautilus_clist_set_foreground (NautilusCList *clist, - gint row, - GdkColor *color) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (color) - { - clist_row->foreground = *color; - clist_row->fg_set = TRUE; - if (GTK_WIDGET_REALIZED (clist)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (clist)), - &clist_row->foreground); - } - else - clist_row->fg_set = FALSE; - - if (CLIST_UNFROZEN (clist) && nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); -} - -void -nautilus_clist_set_background (NautilusCList *clist, - gint row, - GdkColor *color) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (color) - { - clist_row->background = *color; - clist_row->bg_set = TRUE; - if (GTK_WIDGET_REALIZED (clist)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (clist)), - &clist_row->background); - } - else - clist_row->bg_set = FALSE; - - if (CLIST_UNFROZEN (clist) - && (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); -} - -/* PUBLIC ROW/CELL STYLE FUNCTIONS - * nautilus_clist_set_cell_style - * nautilus_clist_get_cell_style - * nautilus_clist_set_row_style - * nautilus_clist_get_row_style - */ -void -nautilus_clist_set_cell_style (NautilusCList *clist, - gint row, - gint column, - GtkStyle *style) -{ - GtkRequisition requisition = { 0 }; - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < 0 || column >= clist->columns) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->cell[column].style == style) - return; - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - - if (clist_row->cell[column].style) - { - if (GTK_WIDGET_REALIZED (clist)) - gtk_style_detach (clist_row->cell[column].style); - gtk_style_unref (clist_row->cell[column].style); - } - - clist_row->cell[column].style = style; - - if (clist_row->cell[column].style) - { - gtk_style_ref (clist_row->cell[column].style); - - if (GTK_WIDGET_REALIZED (clist)) - clist_row->cell[column].style = - gtk_style_attach (clist_row->cell[column].style, - clist->clist_window); - } - - column_auto_resize (clist, clist_row, column, requisition.width); - - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist)) - { - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } -} - -GtkStyle * -nautilus_clist_get_cell_style (NautilusCList *clist, - gint row, - gint column) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - if (row < 0 || row >= clist->rows || column < 0 || column >= clist->columns) - return NULL; - - clist_row = ROW_ELEMENT (clist, row)->data; - - return clist_row->cell[column].style; -} - -void -nautilus_clist_set_row_style (NautilusCList *clist, - gint row, - GtkStyle *style) -{ - GtkRequisition requisition; - NautilusCListRow *clist_row; - gint *old_width; - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->style == style) - return; - - old_width = g_new (gint, clist->columns); - - if (!NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - { - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - i, &requisition); - old_width[i] = requisition.width; - } - } - - if (clist_row->style) - { - if (GTK_WIDGET_REALIZED (clist)) - gtk_style_detach (clist_row->style); - gtk_style_unref (clist_row->style); - } - - clist_row->style = style; - - if (clist_row->style) - { - gtk_style_ref (clist_row->style); - - if (GTK_WIDGET_REALIZED (clist)) - clist_row->style = gtk_style_attach (clist_row->style, - clist->clist_window); - } - - if (NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - for (i = 0; i < clist->columns; i++) - column_auto_resize (clist, clist_row, i, old_width[i]); - - g_free (old_width); - - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist)) - { - if (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } -} - -GtkStyle * -nautilus_clist_get_row_style (NautilusCList *clist, - gint row) -{ - NautilusCListRow *clist_row; - - g_return_val_if_fail (clist != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), NULL); - - if (row < 0 || row >= clist->rows) - return NULL; - - clist_row = ROW_ELEMENT (clist, row)->data; - - return clist_row->style; -} - -/* PUBLIC SELECTION FUNCTIONS - * nautilus_clist_set_selectable - * nautilus_clist_get_selectable - * nautilus_clist_select_row - * nautilus_clist_unselect_row - * nautilus_clist_select_all - * nautilus_clist_unselect_all - * nautilus_clist_undo_selection - */ -void -nautilus_clist_set_selectable (NautilusCList *clist, - gint row, - gboolean selectable) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (selectable == clist_row->selectable) - return; - - clist_row->selectable = selectable; - - if (!selectable && clist_row->state == GTK_STATE_SELECTED) - { - if (clist->anchor >= 0 && - clist->selection_mode == GTK_SELECTION_EXTENDED) - { - clist->drag_button = 0; - remove_grab (clist); - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - } - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - row, -1, NULL); - } -} - -gboolean -nautilus_clist_get_selectable (NautilusCList *clist, - gint row) -{ - g_return_val_if_fail (clist != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), FALSE); - - if (row < 0 || row >= clist->rows) - return FALSE; - - return NAUTILUS_CLIST_ROW (ROW_ELEMENT (clist, row))->selectable; -} - -void -nautilus_clist_select_row (NautilusCList *clist, - gint row, - gint column) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < -1 || column >= clist->columns) - return; - - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - row, column, NULL); -} - -void -nautilus_clist_unselect_row (NautilusCList *clist, - gint row, - gint column) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row >= clist->rows) - return; - if (column < -1 || column >= clist->columns) - return; - - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - row, column, NULL); -} - -void -nautilus_clist_select_all (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - NAUTILUS_CLIST_CLASS_FW (clist)->select_all (clist); -} - -void -nautilus_clist_unselect_all (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - NAUTILUS_CLIST_CLASS_FW (clist)->unselect_all (clist); -} - -void -nautilus_clist_undo_selection (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED && - (clist->undo_selection || clist->undo_unselection)) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNDO_SELECTION]); -} - -/* PRIVATE SELECTION FUNCTIONS - * selection_find - * toggle_row - * fake_toggle_row - * toggle_focus_row - * toggle_add_mode - * real_select_row - * real_unselect_row - * real_select_all - * real_unselect_all - * fake_unselect_all - * real_undo_selection - * set_anchor - * resync_selection - * update_extended_selection - * start_selection - * end_selection - * extend_selection - * sync_selection - */ -static GList * -selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element) -{ - return g_list_find (clist->selection, GINT_TO_POINTER (row_number)); -} - -static void -toggle_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - NautilusCListRow *clist_row; - - switch (clist->selection_mode) - { - case GTK_SELECTION_EXTENDED: - case GTK_SELECTION_MULTIPLE: - case GTK_SELECTION_SINGLE: - clist_row = ROW_ELEMENT (clist, row)->data; - - if (!clist_row) - return; - - if (clist_row->state == GTK_STATE_SELECTED) - { - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - row, column, event); - return; - } - case GTK_SELECTION_BROWSE: - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - row, column, event); - break; - } -} - -static void -fake_toggle_row (NautilusCList *clist, - gint row) -{ - GList *work; - - work = ROW_ELEMENT (clist, row); - - if (!work || !NAUTILUS_CLIST_ROW (work)->selectable) - return; - - if (NAUTILUS_CLIST_ROW (work)->state == GTK_STATE_NORMAL) - clist->anchor_state = NAUTILUS_CLIST_ROW (work)->state = GTK_STATE_SELECTED; - else - clist->anchor_state = NAUTILUS_CLIST_ROW (work)->state = GTK_STATE_NORMAL; - - if (CLIST_UNFROZEN (clist) && - nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, - NAUTILUS_CLIST_ROW (work)); -} - -static void -toggle_focus_row (NautilusCList *clist) -{ - g_return_if_fail (clist != 0); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || - clist->focus_row < 0 || clist->focus_row >= clist->rows) - return; - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_MULTIPLE: - toggle_row (clist, clist->focus_row, 0, NULL); - break; - case GTK_SELECTION_EXTENDED: - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor = clist->focus_row; - clist->drag_pos = clist->focus_row; - clist->undo_anchor = clist->focus_row; - - if (NAUTILUS_CLIST_ADD_MODE(clist)) - fake_toggle_row (clist, clist->focus_row); - else - NAUTILUS_CLIST_CLASS_FW (clist)->fake_unselect_all (clist,clist->focus_row); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - break; - default: - break; - } -} - -static void -toggle_add_mode (NautilusCList *clist) -{ - g_return_if_fail (clist != 0); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || - clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - nautilus_clist_draw_focus (GTK_WIDGET (clist)); - if (!NAUTILUS_CLIST_ADD_MODE(clist)) - { - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_ADD_MODE); - gdk_gc_set_line_attributes (clist->xor_gc, 1, - GDK_LINE_ON_OFF_DASH, 0, 0); - gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2); - } - else - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_ADD_MODE); - gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0); - clist->anchor_state = GTK_STATE_SELECTED; - } - nautilus_clist_draw_focus (GTK_WIDGET (clist)); -} - -static void -real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - NautilusCListRow *clist_row; - GList *list; - gint sel_row; - gboolean row_selected; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row > (clist->rows - 1)) - return; - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - - row_selected = FALSE; - list = clist->selection; - - while (list) - { - sel_row = GPOINTER_TO_INT (list->data); - list = list->next; - - if (row == sel_row) - row_selected = TRUE; - else - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - sel_row, column, event); - } - - if (row_selected) - return; - - default: - break; - } - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->state != GTK_STATE_NORMAL || !clist_row->selectable) - return; - - clist_row->state = GTK_STATE_SELECTED; - if (!clist->selection) - { - clist->selection = g_list_append (clist->selection, - GINT_TO_POINTER (row)); - clist->selection_end = clist->selection; - } - else - clist->selection_end = - g_list_append (clist->selection_end, GINT_TO_POINTER (row))->next; - - if (CLIST_UNFROZEN (clist) - && (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); -} - -static void -real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - NautilusCListRow *clist_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (row < 0 || row > (clist->rows - 1)) - return; - - clist_row = ROW_ELEMENT (clist, row)->data; - - if (clist_row->state == GTK_STATE_SELECTED) - { - clist_row->state = GTK_STATE_NORMAL; - - if (clist->selection_end && - clist->selection_end->data == GINT_TO_POINTER (row)) - clist->selection_end = clist->selection_end->prev; - - clist->selection = g_list_remove (clist->selection, - GINT_TO_POINTER (row)); - - if (CLIST_UNFROZEN (clist) - && (nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row); - } -} - -static void -real_select_all (NautilusCList *clist) -{ - GList *list; - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - return; - - case GTK_SELECTION_EXTENDED: - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - if (clist->rows && - ((NautilusCListRow *) (clist->row_list->data))->state != - GTK_STATE_SELECTED) - fake_toggle_row (clist, 0); - - clist->anchor_state = GTK_STATE_SELECTED; - clist->anchor = 0; - clist->drag_pos = 0; - clist->undo_anchor = clist->focus_row; - update_extended_selection (clist, clist->rows); - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - return; - - case GTK_SELECTION_MULTIPLE: - for (i = 0, list = clist->row_list; list; i++, list = list->next) - { - if (((NautilusCListRow *)(list->data))->state == GTK_STATE_NORMAL) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - i, -1, NULL); - } - return; - } -} - -static void -real_unselect_all (NautilusCList *clist) -{ - GList *list; - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - switch (clist->selection_mode) - { - case GTK_SELECTION_BROWSE: - if (clist->focus_row >= 0) - { - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - return; - } - break; - case GTK_SELECTION_EXTENDED: - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - break; - default: - break; - } - - list = clist->selection; - while (list) - { - i = GPOINTER_TO_INT (list->data); - list = list->next; - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[UNSELECT_ROW], i, -1, NULL); - } -} - -static void -fake_unselect_all (NautilusCList *clist, - gint row) -{ - GList *list; - GList *work; - gint i; - - if (row >= 0 && (work = ROW_ELEMENT (clist, row))) - { - if (NAUTILUS_CLIST_ROW (work)->state == GTK_STATE_NORMAL && - NAUTILUS_CLIST_ROW (work)->selectable) - { - NAUTILUS_CLIST_ROW (work)->state = GTK_STATE_SELECTED; - - if (CLIST_UNFROZEN (clist) && - nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, - NAUTILUS_CLIST_ROW (work)); - } - } - - clist->undo_selection = clist->selection; - clist->selection = NULL; - clist->selection_end = NULL; - - for (list = clist->undo_selection; list; list = list->next) - { - if ((i = GPOINTER_TO_INT (list->data)) == row || - !(work = g_list_nth (clist->row_list, i))) - continue; - - NAUTILUS_CLIST_ROW (work)->state = GTK_STATE_NORMAL; - if (CLIST_UNFROZEN (clist) && - nautilus_clist_row_is_visible (clist, i) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, i, - NAUTILUS_CLIST_ROW (work)); - } -} - -static void -real_undo_selection (NautilusCList *clist) -{ - GList *work; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || - clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - if (!(clist->undo_selection || clist->undo_unselection)) - { - nautilus_clist_unselect_all (clist); - return; - } - - for (work = clist->undo_selection; work; work = work->next) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - GPOINTER_TO_INT (work->data), -1, NULL); - - for (work = clist->undo_unselection; work; work = work->next) - { - /* g_print ("unselect %d\n",GPOINTER_TO_INT (work->data)); */ - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - GPOINTER_TO_INT (work->data), -1, NULL); - } - - if (GTK_WIDGET_HAS_FOCUS(clist) && clist->focus_row != clist->undo_anchor) - { - nautilus_clist_draw_focus (GTK_WIDGET (clist)); - clist->focus_row = clist->undo_anchor; - nautilus_clist_draw_focus (GTK_WIDGET (clist)); - } - else - clist->focus_row = clist->undo_anchor; - - clist->undo_anchor = -1; - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height > - clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); -} - -static void -set_anchor (NautilusCList *clist, - gboolean add_mode, - gint anchor, - gint undo_anchor) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor >= 0) - return; - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - if (add_mode) - fake_toggle_row (clist, anchor); - else - { - NAUTILUS_CLIST_CLASS_FW (clist)->fake_unselect_all (clist, anchor); - clist->anchor_state = GTK_STATE_SELECTED; - } - - clist->anchor = anchor; - clist->drag_pos = anchor; - clist->undo_anchor = undo_anchor; -} - -static void -resync_selection (NautilusCList *clist, - GdkEvent *event) -{ - gint i; - gint e; - gint row; - GList *list; - NautilusCListRow *clist_row; - - if (clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (clist->anchor < 0 || clist->drag_pos < 0) - return; - - nautilus_clist_freeze (clist); - - i = MIN (clist->anchor, clist->drag_pos); - e = MAX (clist->anchor, clist->drag_pos); - - if (clist->undo_selection) - { - list = clist->selection; - clist->selection = clist->undo_selection; - clist->selection_end = g_list_last (clist->selection); - clist->undo_selection = list; - list = clist->selection; - while (list) - { - row = GPOINTER_TO_INT (list->data); - list = list->next; - if (row < i || row > e) - { - clist_row = g_list_nth (clist->row_list, row)->data; - if (clist_row->selectable) - { - clist_row->state = GTK_STATE_SELECTED; - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[UNSELECT_ROW], - row, -1, event); - clist->undo_selection = g_list_prepend - (clist->undo_selection, GINT_TO_POINTER (row)); - } - } - } - } - - if (clist->anchor < clist->drag_pos) - { - for (list = g_list_nth (clist->row_list, i); i <= e; - i++, list = list->next) - if (NAUTILUS_CLIST_ROW (list)->selectable) - { - if (g_list_find (clist->selection, GINT_TO_POINTER(i))) - { - if (NAUTILUS_CLIST_ROW (list)->state == GTK_STATE_NORMAL) - { - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_SELECTED; - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[UNSELECT_ROW], - i, -1, event); - clist->undo_selection = - g_list_prepend (clist->undo_selection, - GINT_TO_POINTER (i)); - } - } - else if (NAUTILUS_CLIST_ROW (list)->state == GTK_STATE_SELECTED) - { - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, - GINT_TO_POINTER (i)); - } - } - } - else - { - for (list = g_list_nth (clist->row_list, e); i <= e; - e--, list = list->prev) - if (NAUTILUS_CLIST_ROW (list)->selectable) - { - if (g_list_find (clist->selection, GINT_TO_POINTER(e))) - { - if (NAUTILUS_CLIST_ROW (list)->state == GTK_STATE_NORMAL) - { - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_SELECTED; - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[UNSELECT_ROW], - e, -1, event); - clist->undo_selection = - g_list_prepend (clist->undo_selection, - GINT_TO_POINTER (e)); - } - } - else if (NAUTILUS_CLIST_ROW (list)->state == GTK_STATE_SELECTED) - { - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, - GINT_TO_POINTER (e)); - } - } - } - - clist->undo_unselection = g_list_reverse (clist->undo_unselection); - for (list = clist->undo_unselection; list; list = list->next) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - GPOINTER_TO_INT (list->data), -1, event); - - clist->anchor = -1; - clist->drag_pos = -1; - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -static void -update_extended_selection (NautilusCList *clist, - gint row) -{ - gint i; - GList *list; - GdkRectangle area; - gint s1 = -1; - gint s2 = -1; - gint e1 = -1; - gint e2 = -1; - gint y1 = clist->clist_window_height; - gint y2 = clist->clist_window_height; - gint h1 = 0; - gint h2 = 0; - gint top; - - if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor == -1) - return; - - if (row < 0) - row = 0; - if (row >= clist->rows) - row = clist->rows - 1; - - /* extending downwards */ - if (row > clist->drag_pos && clist->anchor <= clist->drag_pos) - { - s2 = clist->drag_pos + 1; - e2 = row; - } - /* extending upwards */ - else if (row < clist->drag_pos && clist->anchor >= clist->drag_pos) - { - s2 = row; - e2 = clist->drag_pos - 1; - } - else if (row < clist->drag_pos && clist->anchor < clist->drag_pos) - { - e1 = clist->drag_pos; - /* row and drag_pos on different sides of anchor : - take back the selection between anchor and drag_pos, - select between anchor and row */ - if (row < clist->anchor) - { - s1 = clist->anchor + 1; - s2 = row; - e2 = clist->anchor - 1; - } - /* take back the selection between anchor and drag_pos */ - else - s1 = row + 1; - } - else if (row > clist->drag_pos && clist->anchor > clist->drag_pos) - { - s1 = clist->drag_pos; - /* row and drag_pos on different sides of anchor : - take back the selection between anchor and drag_pos, - select between anchor and row */ - if (row > clist->anchor) - { - e1 = clist->anchor - 1; - s2 = clist->anchor + 1; - e2 = row; - } - /* take back the selection between anchor and drag_pos */ - else - e1 = row - 1; - } - - clist->drag_pos = row; - - area.x = 0; - area.width = clist->clist_window_width; - - /* restore the elements between s1 and e1 */ - if (s1 >= 0) - { - for (i = s1, list = g_list_nth (clist->row_list, i); i <= e1; - i++, list = list->next) - if (NAUTILUS_CLIST_ROW (list)->selectable) - { - if (NAUTILUS_CLIST_CLASS_FW (clist)->selection_find (clist, i, list)) - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_SELECTED; - else - NAUTILUS_CLIST_ROW (list)->state = GTK_STATE_NORMAL; - } - - top = ROW_TOP_YPIXEL (clist, clist->focus_row); - - if (top + clist->row_height <= 0) - { - area.y = 0; - area.height = ROW_TOP_YPIXEL (clist, e1) + clist->row_height; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - } - else if (top >= clist->clist_window_height) - { - area.y = ROW_TOP_YPIXEL (clist, s1) - 1; - area.height = clist->clist_window_height - area.y; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - } - else if (top < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - else if (top + clist->row_height > clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - - y1 = ROW_TOP_YPIXEL (clist, s1) - 1; - h1 = (e1 - s1 + 1) * (clist->row_height + CELL_SPACING); - } - - /* extend the selection between s2 and e2 */ - if (s2 >= 0) - { - for (i = s2, list = g_list_nth (clist->row_list, i); i <= e2; - i++, list = list->next) - if (NAUTILUS_CLIST_ROW (list)->selectable && - NAUTILUS_CLIST_ROW (list)->state != clist->anchor_state) - NAUTILUS_CLIST_ROW (list)->state = clist->anchor_state; - - top = ROW_TOP_YPIXEL (clist, clist->focus_row); - - if (top + clist->row_height <= 0) - { - area.y = 0; - area.height = ROW_TOP_YPIXEL (clist, e2) + clist->row_height; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - } - else if (top >= clist->clist_window_height) - { - area.y = ROW_TOP_YPIXEL (clist, s2) - 1; - area.height = clist->clist_window_height - area.y; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - } - else if (top < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - else if (top + clist->row_height > clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - - y2 = ROW_TOP_YPIXEL (clist, s2) - 1; - h2 = (e2 - s2 + 1) * (clist->row_height + CELL_SPACING); - } - - area.y = MAX (0, MIN (y1, y2)); - if (area.y > clist->clist_window_height) - area.y = 0; - area.height = MIN (clist->clist_window_height, h1 + h2); - if (s1 >= 0 && s2 >= 0) - area.height += (clist->row_height + CELL_SPACING); - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); -} - -static void -start_selection (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - set_anchor (clist, NAUTILUS_CLIST_ADD_MODE(clist), clist->focus_row, - clist->focus_row); -} - -static void -end_selection (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist)) - return; - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); -} - -static void -extend_selection (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) || - clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (auto_start_selection) - set_anchor (clist, NAUTILUS_CLIST_ADD_MODE(clist), clist->focus_row, - clist->focus_row); - else if (clist->anchor == -1) - return; - - move_focus_row (clist, scroll_type, position); - - if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height > - clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - - update_extended_selection (clist, clist->focus_row); -} - -static void -sync_selection (NautilusCList *clist, - gint row, - gint mode) -{ - GList *list; - gint d; - - if (mode == SYNC_INSERT) - d = 1; - else - d = -1; - - if (clist->focus_row >= row) - { - if (d > 0 || clist->focus_row > row) - clist->focus_row += d; - if (clist->focus_row == -1 && clist->rows >= 1) - clist->focus_row = 0; - else if (clist->focus_row >= clist->rows) - clist->focus_row = clist->rows - 1; - } - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - - list = clist->selection; - - while (list) - { - if (GPOINTER_TO_INT (list->data) >= row) - list->data = ((gchar*) list->data) + d; - list = list->next; - } -} - -/* GTKOBJECT - * nautilus_clist_destroy - * nautilus_clist_finalize - */ -static void -nautilus_clist_destroy (GtkObject *object) -{ - gint i; - NautilusCList *clist; - - g_return_if_fail (object != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (object)); - - clist = NAUTILUS_CLIST (object); - - /* freeze the list */ - clist->freeze_count++; - - /* get rid of all the rows */ - nautilus_clist_clear (clist); - - /* Since we don't have a _remove method, unparent the children - * instead of destroying them so the focus will be unset properly. - * (For other containers, the _remove method takes care of the - * unparent) The destroy will happen when the refcount drops - * to zero. - */ - - /* unref adjustments */ - if (clist->hadjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (clist->hadjustment), clist); - gtk_object_unref (GTK_OBJECT (clist->hadjustment)); - clist->hadjustment = NULL; - } - if (clist->vadjustment) - { - gtk_signal_disconnect_by_data (GTK_OBJECT (clist->vadjustment), clist); - gtk_object_unref (GTK_OBJECT (clist->vadjustment)); - clist->vadjustment = NULL; - } - - remove_grab (clist); - - /* destroy the column buttons */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button) - { - gtk_widget_unparent (clist->column[i].button); - clist->column[i].button = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -nautilus_clist_finalize (GtkObject *object) -{ - NautilusCList *clist; - - g_return_if_fail (object != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (object)); - - clist = NAUTILUS_CLIST (object); - - columns_delete (clist); - - g_mem_chunk_destroy (clist->cell_mem_chunk); - g_mem_chunk_destroy (clist->row_mem_chunk); - - if (GTK_OBJECT_CLASS (parent_class)->finalize) - (*GTK_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* GTKWIDGET - * nautilus_clist_realize - * nautilus_clist_unrealize - * nautilus_clist_map - * nautilus_clist_unmap - * nautilus_clist_draw - * nautilus_clist_expose - * nautilus_clist_style_set - * nautilus_clist_key_press - * nautilus_clist_button_press - * nautilus_clist_button_release - * nautilus_clist_motion - * nautilus_clist_size_request - * nautilus_clist_size_allocate - */ -static void -nautilus_clist_realize (GtkWidget *widget) -{ - NautilusCList *clist; - GdkWindowAttr attributes; - GdkGCValues values; - NautilusCListRow *clist_row; - GList *list; - gint attributes_mask; - gint border_width; - gint i; - gint j; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - border_width = GTK_CONTAINER (widget)->border_width; - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + border_width; - attributes.y = widget->allocation.y + border_width; - attributes.width = widget->allocation.width - border_width * 2; - attributes.height = widget->allocation.height - border_width * 2; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK); - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - /* main window */ - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, clist); - - widget->style = gtk_style_attach (widget->style, widget->window); - - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - - /* column-title window */ - - attributes.x = clist->column_title_area.x; - attributes.y = clist->column_title_area.y; - attributes.width = clist->column_title_area.width; - attributes.height = clist->column_title_area.height; - - clist->title_window = gdk_window_new (widget->window, &attributes, - attributes_mask); - gdk_window_set_user_data (clist->title_window, clist); - - gtk_style_set_background (widget->style, clist->title_window, - GTK_STATE_NORMAL); - gdk_window_show (clist->title_window); - - /* set things up so column buttons are drawn in title window */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button) - gtk_widget_set_parent_window (clist->column[i].button, - clist->title_window); - - /* clist-window */ - attributes.x = (clist->internal_allocation.x + - widget->style->klass->xthickness); - attributes.y = (clist->internal_allocation.y + - widget->style->klass->ythickness + - clist->column_title_area.height); - attributes.width = clist->clist_window_width; - attributes.height = clist->clist_window_height; - - clist->clist_window = gdk_window_new (widget->window, &attributes, - attributes_mask); - gdk_window_set_user_data (clist->clist_window, clist); - - gdk_window_set_background (clist->clist_window, - &widget->style->base[GTK_STATE_NORMAL]); - gdk_window_show (clist->clist_window); - gdk_window_get_size (clist->clist_window, &clist->clist_window_width, - &clist->clist_window_height); - - /* create resize windows */ - attributes.wclass = GDK_INPUT_ONLY; - attributes.event_mask = (GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_KEY_PRESS_MASK); - attributes_mask = GDK_WA_CURSOR; - attributes.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - clist->cursor_drag = attributes.cursor; - - attributes.x = LIST_WIDTH (clist) + 1; - attributes.y = 0; - attributes.width = 0; - attributes.height = 0; - - for (i = 0; i < clist->columns; i++) - { - clist->column[i].window = gdk_window_new (clist->title_window, - &attributes, attributes_mask); - gdk_window_set_user_data (clist->column[i].window, clist); - } - - /* This is slightly less efficient than creating them with the - * right size to begin with, but easier - */ - size_allocate_title_buttons (clist); - - /* GCs */ - clist->fg_gc = gdk_gc_new (widget->window); - clist->bg_gc = gdk_gc_new (widget->window); - - /* We'll use this gc to do scrolling as well */ - gdk_gc_set_exposures (clist->fg_gc, TRUE); - - values.foreground = (widget->style->white.pixel==0 ? - widget->style->black:widget->style->white); - values.function = GDK_XOR; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - clist->xor_gc = gdk_gc_new_with_values (widget->window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_FUNCTION | - GDK_GC_SUBWINDOW); - - /* attach optional row/cell styles, allocate foreground/background colors */ - list = clist->row_list; - for (i = 0; i < clist->rows; i++) - { - clist_row = list->data; - list = list->next; - - if (clist_row->style) - clist_row->style = gtk_style_attach (clist_row->style, - clist->clist_window); - - if (clist_row->fg_set || clist_row->bg_set) - { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (widget); - if (clist_row->fg_set) - gdk_color_alloc (colormap, &clist_row->foreground); - if (clist_row->bg_set) - gdk_color_alloc (colormap, &clist_row->background); - } - - for (j = 0; j < clist->columns; j++) - if (clist_row->cell[j].style) - clist_row->cell[j].style = - gtk_style_attach (clist_row->cell[j].style, clist->clist_window); - } -} - -static void -nautilus_clist_unrealize (GtkWidget *widget) -{ - gint i; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - /* freeze the list */ - clist->freeze_count++; - - if (GTK_WIDGET_MAPPED (widget)) - nautilus_clist_unmap (widget); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - - /* detach optional row/cell styles */ - if (GTK_WIDGET_REALIZED (widget)) - { - NautilusCListRow *clist_row; - GList *list; - gint j; - - list = clist->row_list; - for (i = 0; i < clist->rows; i++) - { - clist_row = list->data; - list = list->next; - - if (clist_row->style) - gtk_style_detach (clist_row->style); - for (j = 0; j < clist->columns; j++) - if (clist_row->cell[j].style) - gtk_style_detach (clist_row->cell[j].style); - } - } - - gdk_cursor_destroy (clist->cursor_drag); - gdk_gc_destroy (clist->xor_gc); - gdk_gc_destroy (clist->fg_gc); - gdk_gc_destroy (clist->bg_gc); - - for (i = 0; i < clist->columns; i++) - { - if (clist->column[i].button) - gtk_widget_unrealize (clist->column[i].button); - if (clist->column[i].window) - { - gdk_window_set_user_data (clist->column[i].window, NULL); - gdk_window_destroy (clist->column[i].window); - clist->column[i].window = NULL; - } - } - - gdk_window_set_user_data (clist->clist_window, NULL); - gdk_window_destroy (clist->clist_window); - clist->clist_window = NULL; - - gdk_window_set_user_data (clist->title_window, NULL); - gdk_window_destroy (clist->title_window); - clist->title_window = NULL; - - clist->cursor_drag = NULL; - clist->xor_gc = NULL; - clist->fg_gc = NULL; - clist->bg_gc = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); -} - -static void -nautilus_clist_map (GtkWidget *widget) -{ - gint i; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - if (!GTK_WIDGET_MAPPED (widget)) - { - GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED); - - /* map column buttons */ - for (i = 0; i < clist->columns; i++) - { - if (clist->column[i].button && - GTK_WIDGET_VISIBLE (clist->column[i].button) && - !GTK_WIDGET_MAPPED (clist->column[i].button)) - gtk_widget_map (clist->column[i].button); - } - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].window && clist->column[i].button) - { - gdk_window_raise (clist->column[i].window); - gdk_window_show (clist->column[i].window); - } - - gdk_window_show (clist->title_window); - gdk_window_show (clist->clist_window); - gdk_window_show (widget->window); - - /* unfreeze the list */ - clist->freeze_count = 0; - clist->refresh_at_unfreeze_time = FALSE; - } -} - -static void -nautilus_clist_unmap (GtkWidget *widget) -{ - gint i; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - if (GTK_WIDGET_MAPPED (widget)) - { - GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - { - remove_grab (clist); - - NAUTILUS_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL); - - clist->click_cell.row = -1; - clist->click_cell.column = -1; - clist->drag_button = 0; - - if (NAUTILUS_CLIST_IN_DRAG(clist)) - { - gpointer drag_data; - - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG); - drag_data = gtk_object_get_data (GTK_OBJECT (clist), - "gtk-site-data"); - if (drag_data) - gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), - drag_data); - } - } - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].window) - gdk_window_hide (clist->column[i].window); - - gdk_window_hide (clist->clist_window); - gdk_window_hide (clist->title_window); - gdk_window_hide (widget->window); - - /* unmap column buttons */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button && - GTK_WIDGET_MAPPED (clist->column[i].button)) - gtk_widget_unmap (clist->column[i].button); - - /* freeze the list */ - clist->freeze_count++; - } -} - -static void -nautilus_clist_draw (GtkWidget *widget, - GdkRectangle *area) -{ - g_error ("this should not be called, the NautilusList drawing would be disrupted by this"); -} - -static gint -nautilus_clist_expose (GtkWidget *widget, - GdkEventExpose *event) -{ - g_error ("this should not be called, the NautilusList drawing would be disrupted by this"); - return FALSE; -} - -static void -nautilus_clist_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous_style); - - clist = NAUTILUS_CLIST (widget); - - if (GTK_WIDGET_REALIZED (widget)) - { - gtk_style_set_background (widget->style, widget->window, widget->state); - gtk_style_set_background (widget->style, clist->title_window, GTK_STATE_SELECTED); - gdk_window_set_background (clist->clist_window, &widget->style->base[GTK_STATE_NORMAL]); - } - - /* Fill in data after widget has correct style */ - - /* text properties */ - if (!NAUTILUS_CLIST_ROW_HEIGHT_SET(clist)) - { - clist->row_height = (widget->style->font->ascent + - widget->style->font->descent + 1); - clist->row_center_offset = widget->style->font->ascent + 1.5; - } - else - clist->row_center_offset = 1.5 + (clist->row_height + - widget->style->font->ascent - - widget->style->font->descent - 1) / 2; - - /* Column widths */ - if (!NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist)) - { - gint width; - gint i; - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - width = nautilus_clist_optimal_column_width (clist, i); - if (width != clist->column[i].width) - nautilus_clist_set_column_width (clist, i, width); - } - } -} - -static gint -nautilus_clist_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - if (GTK_WIDGET_CLASS (parent_class)->key_press_event && - GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event)) - return TRUE; - - switch (event->keyval) - { - case GDK_Tab: - case GDK_ISO_Left_Tab: - if (event->state & GDK_SHIFT_MASK) - return gtk_container_focus (GTK_CONTAINER (widget), - GTK_DIR_TAB_BACKWARD); - else - return gtk_container_focus (GTK_CONTAINER (widget), - GTK_DIR_TAB_FORWARD); - default: - break; - } - return FALSE; -} - -static gint -nautilus_clist_button_press (GtkWidget *widget, - GdkEventButton *event) -{ - gint i; - NautilusCList *clist; - gint x; - gint y; - gint row; - gint column; - gint button_actions; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - clist = NAUTILUS_CLIST (widget); - - button_actions = clist->button_actions[event->button - 1]; - - if (button_actions == NAUTILUS_BUTTON_IGNORED) - return FALSE; - - /* selections on the list */ - if (event->window == clist->clist_window) - { - x = event->x; - y = event->y; - - if (get_selection_info (clist, x, y, &row, &column)) - { - gint old_row = clist->focus_row; - - if (clist->focus_row == -1) - old_row = row; - - if (event->type == GDK_BUTTON_PRESS) - { - GdkEventMask mask = ((1 << (4 + event->button)) | - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON_RELEASE_MASK); - - if (gdk_pointer_grab (clist->clist_window, FALSE, mask, - NULL, NULL, event->time)) - return FALSE; - gtk_grab_add (widget); - - clist->click_cell.row = row; - clist->click_cell.column = column; - clist->drag_button = event->button; - } - else - { - clist->click_cell.row = -1; - clist->click_cell.column = -1; - - clist->drag_button = 0; - remove_grab (clist); - } - - if (button_actions & NAUTILUS_BUTTON_SELECTS) - { - if (NAUTILUS_CLIST_ADD_MODE(clist)) - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_ADD_MODE); - if (GTK_WIDGET_HAS_FOCUS(widget)) - { - nautilus_clist_draw_focus (widget); - gdk_gc_set_line_attributes (clist->xor_gc, 1, - GDK_LINE_SOLID, 0, 0); - clist->focus_row = row; - nautilus_clist_draw_focus (widget); - } - else - { - gdk_gc_set_line_attributes (clist->xor_gc, 1, - GDK_LINE_SOLID, 0, 0); - clist->focus_row = row; - } - } - else if (row != clist->focus_row) - { - if (GTK_WIDGET_HAS_FOCUS(widget)) - { - nautilus_clist_draw_focus (widget); - clist->focus_row = row; - nautilus_clist_draw_focus (widget); - } - else - clist->focus_row = row; - } - } - - if (!GTK_WIDGET_HAS_FOCUS(widget)) - gtk_widget_grab_focus (widget); - - if (button_actions & NAUTILUS_BUTTON_SELECTS) - { - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_MULTIPLE: - if (event->type != GDK_BUTTON_PRESS) - { - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - row, column, event); - clist->anchor = -1; - } - else - clist->anchor = row; - break; - case GTK_SELECTION_BROWSE: - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - row, column, event); - break; - case GTK_SELECTION_EXTENDED: - if (event->type != GDK_BUTTON_PRESS) - { - if (clist->anchor != -1) - { - update_extended_selection (clist, clist->focus_row); - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection - (clist, (GdkEvent *) event); - } - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - row, column, event); - break; - } - - if (event->state & GDK_CONTROL_MASK) - { - if (event->state & GDK_SHIFT_MASK) - { - if (clist->anchor < 0) - { - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - clist->anchor = old_row; - clist->drag_pos = old_row; - clist->undo_anchor = old_row; - } - update_extended_selection (clist, clist->focus_row); - } - else - { - if (clist->anchor == -1) - set_anchor (clist, TRUE, row, old_row); - else - update_extended_selection (clist, - clist->focus_row); - } - break; - } - - if (event->state & GDK_SHIFT_MASK) - { - set_anchor (clist, FALSE, old_row, old_row); - update_extended_selection (clist, clist->focus_row); - break; - } - - if (clist->anchor == -1) - set_anchor (clist, FALSE, row, old_row); - else - update_extended_selection (clist, clist->focus_row); - break; - default: - break; - } - } - } - return FALSE; - } - - /* press on resize windows */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].resizeable && clist->column[i].window && - event->window == clist->column[i].window) - { - gpointer drag_data; - - if (gdk_pointer_grab (clist->column[i].window, FALSE, - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON1_MOTION_MASK | - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time)) - return FALSE; - - gtk_grab_add (widget); - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_IN_DRAG); - - /* block attached dnd signal handler */ - drag_data = gtk_object_get_data (GTK_OBJECT (clist), "gtk-site-data"); - if (drag_data) - gtk_signal_handler_block_by_data (GTK_OBJECT (clist), drag_data); - - if (!GTK_WIDGET_HAS_FOCUS(widget)) - gtk_widget_grab_focus (widget); - - clist->drag_pos = i; - clist->x_drag = (COLUMN_LEFT_XPIXEL(clist, i) + COLUMN_INSET + - clist->column[i].area.width + CELL_SPACING); - - if (NAUTILUS_CLIST_ADD_MODE(clist)) - gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0); - draw_xor_line (clist); - } - return FALSE; -} - -static gint -nautilus_clist_button_release (GtkWidget *widget, - GdkEventButton *event) -{ - NautilusCList *clist; - gint button_actions; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - clist = NAUTILUS_CLIST (widget); - - button_actions = clist->button_actions[event->button - 1]; - if (button_actions == NAUTILUS_BUTTON_IGNORED) - return FALSE; - - /* release on resize windows */ - if (NAUTILUS_CLIST_IN_DRAG(clist)) - { - gpointer drag_data; - gint width; - gint x; - gint i; - - i = clist->drag_pos; - clist->drag_pos = -1; - - /* unblock attached dnd signal handler */ - drag_data = gtk_object_get_data (GTK_OBJECT (clist), "gtk-site-data"); - if (drag_data) - gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), drag_data); - - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG); - gtk_widget_get_pointer (widget, &x, NULL); - gtk_grab_remove (widget); - gdk_pointer_ungrab (event->time); - - if (clist->x_drag >= 0) - draw_xor_line (clist); - - if (NAUTILUS_CLIST_ADD_MODE(clist)) - { - gdk_gc_set_line_attributes (clist->xor_gc, 1, - GDK_LINE_ON_OFF_DASH, 0, 0); - gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2); - } - - width = new_column_width (clist, i, &x); - nautilus_clist_set_column_width (clist, i, width); - return FALSE; - } - - if (clist->drag_button == event->button) - { - gint row; - gint column; - - clist->drag_button = 0; - clist->click_cell.row = -1; - clist->click_cell.column = -1; - - remove_grab (clist); - - if (button_actions & NAUTILUS_BUTTON_SELECTS) - { - switch (clist->selection_mode) - { - case GTK_SELECTION_EXTENDED: - if (!(event->state & GDK_SHIFT_MASK) || - !GTK_WIDGET_CAN_FOCUS (widget) || - event->x < 0 || event->x >= clist->clist_window_width || - event->y < 0 || event->y >= clist->clist_window_height) - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection - (clist, (GdkEvent *) event); - break; - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_MULTIPLE: - if (get_selection_info (clist, event->x, event->y, - &row, &column)) - { - if (row >= 0 && row < clist->rows && clist->anchor == row) - toggle_row (clist, row, column, (GdkEvent *) event); - } - clist->anchor = -1; - break; - default: - break; - } - } - } - return FALSE; -} - -static gint -nautilus_clist_motion (GtkWidget *widget, - GdkEventMotion *event) -{ - NautilusCList *clist; - gint x; - gint y; - gint row; - gint new_width; - gint button_actions = 0; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - - clist = NAUTILUS_CLIST (widget); - if (!(gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist))) - return FALSE; - - if (clist->drag_button > 0) - button_actions = clist->button_actions[clist->drag_button - 1]; - - if (NAUTILUS_CLIST_IN_DRAG(clist)) - { - if (event->is_hint || event->window != widget->window) - gtk_widget_get_pointer (widget, &x, NULL); - else - x = event->x; - - new_width = new_column_width (clist, clist->drag_pos, &x); - if (x != clist->x_drag) - { - /* x_drag < 0 indicates that the xor line is already invisible */ - if (clist->x_drag >= 0) - draw_xor_line (clist); - - clist->x_drag = x; - - if (clist->x_drag >= 0) - draw_xor_line (clist); - } - - if (new_width <= MAX (COLUMN_MIN_WIDTH + 1, - clist->column[clist->drag_pos].min_width + 1)) - { - if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) < 0 && x < 0) - nautilus_clist_moveto (clist, -1, clist->drag_pos, 0, 0); - return FALSE; - } - if (clist->column[clist->drag_pos].max_width >= COLUMN_MIN_WIDTH && - new_width >= clist->column[clist->drag_pos].max_width) - { - if (COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) + new_width > - clist->clist_window_width && x < 0) - move_horizontal (clist, - COLUMN_LEFT_XPIXEL (clist, clist->drag_pos) + - new_width - clist->clist_window_width + - COLUMN_INSET + CELL_SPACING); - return FALSE; - } - } - - if (event->is_hint || event->window != clist->clist_window) - gdk_window_get_pointer (clist->clist_window, &x, &y, NULL); - - if (NAUTILUS_CLIST_REORDERABLE(clist) && button_actions & NAUTILUS_BUTTON_DRAGS) - { - /* delayed drag start */ - if (event->window == clist->clist_window && - clist->click_cell.row >= 0 && clist->click_cell.column >= 0 && - (y < 0 || y >= clist->clist_window_height || - x < 0 || x >= clist->clist_window_width || - y < ROW_TOP_YPIXEL (clist, clist->click_cell.row) || - y >= (ROW_TOP_YPIXEL (clist, clist->click_cell.row) + - clist->row_height) || - x < COLUMN_LEFT_XPIXEL (clist, clist->click_cell.column) || - x >= (COLUMN_LEFT_XPIXEL(clist, clist->click_cell.column) + - clist->column[clist->click_cell.column].area.width))) - { - GtkTargetList *target_list; - - target_list = gtk_target_list_new (&clist_target_table, 1); - gtk_drag_begin (widget, target_list, GDK_ACTION_MOVE, - clist->drag_button, (GdkEvent *)event); - - } - return TRUE; - } - - /* horizontal autoscrolling */ - if (clist->hadjustment && LIST_WIDTH (clist) > clist->clist_window_width && - (x < 0 || x >= clist->clist_window_width)) - { - if (clist->htimer) - return FALSE; - - clist->htimer = gtk_timeout_add - (SCROLL_TIME, (GtkFunction) horizontal_timeout, clist); - - if (!((x < 0 && clist->hadjustment->value == 0) || - (x >= clist->clist_window_width && - clist->hadjustment->value == - LIST_WIDTH (clist) - clist->clist_window_width))) - { - if (x < 0) - move_horizontal (clist, -1 + (x/2)); - else - move_horizontal (clist, 1 + (x - clist->clist_window_width) / 2); - } - } - - if (NAUTILUS_CLIST_IN_DRAG(clist)) - return FALSE; - - /* vertical autoscrolling */ - row = ROW_FROM_YPIXEL (clist, y); - - /* don't scroll on last pixel row if it's a cell spacing */ - if (y == clist->clist_window_height - 1 && - y == ROW_TOP_YPIXEL (clist, row-1) + clist->row_height) - return FALSE; - - if (LIST_HEIGHT (clist) > clist->clist_window_height && - (y < 0 || y >= clist->clist_window_height)) - { - if (clist->vtimer) - return FALSE; - - clist->vtimer = gtk_timeout_add (SCROLL_TIME, - (GtkFunction) vertical_timeout, clist); - - if (clist->drag_button && - ((y < 0 && clist->focus_row == 0) || - (y >= clist->clist_window_height && - clist->focus_row == clist->rows - 1))) - return FALSE; - } - - row = CLAMP (row, 0, clist->rows - 1); - - if (button_actions & NAUTILUS_BUTTON_SELECTS & - !gtk_object_get_data (GTK_OBJECT (widget), "gtk-site-data")) - { - if (row == clist->focus_row) - return FALSE; - - nautilus_clist_draw_focus (widget); - clist->focus_row = row; - nautilus_clist_draw_focus (widget); - - switch (clist->selection_mode) - { - case GTK_SELECTION_BROWSE: - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - clist->focus_row, -1, event); - break; - case GTK_SELECTION_EXTENDED: - update_extended_selection (clist, clist->focus_row); - break; - default: - break; - } - } - - if (ROW_TOP_YPIXEL(clist, row) < 0) - move_vertical (clist, row, 0); - else if (ROW_TOP_YPIXEL(clist, row) + clist->row_height > - clist->clist_window_height) - move_vertical (clist, row, 1); - - return FALSE; -} - -static void -nautilus_clist_size_request (GtkWidget *widget, - GtkRequisition *requisition) -{ - NautilusCList *clist; - gint i; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (requisition != NULL); - - clist = NAUTILUS_CLIST (widget); - - requisition->width = 0; - requisition->height = 0; - - /* compute the size of the column title (title) area */ - clist->column_title_area.height = 0; - if (NAUTILUS_CLIST_SHOW_TITLES(clist)) - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button) - { - GtkRequisition child_requisition; - - gtk_widget_size_request (clist->column[i].button, - &child_requisition); - clist->column_title_area.height = - MAX (clist->column_title_area.height, - child_requisition.height); - } - - requisition->width += (widget->style->klass->xthickness + - GTK_CONTAINER (widget)->border_width) * 2; - requisition->height += (clist->column_title_area.height + - (widget->style->klass->ythickness + - GTK_CONTAINER (widget)->border_width) * 2); - - /* if (!clist->hadjustment) */ - requisition->width += list_requisition_width (clist); - /* if (!clist->vadjustment) */ - requisition->height += LIST_HEIGHT (clist); -} - -static void -nautilus_clist_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) -{ - NautilusCList *clist; - GtkAllocation clist_allocation; - gint border_width; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (allocation != NULL); - - clist = NAUTILUS_CLIST (widget); - widget->allocation = *allocation; - border_width = GTK_CONTAINER (widget)->border_width; - - if (GTK_WIDGET_REALIZED (widget)) - { - gdk_window_move_resize (widget->window, - allocation->x + border_width, - allocation->y + border_width, - allocation->width - border_width * 2, - allocation->height - border_width * 2); - } - - /* use internal allocation structure for all the math - * because it's easier than always subtracting the container - * border width */ - clist->internal_allocation.x = 0; - clist->internal_allocation.y = 0; - clist->internal_allocation.width = MAX (1, (gint)allocation->width - - border_width * 2); - clist->internal_allocation.height = MAX (1, (gint)allocation->height - - border_width * 2); - - /* allocate clist window assuming no scrollbars */ - clist_allocation.x = (clist->internal_allocation.x + - widget->style->klass->xthickness); - clist_allocation.y = (clist->internal_allocation.y + - widget->style->klass->ythickness + - clist->column_title_area.height); - clist_allocation.width = MAX (1, (gint)clist->internal_allocation.width - - (2 * (gint)widget->style->klass->xthickness)); - clist_allocation.height = MAX (1, (gint)clist->internal_allocation.height - - (2 * (gint)widget->style->klass->ythickness) - - (gint)clist->column_title_area.height); - - clist->clist_window_width = clist_allocation.width; - clist->clist_window_height = clist_allocation.height; - - if (GTK_WIDGET_REALIZED (widget)) - { - gdk_window_move_resize (clist->clist_window, - clist_allocation.x, - clist_allocation.y, - clist_allocation.width, - clist_allocation.height); - } - - /* position the window which holds the column title buttons */ - clist->column_title_area.x = widget->style->klass->xthickness; - clist->column_title_area.y = widget->style->klass->ythickness; - clist->column_title_area.width = clist_allocation.width; - - if (GTK_WIDGET_REALIZED (widget)) - { - gdk_window_move_resize (clist->title_window, - clist->column_title_area.x, - clist->column_title_area.y, - clist->column_title_area.width, - clist->column_title_area.height); - } - - /* column button allocation */ - size_allocate_columns (clist, FALSE); - size_allocate_title_buttons (clist); - - adjust_adjustments (clist, TRUE); -} - -/* GTKCONTAINER - * nautilus_clist_forall - */ -static void -nautilus_clist_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - NautilusCList *clist; - int i; - - g_return_if_fail (container != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (container)); - g_return_if_fail (callback != NULL); - - if (!include_internals) - return; - - clist = NAUTILUS_CLIST (container); - - /* callback for the column buttons */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].button) - (*callback) (clist->column[i].button, callback_data); -} - -/* PRIVATE DRAWING FUNCTIONS - * get_cell_style - * draw_row - * draw_rows - * draw_xor_line - * clist_refresh - */ -static void -get_cell_style (NautilusCList *clist, - NautilusCListRow *clist_row, - gint state, - gint column, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc) -{ - gint fg_state; - - if ((state == GTK_STATE_NORMAL) && - (GTK_WIDGET (clist)->state == GTK_STATE_INSENSITIVE)) - fg_state = GTK_STATE_INSENSITIVE; - else - fg_state = state; - - if (clist_row->cell[column].style) - { - if (style) - *style = clist_row->cell[column].style; - if (fg_gc) - *fg_gc = clist_row->cell[column].style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->cell[column].style->bg_gc[state]; - else - *bg_gc = clist_row->cell[column].style->base_gc[state]; - } - } - else if (clist_row->style) - { - if (style) - *style = clist_row->style; - if (fg_gc) - *fg_gc = clist_row->style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = clist_row->style->bg_gc[state]; - else - *bg_gc = clist_row->style->base_gc[state]; - } - } - else - { - if (style) - *style = GTK_WIDGET (clist)->style; - if (fg_gc) - *fg_gc = GTK_WIDGET (clist)->style->fg_gc[fg_state]; - if (bg_gc) { - if (state == GTK_STATE_SELECTED) - *bg_gc = GTK_WIDGET (clist)->style->bg_gc[state]; - else - *bg_gc = GTK_WIDGET (clist)->style->base_gc[state]; - } - - if (state != GTK_STATE_SELECTED) - { - if (fg_gc && clist_row->fg_set) - *fg_gc = clist->fg_gc; - if (bg_gc && clist_row->bg_set) - *bg_gc = clist->bg_gc; - } - } -} - -static void -draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row) -{ - g_error ("this should not be called, the NautilusList drawing would be disrupted by this"); -} - - -static void -draw_all (NautilusCList *clist) -{ - g_error ("this should not be called, the NautilusList drawing would be disrupted by this"); -} - -static void -draw_rows (NautilusCList *clist, - GdkRectangle *area) -{ - g_error ("this should not be called, the NautilusList drawing would be disrupted by this"); -} - -static void -draw_xor_line (NautilusCList *clist) -{ - GtkWidget *widget; - - g_return_if_fail (clist != NULL); - - widget = GTK_WIDGET (clist); - - gdk_draw_line (widget->window, clist->xor_gc, - clist->x_drag, - widget->style->klass->ythickness, - clist->x_drag, - clist->column_title_area.height + - clist->clist_window_height + 1); -} - -static void -clist_refresh (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (CLIST_UNFROZEN (clist)) - { - adjust_adjustments (clist, FALSE); - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - } -} - -/* get cell from coordinates - * get_selection_info - * nautilus_clist_get_selection_info - */ -static gint -get_selection_info (NautilusCList *clist, - gint x, - gint y, - gint *row, - gint *column) -{ - gint trow, tcol; - - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - - /* bounds checking, return false if the user clicked - * on a blank area */ - trow = ROW_FROM_YPIXEL (clist, y); - if (trow >= clist->rows) - return 0; - - if (row) - *row = trow; - - tcol = COLUMN_FROM_XPIXEL (clist, x); - if (tcol >= clist->columns) - return 0; - - if (column) - *column = tcol; - - return 1; -} - -gint -nautilus_clist_get_selection_info (NautilusCList *clist, - gint x, - gint y, - gint *row, - gint *column) -{ - g_return_val_if_fail (clist != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CLIST (clist), 0); - return get_selection_info (clist, x, y, row, column); -} - -/* PRIVATE ADJUSTMENT FUNCTIONS - * adjust_adjustments - * vadjustment_changed - * hadjustment_changed - * vadjustment_value_changed - * hadjustment_value_changed - * check_exposures - */ -static void -adjust_adjustments (NautilusCList *clist, - gboolean block_resize) -{ - if (clist->vadjustment) - { - clist->vadjustment->page_size = clist->clist_window_height; - clist->vadjustment->page_increment = clist->clist_window_height / 2; - clist->vadjustment->step_increment = clist->row_height; - clist->vadjustment->lower = 0; - clist->vadjustment->upper = LIST_HEIGHT (clist); - - if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist) || - (clist->voffset + (gint)clist->vadjustment->value) != 0) - { - clist->vadjustment->value = MAX (0, (LIST_HEIGHT (clist) - - clist->clist_window_height)); - gtk_signal_emit_by_name (GTK_OBJECT (clist->vadjustment), - "value_changed"); - } - gtk_signal_emit_by_name (GTK_OBJECT (clist->vadjustment), "changed"); - } - - if (clist->hadjustment) - { - clist->hadjustment->page_size = clist->clist_window_width; - clist->hadjustment->page_increment = clist->clist_window_width / 2; - clist->hadjustment->step_increment = 10; - clist->hadjustment->lower = 0; - clist->hadjustment->upper = LIST_WIDTH (clist); - - if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist) || - (clist->hoffset + (gint)clist->hadjustment->value) != 0) - { - clist->hadjustment->value = MAX (0, (LIST_WIDTH (clist) - - clist->clist_window_width)); - gtk_signal_emit_by_name (GTK_OBJECT (clist->hadjustment), - "value_changed"); - } - gtk_signal_emit_by_name (GTK_OBJECT (clist->hadjustment), "changed"); - } - - if (!block_resize && (!clist->vadjustment || !clist->hadjustment)) - { - GtkWidget *widget; - GtkRequisition requisition; - - widget = GTK_WIDGET (clist); - gtk_widget_size_request (widget, &requisition); - - if ((!clist->hadjustment && - requisition.width != widget->allocation.width) || - (!clist->vadjustment && - requisition.height != widget->allocation.height)) - gtk_widget_queue_resize (widget); - } -} - -static void -vadjustment_changed (GtkAdjustment *adjustment, - gpointer data) -{ - NautilusCList *clist; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - - clist = NAUTILUS_CLIST (data); -} - -static void -hadjustment_changed (GtkAdjustment *adjustment, - gpointer data) -{ - NautilusCList *clist; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - - clist = NAUTILUS_CLIST (data); -} - -static void -vadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data) -{ - NautilusCList *clist; - GdkRectangle area; - gint diff, value; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (data)); - - clist = NAUTILUS_CLIST (data); - - if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->vadjustment) - return; - - value = adjustment->value; - - if (value > -clist->voffset) - { - /* scroll down */ - diff = value + clist->voffset; - - /* we have to re-draw the whole screen here... */ - if (diff >= clist->clist_window_height) - { - clist->voffset = -value; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - return; - } - - if ((diff != 0) && (diff != clist->clist_window_height)) - gdk_window_copy_area (clist->clist_window, clist->fg_gc, - 0, 0, clist->clist_window, 0, diff, - clist->clist_window_width, - clist->clist_window_height - diff); - - area.x = 0; - area.y = clist->clist_window_height - diff; - area.width = clist->clist_window_width; - area.height = diff; - } - else - { - /* scroll up */ - diff = -clist->voffset - value; - - /* we have to re-draw the whole screen here... */ - if (diff >= clist->clist_window_height) - { - clist->voffset = -value; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - return; - } - - if ((diff != 0) && (diff != clist->clist_window_height)) - gdk_window_copy_area (clist->clist_window, clist->fg_gc, - 0, diff, clist->clist_window, 0, 0, - clist->clist_window_width, - clist->clist_window_height - diff); - - area.x = 0; - area.y = 0; - area.width = clist->clist_window_width; - area.height = diff; - } - - clist->voffset = -value; - if ((diff != 0) && (diff != clist->clist_window_height)) - check_exposures (clist); - - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); -} - -static void -hadjustment_value_changed (GtkAdjustment *adjustment, - gpointer data) -{ - NautilusCList *clist; - GdkRectangle area; - gint i; - gint y = 0; - gint diff = 0; - gint value; - - g_return_if_fail (adjustment != NULL); - g_return_if_fail (data != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (data)); - - clist = NAUTILUS_CLIST (data); - - if (!GTK_WIDGET_DRAWABLE (clist) || adjustment != clist->hadjustment) - return; - - value = adjustment->value; - - /* move the column buttons and resize windows */ - for (i = 0; i < clist->columns; i++) - { - if (clist->column[i].button) - { - clist->column[i].button->allocation.x -= value + clist->hoffset; - - if (clist->column[i].button->window) - { - gdk_window_move (clist->column[i].button->window, - clist->column[i].button->allocation.x, - clist->column[i].button->allocation.y); - - if (clist->column[i].window) - gdk_window_move (clist->column[i].window, - clist->column[i].button->allocation.x + - clist->column[i].button->allocation.width - - (DRAG_WIDTH / 2), 0); - } - } - } - - if (value > -clist->hoffset) - { - /* scroll right */ - diff = value + clist->hoffset; - - clist->hoffset = -value; - - /* we have to re-draw the whole screen here... */ - if (diff >= clist->clist_window_width) - { - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - return; - } - - if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) && - !NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist) && NAUTILUS_CLIST_ADD_MODE(clist)) - { - y = ROW_TOP_YPIXEL (clist, clist->focus_row); - - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y, - clist->clist_window_width - 1, - clist->row_height - 1); - } - gdk_window_copy_area (clist->clist_window, - clist->fg_gc, - 0, 0, - clist->clist_window, - diff, - 0, - clist->clist_window_width - diff, - clist->clist_window_height); - - area.x = clist->clist_window_width - diff; - } - else - { - /* scroll left */ - if (!(diff = -clist->hoffset - value)) - return; - - clist->hoffset = -value; - - /* we have to re-draw the whole screen here... */ - if (diff >= clist->clist_window_width) - { - NAUTILUS_CLIST_CLASS_FW (clist)->draw_all (clist); - return; - } - - if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) && - !NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist) && NAUTILUS_CLIST_ADD_MODE(clist)) - { - y = ROW_TOP_YPIXEL (clist, clist->focus_row); - - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y, - clist->clist_window_width - 1, - clist->row_height - 1); - } - - gdk_window_copy_area (clist->clist_window, - clist->fg_gc, - diff, 0, - clist->clist_window, - 0, - 0, - clist->clist_window_width - diff, - clist->clist_window_height); - - area.x = 0; - } - - area.y = 0; - area.width = diff; - area.height = clist->clist_window_height; - - check_exposures (clist); - - if (GTK_WIDGET_CAN_FOCUS(clist) && GTK_WIDGET_HAS_FOCUS(clist) && - !NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist)) - { - if (NAUTILUS_CLIST_ADD_MODE(clist)) - { - gint focus_row; - - focus_row = clist->focus_row; - clist->focus_row = -1; - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); - clist->focus_row = focus_row; - - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, - FALSE, 0, y, clist->clist_window_width - 1, - clist->row_height - 1); - return; - } - else - { - gint x0; - gint x1; - - if (area.x == 0) - { - x0 = clist->clist_window_width - 1; - x1 = diff; - } - else - { - x0 = 0; - x1 = area.x - 1; - } - - y = ROW_TOP_YPIXEL (clist, clist->focus_row); - gdk_draw_line (clist->clist_window, clist->xor_gc, - x0, y + 1, x0, y + clist->row_height - 2); - gdk_draw_line (clist->clist_window, clist->xor_gc, - x1, y + 1, x1, y + clist->row_height - 2); - - } - } - NAUTILUS_CLIST_CLASS_FW (clist)->draw_rows (clist, &area); -} - -static void -check_exposures (NautilusCList *clist) -{ - GdkEvent *event; - - if (!GTK_WIDGET_REALIZED (clist)) - return; - - /* Make sure graphics expose events are processed before scrolling - * again */ - while ((event = gdk_event_get_graphics_expose (clist->clist_window)) != NULL) - { - gtk_widget_event (GTK_WIDGET (clist), event); - if (event->expose.count == 0) - { - gdk_event_free (event); - break; - } - gdk_event_free (event); - } -} - -/* PRIVATE - * Memory Allocation/Distruction Routines for NautilusCList stuctures - * - * functions: - * columns_new - * column_title_new - * columns_delete - * row_new - * row_delete - */ -static NautilusCListColumn * -columns_new (NautilusCList *clist) -{ - NautilusCListColumn *column; - gint i; - - column = g_new (NautilusCListColumn, clist->columns); - - for (i = 0; i < clist->columns; i++) - { - column[i].area.x = 0; - column[i].area.y = 0; - column[i].area.width = 0; - column[i].area.height = 0; - column[i].title = NULL; - column[i].button = NULL; - column[i].window = NULL; - column[i].width = 0; - column[i].min_width = -1; - column[i].max_width = -1; - column[i].visible = TRUE; - column[i].width_set = FALSE; - column[i].resizeable = TRUE; - column[i].auto_resize = FALSE; - column[i].button_passive = FALSE; - column[i].justification = GTK_JUSTIFY_LEFT; - } - - return column; -} - -static void -column_title_new (NautilusCList *clist, - gint column, - const gchar *title) -{ - if (clist->column[column].title) - g_free (clist->column[column].title); - - clist->column[column].title = g_strdup (title); -} - -static void -columns_delete (NautilusCList *clist) -{ - gint i; - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].title) - g_free (clist->column[i].title); - - g_free (clist->column); -} - -static NautilusCListRow * -row_new (NautilusCList *clist) -{ - int i; - NautilusCListRow *clist_row; - - clist_row = g_chunk_new (NautilusCListRow, clist->row_mem_chunk); - clist_row->cell = g_chunk_new (NautilusCell, clist->cell_mem_chunk); - - for (i = 0; i < clist->columns; i++) - { - clist_row->cell[i].type = NAUTILUS_CELL_EMPTY; - clist_row->cell[i].vertical = 0; - clist_row->cell[i].horizontal = 0; - clist_row->cell[i].style = NULL; - } - - clist_row->fg_set = FALSE; - clist_row->bg_set = FALSE; - clist_row->style = NULL; - clist_row->selectable = TRUE; - clist_row->state = GTK_STATE_NORMAL; - clist_row->data = NULL; - clist_row->destroy = NULL; - - return clist_row; -} - -static void -row_delete (NautilusCList *clist, - NautilusCListRow *clist_row) -{ - gint i; - - for (i = 0; i < clist->columns; i++) - { - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, clist_row, i, NAUTILUS_CELL_EMPTY, NULL, 0, NULL); - if (clist_row->cell[i].style) - { - if (GTK_WIDGET_REALIZED (clist)) - gtk_style_detach (clist_row->cell[i].style); - gtk_style_unref (clist_row->cell[i].style); - } - } - - if (clist_row->style) - { - if (GTK_WIDGET_REALIZED (clist)) - gtk_style_detach (clist_row->style); - gtk_style_unref (clist_row->style); - } - - if (clist_row->destroy) - clist_row->destroy (clist_row->data); - - g_mem_chunk_free (clist->cell_mem_chunk, clist_row->cell); - g_mem_chunk_free (clist->row_mem_chunk, clist_row); -} - -/* FOCUS FUNCTIONS - * nautilus_clist_focus - * nautilus_clist_draw_focus - * nautilus_clist_focus_in - * nautilus_clist_focus_out - * nautilus_clist_set_focus_child - * title_focus - */ -static gint -nautilus_clist_focus (GtkContainer *container, - GtkDirectionType direction) -{ - NautilusCList *clist; - GtkWidget *focus_child; - gint old_row; - - g_return_val_if_fail (container != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (container), FALSE); - - if (!GTK_WIDGET_IS_SENSITIVE (container)) - return FALSE; - - clist = NAUTILUS_CLIST (container); - focus_child = container->focus_child; - old_row = clist->focus_row; - - switch (direction) - { - case GTK_DIR_LEFT: - case GTK_DIR_RIGHT: - if (NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist)) - { - if (title_focus (clist, direction)) - return TRUE; - gtk_container_set_focus_child (container, NULL); - return FALSE; - } - gtk_widget_grab_focus (GTK_WIDGET (container)); - return TRUE; - case GTK_DIR_DOWN: - case GTK_DIR_TAB_FORWARD: - if (NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist)) - { - gboolean tf = FALSE; - - if (((focus_child && direction == GTK_DIR_DOWN) || - !(tf = title_focus (clist, GTK_DIR_TAB_FORWARD))) - && clist->rows) - { - if (clist->focus_row < 0) - { - clist->focus_row = 0; - - if ((clist->selection_mode == GTK_SELECTION_BROWSE || - clist->selection_mode == GTK_SELECTION_EXTENDED) && - !clist->selection) - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - } - gtk_widget_grab_focus (GTK_WIDGET (container)); - return TRUE; - } - - if (tf) - return TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS); - break; - case GTK_DIR_UP: - case GTK_DIR_TAB_BACKWARD: - if (!focus_child && - NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist) && clist->rows) - { - if (clist->focus_row < 0) - { - clist->focus_row = 0; - if ((clist->selection_mode == GTK_SELECTION_BROWSE || - clist->selection_mode == GTK_SELECTION_EXTENDED) && - !clist->selection) - gtk_signal_emit (GTK_OBJECT (clist), - clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - } - gtk_widget_grab_focus (GTK_WIDGET (container)); - return TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS); - - if (title_focus (clist, direction)) - return TRUE; - - break; - default: - break; - } - - gtk_container_set_focus_child (container, NULL); - return FALSE; -} - -static void -nautilus_clist_draw_focus (GtkWidget *widget) -{ - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - - if (!GTK_WIDGET_DRAWABLE (widget) || !GTK_WIDGET_CAN_FOCUS (widget)) - return; - - clist = NAUTILUS_CLIST (widget); - if (clist->focus_row >= 0) - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, ROW_TOP_YPIXEL(clist, clist->focus_row), - clist->clist_window_width - 1, - clist->row_height - 1); -} - -static gint -nautilus_clist_focus_in (GtkWidget *widget, - GdkEventFocus *event) -{ - NautilusCList *clist; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - NAUTILUS_CLIST_UNSET_FLAG (widget, CLIST_CHILD_HAS_FOCUS); - - clist = NAUTILUS_CLIST (widget); - - if (clist->selection_mode == GTK_SELECTION_BROWSE && - clist->selection == NULL && clist->focus_row > -1) - { - GList *list; - - list = g_list_nth (clist->row_list, clist->focus_row); - if (list && NAUTILUS_CLIST_ROW (list)->selectable) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - clist->focus_row, -1, event); - else - gtk_widget_draw_focus (widget); - } - else - gtk_widget_draw_focus (widget); - - return FALSE; -} - -static gint -nautilus_clist_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - NautilusCList *clist; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - NAUTILUS_CLIST_SET_FLAG (widget, CLIST_CHILD_HAS_FOCUS); - - gtk_widget_draw_focus (widget); - - clist = NAUTILUS_CLIST (widget); - - NAUTILUS_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event); - - return FALSE; -} - -static void -nautilus_clist_set_focus_child (GtkContainer *container, - GtkWidget *child) -{ - g_return_if_fail (container != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (container)); - - if (child) - { - g_return_if_fail (GTK_IS_WIDGET (child)); - NAUTILUS_CLIST_SET_FLAG (container, CLIST_CHILD_HAS_FOCUS); - } - - parent_class->set_focus_child (container, child); -} - -static gboolean -title_focus (NautilusCList *clist, - gint dir) -{ - GtkWidget *focus_child; - gboolean return_val = FALSE; - gint last_column; - gint d = 1; - gint i = 0; - gint j; - - if (!NAUTILUS_CLIST_SHOW_TITLES(clist)) - return FALSE; - - focus_child = GTK_CONTAINER (clist)->focus_child; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - switch (dir) - { - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_UP: - if (!focus_child || !NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist)) - { - if (dir == GTK_DIR_UP) - i = COLUMN_FROM_XPIXEL (clist, 0); - else - i = last_column; - focus_child = clist->column[i].button; - dir = GTK_DIR_TAB_FORWARD; - } - else - d = -1; - break; - case GTK_DIR_LEFT: - d = -1; - if (!focus_child) - { - i = last_column; - focus_child = clist->column[i].button; - } - break; - case GTK_DIR_RIGHT: - if (!focus_child) - { - i = 0; - focus_child = clist->column[i].button; - } - break; - } - - if (focus_child) - while (i < clist->columns) - { - if (clist->column[i].button == focus_child) - { - if (clist->column[i].button && - GTK_WIDGET_VISIBLE (clist->column[i].button) && - GTK_IS_CONTAINER (clist->column[i].button) && - !GTK_WIDGET_HAS_FOCUS(clist->column[i].button)) - if (gtk_container_focus - (GTK_CONTAINER (clist->column[i].button), dir)) - { - return_val = TRUE; - i -= d; - } - if (!return_val && dir == GTK_DIR_UP) - return FALSE; - i += d; - break; - } - i++; - } - - j = i; - - if (!return_val) - while (j >= 0 && j < clist->columns) - { - if (clist->column[j].button && - GTK_WIDGET_VISIBLE (clist->column[j].button)) - { - if (GTK_IS_CONTAINER (clist->column[j].button) && - gtk_container_focus - (GTK_CONTAINER (clist->column[j].button), dir)) - { - return_val = TRUE; - break; - } - else if (GTK_WIDGET_CAN_FOCUS (clist->column[j].button)) - { - gtk_widget_grab_focus (clist->column[j].button); - return_val = TRUE; - break; - } - } - j += d; - } - - if (return_val) - { - if (COLUMN_LEFT_XPIXEL (clist, j) < CELL_SPACING + COLUMN_INSET) - nautilus_clist_moveto (clist, -1, j, 0, 0); - else if (COLUMN_LEFT_XPIXEL(clist, j) + clist->column[j].area.width > - clist->clist_window_width) - { - if (j == last_column) - nautilus_clist_moveto (clist, -1, j, 0, 0); - else - nautilus_clist_moveto (clist, -1, j, 0, 1); - } - } - return return_val; -} - -/* PRIVATE SCROLLING FUNCTIONS - * move_focus_row - * scroll_horizontal - * scroll_vertical - * move_horizontal - * move_vertical - * horizontal_timeout - * vertical_timeout - * remove_grab - */ -static void -move_focus_row (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position) -{ - GtkWidget *widget; - - g_return_if_fail (clist != 0); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - widget = GTK_WIDGET (clist); - - switch (scroll_type) - { - case GTK_SCROLL_STEP_BACKWARD: - if (clist->focus_row <= 0) - return; - nautilus_clist_draw_focus (widget); - clist->focus_row--; - nautilus_clist_draw_focus (widget); - break; - case GTK_SCROLL_STEP_FORWARD: - if (clist->focus_row >= clist->rows - 1) - return; - nautilus_clist_draw_focus (widget); - clist->focus_row++; - nautilus_clist_draw_focus (widget); - break; - case GTK_SCROLL_PAGE_BACKWARD: - if (clist->focus_row <= 0) - return; - nautilus_clist_draw_focus (widget); - clist->focus_row = MAX (0, clist->focus_row - - (2 * clist->clist_window_height - - clist->row_height - CELL_SPACING) / - (2 * (clist->row_height + CELL_SPACING))); - nautilus_clist_draw_focus (widget); - break; - case GTK_SCROLL_PAGE_FORWARD: - if (clist->focus_row >= clist->rows - 1) - return; - nautilus_clist_draw_focus (widget); - clist->focus_row = MIN (clist->rows - 1, clist->focus_row + - (2 * clist->clist_window_height - - clist->row_height - CELL_SPACING) / - (2 * (clist->row_height + CELL_SPACING))); - nautilus_clist_draw_focus (widget); - break; - case GTK_SCROLL_JUMP: - if (position >= 0 && position <= 1) - { - nautilus_clist_draw_focus (widget); - clist->focus_row = position * (clist->rows - 1); - nautilus_clist_draw_focus (widget); - } - break; - default: - break; - } -} - -static void -scroll_horizontal (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position) -{ - gint column = 0; - gint last_column; - - g_return_if_fail (clist != 0); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - switch (scroll_type) - { - case GTK_SCROLL_STEP_BACKWARD: - column = COLUMN_FROM_XPIXEL (clist, 0); - if (COLUMN_LEFT_XPIXEL (clist, column) - CELL_SPACING - COLUMN_INSET >= 0 - && column > 0) - column--; - break; - case GTK_SCROLL_STEP_FORWARD: - column = COLUMN_FROM_XPIXEL (clist, clist->clist_window_width); - if (column < 0) - return; - if (COLUMN_LEFT_XPIXEL (clist, column) + - clist->column[column].area.width + - CELL_SPACING + COLUMN_INSET - 1 <= clist->clist_window_width && - column < last_column) - column++; - break; - case GTK_SCROLL_PAGE_BACKWARD: - case GTK_SCROLL_PAGE_FORWARD: - return; - case GTK_SCROLL_JUMP: - if (position >= 0 && position <= 1) - { - gint vis_columns = 0; - gint i; - - for (i = 0; i <= last_column; i++) - if (clist->column[i].visible) - vis_columns++; - - column = position * vis_columns; - - for (i = 0; i <= last_column && column > 0; i++) - if (clist->column[i].visible) - column--; - - column = i; - } - else - return; - break; - default: - break; - } - - if (COLUMN_LEFT_XPIXEL (clist, column) < CELL_SPACING + COLUMN_INSET) - nautilus_clist_moveto (clist, -1, column, 0, 0); - else if (COLUMN_LEFT_XPIXEL (clist, column) + CELL_SPACING + COLUMN_INSET - 1 - + clist->column[column].area.width > clist->clist_window_width) - { - if (column == last_column) - nautilus_clist_moveto (clist, -1, column, 0, 0); - else - nautilus_clist_moveto (clist, -1, column, 0, 1); - } -} - -static void -scroll_vertical (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position) -{ - gint old_focus_row; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - switch (clist->selection_mode) - { - case GTK_SELECTION_EXTENDED: - if (clist->anchor >= 0) - return; - case GTK_SELECTION_BROWSE: - - old_focus_row = clist->focus_row; - move_focus_row (clist, scroll_type, position); - - if (old_focus_row != clist->focus_row) - { - if (clist->selection_mode == GTK_SELECTION_BROWSE) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], - old_focus_row, -1, NULL); - else if (!NAUTILUS_CLIST_ADD_MODE(clist)) - { - nautilus_clist_unselect_all (clist); - clist->undo_anchor = old_focus_row; - } - } - - switch (nautilus_clist_row_is_visible (clist, clist->focus_row)) - { - case GTK_VISIBILITY_NONE: - if (old_focus_row != clist->focus_row && - !(clist->selection_mode == GTK_SELECTION_EXTENDED && - NAUTILUS_CLIST_ADD_MODE(clist))) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - switch (scroll_type) - { - case GTK_SCROLL_STEP_BACKWARD: - case GTK_SCROLL_PAGE_BACKWARD: - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - break; - case GTK_SCROLL_STEP_FORWARD: - case GTK_SCROLL_PAGE_FORWARD: - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - break; - case GTK_SCROLL_JUMP: - nautilus_clist_moveto (clist, clist->focus_row, -1, 0.5, 0); - break; - default: - break; - } - break; - case GTK_VISIBILITY_PARTIAL: - switch (scroll_type) - { - case GTK_SCROLL_STEP_BACKWARD: - case GTK_SCROLL_PAGE_BACKWARD: - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - break; - case GTK_SCROLL_STEP_FORWARD: - case GTK_SCROLL_PAGE_FORWARD: - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - break; - case GTK_SCROLL_JUMP: - nautilus_clist_moveto (clist, clist->focus_row, -1, 0.5, 0); - break; - default: - break; - } - default: - if (old_focus_row != clist->focus_row && - !(clist->selection_mode == GTK_SELECTION_EXTENDED && - NAUTILUS_CLIST_ADD_MODE(clist))) - gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW], - clist->focus_row, -1, NULL); - break; - } - break; - default: - move_focus_row (clist, scroll_type, position); - - if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height > - clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - break; - } -} - -static void -move_horizontal (NautilusCList *clist, - gint diff) -{ - gfloat value; - - if (!clist->hadjustment) - return; - - value = CLAMP (clist->hadjustment->value + diff, 0.0, - clist->hadjustment->upper - clist->hadjustment->page_size); - gtk_adjustment_set_value(clist->hadjustment, value); -} - -static void -move_vertical (NautilusCList *clist, - gint row, - gfloat align) -{ - gfloat value; - - if (!clist->vadjustment) - return; - - value = (ROW_TOP_YPIXEL (clist, row) - clist->voffset - - align * (clist->clist_window_height - clist->row_height) + - (2 * align - 1) * CELL_SPACING); - - if (value + clist->vadjustment->page_size > clist->vadjustment->upper) - value = clist->vadjustment->upper - clist->vadjustment->page_size; - - gtk_adjustment_set_value(clist->vadjustment, value); -} - -static gint -horizontal_timeout (NautilusCList *clist) -{ - GdkEventMotion event = { 0 }; - - GDK_THREADS_ENTER (); - - clist->htimer = 0; - - event.type = GDK_MOTION_NOTIFY; - event.send_event = TRUE; - - nautilus_clist_motion (GTK_WIDGET (clist), &event); - - GDK_THREADS_LEAVE (); - - return FALSE; -} - -static gint -vertical_timeout (NautilusCList *clist) -{ - GdkEventMotion event = { 0 }; - - GDK_THREADS_ENTER (); - - clist->vtimer = 0; - - event.type = GDK_MOTION_NOTIFY; - event.send_event = TRUE; - - nautilus_clist_motion (GTK_WIDGET (clist), &event); - - GDK_THREADS_LEAVE (); - - return FALSE; -} - -static void -remove_grab (NautilusCList *clist) -{ - if (GTK_WIDGET_HAS_GRAB (clist)) - { - gtk_grab_remove (GTK_WIDGET (clist)); - if (gdk_pointer_is_grabbed ()) - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - - if (clist->htimer) - { - gtk_timeout_remove (clist->htimer); - clist->htimer = 0; - } - - if (clist->vtimer) - { - gtk_timeout_remove (clist->vtimer); - clist->vtimer = 0; - } -} - -/* PUBLIC SORTING FUNCTIONS - * nautilus_clist_sort - * nautilus_clist_set_compare_func - * nautilus_clist_set_auto_sort - * nautilus_clist_set_sort_type - * nautilus_clist_set_sort_column - */ -void -nautilus_clist_sort (NautilusCList *clist) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - NAUTILUS_CLIST_CLASS_FW (clist)->sort_list (clist); -} - -void -nautilus_clist_set_compare_func (NautilusCList *clist, - NautilusCListCompareFunc cmp_func) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - clist->compare = (cmp_func) ? cmp_func : default_compare; -} - -void -nautilus_clist_set_auto_sort (NautilusCList *clist, - gboolean auto_sort) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (NAUTILUS_CLIST_AUTO_SORT(clist) && !auto_sort) - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_SORT); - else if (!NAUTILUS_CLIST_AUTO_SORT(clist) && auto_sort) - { - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_SORT); - nautilus_clist_sort (clist); - } -} - -void -nautilus_clist_set_sort_type (NautilusCList *clist, - GtkSortType sort_type) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - clist->sort_type = sort_type; -} - -void -nautilus_clist_set_sort_column (NautilusCList *clist, - gint column) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (column < 0 || column >= clist->columns) - return; - - clist->sort_column = column; -} - -/* PRIVATE SORTING FUNCTIONS - * default_compare - * real_sort_list - * nautilus_clist_merge - * nautilus_clist_mergesort - */ -static gint -default_compare (NautilusCList *clist, - gconstpointer ptr1, - gconstpointer ptr2) -{ - char *text1 = NULL; - char *text2 = NULL; - - NautilusCListRow *row1 = (NautilusCListRow *) ptr1; - NautilusCListRow *row2 = (NautilusCListRow *) ptr2; - - switch (row1->cell[clist->sort_column].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - text1 = NAUTILUS_CELL_TEXT (row1->cell[clist->sort_column])->text; - break; - case NAUTILUS_CELL_PIXTEXT: - text1 = NAUTILUS_CELL_PIXTEXT (row1->cell[clist->sort_column])->text; - break; - default: - break; - } - - switch (row2->cell[clist->sort_column].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - text2 = NAUTILUS_CELL_TEXT (row2->cell[clist->sort_column])->text; - break; - case NAUTILUS_CELL_PIXTEXT: - text2 = NAUTILUS_CELL_PIXTEXT (row2->cell[clist->sort_column])->text; - break; - default: - break; - } - - if (!text2) - return (text1 != NULL); - - if (!text1) - return -1; - - return strcmp (text1, text2); -} - -static void -real_sort_list (NautilusCList *clist) -{ - GList *list; - GList *work; - gint i; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (clist->rows <= 1) - return; - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - return; - - if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - clist->row_list = nautilus_clist_mergesort (clist, clist->row_list, clist->rows); - - work = clist->selection; - - for (i = 0, list = clist->row_list; i < clist->rows; i++, list = list->next) - { - if (NAUTILUS_CLIST_ROW (list)->state == GTK_STATE_SELECTED) - { - work->data = GINT_TO_POINTER (i); - work = work->next; - } - - if (i == clist->rows - 1) - clist->row_list_end = list; - } - - CLIST_REFRESH (clist); -} - -static GList * -nautilus_clist_merge (NautilusCList *clist, - GList *a, /* first list to merge */ - GList *b) /* second list to merge */ -{ - GList z = { 0 }; /* auxiliary node */ - GList *c; - gint cmp; - - c = &z; - - while (a || b) - { - if (a && !b) - { - c->next = a; - a->prev = c; - c = a; - a = a->next; - break; - } - else if (!a && b) - { - c->next = b; - b->prev = c; - c = b; - b = b->next; - break; - } - else /* a && b */ - { - cmp = clist->compare (clist, NAUTILUS_CLIST_ROW (a), NAUTILUS_CLIST_ROW (b)); - if ((cmp >= 0 && clist->sort_type == GTK_SORT_DESCENDING) || - (cmp <= 0 && clist->sort_type == GTK_SORT_ASCENDING) || - (a && !b)) - { - c->next = a; - a->prev = c; - c = a; - a = a->next; - } - else - { - c->next = b; - b->prev = c; - c = b; - b = b->next; - } - } - } - - z.next->prev = NULL; - return z.next; -} - -static GList * -nautilus_clist_mergesort (NautilusCList *clist, - GList *list, /* the list to sort */ - gint num) /* the list's length */ -{ - GList *half; - gint i; - - if (num == 1) - { - return list; - } - else - { - /* move "half" to the middle */ - half = list; - for (i = 0; i < num / 2; i++) - half = half->next; - - /* cut the list in two */ - half->prev->next = NULL; - half->prev = NULL; - - /* recursively sort both lists */ - return nautilus_clist_merge (clist, - nautilus_clist_mergesort (clist, list, num / 2), - nautilus_clist_mergesort (clist, half, num - num / 2)); - } -} - -/************************/ - -static void -drag_source_info_destroy (gpointer data) -{ - NautilusCListCellInfo *info = data; - - g_free (info); -} - -static void -drag_dest_info_destroy (gpointer data) -{ - NautilusCListDestInfo *info = data; - - g_free (info); -} - -static void -drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (clist); - - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - - y -= (GTK_CONTAINER (clist)->border_width + - widget->style->klass->ythickness + - clist->column_title_area.height); - - dest_info->cell.row = ROW_FROM_YPIXEL (clist, y); - if (dest_info->cell.row >= clist->rows) - { - dest_info->cell.row = clist->rows - 1; - y = ROW_TOP_YPIXEL (clist, dest_info->cell.row) + clist->row_height; - } - if (dest_info->cell.row < -1) - dest_info->cell.row = -1; - - x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness; - dest_info->cell.column = COLUMN_FROM_XPIXEL (clist, x); - - if (dest_info->cell.row >= 0) - { - gint y_delta; - gint h = 0; - - y_delta = y - ROW_TOP_YPIXEL (clist, dest_info->cell.row); - - if (NAUTILUS_CLIST_DRAW_DRAG_RECT(clist)) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_INTO; - h = clist->row_height / 4; - } - else if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - h = clist->row_height / 2; - } - - if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - if (y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - else if (clist->row_height - y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_AFTER; - } - } -} - -static void -nautilus_clist_drag_begin (GtkWidget *widget, - GdkDragContext *context) -{ - NautilusCList *clist; - NautilusCListCellInfo *info; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (context != NULL); - - clist = NAUTILUS_CLIST (widget); - - clist->drag_button = 0; - remove_grab (clist); - - switch (clist->selection_mode) - { - case GTK_SELECTION_EXTENDED: - update_extended_selection (clist, clist->focus_row); - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - break; - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_MULTIPLE: - clist->anchor = -1; - case GTK_SELECTION_BROWSE: - break; - } - - info = g_dataset_get_data (context, "gtk-clist-drag-source"); - - if (!info) - { - info = g_new (NautilusCListCellInfo, 1); - - if (clist->click_cell.row < 0) - clist->click_cell.row = 0; - else if (clist->click_cell.row >= clist->rows) - clist->click_cell.row = clist->rows - 1; - info->row = clist->click_cell.row; - info->column = clist->click_cell.column; - - g_dataset_set_data_full (context, "gtk-clist-drag-source", info, - drag_source_info_destroy); - } - - if (NAUTILUS_CLIST_USE_DRAG_ICONS (clist)) - gtk_drag_set_icon_default (context); -} - -static void -nautilus_clist_drag_end (GtkWidget *widget, - GdkDragContext *context) -{ - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (context != NULL); - - clist = NAUTILUS_CLIST (widget); - - clist->click_cell.row = -1; - clist->click_cell.column = -1; -} - -static void -nautilus_clist_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time) -{ - NautilusCList *clist; - NautilusCListDestInfo *dest_info; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (context != NULL); - - clist = NAUTILUS_CLIST (widget); - - dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest"); - - if (dest_info) - { - if (dest_info->cell.row >= 0 && - NAUTILUS_CLIST_REORDERABLE(clist) && - gtk_drag_get_source_widget (context) == widget) - { - GList *list; - GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE); - - list = context->targets; - while (list) - { - if (atom == GPOINTER_TO_UINT (list->data)) - { - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, - g_list_nth (clist->row_list, dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - break; - } - list = list->next; - } - } - g_dataset_remove_data (context, "gtk-clist-drag-dest"); - } -} - -static gint -nautilus_clist_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - NautilusCList *clist; - NautilusCListDestInfo new_info; - NautilusCListDestInfo *dest_info; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - - clist = NAUTILUS_CLIST (widget); - - dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest"); - - if (!dest_info) - { - dest_info = g_new (NautilusCListDestInfo, 1); - - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - dest_info->cell.row = -1; - dest_info->cell.column = -1; - - g_dataset_set_data_full (context, "gtk-clist-drag-dest", dest_info, - drag_dest_info_destroy); - } - - drag_dest_cell (clist, x, y, &new_info); - - if (NAUTILUS_CLIST_REORDERABLE (clist)) - { - GList *list; - GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE); - - list = context->targets; - while (list) - { - if (atom == GPOINTER_TO_UINT (list->data)) - break; - list = list->next; - } - - if (list) - { - if (gtk_drag_get_source_widget (context) != widget || - new_info.insert_pos == NAUTILUS_CLIST_DRAG_NONE || - new_info.cell.row == clist->click_cell.row || - (new_info.cell.row == clist->click_cell.row - 1 && - new_info.insert_pos == NAUTILUS_CLIST_DRAG_AFTER) || - (new_info.cell.row == clist->click_cell.row + 1 && - new_info.insert_pos == NAUTILUS_CLIST_DRAG_BEFORE)) - { - if (dest_info->cell.row < 0) - { - gdk_drag_status (context, GDK_ACTION_DEFAULT, time); - return FALSE; - } - return TRUE; - } - - if (new_info.cell.row != dest_info->cell.row || - (new_info.cell.row == dest_info->cell.row && - dest_info->insert_pos != new_info.insert_pos)) - { - if (dest_info->cell.row >= 0) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, g_list_nth (clist->row_list, - dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, g_list_nth (clist->row_list, - dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - gdk_drag_status (context, context->suggested_action, time); - } - return TRUE; - } - } - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - return TRUE; -} - -static gboolean -nautilus_clist_drag_drop (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CLIST (widget), FALSE); - g_return_val_if_fail (context != NULL, FALSE); - - if (NAUTILUS_CLIST_REORDERABLE (widget) && - gtk_drag_get_source_widget (context) == widget) - { - GList *list; - GdkAtom atom = gdk_atom_intern ("gtk-clist-drag-reorder", FALSE); - - list = context->targets; - while (list) - { - if (atom == GPOINTER_TO_UINT (list->data)) - return TRUE; - list = list->next; - } - } - return FALSE; -} - -static void -nautilus_clist_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (context != NULL); - g_return_if_fail (selection_data != NULL); - - clist = NAUTILUS_CLIST (widget); - - if (NAUTILUS_CLIST_REORDERABLE (clist) && - gtk_drag_get_source_widget (context) == widget && - selection_data->target == - gdk_atom_intern ("gtk-clist-drag-reorder", FALSE) && - selection_data->format == GTK_TYPE_POINTER && - selection_data->length == sizeof (NautilusCListCellInfo)) - { - NautilusCListCellInfo *source_info; - - source_info = (NautilusCListCellInfo *)(selection_data->data); - if (source_info) - { - NautilusCListDestInfo dest_info; - - drag_dest_cell (clist, x, y, &dest_info); - - if (dest_info.insert_pos == NAUTILUS_CLIST_DRAG_AFTER) - dest_info.cell.row++; - if (source_info->row < dest_info.cell.row) - dest_info.cell.row--; - if (dest_info.cell.row != source_info->row) - nautilus_clist_row_move (clist, source_info->row, dest_info.cell.row); - - g_dataset_remove_data (context, "gtk-clist-drag-dest"); - } - } -} - -static void -nautilus_clist_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time) -{ - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (widget)); - g_return_if_fail (context != NULL); - g_return_if_fail (selection_data != NULL); - - if (selection_data->target == - gdk_atom_intern ("gtk-clist-drag-reorder", FALSE)) - { - NautilusCListCellInfo *info; - - info = g_dataset_get_data (context, "gtk-clist-drag-source"); - - if (info) - { - NautilusCListCellInfo ret_info; - - ret_info.row = info->row; - ret_info.column = info->column; - - gtk_selection_data_set (selection_data, selection_data->target, - GTK_TYPE_POINTER, (guchar *) &ret_info, - sizeof (NautilusCListCellInfo)); - } - else - gtk_selection_data_set (selection_data, selection_data->target, - GTK_TYPE_POINTER, NULL, 0); - } -} - -static void -draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos) -{ - gint y; - - y = ROW_TOP_YPIXEL (clist, dest_row_number) - 1; - - switch (drag_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - break; - case NAUTILUS_CLIST_DRAG_AFTER: - y += clist->row_height + 1; - case NAUTILUS_CLIST_DRAG_BEFORE: - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, clist->clist_window_width, y); - break; - case NAUTILUS_CLIST_DRAG_INTO: - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y, - clist->clist_window_width - 1, clist->row_height); - break; - } -} - -void -nautilus_clist_set_reorderable (NautilusCList *clist, - gboolean reorderable) -{ - GtkWidget *widget; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if ((NAUTILUS_CLIST_REORDERABLE(clist) != 0) == reorderable) - return; - - widget = GTK_WIDGET (clist); - - if (reorderable) - { - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_REORDERABLE); - gtk_drag_dest_set (widget, - GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, - &clist_target_table, 1, GDK_ACTION_MOVE); - } - else - { - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_REORDERABLE); - gtk_drag_dest_unset (GTK_WIDGET (clist)); - } -} - -void -nautilus_clist_set_use_drag_icons (NautilusCList *clist, - gboolean use_icons) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (use_icons != 0) - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS); - else - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_USE_DRAG_ICONS); -} - -void -nautilus_clist_set_button_actions (NautilusCList *clist, - guint button, - guint8 button_actions) -{ - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CLIST (clist)); - - if (button < MAX_BUTTON) - { - if (gdk_pointer_is_grabbed () || GTK_WIDGET_HAS_GRAB (clist)) - { - remove_grab (clist); - clist->drag_button = 0; - } - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - clist->button_actions[button] = button_actions; - } -} diff --git a/cut-n-paste-code/widgets/nautilusclist/nautilusclist.h b/cut-n-paste-code/widgets/nautilusclist/nautilusclist.h deleted file mode 100644 index 768558854..000000000 --- a/cut-n-paste-code/widgets/nautilusclist/nautilusclist.h +++ /dev/null @@ -1,790 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * Copy-pasted from GtkCList to add some missing overridability. - */ - -#ifndef NAUTILUS_CLIST_H__ -#define NAUTILUS_CLIST_H__ - -#include <gdk/gdk.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkalignment.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkhscrollbar.h> -#include <gtk/gtkvscrollbar.h> -#include <gtk/gtkenums.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* clist flags */ -enum { - NAUTILUS_CLIST_IN_DRAG = 1 << 0, - NAUTILUS_CLIST_ROW_HEIGHT_SET = 1 << 1, - NAUTILUS_CLIST_SHOW_TITLES = 1 << 2, - NAUTILUS_CLIST_CHILD_HAS_FOCUS = 1 << 3, - NAUTILUS_CLIST_ADD_MODE = 1 << 4, - NAUTILUS_CLIST_AUTO_SORT = 1 << 5, - NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED = 1 << 6, - NAUTILUS_CLIST_REORDERABLE = 1 << 7, - NAUTILUS_CLIST_USE_DRAG_ICONS = 1 << 8, - NAUTILUS_CLIST_DRAW_DRAG_LINE = 1 << 9, - NAUTILUS_CLIST_DRAW_DRAG_RECT = 1 << 10 -}; - -/* cell types */ -/* Superset of GtkCellType enum defined in gtk-clist.h */ -typedef enum -{ - NAUTILUS_CELL_EMPTY, - NAUTILUS_CELL_TEXT, - NAUTILUS_CELL_PIXBUF, /* new for Nautilus */ - NAUTILUS_CELL_PIXTEXT, /* now uses pixbuf */ - NAUTILUS_CELL_WIDGET, - NAUTILUS_CELL_PIXBUF_LIST, /* new for Nautilus */ - NAUTILUS_CELL_LINK_TEXT /* new for Nautilus */ -} NautilusCellType; - -typedef enum -{ - NAUTILUS_CLIST_DRAG_NONE, - NAUTILUS_CLIST_DRAG_BEFORE, - NAUTILUS_CLIST_DRAG_INTO, - NAUTILUS_CLIST_DRAG_AFTER -} NautilusCListDragPos; - -typedef enum -{ - NAUTILUS_BUTTON_IGNORED = 0, - NAUTILUS_BUTTON_SELECTS = 1 << 0, - NAUTILUS_BUTTON_DRAGS = 1 << 1, - NAUTILUS_BUTTON_EXPANDS = 1 << 2 -} NautilusButtonAction; - -#define NAUTILUS_TYPE_CLIST (nautilus_clist_get_type ()) -#define NAUTILUS_CLIST(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CLIST, NautilusCList)) -#define NAUTILUS_CLIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CLIST, NautilusCListClass)) -#define NAUTILUS_IS_CLIST(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CLIST)) -#define NAUTILUS_IS_CLIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CLIST)) - -#define NAUTILUS_CLIST_FLAGS(clist) (NAUTILUS_CLIST (clist)->flags) -#define NAUTILUS_CLIST_SET_FLAG(clist,flag) (NAUTILUS_CLIST_FLAGS (clist) |= (NAUTILUS_ ## flag)) -#define NAUTILUS_CLIST_UNSET_FLAG(clist,flag) (NAUTILUS_CLIST_FLAGS (clist) &= ~(NAUTILUS_ ## flag)) - -#define NAUTILUS_CLIST_IN_DRAG(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_IN_DRAG) -#define NAUTILUS_CLIST_ROW_HEIGHT_SET(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_ROW_HEIGHT_SET) -#define NAUTILUS_CLIST_SHOW_TITLES(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_SHOW_TITLES) -#define NAUTILUS_CLIST_CHILD_HAS_FOCUS(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_CHILD_HAS_FOCUS) -#define NAUTILUS_CLIST_ADD_MODE(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_ADD_MODE) -#define NAUTILUS_CLIST_AUTO_SORT(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_AUTO_SORT) -#define NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED) -#define NAUTILUS_CLIST_REORDERABLE(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_REORDERABLE) -#define NAUTILUS_CLIST_USE_DRAG_ICONS(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_USE_DRAG_ICONS) -#define NAUTILUS_CLIST_DRAW_DRAG_LINE(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_DRAW_DRAG_LINE) -#define NAUTILUS_CLIST_DRAW_DRAG_RECT(clist) (NAUTILUS_CLIST_FLAGS (clist) & NAUTILUS_CLIST_DRAW_DRAG_RECT) - -#define NAUTILUS_CLIST_ROW(_glist_) ((NautilusCListRow *)((_glist_)->data)) - -/* pointer casting for cells */ -#define NAUTILUS_CELL_TEXT(cell) (((NautilusCellText *) &(cell))) -#define NAUTILUS_CELL_PIXBUF(cell) (((NautilusCellPixbuf *) &(cell))) -#define NAUTILUS_CELL_PIXTEXT(cell) (((NautilusCellPixText *) &(cell))) -#define NAUTILUS_CELL_WIDGET(cell) (((NautilusCellWidget *) &(cell))) - -typedef struct NautilusCList NautilusCList; -typedef struct NautilusCListClass NautilusCListClass; -typedef struct NautilusCListColumn NautilusCListColumn; -typedef struct NautilusCListRow NautilusCListRow; - -typedef struct NautilusCell NautilusCell; -typedef struct NautilusCellText NautilusCellText; -typedef struct NautilusCellPixbuf NautilusCellPixbuf; -typedef struct NautilusCellPixText NautilusCellPixText; -typedef struct NautilusCellWidget NautilusCellWidget; - -typedef gint (*NautilusCListCompareFunc) (NautilusCList *clist, - gconstpointer ptr1, - gconstpointer ptr2); - -typedef struct NautilusCListCellInfo NautilusCListCellInfo; -typedef struct NautilusCListDestInfo NautilusCListDestInfo; - -struct NautilusCListCellInfo -{ - gint row; - gint column; -}; - -struct NautilusCListDestInfo -{ - NautilusCListCellInfo cell; - NautilusCListDragPos insert_pos; -}; - -struct NautilusCList -{ - GtkContainer container; - - guint16 flags; - - /* mem chunks */ - GMemChunk *row_mem_chunk; - GMemChunk *cell_mem_chunk; - - guint freeze_count; - gboolean refresh_at_unfreeze_time; - - /* allocation rectangle after the conatiner_border_width - * and the width of the shadow border */ - GdkRectangle internal_allocation; - - /* rows */ - gint rows; - gint row_center_offset; - gint row_height; - GList *row_list; - GList *row_list_end; - - /* columns */ - gint columns; - GdkRectangle column_title_area; - GdkWindow *title_window; - - /* dynamicly allocated array of column structures */ - NautilusCListColumn *column; - - /* the scrolling window and its height and width to - * make things a little speedier */ - GdkWindow *clist_window; - gint clist_window_width; - gint clist_window_height; - - /* offsets for scrolling */ - gint hoffset; - gint voffset; - - /* border shadow style */ - GtkShadowType shadow_type; - - /* the list's selection mode (gtkenums.h) */ - GtkSelectionMode selection_mode; - - /* list of selected rows */ - GList *selection; - GList *selection_end; - - GList *undo_selection; - GList *undo_unselection; - gint undo_anchor; - - /* mouse buttons */ - guint8 button_actions[5]; - - guint8 drag_button; - - /* dnd */ - NautilusCListCellInfo click_cell; - - /* scroll adjustments */ - GtkAdjustment *hadjustment; - GtkAdjustment *vadjustment; - - /* xor GC for the vertical drag line */ - GdkGC *xor_gc; - - /* gc for drawing unselected cells */ - GdkGC *fg_gc; - GdkGC *bg_gc; - - /* cursor used to indicate dragging */ - GdkCursor *cursor_drag; - - /* the current x-pixel location of the xor-drag line */ - gint x_drag; - - /* focus handling */ - gint focus_row; - - /* dragging the selection */ - gint anchor; - GtkStateType anchor_state; - gint drag_pos; - gint htimer; - gint vtimer; - - GtkSortType sort_type; - NautilusCListCompareFunc compare; - gint sort_column; -}; - -struct NautilusCListClass -{ - GtkContainerClass parent_class; - - void (*set_scroll_adjustments) (NautilusCList *clist, - GtkAdjustment *hadjustment, - GtkAdjustment *vadjustment); - void (*refresh) (NautilusCList *clist); - void (*select_row) (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); - void (*unselect_row) (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); - void (*row_move) (NautilusCList *clist, - gint source_row, - gint dest_row); - void (*click_column) (NautilusCList *clist, - gint column); - void (*resize_column) (NautilusCList *clist, - gint column, - gint width); - void (*toggle_focus_row) (NautilusCList *clist); - void (*select_all) (NautilusCList *clist); - void (*unselect_all) (NautilusCList *clist); - void (*undo_selection) (NautilusCList *clist); - void (*start_selection) (NautilusCList *clist); - void (*end_selection) (NautilusCList *clist); - void (*extend_selection) (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position, - gboolean auto_start_selection); - void (*scroll_horizontal) (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position); - void (*scroll_vertical) (NautilusCList *clist, - GtkScrollType scroll_type, - gfloat position); - void (*toggle_add_mode) (NautilusCList *clist); - void (*abort_column_resize) (NautilusCList *clist); - void (*resync_selection) (NautilusCList *clist, - GdkEvent *event); - GList* (*selection_find) (NautilusCList *clist, - gint row_number, - GList *row_list_element); - void (*draw_rows) (NautilusCList *clist, - GdkRectangle *area); - void (*draw_row) (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row); - void (*draw_all) (NautilusCList *clist); - void (*draw_drag_highlight) (NautilusCList *clist, - NautilusCListRow *target_row, - gint target_row_number, - NautilusCListDragPos drag_pos); - void (*clear) (NautilusCList *clist); - void (*fake_unselect_all) (NautilusCList *clist, - gint row); - void (*sort_list) (NautilusCList *clist); - gint (*insert_row) (NautilusCList *clist, - gint row, - gchar *text[]); - void (*remove_row) (NautilusCList *clist, - gint row); - gboolean (*set_cell_contents) (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); - void (*cell_size_request) (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition); - -}; - -struct NautilusCListColumn -{ - gchar *title; - GdkRectangle area; - - GtkWidget *button; - GdkWindow *window; - - gint width; - gint min_width; - gint max_width; - GtkJustification justification; - - guint visible : 1; - guint width_set : 1; - guint resizeable : 1; - guint auto_resize : 1; - guint button_passive : 1; -}; - -struct NautilusCListRow -{ - NautilusCell *cell; - GtkStateType state; - - GdkColor foreground; - GdkColor background; - - GtkStyle *style; - - gpointer data; - GtkDestroyNotify destroy; - - guint fg_set : 1; - guint bg_set : 1; - guint selectable : 1; -}; - -/* Cell Structures */ -struct NautilusCellText -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - gchar *text; -}; - -struct NautilusCellPixbuf -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - GdkPixbuf *pixbuf; -}; - -struct NautilusCellPixText -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - gchar *text; - guint8 spacing; - GdkPixbuf *pixbuf; -}; - -struct NautilusCellWidget -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - GtkWidget *widget; -}; - -struct NautilusCell -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - union { - gchar *text; - - struct { - GdkPixbuf *pixbuf; - } pb; - - struct { - gchar *text; - guint8 spacing; - GdkPixbuf *pixbuf; - } pt; - - GtkWidget *widget; - } u; -}; - -GtkType nautilus_clist_get_type (void); - -/* constructors useful for gtk-- wrappers */ -void nautilus_clist_construct (NautilusCList *clist, - gint columns, - gchar *titles[]); - -/* create a new NautilusCList */ -GtkWidget* nautilus_clist_new (gint columns); -GtkWidget* nautilus_clist_new_with_titles (gint columns, - gchar *titles[]); - -/* set adjustments of clist */ -void nautilus_clist_set_hadjustment (NautilusCList *clist, - GtkAdjustment *adjustment); -void nautilus_clist_set_vadjustment (NautilusCList *clist, - GtkAdjustment *adjustment); - -/* get adjustments of clist */ -GtkAdjustment* nautilus_clist_get_hadjustment (NautilusCList *clist); -GtkAdjustment* nautilus_clist_get_vadjustment (NautilusCList *clist); - -/* set the border style of the clist */ -void nautilus_clist_set_shadow_type (NautilusCList *clist, - GtkShadowType type); - -/* set the clist's selection mode */ -void nautilus_clist_set_selection_mode (NautilusCList *clist, - GtkSelectionMode mode); - -/* enable clists reorder ability */ -void nautilus_clist_set_reorderable (NautilusCList *clist, - gboolean reorderable); -void nautilus_clist_set_use_drag_icons (NautilusCList *clist, - gboolean use_icons); -void nautilus_clist_set_button_actions (NautilusCList *clist, - guint button, - guint8 button_actions); - -/* freeze all visual updates of the list, and then thaw the list after - * you have made a number of changes and the updates wil occure in a - * more efficent mannor than if you made them on a unfrozen list - */ -void nautilus_clist_freeze (NautilusCList *clist); -void nautilus_clist_thaw (NautilusCList *clist); - -/* show and hide the column title buttons */ -void nautilus_clist_column_titles_show (NautilusCList *clist); -void nautilus_clist_column_titles_hide (NautilusCList *clist); - -/* set the column title to be a active title (responds to button presses, - * prelights, and grabs keyboard focus), or passive where it acts as just - * a title - */ -void nautilus_clist_column_title_active (NautilusCList *clist, - gint column); -void nautilus_clist_column_title_passive (NautilusCList *clist, - gint column); -void nautilus_clist_column_titles_active (NautilusCList *clist); -void nautilus_clist_column_titles_passive (NautilusCList *clist); - -/* set the title in the column title button */ -void nautilus_clist_set_column_title (NautilusCList *clist, - gint column, - const gchar *title); - -/* returns the title of column. Returns NULL if title is not set */ -gchar * nautilus_clist_get_column_title (NautilusCList *clist, - gint column); - -/* set a widget instead of a title for the column title button */ -void nautilus_clist_set_column_widget (NautilusCList *clist, - gint column, - GtkWidget *widget); - -/* returns the column widget */ -GtkWidget * nautilus_clist_get_column_widget (NautilusCList *clist, - gint column); - -/* set the justification on a column */ -void nautilus_clist_set_column_justification (NautilusCList *clist, - gint column, - GtkJustification justification); - -/* set visibility of a column */ -void nautilus_clist_set_column_visibility (NautilusCList *clist, - gint column, - gboolean visible); - -/* enable/disable column resize operations by mouse */ -void nautilus_clist_set_column_resizeable (NautilusCList *clist, - gint column, - gboolean resizeable); - -/* resize column automatically to its optimal width */ -void nautilus_clist_set_column_auto_resize (NautilusCList *clist, - gint column, - gboolean auto_resize); - -gint nautilus_clist_columns_autosize (NautilusCList *clist); - -/* return the optimal column width, i.e. maximum of all cell widths */ -gint nautilus_clist_optimal_column_width (NautilusCList *clist, - gint column); - -/* set the pixel width of a column; this is a necessary step in - * creating a CList because otherwise the column width is chozen from - * the width of the column title, which will never be right - */ -void nautilus_clist_set_column_width (NautilusCList *clist, - gint column, - gint width); - -/* set column minimum/maximum width. min/max_width < 0 => no restriction */ -void nautilus_clist_set_column_min_width (NautilusCList *clist, - gint column, - gint min_width); -void nautilus_clist_set_column_max_width (NautilusCList *clist, - gint column, - gint max_width); - -/* change the height of the rows, the default (height=0) is - * the hight of the current font. - */ -void nautilus_clist_set_row_height (NautilusCList *clist, - guint height); - -/* scroll the viewing area of the list to the given column and row; - * row_align and col_align are between 0-1 representing the location the - * row should appear on the screnn, 0.0 being top or left, 1.0 being - * bottom or right; if row or column is -1 then then there is no change - */ -void nautilus_clist_moveto (NautilusCList *clist, - gint row, - gint column, - gfloat row_align, - gfloat col_align); - -/* returns whether the row is visible */ -GtkVisibility nautilus_clist_row_is_visible (NautilusCList *clist, - gint row); - -/* returns the cell type */ -NautilusCellType nautilus_clist_get_cell_type (NautilusCList *clist, - gint row, - gint column); - -/* sets a given cell's text, replacing its current contents */ -void nautilus_clist_set_text (NautilusCList *clist, - gint row, - gint column, - const gchar *text); - -/* for the "get" functions, any of the return pointer can be - * NULL if you are not interested - */ -gint nautilus_clist_get_text (NautilusCList *clist, - gint row, - gint column, - gchar **text); - -/* sets a given cell's pixbuf, replacing its current contents */ -void nautilus_clist_set_pixbuf (NautilusCList *clist, - gint row, - gint column, - GdkPixbuf *pixbuf); - -gint nautilus_clist_get_pixbuf (NautilusCList *clist, - gint row, - gint column, - GdkPixbuf **pixbuf); - -/* sets a given cell's pixbuf and text, replacing its current contents */ -void nautilus_clist_set_pixtext (NautilusCList *clist, - gint row, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); - -gint nautilus_clist_get_pixtext (NautilusCList *clist, - gint row, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf); - -/* sets the foreground color of a row, the color must already - * be allocated - */ -void nautilus_clist_set_foreground (NautilusCList *clist, - gint row, - GdkColor *color); - -/* sets the background color of a row, the color must already - * be allocated - */ -void nautilus_clist_set_background (NautilusCList *clist, - gint row, - GdkColor *color); - -/* set / get cell styles */ -void nautilus_clist_set_cell_style (NautilusCList *clist, - gint row, - gint column, - GtkStyle *style); - -GtkStyle *nautilus_clist_get_cell_style (NautilusCList *clist, - gint row, - gint column); - -void nautilus_clist_set_row_style (NautilusCList *clist, - gint row, - GtkStyle *style); - -GtkStyle *nautilus_clist_get_row_style (NautilusCList *clist, - gint row); - -/* this sets a horizontal and vertical shift for drawing - * the contents of a cell; it can be positive or negitive; - * this is particulary useful for indenting items in a column - */ -void nautilus_clist_set_shift (NautilusCList *clist, - gint row, - gint column, - gint vertical, - gint horizontal); - -/* set/get selectable flag of a single row */ -void nautilus_clist_set_selectable (NautilusCList *clist, - gint row, - gboolean selectable); -gboolean nautilus_clist_get_selectable (NautilusCList *clist, - gint row); - -/* prepend/append returns the index of the row you just added, - * making it easier to append and modify a row - */ -gint nautilus_clist_prepend (NautilusCList *clist, - gchar *text[]); -gint nautilus_clist_append (NautilusCList *clist, - gchar *text[]); - -/* inserts a row at index row and returns the row where it was - * actually inserted (may be different from "row" in auto_sort mode) - */ -gint nautilus_clist_insert (NautilusCList *clist, - gint row, - gchar *text[]); - -/* removes row at index row */ -void nautilus_clist_remove (NautilusCList *clist, - gint row); - -/* sets a arbitrary data pointer for a given row */ -void nautilus_clist_set_row_data (NautilusCList *clist, - gint row, - gpointer data); - -/* sets a data pointer for a given row with destroy notification */ -void nautilus_clist_set_row_data_full (NautilusCList *clist, - gint row, - gpointer data, - GtkDestroyNotify destroy); - -/* returns the data set for a row */ -gpointer nautilus_clist_get_row_data (NautilusCList *clist, - gint row); - -/* givin a data pointer, find the first (and hopefully only!) - * row that points to that data, or -1 if none do - */ -gint nautilus_clist_find_row_from_data (NautilusCList *clist, - gpointer data); - -/* force selection of a row */ -void nautilus_clist_select_row (NautilusCList *clist, - gint row, - gint column); - -/* force unselection of a row */ -void nautilus_clist_unselect_row (NautilusCList *clist, - gint row, - gint column); - -/* undo the last select/unselect operation */ -void nautilus_clist_undo_selection (NautilusCList *clist); - -/* clear the entire list -- this is much faster than removing - * each item with nautilus_clist_remove - */ -void nautilus_clist_clear (NautilusCList *clist); - -/* return the row column corresponding to the x and y coordinates, - * the returned values are only valid if the x and y coordinates - * are respectively to a window == clist->clist_window - */ -gint nautilus_clist_get_selection_info (NautilusCList *clist, - gint x, - gint y, - gint *row, - gint *column); - -/* in multiple or extended mode, select all rows */ -void nautilus_clist_select_all (NautilusCList *clist); - -/* in all modes except browse mode, deselect all rows */ -void nautilus_clist_unselect_all (NautilusCList *clist); - -/* swap the position of two rows */ -void nautilus_clist_swap_rows (NautilusCList *clist, - gint row1, - gint row2); - -/* move row from source_row position to dest_row position */ -void nautilus_clist_row_move (NautilusCList *clist, - gint source_row, - gint dest_row); - -/* sets a compare function different to the default */ -void nautilus_clist_set_compare_func (NautilusCList *clist, - NautilusCListCompareFunc cmp_func); - -/* the column to sort by */ -void nautilus_clist_set_sort_column (NautilusCList *clist, - gint column); - -/* how to sort : ascending or descending */ -void nautilus_clist_set_sort_type (NautilusCList *clist, - GtkSortType sort_type); - -/* sort the list with the current compare function */ -void nautilus_clist_sort (NautilusCList *clist); - -/* Automatically sort upon insertion */ -void nautilus_clist_set_auto_sort (NautilusCList *clist, - gboolean auto_sort); - -gboolean nautilus_clist_check_unfrozen (NautilusCList *clist); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NAUTILUS_CLIST_H__ */ diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am index 733834e09..aec8b8514 100644 --- a/libnautilus-extensions/Makefile.am +++ b/libnautilus-extensions/Makefile.am @@ -27,7 +27,6 @@ INCLUDES = \ dependency_static_libs = \ $(top_builddir)/cut-n-paste-code/widgets/e-paned/libe-paned.la \ - $(top_builddir)/cut-n-paste-code/widgets/nautilusclist/libnautilusclist.la \ $(top_builddir)/cut-n-paste-code/widgets/gimphwrapbox/libgtkhwrapbox.la \ $(NULL) @@ -67,7 +66,6 @@ libnautilus_extensions_la_SOURCES = \ nautilus-audio-player.c \ nautilus-bonobo-extensions.c \ nautilus-bookmark.c \ - nautilus-ctree.c \ nautilus-customization-data.c \ nautilus-dateedit-extensions.c \ nautilus-default-file-icon.c \ @@ -77,11 +75,11 @@ libnautilus_extensions_la_SOURCES = \ nautilus-directory-metafile.c \ nautilus-directory.c \ nautilus-drag-window.c \ - nautilus-drag.c \ nautilus-druid-page-eazel.c \ nautilus-druid.c \ nautilus-entry.c \ nautilus-file-changes-queue.c \ + nautilus-file-dnd.c \ nautilus-file-operations-progress.c \ nautilus-file-operations.c \ nautilus-file-utilities.c \ @@ -100,8 +98,6 @@ libnautilus_extensions_la_SOURCES = \ nautilus-lib-self-check-functions.c \ nautilus-link-set.c \ nautilus-link.c \ - nautilus-list-column-title.c \ - nautilus-list.c \ nautilus-medusa-support.c \ nautilus-merged-directory.c \ nautilus-metafile-factory.c \ @@ -139,7 +135,6 @@ noinst_HEADERS = \ nautilus-bonobo-extensions.h \ nautilus-bookmark.h \ nautilus-cdrom-extensions.h \ - nautilus-ctree.h \ nautilus-customization-data.h \ nautilus-dateedit-extensions.h \ nautilus-default-file-icon.h \ @@ -150,12 +145,12 @@ noinst_HEADERS = \ nautilus-directory-private.h \ nautilus-directory.h \ nautilus-drag-window.h \ - nautilus-drag.h \ nautilus-druid-page-eazel.h \ nautilus-druid.h \ nautilus-entry.h \ nautilus-file-attributes.h \ nautilus-file-changes-queue.h \ + nautilus-file-dnd.h \ nautilus-file-operations-progress.h \ nautilus-file-operations.h \ nautilus-file-private.h \ @@ -178,8 +173,6 @@ noinst_HEADERS = \ nautilus-lib-self-check-functions.h \ nautilus-link-set.h \ nautilus-link.h \ - nautilus-list-column-title.h \ - nautilus-list.h \ nautilus-medusa-support.h \ nautilus-merged-directory.h \ nautilus-metadata.h \ diff --git a/libnautilus-extensions/nautilus-ctree.c b/libnautilus-extensions/nautilus-ctree.c deleted file mode 100644 index 029f04128..000000000 --- a/libnautilus-extensions/nautilus-ctree.c +++ /dev/null @@ -1,6125 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald, - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * NautilusCTree widget for GTK+ - * Copyright (C) 1998 Lars Hamann and Stefan Jeske - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - - -#include <config.h> -#include "nautilus-ctree.h" - -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkx.h> -#include <gdk/gdkx.h> -#include <gtk/gtkbindings.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkmain.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-graphic-effects.h> -#include <eel/eel-gtk-extensions.h> -#include <stdlib.h> -#include <string.h> - -#define PM_SIZE 8 -#define TAB_SIZE (PM_SIZE + 6) -#define CELL_SPACING 1 -#define CLIST_OPTIMUM_SIZE 64 -#define COLUMN_INSET 3 -#define DRAG_WIDTH 6 - -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) -#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ - ((clist)->row_height + CELL_SPACING)) -#define COLUMN_LEFT_XPIXEL(clist, col) ((clist)->column[(col)].area.x \ - + (clist)->hoffset) -#define COLUMN_LEFT(clist, column) ((clist)->column[(column)].area.x) - -static inline gint -COLUMN_FROM_XPIXEL (NautilusCList * clist, - gint x) -{ - gint i, cx; - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].visible) - { - cx = clist->column[i].area.x + clist->hoffset; - - if (x >= (cx - (COLUMN_INSET + CELL_SPACING)) && - x <= (cx + clist->column[i].area.width + COLUMN_INSET)) - return i; - } - - /* no match */ - return -1; -} - -#define NAUTILUS_CLIST_CLASS_FW(_widget_) NAUTILUS_CLIST_CLASS (((GtkObject*) (_widget_))->klass) -#define CLIST_UNFROZEN(clist) nautilus_clist_check_unfrozen (clist) -#define CLIST_REFRESH(clist) G_STMT_START { \ - if (CLIST_UNFROZEN (clist)) \ - NAUTILUS_CLIST_CLASS_FW (clist)->refresh (clist); \ -} G_STMT_END - - -enum { - ARG_0, - ARG_N_COLUMNS, - ARG_TREE_COLUMN, - ARG_INDENT, - ARG_SPACING, - ARG_SHOW_STUB, - ARG_LINE_STYLE -}; - - -static void nautilus_ctree_class_init (NautilusCTreeClass *klass); -static void nautilus_ctree_init (NautilusCTree *ctree); -static void nautilus_ctree_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_ctree_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_ctree_realize (GtkWidget *widget); -static void nautilus_ctree_unrealize (GtkWidget *widget); -static gint nautilus_ctree_button_press (GtkWidget *widget, - GdkEventButton *event); -static gboolean nautilus_ctree_event (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); -static void ctree_attach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void ctree_detach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static gint nautilus_ctree_draw_expander (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - GtkStyle *style, - GdkRectangle *clip_rectangle, - gint x); -static gint nautilus_ctree_draw_lines (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style); -static void draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row); -static void draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos); -static void tree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -static gboolean set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -static void set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -static NautilusCTreeRow *row_new (NautilusCTree *ctree); -static void row_delete (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row); -static void tree_delete (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_delete_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void real_clear (NautilusCList *clist); -static void tree_update_level (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void real_select_all (NautilusCList *clist); -static void real_unselect_all (NautilusCList *clist); -static void tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -static void tree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void change_focus_row_expansion (NautilusCTree *ctree, - NautilusCTreeExpansionType expansion); -static void real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void real_tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void real_tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node); -static void real_tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node); -static void real_tree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); -static void real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row); -static void real_tree_activate_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void nautilus_ctree_link (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gboolean update_focus_row); -static void nautilus_ctree_unlink (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean update_focus_row); -static NautilusCTreeNode * nautilus_ctree_last_visible (NautilusCTree *ctree, - NautilusCTreeNode *node); -static gboolean ctree_is_hot_spot (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint row, - gint x, - gint y); -static void tree_sort (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void fake_unselect_all (NautilusCList *clist, - gint row); -static GList * selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element); -static void resync_selection (NautilusCList *clist, - GdkEvent *event); -static void real_undo_selection (NautilusCList *clist); -static void select_row_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static gint real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]); -static void real_remove_row (NautilusCList *clist, - gint row); -static void real_sort_list (NautilusCList *clist); -static void cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition); -static void column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width); -static void auto_resize_columns (NautilusCList *clist); - - -static gboolean check_drag (NautilusCTree *ctree, - NautilusCTreeNode *drag_source, - NautilusCTreeNode *drag_target, - NautilusCListDragPos insert_pos); -static void nautilus_ctree_drag_begin (GtkWidget *widget, - GdkDragContext *context); -static gint nautilus_ctree_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void nautilus_ctree_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint32 time); -static void remove_grab (NautilusCList *clist); -static void drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info); - - -enum -{ - TREE_SELECT_ROW, - TREE_UNSELECT_ROW, - TREE_EXPAND, - TREE_COLLAPSE, - TREE_MOVE, - CHANGE_FOCUS_ROW_EXPANSION, - TREE_ACTIVATE_ROW, - LAST_SIGNAL -}; - -static NautilusCListClass *parent_class = NULL; -static GtkContainerClass *container_class = NULL; -static guint ctree_signals[LAST_SIGNAL] = {0}; - - -GtkType -nautilus_ctree_get_type (void) -{ - static GtkType ctree_type = 0; - - if (!ctree_type) - { - static const GtkTypeInfo ctree_info = - { - "NautilusCTree", - sizeof (NautilusCTree), - sizeof (NautilusCTreeClass), - (GtkClassInitFunc) nautilus_ctree_class_init, - (GtkObjectInitFunc) nautilus_ctree_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - ctree_type = gtk_type_unique (NAUTILUS_TYPE_LIST, &ctree_info); - } - - return ctree_type; -} - -static void -nautilus_ctree_class_init (NautilusCTreeClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - NautilusCListClass *clist_class; - GtkBindingSet *binding_set; - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - container_class = (GtkContainerClass *) klass; - clist_class = (NautilusCListClass *) klass; - - parent_class = gtk_type_class (NAUTILUS_TYPE_LIST); - container_class = gtk_type_class (GTK_TYPE_CONTAINER); - - gtk_object_add_arg_type ("NautilusCTree::n_columns", - GTK_TYPE_UINT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_N_COLUMNS); - gtk_object_add_arg_type ("NautilusCTree::tree_column", - GTK_TYPE_UINT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_TREE_COLUMN); - gtk_object_add_arg_type ("NautilusCTree::indent", - GTK_TYPE_UINT, - GTK_ARG_READWRITE, - ARG_INDENT); - gtk_object_add_arg_type ("NautilusCTree::spacing", - GTK_TYPE_UINT, - GTK_ARG_READWRITE, - ARG_SPACING); - gtk_object_add_arg_type ("NautilusCTree::show_stub", - GTK_TYPE_BOOL, - GTK_ARG_READWRITE, - ARG_SHOW_STUB); - object_class->set_arg = nautilus_ctree_set_arg; - object_class->get_arg = nautilus_ctree_get_arg; - - ctree_signals[TREE_SELECT_ROW] = - gtk_signal_new ("tree_select_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_select_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - ctree_signals[TREE_UNSELECT_ROW] = - gtk_signal_new ("tree_unselect_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_unselect_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - ctree_signals[TREE_EXPAND] = - gtk_signal_new ("tree_expand", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_expand), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); - ctree_signals[TREE_COLLAPSE] = - gtk_signal_new ("tree_collapse", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_collapse), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); - ctree_signals[TREE_MOVE] = - gtk_signal_new ("tree_move", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_move), - gtk_marshal_NONE__POINTER_POINTER_POINTER, - GTK_TYPE_NONE, 3, GTK_TYPE_CTREE_NODE, - GTK_TYPE_CTREE_NODE, GTK_TYPE_CTREE_NODE); - ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] = - gtk_signal_new ("change_focus_row_expansion", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, - change_focus_row_expansion), - gtk_marshal_NONE__ENUM, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_EXPANSION_TYPE); - ctree_signals[TREE_ACTIVATE_ROW] = - gtk_signal_new ("tree_activate_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_activate_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, ctree_signals, LAST_SIGNAL); - - widget_class->realize = nautilus_ctree_realize; - widget_class->unrealize = nautilus_ctree_unrealize; - widget_class->button_press_event = nautilus_ctree_button_press; - - widget_class->drag_begin = nautilus_ctree_drag_begin; - widget_class->drag_motion = nautilus_ctree_drag_motion; - widget_class->drag_data_received = nautilus_ctree_drag_data_received; - - clist_class->select_row = real_select_row; - clist_class->unselect_row = real_unselect_row; - clist_class->row_move = real_row_move; - clist_class->undo_selection = real_undo_selection; - clist_class->resync_selection = resync_selection; - clist_class->selection_find = selection_find; - clist_class->click_column = NULL; - clist_class->draw_row = draw_row; - clist_class->draw_drag_highlight = draw_drag_highlight; - clist_class->clear = real_clear; - clist_class->select_all = real_select_all; - clist_class->unselect_all = real_unselect_all; - clist_class->fake_unselect_all = fake_unselect_all; - clist_class->insert_row = real_insert_row; - clist_class->remove_row = real_remove_row; - clist_class->sort_list = real_sort_list; - clist_class->set_cell_contents = set_cell_contents; - clist_class->cell_size_request = cell_size_request; - - klass->tree_select_row = real_tree_select; - klass->tree_unselect_row = real_tree_unselect; - klass->tree_expand = real_tree_expand; - klass->tree_collapse = real_tree_collapse; - klass->tree_move = real_tree_move; - klass->change_focus_row_expansion = change_focus_row_expansion; - klass->tree_activate_row = real_tree_activate_row; - - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, - '+', GDK_SHIFT_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Add, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Add, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - '-', 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Subtract, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Subtract, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - '=', 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Multiply, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Multiply, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE); -} - -static void -nautilus_ctree_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCTree *ctree; - - ctree = NAUTILUS_CTREE (object); - - switch (arg_id) - { - case ARG_N_COLUMNS: /* construct-only arg, only set when !GTK_CONSTRUCTED */ - if (ctree->tree_column) - nautilus_ctree_construct (ctree, - MAX (1, GTK_VALUE_UINT (*arg)), - ctree->tree_column, NULL); - else - NAUTILUS_CLIST (ctree)->columns = MAX (1, GTK_VALUE_UINT (*arg)); - break; - case ARG_TREE_COLUMN: /* construct-only arg, only set when !GTK_CONSTRUCTED */ - if (NAUTILUS_CLIST (ctree)->columns) - nautilus_ctree_construct (ctree, - NAUTILUS_CLIST (ctree)->columns, - MAX (1, GTK_VALUE_UINT (*arg)), - NULL); - else - ctree->tree_column = MAX (1, GTK_VALUE_UINT (*arg)); - break; - case ARG_INDENT: - nautilus_ctree_set_indent (ctree, GTK_VALUE_UINT (*arg)); - break; - case ARG_SPACING: - nautilus_ctree_set_spacing (ctree, GTK_VALUE_UINT (*arg)); - break; - case ARG_SHOW_STUB: - nautilus_ctree_set_show_stub (ctree, GTK_VALUE_BOOL (*arg)); - break; - case ARG_LINE_STYLE: - nautilus_ctree_set_line_style (ctree, GTK_VALUE_ENUM (*arg)); - break; - default: - break; - } -} - -static void -nautilus_ctree_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCTree *ctree; - - ctree = NAUTILUS_CTREE (object); - - switch (arg_id) - { - case ARG_N_COLUMNS: - GTK_VALUE_UINT (*arg) = NAUTILUS_CLIST (ctree)->columns; - break; - case ARG_TREE_COLUMN: - GTK_VALUE_UINT (*arg) = ctree->tree_column; - break; - case ARG_INDENT: - GTK_VALUE_UINT (*arg) = ctree->tree_indent; - break; - case ARG_SPACING: - GTK_VALUE_UINT (*arg) = ctree->tree_spacing; - break; - case ARG_SHOW_STUB: - GTK_VALUE_BOOL (*arg) = ctree->show_stub; - break; - case ARG_LINE_STYLE: - GTK_VALUE_ENUM (*arg) = ctree->line_style; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static void -nautilus_ctree_init (NautilusCTree *ctree) -{ - NautilusCList *clist; - - NAUTILUS_CLIST_SET_FLAG (ctree, CLIST_DRAW_DRAG_RECT); - NAUTILUS_CLIST_SET_FLAG (ctree, CLIST_DRAW_DRAG_LINE); - - clist = NAUTILUS_CLIST (ctree); - - ctree->tree_indent = 20; - ctree->tree_spacing = 5; - ctree->tree_column = 0; - ctree->line_style = NAUTILUS_CTREE_LINES_NONE; - ctree->drag_compare = NULL; - ctree->show_stub = TRUE; - ctree->prelight_node = NULL; - - clist->button_actions[0] |= NAUTILUS_BUTTON_EXPANDS; - - /* Some random GNOME luser wants trees to look `normal' */ - nautilus_list_set_alternate_row_colors (NAUTILUS_LIST (ctree), FALSE); - nautilus_list_set_background_color_offsets (NAUTILUS_LIST (ctree), - G_STRUCT_OFFSET (GtkStyle, - base[GTK_STATE_NORMAL]), -1); - - gtk_signal_connect (GTK_OBJECT (ctree), "event", - GTK_SIGNAL_FUNC (nautilus_ctree_event), ctree); -} - -static void -ctree_attach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style) - NAUTILUS_CTREE_ROW (node)->row.style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.style, clist->clist_window); - - if (NAUTILUS_CTREE_ROW (node)->row.fg_set || NAUTILUS_CTREE_ROW (node)->row.bg_set) - { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (ctree)); - if (NAUTILUS_CTREE_ROW (node)->row.fg_set) - gdk_color_alloc (colormap, &(NAUTILUS_CTREE_ROW (node)->row.foreground)); - if (NAUTILUS_CTREE_ROW (node)->row.bg_set) - gdk_color_alloc (colormap, &(NAUTILUS_CTREE_ROW (node)->row.background)); - } - - for (i = 0; i < clist->columns; i++) - if (NAUTILUS_CTREE_ROW (node)->row.cell[i].style) - NAUTILUS_CTREE_ROW (node)->row.cell[i].style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.cell[i].style, - clist->clist_window); -} - -static void -ctree_detach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.style); - for (i = 0; i < clist->columns; i++) - if (NAUTILUS_CTREE_ROW (node)->row.cell[i].style) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.cell[i].style); -} - -static void -nautilus_ctree_realize (GtkWidget *widget) -{ - NautilusCTree *ctree; - NautilusCList *clist; - GdkGCValues values; - NautilusCTreeNode *node; - NautilusCTreeNode *child; - gint i; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - - GTK_WIDGET_CLASS (parent_class)->realize (widget); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - node = NAUTILUS_CTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) - { - if (!NAUTILUS_CTREE_ROW (node)->is_leaf && !NAUTILUS_CTREE_ROW (node)->expanded) - for (child = NAUTILUS_CTREE_ROW (node)->children; - child != NULL; - child = NAUTILUS_CTREE_ROW (child)->sibling) - nautilus_ctree_pre_recursive (ctree, child, ctree_attach_styles, NULL); - node = NAUTILUS_CTREE_NODE_NEXT (node); - } - - values.foreground = widget->style->fg[GTK_STATE_NORMAL]; - values.background = widget->style->base[GTK_STATE_NORMAL]; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - values.line_style = GDK_LINE_SOLID; - ctree->lines_gc = gdk_gc_new_with_values (NAUTILUS_CLIST(widget)->clist_window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_BACKGROUND | - GDK_GC_SUBWINDOW | - GDK_GC_LINE_STYLE); - - if (ctree->line_style == NAUTILUS_CTREE_LINES_DOTTED) - { - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, None, None); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - } -} - -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -static gint -nautilus_ctree_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - GdkEventMotion *motion; - int press_row, press_column, row; - NautilusCTree *tree; - NautilusCTreeNode *node, *old_node; - NautilusCTreeRow *ctree_row; - NautilusCList *clist; - gint x, y; - GdkModifierType button; - - tree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - /* Do prelighting */ - if (event->type == GDK_MOTION_NOTIFY) { - motion = (GdkEventMotion *) event; - - /* Get node that we are over */ - row = nautilus_clist_get_selection_info (clist, motion->x, motion->y, &press_row, &press_column); - if (row <= 0) { - return FALSE; - } - - ctree_row = ROW_ELEMENT (clist, press_row)->data; - if (ctree_row == NULL) { - return FALSE; - } - - node = nautilus_ctree_find_node_ptr (tree, ctree_row); - if (node == NULL) { - return FALSE; - } - - /* Cancel prelighting if we have a button pressed */ - gdk_window_get_pointer (widget->window, &x, &y, &button); - if ((button & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) != 0) { - if (nautilus_ctree_is_hot_spot (tree, motion->x, motion->y)) { - /* Handle moving in and out of hotspot while mouse is down */ - if (!ctree_row->in_hotspot) { - ctree_row->in_hotspot = TRUE; - nautilus_ctree_draw_node (tree, node); - } - } else { - if (ctree_row->in_hotspot) { - ctree_row->in_hotspot = FALSE; - nautilus_ctree_draw_node (tree, node); - } - } - - /* Remove prelighting */ - if (tree->prelight_node != NULL) { - old_node = tree->prelight_node; - tree->prelight_node = NULL; - nautilus_ctree_draw_node (tree, old_node); - } - return FALSE; - } - - if (nautilus_ctree_is_hot_spot (tree, motion->x, motion->y)) { - if (node != tree->prelight_node) { - /* Redraw old prelit node and save and draw new highlight */ - old_node = tree->prelight_node; - tree->prelight_node = node; - nautilus_ctree_draw_node (tree, old_node); - nautilus_ctree_draw_node (tree, tree->prelight_node); - } - } else if (tree->prelight_node != NULL) { - /* End prelighting of last expander */ - old_node = tree->prelight_node; - tree->prelight_node = NULL; - nautilus_ctree_draw_node (tree, old_node); - } - } - - return FALSE; -} - -static void -nautilus_ctree_unrealize (GtkWidget *widget) -{ - NautilusCTree *ctree; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - - GTK_WIDGET_CLASS (parent_class)->unrealize (widget); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - if (GTK_WIDGET_REALIZED (widget)) - { - NautilusCTreeNode *node; - NautilusCTreeNode *child; - gint i; - - node = NAUTILUS_CTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) - { - if (!NAUTILUS_CTREE_ROW (node)->is_leaf && - !NAUTILUS_CTREE_ROW (node)->expanded) - for (child = NAUTILUS_CTREE_ROW (node)->children; - child != NULL; - child = NAUTILUS_CTREE_ROW (child)->sibling) - nautilus_ctree_pre_recursive(ctree, child, ctree_detach_styles, NULL); - node = NAUTILUS_CTREE_NODE_NEXT (node); - } - } - - gdk_gc_destroy (ctree->lines_gc); -} - -static gint -nautilus_ctree_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusCTree *ctree; - NautilusCList *clist; - gint button_actions; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - button_actions = clist->button_actions[event->button - 1]; - - if (button_actions == NAUTILUS_BUTTON_IGNORED) { - return FALSE; - } - - if (event->window == clist->clist_window) - { - NautilusCTreeNode *work; - gint x; - gint y; - gint row; - gint column; - - x = event->x; - y = event->y; - - if (!nautilus_clist_get_selection_info (clist, x, y, &row, &column)) { - return FALSE; - } - - work = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - - if (button_actions & NAUTILUS_BUTTON_EXPANDS && - (!NAUTILUS_CTREE_ROW (work)->is_leaf && - ctree_is_hot_spot (ctree, work, row, x, y))) - { - if (NAUTILUS_CTREE_ROW (work)->expanded) { - nautilus_ctree_collapse (ctree, work); - } else { - nautilus_ctree_expand (ctree, work); - } - return FALSE; - } else if (event->type == GDK_2BUTTON_PRESS) { - /* double-click on a row = "activate" */ - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_ACTIVATE_ROW], - work, column); - } - } - - return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); -} - -static void -draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos) -{ - NautilusCTree *ctree; - GdkPoint points[4]; - gint level; - gint i; - gint y = 0; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - level = ((NautilusCTreeRow *)(dest_row))->level; - - y = ROW_TOP_YPIXEL (clist, dest_row_number) - 1; - - switch (drag_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - break; - case NAUTILUS_CLIST_DRAG_AFTER: - y += clist->row_height + 1; - case NAUTILUS_CLIST_DRAG_BEFORE: - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - if (ctree->tree_column > 0) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, 0), y, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1)+ - clist->column[ctree->tree_column - 1].area.width, - y); - - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - - (ctree->tree_indent - PM_SIZE) / 2, y, - GTK_WIDGET (ctree)->allocation.width, y); - break; - case GTK_JUSTIFY_RIGHT: - if (ctree->tree_column < clist->columns - 1) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), - y, - COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) + - clist->column[clist->columns - 1].area.width, y); - - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - + clist->column[ctree->tree_column].area.width - - ctree->tree_indent * level + - (ctree->tree_indent - PM_SIZE) / 2, y); - break; - } - else - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, clist->clist_window_width, y); - break; - case NAUTILUS_CLIST_DRAG_INTO: - y = ROW_TOP_YPIXEL (clist, dest_row_number) + clist->row_height; - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - - if (ctree->tree_column > 0) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, - ctree->tree_column - 1) + - clist->column[ctree->tree_column - 1].area.width ; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, points[i+1].x, - points[i+1].y); - } - break; - case GTK_JUSTIFY_RIGHT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - - ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2 + - clist->column[ctree->tree_column].area.width; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - - if (ctree->tree_column < clist->columns - 1) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column +1); - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - } - break; - } - else - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, y - clist->row_height, - clist->clist_window_width - 1, clist->row_height); - break; - } -} - -static NautilusCTreeRow * -nautilus_ctree_row_at (NautilusCTree *ctree, int y) -{ - int row_index, column_index; - - y -= (GTK_CONTAINER (ctree)->border_width + - GTK_WIDGET (ctree)->style->klass->ythickness + - NAUTILUS_CLIST (ctree)->column_title_area.height); - - if (!nautilus_clist_get_selection_info (NAUTILUS_CLIST (ctree), 10, y, &row_index, &column_index)) { - return NULL; - } - - return g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row_index)->data; -} - - -static void -get_cell_rectangle (NautilusCList *clist, int row_index, int column_index, GdkRectangle *result) -{ - result->x = clist->column[column_index].area.x + clist->hoffset; - result->y = ROW_TOP_YPIXEL (clist, row_index); - result->width = clist->column[column_index].area.width; - result->height = clist->row_height; -} - - -void -nautilus_ctree_set_prelight (NautilusCTree *ctree, - int y) -{ - NautilusCList *clist; - NautilusCTreeRow *row, *last_row; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - row = NULL; - - if (y >= 0) { - row = nautilus_ctree_row_at (ctree, y); - } - - if (row != ctree->dnd_prelighted_row) { - last_row = ctree->dnd_prelighted_row; - ctree->dnd_prelighted_row = row; - - { - GdkRectangle rect; - int row_index; - /* Redraw old cell */ - if (last_row != NULL) { - row_index = g_list_index (clist->row_list, last_row); - get_cell_rectangle (clist, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (clist), &rect); - } - - /* Draw new cell */ - if (ctree->dnd_prelighted_row != NULL) { - row_index = g_list_index (clist->row_list, ctree->dnd_prelighted_row); - get_cell_rectangle (clist, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (clist), &rect); - } - } - } -} - -static gint -nautilus_ctree_draw_expander (NautilusCTree *ctree, NautilusCTreeRow *ctree_row, GtkStyle *style, - GdkRectangle *clip_rectangle, gint x) -{ - NautilusCList *clist; - GdkPoint points[3]; - gint justification_factor; - gint y; - NautilusCTreeNode *node; - - clist = NAUTILUS_CLIST (ctree); - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) - justification_factor = -1; - else - justification_factor = 1; - - y = (clip_rectangle->y + (clip_rectangle->height - PM_SIZE) / 2 - (clip_rectangle->height + 1) % 2); - - if (ctree_row->is_leaf) { - return x + justification_factor * (PM_SIZE + 3); - } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], clip_rectangle); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], clip_rectangle); - - if (ctree_row->expanded) - { - points[0].x = x; - points[0].y = y + (PM_SIZE + 2) / 6; - points[1].x = points[0].x + justification_factor * (PM_SIZE + 2); - points[1].y = points[0].y; - points[2].x = (points[0].x + justification_factor * (PM_SIZE + 2) / 2); - points[2].y = y + 2 * (PM_SIZE + 2) / 3; - } else { - points[0].x = x + justification_factor * ((PM_SIZE + 2) / 6 + 2); - points[0].y = y - 1; - points[1].x = points[0].x; - points[1].y = points[0].y + (PM_SIZE + 2); - points[2].x = (points[0].x + justification_factor * (2 * (PM_SIZE + 2) / 3 - 1)); - points[2].y = points[0].y + (PM_SIZE + 2) / 2; - } - - gdk_draw_polygon (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], TRUE, points, 3); - if (ctree_row->mouse_down) { - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], !ctree_row->in_hotspot, points, 3); - } else { - node = nautilus_ctree_find_node_ptr (ctree, ctree_row); - if (node != NULL) { - if (node == ctree->prelight_node) { - /* Draw prelight state */ - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], FALSE, points, 3); - } else { - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], TRUE, points, 3); - } - } - } - - x += justification_factor * (PM_SIZE + 3); - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL); - - return x; -} - -static gint -nautilus_ctree_draw_lines (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style) -{ - NautilusCList *clist; - NautilusCTreeNode *node; - NautilusCTreeNode *parent; - GdkRectangle tree_rectangle; - GdkRectangle tc_rectangle; - GdkGC *bg_gc; - gint offset; - gint offset_x; - gint offset_y; - gint xcenter; - gint ycenter; - gint next_level; - gint column_right; - gint column_left; - gint justify_right; - gint justification_factor; - - clist = NAUTILUS_CLIST (ctree); - ycenter = clip_rectangle->y + (clip_rectangle->height / 2); - justify_right = (clist->column[column].justification == GTK_JUSTIFY_RIGHT); - - if (justify_right) - { - offset = (clip_rectangle->x + clip_rectangle->width - 1 - - ctree->tree_indent * (ctree_row->level - 1)); - justification_factor = -1; - } - else - { - offset = clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); - justification_factor = 1; - } - - switch (ctree->line_style) - { - case NAUTILUS_CTREE_LINES_NONE: - break; - case NAUTILUS_CTREE_LINES_TABBED: - xcenter = offset + justification_factor * TAB_SIZE; - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - CELL_SPACING); - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter; - tree_rectangle.width = column_right - xcenter; - } - else - { - tree_rectangle.x = column_left; - tree_rectangle.width = xcenter - column_left; - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - { - offset += justification_factor * 3; - break; - } - } - - gdk_gc_set_clip_rectangle (ctree->lines_gc, crect); - - next_level = ctree_row->level; - - if (!ctree_row->sibling || (ctree_row->children && ctree_row->expanded)) - { - node = nautilus_ctree_find_node_ptr (ctree, ctree_row); - if (NAUTILUS_CTREE_NODE_NEXT (node)) - next_level = NAUTILUS_CTREE_ROW (NAUTILUS_CTREE_NODE_NEXT (node))->level; - else - next_level = 0; - } - - if (ctree->tree_indent > 0) - { - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if ((justify_right && xcenter < column_left) || - (!justify_right && xcenter > column_right)) - { - node = NAUTILUS_CTREE_ROW (node)->parent; - continue; - } - - tree_rectangle.y = cell_rectangle->y; - tree_rectangle.height = cell_rectangle->height; - if (justify_right) - { - tree_rectangle.x = MAX (xcenter - ctree->tree_indent + 1, - column_left); - tree_rectangle.width = MIN (xcenter - column_left, - ctree->tree_indent); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - ctree->tree_indent); - } - - if (!area || gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &NAUTILUS_CTREE_ROW (node)->row.background); - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - if (next_level > NAUTILUS_CTREE_ROW (node)->level) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, crect->y, - xcenter, crect->y + crect->height); - else - { - gint width; - - offset_x = MIN (ctree->tree_indent, 2 * TAB_SIZE); - width = offset_x / 2 + offset_x % 2; - - parent = NAUTILUS_CTREE_ROW (node)->parent; - - tree_rectangle.y = ycenter; - tree_rectangle.height = (cell_rectangle->y - ycenter + - cell_rectangle->height); - - if (justify_right) - { - tree_rectangle.x = MAX(xcenter + 1 - width, column_left); - tree_rectangle.width = MIN (xcenter + 1 - column_left, - width); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - width); - } - - if (!area || - gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - if (parent) - { - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (parent)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, - &NAUTILUS_CTREE_ROW (parent)->row.background); - } - else if (state == GTK_STATE_SELECTED) - bg_gc = style->base_gc[state]; - else - bg_gc = GTK_WIDGET (clist)->style->base_gc[state]; - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, - bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &NAUTILUS_CTREE_ROW (node)->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - xcenter - (justify_right * offset_x), - cell_rectangle->y, - offset_x, clist->row_height, - (180 + (justify_right * 90)) * 64, 90 * 64); - gdk_gc_set_clip_rectangle (bg_gc, NULL); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y, xcenter, ycenter); - - if (justify_right) - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter - offset_x, cell_rectangle->y, - offset_x, clist->row_height, - 270 * 64, 90 * 64); - else - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter, cell_rectangle->y, - offset_x, clist->row_height, - 180 * 64, 90 * 64); - } - node = NAUTILUS_CTREE_ROW (node)->parent; - } - } - - if (state != GTK_STATE_SELECTED) - { - tree_rectangle.y = clip_rectangle->y; - tree_rectangle.height = clip_rectangle->height; - tree_rectangle.width = COLUMN_INSET + CELL_SPACING + - MIN (clist->column[ctree->tree_column].area.width + COLUMN_INSET, - TAB_SIZE); - - if (justify_right) - tree_rectangle.x = MAX (xcenter + 1, column_left); - else - tree_rectangle.x = column_left; - - if (!area) - gdk_draw_rectangle (clist->clist_window, - GTK_WIDGET - (ctree)->style->base_gc[GTK_STATE_NORMAL], - TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else if (gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - gdk_draw_rectangle (clist->clist_window, - GTK_WIDGET - (ctree)->style->base_gc[GTK_STATE_NORMAL], - TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - xcenter = offset + (justification_factor * ctree->tree_indent / 2); - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &ctree_row->row, state, row, column, - NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground (clist->bg_gc, &ctree_row->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - if (ctree_row->is_leaf) - { - GdkPoint points[6]; - - points[0].x = offset + justification_factor * TAB_SIZE; - points[0].y = cell_rectangle->y; - - points[1].x = points[0].x - justification_factor * 4; - points[1].y = points[0].y; - - points[2].x = points[1].x - justification_factor * 2; - points[2].y = points[1].y + 3; - - points[3].x = points[2].x; - points[3].y = points[2].y + clist->row_height - 5; - - points[4].x = points[3].x + justification_factor * 2; - points[4].y = points[3].y + 3; - - points[5].x = points[4].x + justification_factor * 4; - points[5].y = points[4].y; - - gdk_draw_polygon (clist->clist_window, bg_gc, TRUE, points, 6); - gdk_draw_lines (clist->clist_window, ctree->lines_gc, points, 6); - } - else - { - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - } - gdk_gc_set_clip_rectangle (bg_gc, NULL); - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - - offset += justification_factor * 3; - break; - default: - xcenter = offset + justification_factor * PM_SIZE / 2; - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter - PM_SIZE / 2 - 2; - tree_rectangle.width = (clip_rectangle->x + - clip_rectangle->width -tree_rectangle.x); - } - else - { - tree_rectangle.x = clip_rectangle->x + PM_SIZE / 2; - tree_rectangle.width = (xcenter + PM_SIZE / 2 + 2 - - clip_rectangle->x); - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - break; - } - - offset_x = 1; - offset_y = 0; - if (ctree->line_style == NAUTILUS_CTREE_LINES_DOTTED) - { - offset_x += abs((clip_rectangle->x + clist->hoffset) % 2); - offset_y = abs((cell_rectangle->y + clist->voffset) % 2); - } - - clip_rectangle->y--; - clip_rectangle->height++; - gdk_gc_set_clip_rectangle (ctree->lines_gc, clip_rectangle); - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, - (ctree->show_stub || clist->row_list->data != ctree_row) ? - cell_rectangle->y + offset_y : ycenter, - xcenter, - (ctree_row->sibling) ? crect->y +crect->height : ycenter); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter + (justification_factor * offset_x), ycenter, - xcenter + (justification_factor * (PM_SIZE / 2 + 2)), - ycenter); - - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if (NAUTILUS_CTREE_ROW (node)->sibling) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y + offset_y, - xcenter, crect->y + crect->height); - node = NAUTILUS_CTREE_ROW (node)->parent; - } - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - clip_rectangle->y++; - clip_rectangle->height--; - break; - } - return offset; -} - -static void -draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row) -{ - GtkWidget *widget; - NautilusCTree *ctree; - GdkRectangle *rect; - GdkRectangle *crect; - GdkRectangle row_rectangle; - GdkRectangle cell_rectangle; - GdkRectangle clip_rectangle; - GdkRectangle intersect_rectangle; - gint last_column; - gint column_left = 0; - gint column_right = 0; - gint offset = 0; - gint state; - gint i; - - g_return_if_fail (clist != NULL); - - /* bail now if we arn't drawable yet */ - if (!GTK_WIDGET_DRAWABLE (clist) || row < 0 || row >= clist->rows) - return; - - widget = GTK_WIDGET (clist); - ctree = NAUTILUS_CTREE (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup */ - if (!clist_row) - clist_row = (g_list_nth (clist->row_list, row))->data; - - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; - - /* rectangle of the cell spacing above the row */ - cell_rectangle.x = 0; - cell_rectangle.y = row_rectangle.y - CELL_SPACING; - cell_rectangle.width = row_rectangle.width; - cell_rectangle.height = CELL_SPACING; - - /* rectangle used to clip drawing operations, its y and height - * positions only need to be set once, so we set them once here. - * the x and width are set withing the drawing loop below once per - * column */ - clip_rectangle.y = row_rectangle.y; - clip_rectangle.height = row_rectangle.height; - - if (clist_row->state == GTK_STATE_NORMAL) - { - if (clist_row->fg_set) - gdk_gc_set_foreground (clist->fg_gc, &clist_row->foreground); - if (clist_row->bg_set) - gdk_gc_set_foreground (clist->bg_gc, &clist_row->background); - } - - state = clist_row->state; - - gdk_gc_set_foreground (ctree->lines_gc, - &widget->style->fg[clist_row->state]); - - /* draw the cell borders */ - if (area) - { - rect = &intersect_rectangle; - crect = &intersect_rectangle; - - if (gdk_rectangle_intersect (area, &cell_rectangle, crect)) - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - else - { - rect = &clip_rectangle; - crect = &cell_rectangle; - - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - - /* horizontal black lines */ - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) - { - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - (ctree->tree_column != 0) * CELL_SPACING); - - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - offset = (column_left + ctree->tree_indent * - (((NautilusCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (offset + TAB_SIZE, column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - offset = (column_right - 1 - ctree->tree_indent * - (((NautilusCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (offset - TAB_SIZE, column_left), - cell_rectangle.y); - break; - } - } - - /* the last row has to clear its bottom cell spacing too */ - if (clist_row == clist->row_list_end->data) - { - cell_rectangle.y += clist->row_height + CELL_SPACING; - - if (!area || gdk_rectangle_intersect (area, &cell_rectangle, crect)) - { - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* horizontal black lines */ - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) - { - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (column_left + TAB_SIZE + COLUMN_INSET + - (((NautilusCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (column_right - TAB_SIZE - 1 - - COLUMN_INSET - - (((NautilusCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_left - 1), cell_rectangle.y); - break; - } - } - } - } - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - /* iterate and draw all the columns (row cells) and draw their contents */ - for (i = 0; i < clist->columns; i++) - { - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - guint bg_rgb; - - gint width; - gint height; - gint pixbuf_width; - gint string_width; - gint old_offset; - gint row_center_offset; - - if (!clist->column[i].visible) - continue; - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), clist_row, state, row, i, - &style, &fg_gc, &bg_gc, &bg_rgb); - - /* calculate clipping region */ - clip_rectangle.x = clist->column[i].area.x + clist->hoffset; - clip_rectangle.width = clist->column[i].area.width; - - cell_rectangle.x = clip_rectangle.x - COLUMN_INSET - CELL_SPACING; - cell_rectangle.width = (clip_rectangle.width + 2 * COLUMN_INSET + - (1 + (i == last_column)) * CELL_SPACING); - cell_rectangle.y = clip_rectangle.y; - cell_rectangle.height = clip_rectangle.height; - - string_width = 0; - pixbuf_width = 0; - height = 0; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - { - if (i != ctree->tree_column) - continue; - } - else - { - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* calculate real width for column justification */ - switch (clist_row->cell[i].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - width = gdk_string_width - (style->font, NAUTILUS_CELL_TEXT (clist_row->cell[i])->text); - break; - case NAUTILUS_CELL_PIXBUF: - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf); - width = pixbuf_width; - break; - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - { - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf); - } - - width = pixbuf_width; - - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text) - { - string_width = gdk_string_width - (style->font, NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text); - width += string_width; - } - - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text && - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - width += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - - if (i == ctree->tree_column) - width += (ctree->tree_indent * - ((NautilusCTreeRow *)clist_row)->level); - break; - default: - continue; - break; - } - - switch (clist->column[i].justification) - { - case GTK_JUSTIFY_LEFT: - offset = clip_rectangle.x + clist_row->cell[i].horizontal; - break; - case GTK_JUSTIFY_RIGHT: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - clip_rectangle.width - width); - break; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - (clip_rectangle.width / 2) - (width / 2)); - break; - }; - - if (i != ctree->tree_column) - { - offset += clist_row->cell[i].horizontal; - switch (clist_row->cell[i].type) - { - case NAUTILUS_CELL_PIXBUF: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - break; - case NAUTILUS_CELL_PIXTEXT: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &clip_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - offset += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - case NAUTILUS_CELL_TEXT: - row_center_offset = ((clist->row_height - - (style->font->ascent - + style->font->descent)) / 2 - + style->font->ascent); - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_string - (clist->clist_window, style->font, fg_gc, - offset, - row_rectangle.y + row_center_offset + - clist_row->cell[i].vertical, - (clist_row->cell[i].type == NAUTILUS_CELL_PIXTEXT) ? - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text : - NAUTILUS_CELL_TEXT (clist_row->cell[i])->text); - gdk_gc_set_clip_rectangle (fg_gc, NULL); - break; - default: - break; - } - continue; - } - } - - if (bg_gc == clist->bg_gc) - gdk_gc_set_background (ctree->lines_gc, &clist_row->background); - - /* draw ctree->tree_column */ - cell_rectangle.y -= CELL_SPACING; - cell_rectangle.height += CELL_SPACING; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - continue; - - /* draw lines */ - offset = nautilus_ctree_draw_lines (ctree, (NautilusCTreeRow *)clist_row, row, i, - state, &clip_rectangle, &cell_rectangle, - crect, area, style); - - /* draw expander */ - offset = nautilus_ctree_draw_expander (ctree, (NautilusCTreeRow *)clist_row, - style, &clip_rectangle, offset); - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= ctree->tree_spacing; - else - offset += ctree->tree_spacing; - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= (pixbuf_width + clist_row->cell[i].horizontal); - else - offset += clist_row->cell[i].horizontal; - - old_offset = offset; - if (height > 0) { - GdkPixbuf *src_pixbuf, *dark_pixbuf; - - if (((NautilusCListRow *)ctree->dnd_prelighted_row) == clist_row) { - - src_pixbuf = NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf; - - if (src_pixbuf != NULL) { - /* Create darkened pixbuf */ - dark_pixbuf = eel_create_darkened_pixbuf (src_pixbuf, - 0.8 * 255, - 0.8 * 255); - if (dark_pixbuf != NULL) { - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - dark_pixbuf, offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - gdk_pixbuf_unref (dark_pixbuf); - } - } - } else { - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &clip_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - - } - } - - if (string_width) - { - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - { - offset = (old_offset - string_width); - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset -= NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - } - else - { - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - } - - row_center_offset = ((clist->row_height - - (style->font->ascent - + style->font->descent)) / 2 - + style->font->ascent); - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_string (clist->clist_window, style->font, fg_gc, offset, - row_rectangle.y + row_center_offset + - clist_row->cell[i].vertical, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text); - } - gdk_gc_set_clip_rectangle (fg_gc, NULL); - } - - /* draw focus rectangle */ - if (clist->focus_row == row && - GTK_WIDGET_CAN_FOCUS (widget) && GTK_WIDGET_HAS_FOCUS (widget)) - { - if (!area) - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - else if (gdk_rectangle_intersect (area, &row_rectangle, - &intersect_rectangle)) - { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } - } -} - -void -nautilus_ctree_draw_node (NautilusCTree *ctree, NautilusCTreeNode *node) -{ - if (ctree == NULL || node == NULL) { - return; - } - - tree_draw_node (ctree, node); -} - -static void -tree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && nautilus_ctree_is_viewable (ctree, node)) - { - NautilusCTreeNode *work; - gint num = 0; - - work = NAUTILUS_CTREE_NODE (clist->row_list); - while (work && work != node) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - num++; - } - - if (work && nautilus_clist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE) { - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row - (clist, NULL, num, NAUTILUS_CLIST_ROW ((GList *) node)); - } - } -} - -static NautilusCTreeNode * -nautilus_ctree_last_visible (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeNode *work; - - if (!node) - return NULL; - - work = NAUTILUS_CTREE_ROW (node)->children; - - if (!work || !NAUTILUS_CTREE_ROW (node)->expanded) - return node; - - while (NAUTILUS_CTREE_ROW (work)->sibling) - work = NAUTILUS_CTREE_ROW (work)->sibling; - - return nautilus_ctree_last_visible (ctree, work); -} - -static void -nautilus_ctree_link (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gboolean update_focus_row) -{ - NautilusCList *clist; - GList *list_end; - GList *list; - GList *work; - gboolean visible = FALSE; - gint rows = 0; - - if (sibling) - g_return_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent); - g_return_if_fail (node != NULL); - g_return_if_fail (node != sibling); - g_return_if_fail (node != parent); - - clist = NAUTILUS_CLIST (ctree); - - if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - for (rows = 1, list_end = (GList *)node; list_end->next; - list_end = list_end->next) - rows++; - - NAUTILUS_CTREE_ROW (node)->parent = parent; - NAUTILUS_CTREE_ROW (node)->sibling = sibling; - - if (!parent || (parent && (nautilus_ctree_is_viewable (ctree, parent) && - NAUTILUS_CTREE_ROW (parent)->expanded))) - { - visible = TRUE; - clist->rows += rows; - } - - if (parent) - work = (GList *)(NAUTILUS_CTREE_ROW (parent)->children); - else - work = clist->row_list; - - if (sibling) - { - if (work != (GList *)sibling) - { - while (NAUTILUS_CTREE_ROW (work)->sibling != sibling) - work = (GList *)(NAUTILUS_CTREE_ROW (work)->sibling); - NAUTILUS_CTREE_ROW (work)->sibling = node; - } - - if (sibling == NAUTILUS_CTREE_NODE (clist->row_list)) - clist->row_list = (GList *) node; - if (NAUTILUS_CTREE_NODE_PREV (sibling) && - NAUTILUS_CTREE_NODE_NEXT (NAUTILUS_CTREE_NODE_PREV (sibling)) == sibling) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (sibling); - list->next = (GList *)node; - } - - list = (GList *)node; - list->prev = (GList *)NAUTILUS_CTREE_NODE_PREV (sibling); - list_end->next = (GList *)sibling; - list = (GList *)sibling; - list->prev = list_end; - if (parent && NAUTILUS_CTREE_ROW (parent)->children == sibling) - NAUTILUS_CTREE_ROW (parent)->children = node; - } - else - { - if (work) - { - /* find sibling */ - while (NAUTILUS_CTREE_ROW (work)->sibling) - work = (GList *)(NAUTILUS_CTREE_ROW (work)->sibling); - NAUTILUS_CTREE_ROW (work)->sibling = node; - - /* find last visible child of sibling */ - work = (GList *) nautilus_ctree_last_visible (ctree, - NAUTILUS_CTREE_NODE (work)); - - list_end->next = work->next; - if (work->next) - list = work->next->prev = list_end; - work->next = (GList *)node; - list = (GList *)node; - list->prev = work; - } - else - { - if (parent) - { - NAUTILUS_CTREE_ROW (parent)->children = node; - list = (GList *)node; - list->prev = (GList *)parent; - if (NAUTILUS_CTREE_ROW (parent)->expanded) - { - list_end->next = (GList *)NAUTILUS_CTREE_NODE_NEXT (parent); - if (NAUTILUS_CTREE_NODE_NEXT(parent)) - { - list = (GList *)NAUTILUS_CTREE_NODE_NEXT (parent); - list->prev = list_end; - } - list = (GList *)parent; - list->next = (GList *)node; - } - else - list_end->next = NULL; - } - else - { - clist->row_list = (GList *)node; - list = (GList *)node; - list->prev = NULL; - list_end->next = NULL; - } - } - } - - nautilus_ctree_pre_recursive (ctree, node, tree_update_level, NULL); - - if (clist->row_list_end == NULL || - clist->row_list_end->next == (GList *)node) - clist->row_list_end = list_end; - - if (visible && update_focus_row) - { - gint pos; - - pos = g_list_position (clist->row_list, (GList *)node); - - if (pos <= clist->focus_row) - { - clist->focus_row += rows; - clist->undo_anchor = clist->focus_row; - } - } -} - -static void -nautilus_ctree_unlink (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean update_focus_row) -{ - NautilusCList *clist; - gint rows; - gint level; - gint visible; - NautilusCTreeNode *work; - NautilusCTreeNode *parent; - GList *list; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - visible = nautilus_ctree_is_viewable (ctree, node); - - /* clist->row_list_end unlinked ? */ - if (visible && - (NAUTILUS_CTREE_NODE_NEXT (node) == NULL || - (NAUTILUS_CTREE_ROW (node)->children && - nautilus_ctree_is_ancestor (ctree, node, - NAUTILUS_CTREE_NODE (clist->row_list_end))))) - clist->row_list_end = (GList *) (NAUTILUS_CTREE_NODE_PREV (node)); - - /* update list */ - rows = 0; - level = NAUTILUS_CTREE_ROW (node)->level; - work = NAUTILUS_CTREE_NODE_NEXT (node); - while (work && NAUTILUS_CTREE_ROW (work)->level > level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - rows++; - } - - if (visible) - { - clist->rows -= (rows + 1); - - if (update_focus_row) - { - gint pos; - - pos = g_list_position (clist->row_list, (GList *)node); - if (pos + rows < clist->focus_row) - clist->focus_row -= (rows + 1); - else if (pos <= clist->focus_row) - { - if (!NAUTILUS_CTREE_ROW (node)->sibling) - clist->focus_row = MAX (pos - 1, 0); - else - clist->focus_row = pos; - - clist->focus_row = MIN (clist->focus_row, clist->rows - 1); - } - clist->undo_anchor = clist->focus_row; - } - } - - if (work) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (work); - list->next = NULL; - list = (GList *)work; - list->prev = (GList *)NAUTILUS_CTREE_NODE_PREV (node); - } - - if (NAUTILUS_CTREE_NODE_PREV (node) && - NAUTILUS_CTREE_NODE_NEXT (NAUTILUS_CTREE_NODE_PREV (node)) == node) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (node); - list->next = (GList *)work; - } - - /* update tree */ - parent = NAUTILUS_CTREE_ROW (node)->parent; - if (parent) - { - if (NAUTILUS_CTREE_ROW (parent)->children == node) - { - NAUTILUS_CTREE_ROW (parent)->children = NAUTILUS_CTREE_ROW (node)->sibling; - if (NAUTILUS_CTREE_ROW (parent)->is_leaf) - nautilus_ctree_collapse (ctree, parent); - } - else - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_ROW (parent)->children; - while (NAUTILUS_CTREE_ROW (sibling)->sibling != node) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - NAUTILUS_CTREE_ROW (sibling)->sibling = NAUTILUS_CTREE_ROW (node)->sibling; - } - } - else - { - if (clist->row_list == (GList *)node) - clist->row_list = (GList *) (NAUTILUS_CTREE_ROW (node)->sibling); - else - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - while (NAUTILUS_CTREE_ROW (sibling)->sibling != node) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - NAUTILUS_CTREE_ROW (sibling)->sibling = NAUTILUS_CTREE_ROW (node)->sibling; - } - } -} - -static void -real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - return; - - if (source_row < 0 || source_row >= clist->rows || - dest_row < 0 || dest_row >= clist->rows || - source_row == dest_row) - return; - - ctree = NAUTILUS_CTREE (clist); - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, source_row)); - - if (source_row < dest_row) - { - NautilusCTreeNode *work; - - dest_row++; - work = NAUTILUS_CTREE_ROW (node)->children; - - while (work && NAUTILUS_CTREE_ROW (work)->level > NAUTILUS_CTREE_ROW (node)->level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - dest_row++; - } - - if (dest_row > clist->rows) - dest_row = clist->rows; - } - - if (dest_row < clist->rows) - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, dest_row)); - nautilus_ctree_move (ctree, node, NAUTILUS_CTREE_ROW (sibling)->parent, sibling); - } - else - nautilus_ctree_move (ctree, node, NULL, NULL); -} - -static void -real_tree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (node != NULL); - g_return_if_fail (!new_sibling || - NAUTILUS_CTREE_ROW (new_sibling)->parent == new_parent); - - if (new_parent && NAUTILUS_CTREE_ROW (new_parent)->is_leaf) - return; - - /* new_parent != child of child */ - for (work = new_parent; work; work = NAUTILUS_CTREE_ROW (work)->parent) - if (work == node) - return; - - clist = NAUTILUS_CLIST (ctree); - - visible = nautilus_ctree_is_viewable (ctree, node); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (new_parent == NAUTILUS_CTREE_ROW (node)->parent) - return; - - if (new_parent) - new_sibling = NAUTILUS_CTREE_ROW (new_parent)->children; - else - new_sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (new_sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (new_sibling)) > 0) - new_sibling = NAUTILUS_CTREE_ROW (new_sibling)->sibling; - } - - if (new_parent == NAUTILUS_CTREE_ROW (node)->parent && - new_sibling == NAUTILUS_CTREE_ROW (node)->sibling) - return; - - nautilus_clist_freeze (clist); - - work = NULL; - if (nautilus_ctree_is_viewable (ctree, node) || - nautilus_ctree_is_viewable (ctree, new_sibling)) - work = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row)); - - nautilus_ctree_unlink (ctree, node, FALSE); - nautilus_ctree_link (ctree, node, new_parent, new_sibling, FALSE); - - if (work) - { - while (work && !nautilus_ctree_is_viewable (ctree, work)) - work = NAUTILUS_CTREE_ROW (work)->parent; - clist->focus_row = g_list_position (clist->row_list, (GList *)work); - clist->undo_anchor = clist->focus_row; - CLIST_REFRESH (clist); - } - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist) && - (visible || nautilus_ctree_is_viewable (ctree, node))) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - nautilus_clist_optimal_column_width (clist, ctree->tree_column)); - - nautilus_clist_thaw (clist); -} - -static void -change_focus_row_expansion (NautilusCTree *ctree, - NautilusCTreeExpansionType action) -{ - NautilusCList *clist; - NautilusCTreeNode *node; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (ctree)) - return; - - if (!(node = - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row))) || - NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - switch (action) - { - case NAUTILUS_CTREE_EXPANSION_EXPAND: - nautilus_ctree_expand (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE: - nautilus_ctree_expand_recursive (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_COLLAPSE: - nautilus_ctree_collapse (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE: - nautilus_ctree_collapse_recursive (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_TOGGLE: - nautilus_ctree_toggle_expansion (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE: - nautilus_ctree_toggle_expansion_recursive (ctree, node); - break; - } -} - -static void -real_tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - GtkRequisition requisition; - gboolean visible; - gint level; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->expanded || NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - NAUTILUS_CTREE_ROW (node)->expanded = TRUE; - level = NAUTILUS_CTREE_ROW (node)->level; - - visible = nautilus_ctree_is_viewable (ctree, node); - /* get cell width if tree_column is auto resized */ - if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, &requisition); - - /* unref/unset closed pixbuf */ - if (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf); - - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = NULL; - } - - /* set/ref opened pixbuf */ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_opened) - { - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = - gdk_pixbuf_ref (NAUTILUS_CTREE_ROW (node)->pixbuf_opened); - } - - - work = NAUTILUS_CTREE_ROW (node)->children; - if (work) - { - GList *list = (GList *)work; - gint *cell_width = NULL; - gint tmp = 0; - gint row; - gint i; - - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - cell_width = g_new0 (gint, clist->columns); - if (clist->column[ctree->tree_column].auto_resize) - cell_width[ctree->tree_column] = requisition.width; - - while (work) - { - /* search maximum cell widths of auto_resize columns */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (work)->row, i, &requisition); - cell_width[i] = MAX (requisition.width, cell_width[i]); - } - - list = (GList *)work; - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - } - else - while (work) - { - list = (GList *)work; - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - - list->next = (GList *)NAUTILUS_CTREE_NODE_NEXT (node); - - if (NAUTILUS_CTREE_NODE_NEXT (node)) - { - GList *tmp_list; - - tmp_list = (GList *)NAUTILUS_CTREE_NODE_NEXT (node); - tmp_list->prev = list; - } - else - clist->row_list_end = list; - - list = (GList *)node; - list->next = (GList *)(NAUTILUS_CTREE_ROW (node)->children); - - if (visible) - { - /* resize auto_resize columns if needed */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize && - cell_width[i] > clist->column[i].width) - nautilus_clist_set_column_width (clist, i, cell_width[i]); - g_free (cell_width); - - /* update focus_row position */ - row = g_list_position (clist->row_list, (GList *)node); - if (row < clist->focus_row) - clist->focus_row += tmp; - - clist->rows += tmp; - CLIST_REFRESH (clist); - } - } - else if (visible && clist->column[ctree->tree_column].auto_resize) - /* resize tree_column if needed */ - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, - requisition.width); - - tree_draw_node (ctree, node); -} - -static void -real_tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - GtkRequisition requisition; - gboolean visible; - gint level; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || !NAUTILUS_CTREE_ROW (node)->expanded || - NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - NAUTILUS_CTREE_ROW (node)->expanded = FALSE; - level = NAUTILUS_CTREE_ROW (node)->level; - - visible = nautilus_ctree_is_viewable (ctree, node); - /* get cell width if tree_column is auto resized */ - if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, &requisition); - - /* unref/unset opened pixbuf */ - if (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf); - - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = NULL; - } - - /* set/ref closed pixbuf */ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_closed) - { - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = - gdk_pixbuf_ref (NAUTILUS_CTREE_ROW (node)->pixbuf_closed); - } - - work = NAUTILUS_CTREE_ROW (node)->children; - if (work) - { - gint tmp = 0; - gint row; - GList *list; - - while (work && NAUTILUS_CTREE_ROW (work)->level > level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - - if (work) - { - list = (GList *)node; - list->next = (GList *)work; - list = (GList *)NAUTILUS_CTREE_NODE_PREV (work); - list->next = NULL; - list = (GList *)work; - list->prev = (GList *)node; - } - else - { - list = (GList *)node; - list->next = NULL; - clist->row_list_end = (GList *)node; - } - - if (visible) - { - /* resize auto_resize columns if needed */ - auto_resize_columns (clist); - - row = g_list_position (clist->row_list, (GList *)node); - if (row < clist->focus_row) - clist->focus_row -= tmp; - clist->rows -= tmp; - CLIST_REFRESH (clist); - } - } - else if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - /* resize tree_column if needed */ - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, - requisition.width); - - tree_draw_node (ctree, node); -} - -static void -column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width) -{ - /* resize column if needed for auto_resize */ - GtkRequisition requisition; - - if (!clist->column[column].auto_resize || - NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - return; - - if (clist_row) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - else - requisition.width = 0; - - if (requisition.width > clist->column[column].width) - nautilus_clist_set_column_width (clist, column, requisition.width); - else if (requisition.width < old_width && - old_width == clist->column[column].width) - { - GList *list; - gint new_width; - - /* run a "nautilus_clist_optimal_column_width" but break, if - * the column doesn't shrink */ - if (NAUTILUS_CLIST_SHOW_TITLES (clist) && clist->column[column].button) - new_width = (clist->column[column].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - else - new_width = 0; - - for (list = clist->row_list; list; list = list->next) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, NAUTILUS_CLIST_ROW (list), column, &requisition); - new_width = MAX (new_width, requisition.width); - if (new_width == clist->column[column].width) - break; - } - if (new_width < clist->column[column].width) - nautilus_clist_set_column_width (clist, column, new_width); - } -} - -static void -auto_resize_columns (NautilusCList *clist) -{ - gint i; - - if (NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - return; - - for (i = 0; i < clist->columns; i++) - column_auto_resize (clist, NULL, i, clist->column[i].width); -} - -static void -cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition) -{ - NautilusCTree *ctree; - GtkStyle *style; - gint width; - gint height; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - g_return_if_fail (requisition != NULL); - - ctree = NAUTILUS_CTREE (clist); - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), clist_row, - GTK_STATE_NORMAL, 0, column, - &style, NULL, NULL, NULL); - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - requisition->width = - gdk_string_width (style->font, NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - requisition->height = style->font->ascent + style->font->descent; - break; - - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) { - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - width += NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing; - } else { - width = height = 0; - } - - requisition->width = width + gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - requisition->height = MAX (style->font->ascent + style->font->descent, height); - - if (column == ctree->tree_column) { - requisition->width += (ctree->tree_spacing + ctree->tree_indent * - (((NautilusCTreeRow *) clist_row)->level - 1)); - requisition->width += PM_SIZE + 3; - } - - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) { - requisition->width += 3; - } - break; - - case NAUTILUS_CELL_PIXBUF: - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - requisition->width = width; - requisition->height = height; - break; - - default: - requisition->width = 0; - requisition->height = 0; - break; - } - - requisition->width += clist_row->cell[column].horizontal; - requisition->height += clist_row->cell[column].vertical; -} - -static gboolean -set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - gboolean visible = FALSE; - NautilusCTree *ctree; - GtkRequisition requisition; - - g_return_val_if_fail (NAUTILUS_IS_CTREE (clist), FALSE); - g_return_val_if_fail (clist_row != NULL, FALSE); - - ctree = NAUTILUS_CTREE (clist); - - if (type == clist_row->cell[column].type) - { - switch (type) - { - case NAUTILUS_CELL_EMPTY: - return FALSE; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf == NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf) - return FALSE; - break; - case NAUTILUS_CELL_PIXTEXT: - if (pixbuf == NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) - { - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - } - break; - case NAUTILUS_CELL_WIDGET: - /* unimplemented */ - break; - case NAUTILUS_CELL_PIXBUF_LIST: - /* handled at the higher level */ - break; - } - } - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - NautilusCTreeNode *parent; - - parent = ((NautilusCTreeRow *)clist_row)->parent; - if (!parent || (parent && NAUTILUS_CTREE_ROW (parent)->expanded && - nautilus_ctree_is_viewable (ctree, parent))) - { - visible = TRUE; - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - } - } - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_EMPTY: - break; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - g_free (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - break; - case NAUTILUS_CELL_PIXBUF: - gdk_pixbuf_unref (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - break; - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text) - g_free (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text); - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - } - break; - case NAUTILUS_CELL_WIDGET: - /* unimplimented */ - break; - - default: - break; - } - - clist_row->cell[column].type = NAUTILUS_CELL_EMPTY; - if (column == ctree->tree_column && type != NAUTILUS_CELL_EMPTY) - type = NAUTILUS_CELL_PIXTEXT; - - switch (type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (text) - { - clist_row->cell[column].type = NAUTILUS_CELL_TEXT; - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text = g_strdup (text); - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXBUF; - NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - case NAUTILUS_CELL_PIXTEXT: - if (column == ctree->tree_column) - { - if (pixbuf) - pixbuf = gdk_pixbuf_ref (pixbuf); - clist_row->cell[column].type = NAUTILUS_CELL_PIXTEXT; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text = g_strdup (text); - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing = spacing; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf = pixbuf; - } - else if (text && pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXTEXT; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text = g_strdup (text); - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing = spacing; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - default: - break; - } - - if (visible && clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - column_auto_resize (clist, clist_row, column, requisition.width); - - return TRUE; -} - -static void -set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_opened) - { - gdk_pixbuf_unref (NAUTILUS_CTREE_ROW (node)->pixbuf_opened); - } - if (NAUTILUS_CTREE_ROW (node)->pixbuf_closed) - { - gdk_pixbuf_unref (NAUTILUS_CTREE_ROW (node)->pixbuf_closed); - } - - NAUTILUS_CTREE_ROW (node)->pixbuf_opened = NULL; - NAUTILUS_CTREE_ROW (node)->pixbuf_closed = NULL; - - if (pixbuf_closed) - { - NAUTILUS_CTREE_ROW (node)->pixbuf_closed = gdk_pixbuf_ref (pixbuf_closed); - } - if (pixbuf_opened) - { - NAUTILUS_CTREE_ROW (node)->pixbuf_opened = gdk_pixbuf_ref (pixbuf_opened); - } - - NAUTILUS_CTREE_ROW (node)->is_leaf = is_leaf; - NAUTILUS_CTREE_ROW (node)->expanded = (is_leaf) ? FALSE : expanded; - - if (NAUTILUS_CTREE_ROW (node)->expanded) - nautilus_ctree_node_set_pixtext (ctree, node, ctree->tree_column, - text, spacing, pixbuf_opened); - else - nautilus_ctree_node_set_pixtext (ctree, node, ctree->tree_column, - text, spacing, pixbuf_closed); -} - -static void -tree_delete (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - tree_unselect (ctree, node, NULL); - row_delete (ctree, NAUTILUS_CTREE_ROW (node)); - g_list_free_1 ((GList *)node); -} - -static void -tree_delete_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - row_delete (ctree, NAUTILUS_CTREE_ROW (node)); - g_list_free_1 ((GList *)node); -} - -static void -tree_update_level (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node) - return; - - if (NAUTILUS_CTREE_ROW (node)->parent) - NAUTILUS_CTREE_ROW (node)->level = - NAUTILUS_CTREE_ROW (NAUTILUS_CTREE_ROW (node)->parent)->level + 1; - else - NAUTILUS_CTREE_ROW (node)->level = 1; -} - -static void -tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED && - NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_SELECT_ROW], - node, -1); -} - -static void -tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_UNSELECT_ROW], - node, -1); -} - -static void -tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && !NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -static void -tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); -} - -static void -tree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - if (node && NAUTILUS_CTREE_ROW (node)->level == depth) - nautilus_ctree_collapse_recursive (ctree, node); -} - -static void -tree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node) - return; - - if (NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); - else - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -static NautilusCTreeRow * -row_new (NautilusCTree *ctree) -{ - NautilusCList *clist; - NautilusCTreeRow *ctree_row; - int i; - - clist = NAUTILUS_CLIST (ctree); - ctree_row = g_chunk_new (NautilusCTreeRow, clist->row_mem_chunk); - ctree_row->row.cell = g_chunk_new (NautilusCell, clist->cell_mem_chunk); - - for (i = 0; i < clist->columns; i++) { - ctree_row->row.cell[i].type = NAUTILUS_CELL_EMPTY; - ctree_row->row.cell[i].vertical = 0; - ctree_row->row.cell[i].horizontal = 0; - ctree_row->row.cell[i].style = NULL; - } - - NAUTILUS_CELL_PIXTEXT (ctree_row->row.cell[ctree->tree_column])->text = NULL; - - ctree_row->row.fg_set = FALSE; - ctree_row->row.bg_set = FALSE; - ctree_row->row.style = NULL; - ctree_row->row.selectable = TRUE; - ctree_row->row.state = GTK_STATE_NORMAL; - ctree_row->row.data = NULL; - ctree_row->row.destroy = NULL; - - ctree_row->level = 0; - ctree_row->expanded = FALSE; - ctree_row->parent = NULL; - ctree_row->sibling = NULL; - ctree_row->children = NULL; - ctree_row->pixbuf_closed = NULL; - ctree_row->pixbuf_opened = NULL; - ctree_row->mouse_down = FALSE; - ctree_row->in_hotspot = FALSE; - - return ctree_row; -} - -static void -row_delete (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - for (i = 0; i < clist->columns; i++) - { - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(ctree_row->row), i, NAUTILUS_CELL_EMPTY, NULL, 0, NULL); - if (ctree_row->row.cell[i].style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (ctree_row->row.cell[i].style); - gtk_style_unref (ctree_row->row.cell[i].style); - } - } - - if (ctree_row->row.style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (ctree_row->row.style); - gtk_style_unref (ctree_row->row.style); - } - - if (ctree_row->pixbuf_closed) - { - gdk_pixbuf_unref (ctree_row->pixbuf_closed); - } - - if (ctree_row->pixbuf_opened) - { - gdk_pixbuf_unref (ctree_row->pixbuf_opened); - } - - if (ctree_row->row.destroy) - { - GtkDestroyNotify dnotify = ctree_row->row.destroy; - gpointer ddata = ctree_row->row.data; - - ctree_row->row.destroy = NULL; - ctree_row->row.data = NULL; - - dnotify (ddata); - } - - g_mem_chunk_free (clist->cell_mem_chunk, ctree_row->row.cell); - g_mem_chunk_free (clist->row_mem_chunk, ctree_row); -} - -static void -real_tree_activate_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - /* don't care */ -} - -static void -real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - GList *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if ((node = g_list_nth (clist->row_list, row)) && - NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_SELECT_ROW], - node, column); -} - -static void -real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - GList *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if ((node = g_list_nth (clist->row_list, row))) - gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_UNSELECT_ROW], - node, column); -} - -static void -real_tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - NautilusCList *clist; - GList *list; - NautilusCTreeNode *sel_row; - gboolean node_selected; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED || - !NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - clist = NAUTILUS_CLIST (ctree); - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - - node_selected = FALSE; - list = clist->selection; - - while (list) - { - sel_row = list->data; - list = list->next; - - if (node == sel_row) - node_selected = TRUE; - else - gtk_signal_emit (GTK_OBJECT (ctree), - ctree_signals[TREE_UNSELECT_ROW], sel_row, column); - } - - if (node_selected) - return; - - default: - break; - } - - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - - if (!clist->selection) - { - clist->selection = g_list_append (clist->selection, node); - clist->selection_end = clist->selection; - } - else - clist->selection_end = g_list_append (clist->selection_end, node)->next; - - tree_draw_node (ctree, node); -} - -static void -real_tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->selection_end && clist->selection_end->data == node) - clist->selection_end = clist->selection_end->prev; - - clist->selection = g_list_remove (clist->selection, node); - - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - - tree_draw_node (ctree, node); -} - -static void -select_row_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node || NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED || - !NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - NAUTILUS_CLIST (ctree)->undo_unselection = - g_list_prepend (NAUTILUS_CLIST (ctree)->undo_unselection, node); - nautilus_ctree_select (ctree, node); -} - -static void -real_select_all (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - return; - - case GTK_SELECTION_EXTENDED: - nautilus_clist_freeze (clist); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor_state = GTK_STATE_SELECTED; - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - - for (node = NAUTILUS_CTREE_NODE (clist->row_list); node; - node = NAUTILUS_CTREE_NODE_NEXT (node)) - nautilus_ctree_pre_recursive (ctree, node, select_row_recursive, NULL); - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); - break; - - case GTK_SELECTION_MULTIPLE: - nautilus_ctree_select_recursive (ctree, NULL); - break; - - default: - /* do nothing */ - break; - } -} - -static void -real_unselect_all (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - GList *list; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - switch (clist->selection_mode) - { - case GTK_SELECTION_BROWSE: - if (clist->focus_row >= 0) - { - nautilus_ctree_select - (ctree, - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row))); - return; - } - break; - - case GTK_SELECTION_EXTENDED: - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - break; - - default: - break; - } - - list = clist->selection; - - while (list) - { - node = list->data; - list = list->next; - nautilus_ctree_unselect (ctree, node); - } -} - -static gboolean -ctree_is_hot_spot (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint row, - gint x, - gint y) -{ - NautilusCTreeRow *tree_row; - NautilusCList *clist; - NautilusCellPixText *cell; - gint xl; - gint yu; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - clist = NAUTILUS_CLIST (ctree); - - if (!clist->column[ctree->tree_column].visible) { - return FALSE; - } - - tree_row = NAUTILUS_CTREE_ROW (node); - - cell = NAUTILUS_CELL_PIXTEXT(tree_row->row.cell[ctree->tree_column]); - - yu = (ROW_TOP_YPIXEL (clist, row) + (clist->row_height - PM_SIZE) / 2 - (clist->row_height - 1) % 2); - - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) { - xl = (clist->column[ctree->tree_column].area.x + - clist->column[ctree->tree_column].area.width - 1 + clist->hoffset - - (tree_row->level - 1) * ctree->tree_indent - PM_SIZE - - (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) * 3); - } else { - xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) * 3); - } - - return (x >= xl - 3 && x <= xl + 3 + PM_SIZE && y >= yu - 3 && y <= yu + PM_SIZE + 3); -} - -/*********************************************************** - *********************************************************** - *** Public interface *** - *********************************************************** - ***********************************************************/ - - -/*********************************************************** - * Creation, insertion, deletion * - ***********************************************************/ - -void -nautilus_ctree_construct (NautilusCTree *ctree, - gint columns, - gint tree_column, - gchar *titles[]) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (GTK_OBJECT_CONSTRUCTED (ctree) == FALSE); - - clist = NAUTILUS_CLIST (ctree); - - clist->row_mem_chunk = g_mem_chunk_new ("ctree row mem chunk", - sizeof (NautilusCTreeRow), - sizeof (NautilusCTreeRow) - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - clist->cell_mem_chunk = g_mem_chunk_new ("ctree cell mem chunk", - sizeof (NautilusCell) * columns, - sizeof (NautilusCell) * columns - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - ctree->tree_column = tree_column; - - nautilus_clist_construct (clist, columns, titles); -} - -GtkWidget * -nautilus_ctree_new_with_titles (gint columns, - gint tree_column, - gchar *titles[]) -{ - GtkWidget *widget; - - g_return_val_if_fail (columns > 0, NULL); - g_return_val_if_fail (tree_column >= 0 && tree_column < columns, NULL); - - widget = GTK_WIDGET (gtk_type_new (NAUTILUS_TYPE_CTREE)); - nautilus_ctree_construct (NAUTILUS_CTREE (widget), columns, tree_column, titles); - - return widget; -} - -GtkWidget * -nautilus_ctree_new (gint columns, - gint tree_column) -{ - return nautilus_ctree_new_with_titles (columns, tree_column, NULL); -} - -static gint -real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]) -{ - NautilusCTreeNode *parent = NULL; - NautilusCTreeNode *sibling; - NautilusCTreeNode *node; - - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CTREE (clist), -1); - - sibling = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - if (sibling) - parent = NAUTILUS_CTREE_ROW (sibling)->parent; - - node = nautilus_ctree_insert_node (NAUTILUS_CTREE (clist), parent, sibling, text, 5, - NULL, NULL, TRUE, FALSE); - - if (NAUTILUS_CLIST_AUTO_SORT (clist) || !sibling) - return g_list_position (clist->row_list, (GList *) node); - - return row; -} - -NautilusCTreeNode * -nautilus_ctree_insert_node (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gchar *text[], - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - NautilusCList *clist; - NautilusCTreeRow *new_row; - NautilusCTreeNode *node; - GList *list; - gint i; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - if (sibling) { - g_return_val_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent, NULL); - } - - if (parent && NAUTILUS_CTREE_ROW (parent)->is_leaf) { - return NULL; - } - - clist = NAUTILUS_CLIST (ctree); - - /* create the row */ - new_row = row_new (ctree); - list = g_list_alloc (); - list->data = new_row; - node = NAUTILUS_CTREE_NODE (list); - - if (text) - for (i = 0; i < clist->columns; i++) - if (text[i] && i != ctree->tree_column) - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(new_row->row), i, NAUTILUS_CELL_TEXT, text[i], 0, NULL); - - set_node_info (ctree, node, text ? - text[ctree->tree_column] : NULL, spacing, pixbuf_closed, - pixbuf_opened, is_leaf, expanded); - - /* sorted insertion */ - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (sibling)) > 0) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - - } - - nautilus_ctree_link (ctree, node, parent, sibling, TRUE); - - if (text && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist) && - nautilus_ctree_is_viewable (ctree, node)) - { - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - column_auto_resize (clist, &(new_row->row), i, 0); - } - - if (clist->rows == 1) - { - clist->focus_row = 0; - if (clist->selection_mode == GTK_SELECTION_BROWSE) - nautilus_ctree_select (ctree, node); - } - - - CLIST_REFRESH (clist); - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_insert_gnode (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - GNode *gnode, - NautilusCTreeGNodeFunc func, - gpointer data) -{ - NautilusCList *clist; - NautilusCTreeNode *cnode = NULL; - NautilusCTreeNode *child = NULL; - NautilusCTreeNode *new_child; - GList *list; - GNode *work; - guint depth = 1; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (gnode != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - if (sibling) - g_return_val_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent, NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (parent) - depth = NAUTILUS_CTREE_ROW (parent)->level + 1; - - list = g_list_alloc (); - list->data = row_new (ctree); - cnode = NAUTILUS_CTREE_NODE (list); - - nautilus_clist_freeze (clist); - - set_node_info (ctree, cnode, "", 0, NULL, NULL, TRUE, FALSE); - - if (!func (ctree, depth, gnode, cnode, data)) - { - tree_delete_row (ctree, cnode, NULL); - return NULL; - } - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (cnode), NAUTILUS_CTREE_ROW (sibling)) > 0) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - } - - nautilus_ctree_link (ctree, cnode, parent, sibling, TRUE); - - for (work = g_node_last_child (gnode); work; work = work->prev) - { - new_child = nautilus_ctree_insert_gnode (ctree, cnode, child, - work, func, data); - if (new_child) - child = new_child; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); - - return cnode; -} - -GNode * -nautilus_ctree_export_to_gnode (NautilusCTree *ctree, - GNode *parent, - GNode *sibling, - NautilusCTreeNode *node, - NautilusCTreeGNodeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - GNode *gnode; - gint depth; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - if (sibling) - { - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (sibling->parent == parent, NULL); - } - - gnode = g_node_new (NULL); - depth = g_node_depth (parent) + 1; - - if (!func (ctree, depth, gnode, node, data)) - { - g_node_destroy (gnode); - return NULL; - } - - if (parent) - g_node_insert_before (parent, sibling, gnode); - - if (!NAUTILUS_CTREE_ROW (node)->is_leaf) - { - GNode *new_sibling = NULL; - - for (work = NAUTILUS_CTREE_ROW (node)->children; work; - work = NAUTILUS_CTREE_ROW (work)->sibling) - new_sibling = nautilus_ctree_export_to_gnode (ctree, gnode, new_sibling, - work, func, data); - - g_node_reverse_children (gnode); - } - - return gnode; -} - -static void -real_remove_row (NautilusCList *clist, - gint row) -{ - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - - if (node) - nautilus_ctree_remove_node (NAUTILUS_CTREE (clist), node); -} - -void -nautilus_ctree_remove_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (node) - { - gboolean visible; - - visible = nautilus_ctree_is_viewable (ctree, node); - nautilus_ctree_unlink (ctree, node, TRUE); - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_delete), - NULL); - if (clist->selection_mode == GTK_SELECTION_BROWSE && !clist->selection && - clist->focus_row >= 0) - nautilus_clist_select_row (clist, clist->focus_row, -1); - - auto_resize_columns (clist); - } - else - nautilus_clist_clear (clist); - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -static void -real_clear (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *work; - NautilusCTreeNode *ptr; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - /* remove all rows */ - work = NAUTILUS_CTREE_NODE (clist->row_list); - clist->row_list = NULL; - clist->row_list_end = NULL; - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - while (work) - { - ptr = work; - work = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive (ctree, ptr, NAUTILUS_CTREE_FUNC (tree_delete_row), - NULL); - } - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - - parent_class->clear (clist); -} - - -/*********************************************************** - * Generic recursive functions, querying / finding tree * - * information * - ***********************************************************/ - - -void -nautilus_ctree_post_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (node) - work = NAUTILUS_CTREE_ROW (node)->children; - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive (ctree, work, func, data); - work = tmp; - } - - if (node) - func (ctree, node, data); -} - -void -nautilus_ctree_post_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (depth < 0) - { - nautilus_ctree_post_recursive (ctree, node, func, data); - return; - } - - if (node) - work = NAUTILUS_CTREE_ROW (node)->children; - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - if (work && NAUTILUS_CTREE_ROW (work)->level <= depth) - { - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive_to_depth (ctree, work, depth, func, data); - work = tmp; - } - } - - if (node && NAUTILUS_CTREE_ROW (node)->level <= depth) - func (ctree, node, data); -} - -void -nautilus_ctree_pre_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (node) - { - work = NAUTILUS_CTREE_ROW (node)->children; - func (ctree, node, data); - } - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_pre_recursive (ctree, work, func, data); - work = tmp; - } -} - -void -nautilus_ctree_pre_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (depth < 0) - { - nautilus_ctree_pre_recursive (ctree, node, func, data); - return; - } - - if (node) - { - work = NAUTILUS_CTREE_ROW (node)->children; - if (NAUTILUS_CTREE_ROW (node)->level <= depth) - func (ctree, node, data); - } - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - if (work && NAUTILUS_CTREE_ROW (work)->level <= depth) - { - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_pre_recursive_to_depth (ctree, work, depth, func, data); - work = tmp; - } - } -} - -gboolean -nautilus_ctree_is_viewable (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeRow *work; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - work = NAUTILUS_CTREE_ROW (node); - - while (work->parent && NAUTILUS_CTREE_ROW (work->parent)->expanded) - work = NAUTILUS_CTREE_ROW (work->parent); - - if (!work->parent) - return TRUE; - - return FALSE; -} - -NautilusCTreeNode * -nautilus_ctree_last (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - if (!node) - return NULL; - - while (NAUTILUS_CTREE_ROW (node)->sibling) - node = NAUTILUS_CTREE_ROW (node)->sibling; - - if (NAUTILUS_CTREE_ROW (node)->children) - return nautilus_ctree_last (ctree, NAUTILUS_CTREE_ROW (node)->children); - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_find_node_ptr (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row) -{ - NautilusCTreeNode *node; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (ctree_row != NULL, FALSE); - - if (ctree_row->parent) - node = NAUTILUS_CTREE_ROW (ctree_row->parent)->children; - else - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (NAUTILUS_CTREE_ROW (node) != ctree_row) - node = NAUTILUS_CTREE_ROW (node)->sibling; - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_node_nth (NautilusCTree *ctree, - int row) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - if ((row < 0) || (row >= NAUTILUS_CLIST(ctree)->rows)) - return NULL; - - return NAUTILUS_CTREE_NODE (g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row)); -} - -gboolean -nautilus_ctree_find (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child) -{ - if (!child) - return FALSE; - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (node == child) - return TRUE; - if (NAUTILUS_CTREE_ROW (node)->children) - { - if (nautilus_ctree_find (ctree, NAUTILUS_CTREE_ROW (node)->children, child)) - return TRUE; - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return FALSE; -} - -gboolean -nautilus_ctree_is_ancestor (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child) -{ - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - if (NAUTILUS_CTREE_ROW (node)->children) - return nautilus_ctree_find (ctree, NAUTILUS_CTREE_ROW (node)->children, child); - - return FALSE; -} - -NautilusCTreeNode * -nautilus_ctree_find_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCTreeNode *work; - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (NAUTILUS_CTREE_ROW (node)->row.data == data) - return node; - if (NAUTILUS_CTREE_ROW (node)->children && - (work = nautilus_ctree_find_by_row_data - (ctree, NAUTILUS_CTREE_ROW (node)->children, data))) - return work; - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return NULL; -} - -GList * -nautilus_ctree_find_all_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - GList *list = NULL; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - /* if node == NULL then look in the whole tree */ - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (NAUTILUS_CTREE_ROW (node)->row.data == data) - list = g_list_append (list, node); - - if (NAUTILUS_CTREE_ROW (node)->children) - { - GList *sub_list; - - sub_list = nautilus_ctree_find_all_by_row_data (ctree, - NAUTILUS_CTREE_ROW - (node)->children, - data); - list = g_list_concat (list, sub_list); - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return list; -} - -NautilusCTreeNode * -nautilus_ctree_find_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func) -{ - NautilusCTreeNode *work; - - g_return_val_if_fail (func != NULL, NULL); - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (!func (NAUTILUS_CTREE_ROW (node)->row.data, data)) - return node; - if (NAUTILUS_CTREE_ROW (node)->children && - (work = nautilus_ctree_find_by_row_data_custom - (ctree, NAUTILUS_CTREE_ROW (node)->children, data, func))) - return work; - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return NULL; -} - -GList * -nautilus_ctree_find_all_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func) -{ - GList *list = NULL; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (func != NULL, NULL); - - /* if node == NULL then look in the whole tree */ - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (!func (NAUTILUS_CTREE_ROW (node)->row.data, data)) - list = g_list_append (list, node); - - if (NAUTILUS_CTREE_ROW (node)->children) - { - GList *sub_list; - - sub_list = nautilus_ctree_find_all_by_row_data_custom (ctree, - NAUTILUS_CTREE_ROW - (node)->children, - data, - func); - list = g_list_concat (list, sub_list); - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return list; -} - -gboolean -nautilus_ctree_is_hot_spot (NautilusCTree *ctree, - gint x, - gint y) -{ - NautilusCTreeNode *node; - gint column; - gint row; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - - if (nautilus_clist_get_selection_info (NAUTILUS_CLIST (ctree), x, y, &row, &column)) { - if ((node = NAUTILUS_CTREE_NODE(g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row)))) { - return ctree_is_hot_spot (ctree, node, row, x, y); - } - } - - return FALSE; -} - - -/*********************************************************** - * Tree signals : move, expand, collapse, (un)select * - ***********************************************************/ - - -void -nautilus_ctree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_MOVE], node, - new_parent, new_sibling); -} - -void -nautilus_ctree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -void -nautilus_ctree_expand_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_expand), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_expand_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive_to_depth (ctree, node, depth, - NAUTILUS_CTREE_FUNC (tree_expand), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); -} - -void -nautilus_ctree_collapse_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_collapse), NULL); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - nautilus_clist_set_column_width (clist, i, - nautilus_clist_optimal_column_width (clist, i)); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - nautilus_ctree_post_recursive_to_depth (ctree, node, depth, - NAUTILUS_CTREE_FUNC (tree_collapse_to_depth), - GINT_TO_POINTER (depth)); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - nautilus_clist_set_column_width (clist, i, - nautilus_clist_optimal_column_width (clist, i)); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - tree_toggle_expansion (ctree, node, NULL); -} - -void -nautilus_ctree_toggle_expansion_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_toggle_expansion), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_select (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_SELECT_ROW], - node, -1); -} - -void -nautilus_ctree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_UNSELECT_ROW], - node, -1); -} - -void -nautilus_ctree_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - nautilus_ctree_real_select_recursive (ctree, node, TRUE); -} - -void -nautilus_ctree_unselect_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - nautilus_ctree_real_select_recursive (ctree, node, FALSE); -} - -void -nautilus_ctree_real_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint state) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if ((state && - (clist->selection_mode == GTK_SELECTION_BROWSE || - clist->selection_mode == GTK_SELECTION_SINGLE)) || - (!state && clist->selection_mode == GTK_SELECTION_BROWSE)) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (state) - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_select), NULL); - else - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_unselect), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - - -/*********************************************************** - * Analogons of NautilusCList functions * - ***********************************************************/ - - -void -nautilus_ctree_node_set_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW(node)->row), column, NAUTILUS_CELL_TEXT, - text, 0, NULL)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf *pixbuf) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - g_return_if_fail (pixbuf != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW (node)->row), column, NAUTILUS_CELL_PIXBUF, - NULL, 0, pixbuf)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - if (column != ctree->tree_column) - g_return_if_fail (pixbuf != NULL); - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW (node)->row), column, NAUTILUS_CELL_PIXTEXT, - text, spacing, pixbuf)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - gboolean old_leaf; - gboolean old_expanded; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - old_leaf = NAUTILUS_CTREE_ROW (node)->is_leaf; - old_expanded = NAUTILUS_CTREE_ROW (node)->expanded; - - if (is_leaf && NAUTILUS_CTREE_ROW (node)->children) - { - NautilusCTreeNode *work; - NautilusCTreeNode *ptr; - - work = NAUTILUS_CTREE_ROW (node)->children; - while (work) - { - ptr = work; - work = NAUTILUS_CTREE_ROW(work)->sibling; - nautilus_ctree_remove_node (ctree, ptr); - } - } - - set_node_info (ctree, node, text, spacing, pixbuf_closed, - pixbuf_opened, is_leaf, expanded); - - if (!is_leaf && !old_leaf) - { - NAUTILUS_CTREE_ROW (node)->expanded = old_expanded; - if (expanded && !old_expanded) - nautilus_ctree_expand (ctree, node); - else if (!expanded && old_expanded) - nautilus_ctree_collapse (ctree, node); - } - - NAUTILUS_CTREE_ROW (node)->expanded = (is_leaf) ? FALSE : expanded; - - if (NAUTILUS_CLIST_AUTO_SORT (NAUTILUS_CLIST (ctree)) - && NAUTILUS_CTREE_ROW (node)->parent != NULL) - { - nautilus_ctree_sort_single_node (ctree, NAUTILUS_CTREE_ROW (node)->parent); - } -} - -void -nautilus_ctree_node_set_shift (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gint vertical, - gint horizontal) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, column, &requisition); - } - - NAUTILUS_CTREE_ROW (node)->row.cell[column].vertical = vertical; - NAUTILUS_CTREE_ROW (node)->row.cell[column].horizontal = horizontal; - - if (visible) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, - column, requisition.width); - - tree_draw_node (ctree, node); -} - -static void -remove_grab (NautilusCList *clist) -{ - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - { - gtk_grab_remove (GTK_WIDGET (clist)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - - if (clist->htimer) - { - gtk_timeout_remove (clist->htimer); - clist->htimer = 0; - } - - if (clist->vtimer) - { - gtk_timeout_remove (clist->vtimer); - clist->vtimer = 0; - } -} - -void -nautilus_ctree_node_set_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean selectable) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (selectable == NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - NAUTILUS_CTREE_ROW (node)->row.selectable = selectable; - - if (!selectable && NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->anchor >= 0 && - clist->selection_mode == GTK_SELECTION_EXTENDED) - { - clist->drag_button = 0; - remove_grab (clist); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - } - nautilus_ctree_unselect (ctree, node); - } -} - -gboolean -nautilus_ctree_node_get_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (node != NULL, FALSE); - - return NAUTILUS_CTREE_ROW (node)->row.selectable; -} - -NautilusCellType -nautilus_ctree_node_get_cell_type (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_val_if_fail (ctree != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), -1); - g_return_val_if_fail (node != NULL, -1); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return -1; - - return NAUTILUS_CTREE_ROW (node)->row.cell[column].type; -} - -gint -nautilus_ctree_node_get_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_TEXT - && NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_LINK_TEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_TEXT (NAUTILUS_CTREE_ROW (node)->row.cell[column])->text; - - return 1; -} - -gint -nautilus_ctree_node_get_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf **pixbuf) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_PIXBUF) - return 0; - - if (pixbuf) - *pixbuf = NAUTILUS_CELL_PIXBUF (NAUTILUS_CTREE_ROW(node)->row.cell[column])->pixbuf; - - return 1; -} - -gint -nautilus_ctree_node_get_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_PIXTEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW (node)->row.cell[column])->text; - if (spacing) - *spacing = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW - (node)->row.cell[column])->spacing; - if (pixbuf) - *pixbuf = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW - (node)->row.cell[column])->pixbuf; - - return 1; -} - -gint -nautilus_ctree_get_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf_closed, - GdkPixbuf **pixbuf_opened, - gboolean *is_leaf, - gboolean *expanded) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (text) - *text = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->text; - if (spacing) - *spacing = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->spacing; - if (pixbuf_closed) - *pixbuf_closed = NAUTILUS_CTREE_ROW (node)->pixbuf_closed; - if (pixbuf_opened) - *pixbuf_opened = NAUTILUS_CTREE_ROW (node)->pixbuf_opened; - if (is_leaf) - *is_leaf = NAUTILUS_CTREE_ROW (node)->is_leaf; - if (expanded) - *expanded = NAUTILUS_CTREE_ROW (node)->expanded; - - return 1; -} - -void -nautilus_ctree_node_set_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GtkStyle *style) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (column < 0 || column >= clist->columns) - return; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style == style) - return; - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, column, &requisition); - } - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - gtk_style_unref (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - } - - NAUTILUS_CTREE_ROW (node)->row.cell[column].style = style; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style) - { - gtk_style_ref (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - - if (GTK_WIDGET_REALIZED (ctree)) - NAUTILUS_CTREE_ROW (node)->row.cell[column].style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.cell[column].style, - clist->clist_window); - } - - if (visible) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, column, - requisition.width); - - tree_draw_node (ctree, node); -} - -GtkStyle * -nautilus_ctree_node_get_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return NULL; - - return NAUTILUS_CTREE_ROW (node)->row.cell[column].style; -} - -void -nautilus_ctree_node_set_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - GtkStyle *style) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible; - gint *old_width = NULL; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style == style) - return; - - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - old_width = g_new (gint, clist->columns); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, i, &requisition); - old_width[i] = requisition.width; - } - } - - if (NAUTILUS_CTREE_ROW (node)->row.style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.style); - gtk_style_unref (NAUTILUS_CTREE_ROW (node)->row.style); - } - - NAUTILUS_CTREE_ROW (node)->row.style = style; - - if (NAUTILUS_CTREE_ROW (node)->row.style) - { - gtk_style_ref (NAUTILUS_CTREE_ROW (node)->row.style); - - if (GTK_WIDGET_REALIZED (ctree)) - NAUTILUS_CTREE_ROW (node)->row.style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.style, - clist->clist_window); - } - - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, i, - old_width[i]); - g_free (old_width); - } - tree_draw_node (ctree, node); -} - -GtkStyle * -nautilus_ctree_node_get_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - - return NAUTILUS_CTREE_ROW (node)->row.style; -} - -void -nautilus_ctree_node_set_foreground (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (color) - { - NAUTILUS_CTREE_ROW (node)->row.foreground = *color; - NAUTILUS_CTREE_ROW (node)->row.fg_set = TRUE; - if (GTK_WIDGET_REALIZED (ctree)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), - &NAUTILUS_CTREE_ROW (node)->row.foreground); - } - else - NAUTILUS_CTREE_ROW (node)->row.fg_set = FALSE; - - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_background (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (color) - { - NAUTILUS_CTREE_ROW (node)->row.background = *color; - NAUTILUS_CTREE_ROW (node)->row.bg_set = TRUE; - if (GTK_WIDGET_REALIZED (ctree)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), - &NAUTILUS_CTREE_ROW (node)->row.background); - } - else - NAUTILUS_CTREE_ROW (node)->row.bg_set = FALSE; - - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - nautilus_ctree_node_set_row_data_full (ctree, node, data, NULL); -} - -void -nautilus_ctree_node_set_row_data_full (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GtkDestroyNotify destroy) -{ - GtkDestroyNotify dnotify; - gpointer ddata; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - dnotify = NAUTILUS_CTREE_ROW (node)->row.destroy; - ddata = NAUTILUS_CTREE_ROW (node)->row.data; - - NAUTILUS_CTREE_ROW (node)->row.data = data; - NAUTILUS_CTREE_ROW (node)->row.destroy = destroy; - - if (dnotify) - dnotify (ddata); -} - -gpointer -nautilus_ctree_node_get_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - return node ? NAUTILUS_CTREE_ROW (node)->row.data : NULL; -} - -void -nautilus_ctree_node_moveto (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gfloat row_align, - gfloat col_align) -{ - gint row = -1; - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - while (node && !nautilus_ctree_is_viewable (ctree, node)) - node = NAUTILUS_CTREE_ROW (node)->parent; - - if (node) - row = g_list_position (clist->row_list, (GList *)node); - - nautilus_clist_moveto (clist, row, column, row_align, col_align); -} - -GtkVisibility nautilus_ctree_node_is_visible (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - gint row; - - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (node != NULL, 0); - - row = g_list_position (NAUTILUS_CLIST (ctree)->row_list, (GList*) node); - return nautilus_clist_row_is_visible (NAUTILUS_CLIST (ctree), row); -} - - -/*********************************************************** - * NautilusCTree specific functions * - ***********************************************************/ - -void -nautilus_ctree_set_indent (NautilusCTree *ctree, - gint indent) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (indent >= 0); - - if (indent == ctree->tree_indent) - return; - - clist = NAUTILUS_CLIST (ctree); - ctree->tree_indent = indent; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - nautilus_clist_optimal_column_width (clist, ctree->tree_column)); - else - CLIST_REFRESH (clist); -} - -void -nautilus_ctree_set_spacing (NautilusCTree *ctree, - gint spacing) -{ - NautilusCList *clist; - gint old_spacing; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (spacing >= 0); - - if (spacing == ctree->tree_spacing) - return; - - clist = NAUTILUS_CLIST (ctree); - - old_spacing = ctree->tree_spacing; - ctree->tree_spacing = spacing; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - nautilus_clist_set_column_width (clist, ctree->tree_column, - clist->column[ctree->tree_column].width + - spacing - old_spacing); - else - CLIST_REFRESH (clist); -} - -void -nautilus_ctree_set_show_stub (NautilusCTree *ctree, - gboolean show_stub) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - show_stub = show_stub != FALSE; - - if (show_stub != ctree->show_stub) - { - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - ctree->show_stub = show_stub; - - if (CLIST_UNFROZEN (clist) && clist->rows && - nautilus_clist_row_is_visible (clist, 0) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row - (clist, NULL, 0, NAUTILUS_CLIST_ROW (clist->row_list)); - } -} - -void -nautilus_ctree_set_line_style (NautilusCTree *ctree, - NautilusCTreeLineStyle line_style) -{ - NautilusCList *clist; - NautilusCTreeLineStyle old_style; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (line_style == ctree->line_style) - return; - - clist = NAUTILUS_CLIST (ctree); - - old_style = ctree->line_style; - ctree->line_style = line_style; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - if (old_style == NAUTILUS_CTREE_LINES_TABBED) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width - 3); - else if (line_style == NAUTILUS_CTREE_LINES_TABBED) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width + 3); - } - - if (GTK_WIDGET_REALIZED (ctree)) - { - switch (line_style) - { - case NAUTILUS_CTREE_LINES_SOLID: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - None, None); - break; - case NAUTILUS_CTREE_LINES_DOTTED: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, None, None); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - break; - case NAUTILUS_CTREE_LINES_TABBED: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - None, None); - break; - case NAUTILUS_CTREE_LINES_NONE: - break; - default: - return; - } - CLIST_REFRESH (clist); - } -} - -/*********************************************************** - * Tree sorting functions * - ***********************************************************/ - - -static void -tree_sort (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCTreeNode *list_start; - NautilusCTreeNode *cmp; - NautilusCTreeNode *work; - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (node) - list_start = NAUTILUS_CTREE_ROW (node)->children; - else - list_start = NAUTILUS_CTREE_NODE (clist->row_list); - - while (list_start) - { - cmp = list_start; - work = NAUTILUS_CTREE_ROW (cmp)->sibling; - while (work) - { - if (clist->sort_type == GTK_SORT_ASCENDING) - { - if (clist->compare - (clist, NAUTILUS_CTREE_ROW (work), NAUTILUS_CTREE_ROW (cmp)) < 0) - cmp = work; - } - else - { - if (clist->compare - (clist, NAUTILUS_CTREE_ROW (work), NAUTILUS_CTREE_ROW (cmp)) > 0) - cmp = work; - } - work = NAUTILUS_CTREE_ROW (work)->sibling; - } - if (cmp == list_start) - list_start = NAUTILUS_CTREE_ROW (cmp)->sibling; - else - { - nautilus_ctree_unlink (ctree, cmp, FALSE); - nautilus_ctree_link (ctree, cmp, node, list_start, FALSE); - } - } -} - -void -nautilus_ctree_sort_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *focus_node = NULL; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (!node || (node && nautilus_ctree_is_viewable (ctree, node))) - focus_node = - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row)); - - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_sort), NULL); - - if (!node) - tree_sort (ctree, NULL, NULL); - - if (focus_node) - { - clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node); - clist->undo_anchor = clist->focus_row; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -static void -real_sort_list (NautilusCList *clist) -{ - nautilus_ctree_sort_recursive (NAUTILUS_CTREE (clist), NULL); -} - -void -nautilus_ctree_sort_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *focus_node = NULL; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (!node || (node && nautilus_ctree_is_viewable (ctree, node))) - focus_node = NAUTILUS_CTREE_NODE - (g_list_nth (clist->row_list, clist->focus_row)); - - tree_sort (ctree, node, NULL); - - if (focus_node) - { - clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node); - clist->undo_anchor = clist->focus_row; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_sort_single_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeNode *sibling, *parent; - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - parent = NAUTILUS_CTREE_ROW (node)->parent; - - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling - && (sibling == node || clist->compare (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (sibling)) > 0)) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - - nautilus_ctree_unlink (ctree, node, TRUE); - nautilus_ctree_link (ctree, node, parent, sibling, TRUE); - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -/************************************************************************/ - -static void -fake_unselect_all (NautilusCList *clist, - gint row) -{ - GList *list; - GList *focus_node = NULL; - - if (row >= 0 && (focus_node = g_list_nth (clist->row_list, row))) - { - if (NAUTILUS_CTREE_ROW (focus_node)->row.state == GTK_STATE_NORMAL && - NAUTILUS_CTREE_ROW (focus_node)->row.selectable) - { - NAUTILUS_CTREE_ROW (focus_node)->row.state = GTK_STATE_SELECTED; - - if (CLIST_UNFROZEN (clist) && - nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, - NAUTILUS_CLIST_ROW (focus_node)); - } - } - - clist->undo_selection = clist->selection; - clist->selection = NULL; - clist->selection_end = NULL; - - for (list = clist->undo_selection; list; list = list->next) - { - if (list->data == focus_node) - continue; - - NAUTILUS_CTREE_ROW ((GList *)(list->data))->row.state = GTK_STATE_NORMAL; - tree_draw_node (NAUTILUS_CTREE (clist), NAUTILUS_CTREE_NODE (list->data)); - } -} - -static GList * -selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element) -{ - return g_list_find (clist->selection, row_list_element); -} - -static void -resync_selection (NautilusCList *clist, GdkEvent *event) -{ - NautilusCTree *ctree; - GList *list; - NautilusCTreeNode *node; - gint i; - gint e; - gint row; - gboolean unselect; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (clist->anchor < 0 || clist->drag_pos < 0) - return; - - ctree = NAUTILUS_CTREE (clist); - - clist->freeze_count++; - - i = MIN (clist->anchor, clist->drag_pos); - e = MAX (clist->anchor, clist->drag_pos); - - if (clist->undo_selection) - { - list = clist->selection; - clist->selection = clist->undo_selection; - clist->selection_end = g_list_last (clist->selection); - clist->undo_selection = list; - list = clist->selection; - - while (list) - { - node = list->data; - list = list->next; - - unselect = TRUE; - - if (nautilus_ctree_is_viewable (ctree, node)) - { - row = g_list_position (clist->row_list, (GList *)node); - if (row >= i && row <= e) - unselect = FALSE; - } - if (unselect && NAUTILUS_CTREE_ROW (node)->row.selectable) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = g_list_prepend (clist->undo_selection, - node); - } - } - } - - if (clist->anchor < clist->drag_pos) - { - for (node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, i)); i <= e; - i++, node = NAUTILUS_CTREE_NODE_NEXT (node)) - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - { - if (g_list_find (clist->selection, node)) - { - if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = - g_list_prepend (clist->undo_selection, node); - } - } - else if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, node); - } - } - } - else - { - for (node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, e)); i <= e; - e--, node = NAUTILUS_CTREE_NODE_PREV (node)) - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - { - if (g_list_find (clist->selection, node)) - { - if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = - g_list_prepend (clist->undo_selection, node); - } - } - else if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, node); - } - } - } - - clist->undo_unselection = g_list_reverse (clist->undo_unselection); - for (list = clist->undo_unselection; list; list = list->next) - nautilus_ctree_select (ctree, list->data); - - clist->anchor = -1; - clist->drag_pos = -1; - - if (!CLIST_UNFROZEN (clist)) - clist->freeze_count--; -} - -static void -real_undo_selection (NautilusCList *clist) -{ - NautilusCTree *ctree; - GList *work; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (!(clist->undo_selection || clist->undo_unselection)) - { - nautilus_clist_unselect_all (clist); - return; - } - - ctree = NAUTILUS_CTREE (clist); - - for (work = clist->undo_selection; work; work = work->next) - if (NAUTILUS_CTREE_ROW (work->data)->row.selectable) - nautilus_ctree_select (ctree, NAUTILUS_CTREE_NODE (work->data)); - - for (work = clist->undo_unselection; work; work = work->next) - if (NAUTILUS_CTREE_ROW (work->data)->row.selectable) - nautilus_ctree_unselect (ctree, NAUTILUS_CTREE_NODE (work->data)); - - if (GTK_WIDGET_HAS_FOCUS (clist) && clist->focus_row != clist->undo_anchor) - { - gtk_widget_draw_focus (GTK_WIDGET (clist)); - clist->focus_row = clist->undo_anchor; - gtk_widget_draw_focus (GTK_WIDGET (clist)); - } - else - clist->focus_row = clist->undo_anchor; - - clist->undo_anchor = -1; - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height > - clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - -} - -void -nautilus_ctree_set_drag_compare_func (NautilusCTree *ctree, - NautilusCTreeCompareDragFunc cmp_func) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - ctree->drag_compare = cmp_func; -} - -static gboolean -check_drag (NautilusCTree *ctree, - NautilusCTreeNode *drag_source, - NautilusCTreeNode *drag_target, - NautilusCListDragPos insert_pos) -{ - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - - if (drag_source && drag_source != drag_target && - (!NAUTILUS_CTREE_ROW (drag_source)->children || - !nautilus_ctree_is_ancestor (ctree, drag_source, drag_target))) - { - switch (insert_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - return FALSE; - case NAUTILUS_CLIST_DRAG_AFTER: - if (NAUTILUS_CTREE_ROW (drag_target)->sibling != drag_source) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - NAUTILUS_CTREE_ROW (drag_target)->parent, - NAUTILUS_CTREE_ROW(drag_target)->sibling)); - break; - case NAUTILUS_CLIST_DRAG_BEFORE: - if (NAUTILUS_CTREE_ROW (drag_source)->sibling != drag_target) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - NAUTILUS_CTREE_ROW (drag_target)->parent, - drag_target)); - break; - case NAUTILUS_CLIST_DRAG_INTO: - if (!NAUTILUS_CTREE_ROW (drag_target)->is_leaf && - NAUTILUS_CTREE_ROW (drag_target)->children != drag_source) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - drag_target, - NAUTILUS_CTREE_ROW (drag_target)->children)); - break; - } - } - return FALSE; -} - - - -/************************************/ -static void -drag_dest_info_destroy (gpointer data) -{ - NautilusCListDestInfo *info = data; - - g_free (info); -} - -static void -drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (clist); - - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - - y -= (GTK_CONTAINER (widget)->border_width + - widget->style->klass->ythickness + clist->column_title_area.height); - dest_info->cell.row = ROW_FROM_YPIXEL (clist, y); - - if (dest_info->cell.row >= clist->rows) - { - dest_info->cell.row = clist->rows - 1; - y = ROW_TOP_YPIXEL (clist, dest_info->cell.row) + clist->row_height; - } - if (dest_info->cell.row < -1) - dest_info->cell.row = -1; - - x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness; - dest_info->cell.column = COLUMN_FROM_XPIXEL (clist, x); - - if (dest_info->cell.row >= 0) - { - gint y_delta; - gint h = 0; - - y_delta = y - ROW_TOP_YPIXEL (clist, dest_info->cell.row); - - if (NAUTILUS_CLIST_DRAW_DRAG_RECT(clist) && - !NAUTILUS_CTREE_ROW (g_list_nth (clist->row_list, - dest_info->cell.row))->is_leaf) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_INTO; - h = clist->row_height / 4; - } - else if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - h = clist->row_height / 2; - } - - if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - if (y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - else if (clist->row_height - y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_AFTER; - } - } -} - -static void -nautilus_ctree_drag_begin (GtkWidget *widget, - GdkDragContext *context) -{ - NautilusCList *clist; - NautilusCTree *ctree; - gboolean use_icons; - GdkPixbuf *pixbuf; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - g_return_if_fail (context != NULL); - - clist = NAUTILUS_CLIST (widget); - ctree = NAUTILUS_CTREE (widget); - - use_icons = NAUTILUS_CLIST_USE_DRAG_ICONS (clist); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_USE_DRAG_ICONS); - GTK_WIDGET_CLASS (parent_class)->drag_begin (widget, context); - - if (use_icons) - { - NautilusCTreeNode *node; - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS); - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - clist->click_cell.row)); - if (node) - { - pixbuf = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf; - if (pixbuf) - { - eel_drag_set_icon_pixbuf (context, pixbuf, -2, -2); - return; - } - } - gtk_drag_set_icon_default (context); - } -} - -static gint -nautilus_ctree_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - NautilusCList *clist; - NautilusCTree *ctree; - NautilusCListDestInfo new_info; - NautilusCListDestInfo *dest_info; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (widget), FALSE); - - clist = NAUTILUS_CLIST (widget); - ctree = NAUTILUS_CTREE (widget); - - dest_info = g_dataset_get_data (context, "nautilus-clist-drag-dest"); - - if (!dest_info) - { - dest_info = g_new (NautilusCListDestInfo, 1); - - dest_info->cell.row = -1; - dest_info->cell.column = -1; - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - - g_dataset_set_data_full (context, "nautilus-clist-drag-dest", dest_info, - drag_dest_info_destroy); - } - - drag_dest_cell (clist, x, y, &new_info); - - if (NAUTILUS_CLIST_REORDERABLE (clist)) - { - GList *list; - GdkAtom atom = gdk_atom_intern ("nautilus-clist-drag-reorder", FALSE); - - list = context->targets; - while (list) - { - if (atom == GPOINTER_TO_UINT (list->data)) - break; - list = list->next; - } - - if (list) - { - NautilusCTreeNode *drag_source; - NautilusCTreeNode *drag_target; - - drag_source = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - clist->click_cell.row)); - drag_target = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - new_info.cell.row)); - - if (gtk_drag_get_source_widget (context) != widget || - !check_drag (ctree, drag_source, drag_target, - new_info.insert_pos)) - { - if (dest_info->cell.row < 0) - { - gdk_drag_status (context, GDK_ACTION_DEFAULT, time); - return FALSE; - } - return TRUE; - } - - if (new_info.cell.row != dest_info->cell.row || - (new_info.cell.row == dest_info->cell.row && - dest_info->insert_pos != new_info.insert_pos)) - { - if (dest_info->cell.row >= 0) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, - g_list_nth (clist->row_list, dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, - g_list_nth (clist->row_list, dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - gdk_drag_status (context, context->suggested_action, time); - } - return TRUE; - } - } - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - return TRUE; -} - -static void -nautilus_ctree_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint32 time) -{ - NautilusCTree *ctree; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - g_return_if_fail (context != NULL); - g_return_if_fail (selection_data != NULL); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - if (NAUTILUS_CLIST_REORDERABLE (clist) && - gtk_drag_get_source_widget (context) == widget && - selection_data->target == - gdk_atom_intern ("nautilus-clist-drag-reorder", FALSE) && - selection_data->format == GTK_TYPE_POINTER && - selection_data->length == sizeof (NautilusCListCellInfo)) - { - NautilusCListCellInfo *source_info; - - source_info = (NautilusCListCellInfo *)(selection_data->data); - if (source_info) - { - NautilusCListDestInfo dest_info; - NautilusCTreeNode *source_node; - NautilusCTreeNode *dest_node; - - drag_dest_cell (clist, x, y, &dest_info); - - source_node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - source_info->row)); - dest_node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - dest_info.cell.row)); - - if (!source_node || !dest_node) - return; - - switch (dest_info.insert_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - break; - case NAUTILUS_CLIST_DRAG_INTO: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, dest_node, - NAUTILUS_CTREE_ROW (dest_node)->children); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - case NAUTILUS_CLIST_DRAG_BEFORE: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, - NAUTILUS_CTREE_ROW (dest_node)->parent, dest_node); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - case NAUTILUS_CLIST_DRAG_AFTER: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, - NAUTILUS_CTREE_ROW (dest_node)->parent, - NAUTILUS_CTREE_ROW (dest_node)->sibling); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - } - } - } -} diff --git a/libnautilus-extensions/nautilus-ctree.h b/libnautilus-extensions/nautilus-ctree.h deleted file mode 100644 index 1f7982874..000000000 --- a/libnautilus-extensions/nautilus-ctree.h +++ /dev/null @@ -1,441 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * NautilusCTree widget for GTK+ - * Copyright (C) 1998 Lars Hamann and Stefan Jeske - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef NAUTILUS_CTREE_H -#define NAUTILUS_CTREE_H - -#include "nautilus-list.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define NAUTILUS_TYPE_CTREE (nautilus_ctree_get_type ()) -#define NAUTILUS_CTREE(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CTREE, NautilusCTree)) -#define NAUTILUS_CTREE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CTREE, NautilusCTreeClass)) -#define NAUTILUS_IS_CTREE(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CTREE)) -#define NAUTILUS_IS_CTREE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CTREE)) - -#define NAUTILUS_CTREE_ROW(_node_) ((NautilusCTreeRow *)(((GList *)(_node_))->data)) -#define NAUTILUS_CTREE_NODE(_node_) ((NautilusCTreeNode *)((_node_))) -#define NAUTILUS_CTREE_NODE_NEXT(_nnode_) ((NautilusCTreeNode *)(((GList *)(_nnode_))->next)) -#define NAUTILUS_CTREE_NODE_PREV(_pnode_) ((NautilusCTreeNode *)(((GList *)(_pnode_))->prev)) -#define NAUTILUS_CTREE_FUNC(_func_) ((NautilusCTreeFunc)(_func_)) - -typedef enum -{ - NAUTILUS_CTREE_POS_BEFORE, - NAUTILUS_CTREE_POS_AS_CHILD, - NAUTILUS_CTREE_POS_AFTER -} NautilusCTreePos; - -typedef enum -{ - NAUTILUS_CTREE_LINES_NONE, - NAUTILUS_CTREE_LINES_SOLID, - NAUTILUS_CTREE_LINES_DOTTED, - NAUTILUS_CTREE_LINES_TABBED -} NautilusCTreeLineStyle; - -typedef enum -{ - NAUTILUS_CTREE_EXPANDER_TRIANGLE -} NautilusCTreeExpanderStyle; - -typedef enum -{ - NAUTILUS_CTREE_EXPANSION_EXPAND, - NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE, - NAUTILUS_CTREE_EXPANSION_COLLAPSE, - NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE, - NAUTILUS_CTREE_EXPANSION_TOGGLE, - NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE -} NautilusCTreeExpansionType; - -typedef struct _NautilusCTree NautilusCTree; -typedef struct _NautilusCTreeClass NautilusCTreeClass; -typedef struct _NautilusCTreeRow NautilusCTreeRow; -typedef struct _NautilusCTreeNode NautilusCTreeNode; - -typedef void (*NautilusCTreeFunc) (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); - -typedef gboolean (*NautilusCTreeGNodeFunc) (NautilusCTree *ctree, - guint depth, - GNode *gnode, - NautilusCTreeNode *cnode, - gpointer data); - -typedef gboolean (*NautilusCTreeCompareDragFunc) (NautilusCTree *ctree, - NautilusCTreeNode *source_node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); - -struct _NautilusCTree -{ - NautilusList list; - - GdkGC *lines_gc; - - gint tree_indent; - gint tree_spacing; - gint tree_column; - - guint line_style : 2; - guint show_stub : 1; - - NautilusCTreeNode *prelight_node; - - NautilusCTreeRow *dnd_prelighted_row; - - NautilusCTreeCompareDragFunc drag_compare; -}; - -struct _NautilusCTreeClass -{ - NautilusListClass parent_class; - - void (*tree_select_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); - void (*tree_unselect_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); - void (*tree_expand) (NautilusCTree *ctree, - NautilusCTreeNode *node); - void (*tree_collapse) (NautilusCTree *ctree, - NautilusCTreeNode *node); - void (*tree_move) (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); - void (*change_focus_row_expansion) (NautilusCTree *ctree, - NautilusCTreeExpansionType action); - void (*tree_activate_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); -}; - -struct _NautilusCTreeRow -{ - NautilusCListRow row; - - NautilusCTreeNode *parent; - NautilusCTreeNode *sibling; - NautilusCTreeNode *children; - - GdkPixbuf *pixbuf_closed; - GdkPixbuf *pixbuf_opened; - - guint16 level; - - guint is_leaf : 1; - guint expanded : 1; - - gboolean mouse_down; - gboolean in_hotspot; - -}; - -struct _NautilusCTreeNode { - GList list; -}; - - -/*********************************************************** - * Creation, insertion, deletion * - ***********************************************************/ - -GtkType nautilus_ctree_get_type (void); -void nautilus_ctree_construct (NautilusCTree *ctree, - gint columns, - gint tree_column, - gchar *titles[]); -GtkWidget * nautilus_ctree_new_with_titles (gint columns, - gint tree_column, - gchar *titles[]); -GtkWidget * nautilus_ctree_new (gint columns, - gint tree_column); -NautilusCTreeNode * nautilus_ctree_insert_node (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gchar *text[], - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -void nautilus_ctree_remove_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_insert_gnode (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - GNode *gnode, - NautilusCTreeGNodeFunc func, - gpointer data); -GNode * nautilus_ctree_export_to_gnode (NautilusCTree *ctree, - GNode *parent, - GNode *sibling, - NautilusCTreeNode *node, - NautilusCTreeGNodeFunc func, - gpointer data); - -/*********************************************************** - * Generic recursive functions, querying / finding tree * - * information * - ***********************************************************/ - -void nautilus_ctree_post_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_post_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_pre_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_pre_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data); -gboolean nautilus_ctree_is_viewable (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_last (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_find_node_ptr (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row); -NautilusCTreeNode * nautilus_ctree_node_nth (NautilusCTree *ctree, - int row); -gboolean nautilus_ctree_find (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child); -gboolean nautilus_ctree_is_ancestor (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child); -NautilusCTreeNode * nautilus_ctree_find_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -/* returns a GList of all NautilusCTreeNodes with row->data == data. */ -GList * nautilus_ctree_find_all_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -NautilusCTreeNode * nautilus_ctree_find_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func); -/* returns a GList of all NautilusCTreeNodes with row->data == data. */ -GList * nautilus_ctree_find_all_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func); -gboolean nautilus_ctree_is_hot_spot (NautilusCTree *ctree, - gint x, - gint y); - -/*********************************************************** - * Tree signals : move, expand, collapse, (un)select * - ***********************************************************/ - -void nautilus_ctree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); -void nautilus_ctree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_expand_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_expand_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -void nautilus_ctree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_collapse_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -void nautilus_ctree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_toggle_expansion_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_select (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_unselect_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_real_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint state); -void nautilus_ctree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node); - -/*********************************************************** - * Analogons of GtkCList functions * - ***********************************************************/ - -void nautilus_ctree_node_set_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text); -void nautilus_ctree_node_set_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf *pixbuf); -void nautilus_ctree_node_set_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -void nautilus_ctree_set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -void nautilus_ctree_node_set_shift (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gint vertical, - gint horizontal); -void nautilus_ctree_node_set_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean selectable); -gboolean nautilus_ctree_node_get_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCellType nautilus_ctree_node_get_cell_type (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -gint nautilus_ctree_node_get_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text); -gint nautilus_ctree_node_get_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf **pixbuf); -gint nautilus_ctree_node_get_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf); -gint nautilus_ctree_get_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf_closed, - GdkPixbuf **pixbuf_opened, - gboolean *is_leaf, - gboolean *expanded); - -void nautilus_ctree_set_prelight (NautilusCTree *ctree, - int y); - -void nautilus_ctree_node_set_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - GtkStyle *style); -GtkStyle * nautilus_ctree_node_get_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_node_set_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GtkStyle *style); -GtkStyle * nautilus_ctree_node_get_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -void nautilus_ctree_node_set_foreground (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color); -void nautilus_ctree_node_set_background (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color); -void nautilus_ctree_node_set_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -void nautilus_ctree_node_set_row_data_full (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GtkDestroyNotify destroy); -gpointer nautilus_ctree_node_get_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_node_moveto (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gfloat row_align, - gfloat col_align); -GtkVisibility nautilus_ctree_node_is_visible (NautilusCTree *ctree, - NautilusCTreeNode *node); - -/*********************************************************** - * NautilusCTree specific functions * - ***********************************************************/ - -void nautilus_ctree_set_indent (NautilusCTree *ctree, - gint indent); -void nautilus_ctree_set_spacing (NautilusCTree *ctree, - gint spacing); -void nautilus_ctree_set_show_stub (NautilusCTree *ctree, - gboolean show_stub); -void nautilus_ctree_set_line_style (NautilusCTree *ctree, - NautilusCTreeLineStyle line_style); -void nautilus_ctree_set_drag_compare_func (NautilusCTree *ctree, - NautilusCTreeCompareDragFunc cmp_func); - -/*********************************************************** - * Tree sorting functions * - ***********************************************************/ - -void nautilus_ctree_sort_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_sort_single_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_sort_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NAUTILUS_CTREE_H */ diff --git a/libnautilus-extensions/nautilus-drag.c b/libnautilus-extensions/nautilus-drag.c deleted file mode 100644 index e609993b3..000000000 --- a/libnautilus-extensions/nautilus-drag.c +++ /dev/null @@ -1,688 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-drag.c - Common Drag & drop handling code shared by the icon container - and the list view. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com>, - Ettore Perazzoli <ettore@gnu.org> -*/ - -#include <config.h> -#include "nautilus-drag.h" - -#include "nautilus-link.h" -#include <eel/eel-glib-extensions.h> -#include <eel/eel-string.h> -#include <eel/eel-vfs-extensions.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-popup-menu.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomevfs/gnome-vfs-find-directory.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-types.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-utils.h> -#include <stdio.h> -#include <string.h> - -#define NAUTILUS_COMMAND_SPECIFIER "command:" - -void -nautilus_drag_init (NautilusDragInfo *drag_info, - const GtkTargetEntry *drag_types, int drag_type_count, - GdkBitmap *stipple) -{ - drag_info->target_list = gtk_target_list_new (drag_types, - drag_type_count); - - if (stipple != NULL) { - drag_info->stipple = gdk_bitmap_ref (stipple); - } - - drag_info->drop_occured = FALSE; - drag_info->need_to_destroy = FALSE; -} - -void -nautilus_drag_finalize (NautilusDragInfo *drag_info) -{ - gtk_target_list_unref (drag_info->target_list); - nautilus_drag_destroy_selection_list (drag_info->selection_list); - - if (drag_info->stipple != NULL) { - gdk_bitmap_unref (drag_info->stipple); - } - - g_free (drag_info); -} - - -/* Functions to deal with DragSelectionItems. */ - -DragSelectionItem * -nautilus_drag_selection_item_new (void) -{ - return g_new0 (DragSelectionItem, 1); -} - -static void -drag_selection_item_destroy (DragSelectionItem *item) -{ - g_free (item->uri); - g_free (item); -} - -void -nautilus_drag_destroy_selection_list (GList *list) -{ - GList *p; - - if (list == NULL) - return; - - for (p = list; p != NULL; p = p->next) - drag_selection_item_destroy (p->data); - - g_list_free (list); -} - -GList * -nautilus_drag_build_selection_list (GtkSelectionData *data) -{ - GList *result; - const guchar *p, *oldp; - int size; - - result = NULL; - oldp = data->data; - size = data->length; - - while (size > 0) { - DragSelectionItem *item; - guint len; - - /* The list is in the form: - - name\rx:y:width:height\r\n - - The geometry information after the first \r is optional. */ - - /* 1: Decode name. */ - - p = memchr (oldp, '\r', size); - if (p == NULL) { - break; - } - - item = nautilus_drag_selection_item_new (); - - len = p - oldp; - - item->uri = g_malloc (len + 1); - memcpy (item->uri, oldp, len); - item->uri[len] = 0; - - p++; - if (*p == '\n' || *p == '\0') { - result = g_list_prepend (result, item); - if (p == 0) { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "missing newline character."); - break; - } else { - oldp = p + 1; - continue; - } - } - - size -= p - oldp; - oldp = p; - - /* 2: Decode geometry information. */ - - item->got_icon_position = sscanf (p, "%d:%d:%d:%d%*s", - &item->icon_x, &item->icon_y, - &item->icon_width, &item->icon_height) == 4; - if (!item->got_icon_position) { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "invalid icon position specification."); - } - - result = g_list_prepend (result, item); - - p = memchr (p, '\r', size); - if (p == NULL || p[1] != '\n') { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "missing newline character."); - if (p == NULL) { - break; - } - } else { - p += 2; - } - - size -= p - oldp; - oldp = p; - } - - return result; -} - - -gboolean -nautilus_drag_items_local (const char *target_uri_string, const GList *selection_list) -{ - /* check if the first item on the list has target_uri_string as a parent - * FIXME: - * we should really test each item but that would be slow for large selections - * and currently dropped items can only be from the same container - */ - GnomeVFSURI *target_uri; - GnomeVFSURI *item_uri; - gboolean result; - - /* must have at least one item */ - g_assert (selection_list); - - result = FALSE; - - target_uri = gnome_vfs_uri_new (target_uri_string); - - /* get the parent URI of the first item in the selection */ - item_uri = gnome_vfs_uri_new (((DragSelectionItem *)selection_list->data)->uri); - result = gnome_vfs_uri_is_parent (target_uri, item_uri, FALSE); - - gnome_vfs_uri_unref (item_uri); - gnome_vfs_uri_unref (target_uri); - - return result; -} - -gboolean -nautilus_drag_items_in_trash (const GList *selection_list) -{ - /* check if the first item on the list is in trash. - * FIXME: - * we should really test each item but that would be slow for large selections - * and currently dropped items can only be from the same container - */ - return eel_uri_is_in_trash (((DragSelectionItem *)selection_list->data)->uri); -} - -gboolean -nautilus_drag_can_accept_item (NautilusFile *drop_target_item, - const char *item_uri) -{ - if (nautilus_file_matches_uri (drop_target_item, item_uri)) { - /* can't accept itself */ - return FALSE; - } - - if (nautilus_file_is_directory (drop_target_item)) { - /* target is a directory, accept anything */ - return TRUE; - } - - /* All Nautilus links are assumed to be links to directories. - * Therefore, they all can accept drags, like all other - * directories to. As with other directories, there can be - * errors when the actual copy is attempted due to - * permissions. - */ - if (nautilus_file_is_nautilus_link (drop_target_item)) { - return TRUE; - } - - return FALSE; -} - -gboolean -nautilus_drag_can_accept_items (NautilusFile *drop_target_item, - const GList *items) -{ - int max; - - if (drop_target_item == NULL) - return FALSE; - - g_assert (NAUTILUS_IS_FILE (drop_target_item)); - - /* Iterate through selection checking if item will get accepted by the - * drop target. If more than 100 items selected, return an over-optimisic - * result - */ - for (max = 100; items != NULL && max >= 0; items = items->next, max--) { - if (!nautilus_drag_can_accept_item (drop_target_item, - ((DragSelectionItem *)items->data)->uri)) { - return FALSE; - } - } - - return TRUE; -} - -void -nautilus_drag_default_drop_action_for_icons (GdkDragContext *context, - const char *target_uri_string, const GList *items, - int *default_action, int *non_default_action) -{ - gboolean same_fs; - GnomeVFSURI *target_uri; - GnomeVFSURI *dropped_uri; - GdkDragAction actions; - GnomeVFSResult result; - - if (target_uri_string == NULL) { - *default_action = 0; - *non_default_action = 0; - return; - } - - actions = context->actions & (GDK_ACTION_MOVE | GDK_ACTION_COPY); - if (actions == 0) { - /* We can't use copy or move, just go with the suggested action. - * - * Note: it would be more correct to only choose between move - * and copy if both are specified in context->actions. - * There is a problem in gtk-dnd.c though where context->actions - * gets set only to copy when Control is held down, despite the - * fact that bot copy and move were requested. - * - */ - *default_action = context->suggested_action; - *non_default_action = context->suggested_action; - return; - } - - /* Check for trash URI. We do a find_directory for any Trash directory. */ - if (eel_uri_is_trash (target_uri_string)) { - result = gnome_vfs_find_directory (NULL, GNOME_VFS_DIRECTORY_KIND_TRASH, - &target_uri, FALSE, FALSE, 0777); - if (result != GNOME_VFS_OK) { - *default_action = 0; - *non_default_action = 0; - return; - } - - /* Only move to Trash */ - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_MOVE; - return; - - } else if (eel_str_has_prefix (target_uri_string, NAUTILUS_COMMAND_SPECIFIER)) { - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_MOVE; - return; - } else { - target_uri = gnome_vfs_uri_new (target_uri_string); - } - - if (target_uri == NULL) { - *default_action = 0; - *non_default_action = 0; - return; - } - - /* Compare the first dropped uri with the target uri for same fs match. */ - dropped_uri = gnome_vfs_uri_new (((DragSelectionItem *)items->data)->uri); - same_fs = TRUE; - - gnome_vfs_check_same_fs_uris (dropped_uri, target_uri, &same_fs); - gnome_vfs_uri_unref (dropped_uri); - gnome_vfs_uri_unref (target_uri); - - if (same_fs) { - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_COPY; - } else { - *default_action = GDK_ACTION_COPY; - *non_default_action = GDK_ACTION_MOVE; - } -} - -/* Encode a "x-special/gnome-icon-list" selection. - Along with the URIs of the dragged files, this encodes - the location and size of each icon relative to the cursor. -*/ -static void -add_one_gnome_icon_list (const char *uri, int x, int y, int w, int h, - gpointer data) -{ - GString *result = (GString *)data; - char *s; - - s = g_strdup_printf ("%s\r%d:%d:%hu:%hu\r\n", - uri, x, y, w, h); - - g_string_append (result, s); - g_free (s); -} - -/* Encode a "text/uri-list" selection. */ -static void -add_one_uri_list (const char *uri, int x, int y, int w, int h, - gpointer data) -{ - GString *result = (GString *)data; - g_string_append (result, uri); - g_string_append (result, "\r\n"); -} - -/* Encode a "_NETSCAPE_URL_" selection. - * As far as I can tell, Netscape is expecting a single - * URL to be returned. I cannot discover a way to construct - * a list to be returned that Netscape can understand. - * GMC also fails to do this as well. - */ -static void -add_one_netscape_url_list (const char *url, int x, int y, int w, int h, gpointer data) -{ - GString *result = (GString *)data; - if (result->len == 0) { - g_string_append (result, url); - } -} - -/* Encode a "text/path" selection. */ -static void -add_one_path_list (const char *uri, int x, int y, int w, int h, gpointer data) -{ - GString *result = (GString *)data; - char *local_path; - - g_return_if_fail (uri != NULL); - - local_path = gnome_vfs_get_local_path_from_uri (uri); - if (local_path == NULL) - return; - - g_string_append (result, local_path); - g_string_append (result, "\r\n"); - g_free (local_path); -} - - -/* Common function for drag_data_get_callback calls. - * Returns FALSE if it doesn't handle drag data - */ -gboolean -nautilus_drag_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint32 time, - gpointer container_context, - NautilusDragEachSelectedItemIterator each_selected_item_iterator) -{ - GString *result; - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_gnome_icon_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_URI_LIST: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_uri_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_TEXT: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_path_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_URL: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_netscape_url_list, container_context, result); - break; - - default: - return FALSE; - } - - gtk_selection_data_set (selection_data, - selection_data->target, - 8, result->str, result->len); - - return TRUE; -} - -int -nautilus_drag_modifier_based_action (int default_action, int non_default_action) -{ - GdkModifierType modifiers; - gdk_window_get_pointer (NULL, NULL, NULL, &modifiers); - - if ((modifiers & GDK_CONTROL_MASK) != 0) { - return non_default_action; - } else if ((modifiers & GDK_SHIFT_MASK) != 0) { - return GDK_ACTION_LINK; - } else if ((modifiers & GDK_MOD1_MASK) != 0) { - return GDK_ACTION_ASK; - } - - return default_action; -} - -/* The menu of DnD actions */ -static GnomeUIInfo menu_items[] = { - GNOMEUIINFO_ITEM_NONE (N_("_Move here"), NULL, NULL), - GNOMEUIINFO_ITEM_NONE (N_("_Copy here"), NULL, NULL), - GNOMEUIINFO_ITEM_NONE (N_("_Link here"), NULL, NULL), - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("Cancel"), NULL, NULL), - GNOMEUIINFO_END -}; - -/* Pops up a menu of actions to perform on dropped files */ -GdkDragAction -nautilus_drag_drop_action_ask (GdkDragAction actions) -{ - GtkWidget *menu; - int action; - - /* Create the menu and set the sensitivity of the items based on the - * allowed actions. - */ - menu = gnome_popup_menu_new (menu_items); - - gtk_widget_set_sensitive (menu_items[0].widget, (actions & GDK_ACTION_MOVE) != 0); - gtk_widget_set_sensitive (menu_items[1].widget, (actions & GDK_ACTION_COPY) != 0); - gtk_widget_set_sensitive (menu_items[2].widget, (actions & GDK_ACTION_LINK) != 0); - - switch (gnome_popup_menu_do_popup_modal (menu, NULL, NULL, NULL, NULL)) { - case 0: - action = GDK_ACTION_MOVE; - break; - case 1: - action = GDK_ACTION_COPY; - break; - case 2: - action = GDK_ACTION_LINK; - break; - default: - action = 0; - } - - gtk_widget_destroy (menu); - - return action; -} - -#define AUTO_SCROLL_MARGIN 20 - /* drag this close to the view edge to start auto scroll*/ - -#define MIN_AUTOSCROLL_DELTA 5 - /* the smallest amount of auto scroll used when we just enter the autoscroll - * margin - */ - -#define MAX_AUTOSCROLL_DELTA 50 - /* the largest amount of auto scroll used when we are right over the view - * edge - */ - - - -gboolean -nautilus_drag_autoscroll_in_scroll_region (GtkWidget *widget) -{ - float x_scroll_delta, y_scroll_delta; - - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); - - return x_scroll_delta != 0 || y_scroll_delta != 0; -} - - -void -nautilus_drag_autoscroll_calculate_delta (GtkWidget *widget, float *x_scroll_delta, float *y_scroll_delta) -{ - int x, y; - - g_assert (GTK_IS_WIDGET (widget)); - - gdk_window_get_pointer (widget->window, &x, &y, NULL); - - /* Find out if we are anywhere close to the tree view edges - * to see if we need to autoscroll. - */ - *x_scroll_delta = 0; - *y_scroll_delta = 0; - - if (x < AUTO_SCROLL_MARGIN) { - *x_scroll_delta = (float)(x - AUTO_SCROLL_MARGIN); - } - - if (x > widget->allocation.width - AUTO_SCROLL_MARGIN) { - if (*x_scroll_delta != 0) { - /* Already trying to scroll because of being too close to - * the top edge -- must be the window is really short, - * don't autoscroll. - */ - return; - } - *x_scroll_delta = (float)(x - (widget->allocation.width - AUTO_SCROLL_MARGIN)); - } - - if (y < AUTO_SCROLL_MARGIN) { - *y_scroll_delta = (float)(y - AUTO_SCROLL_MARGIN); - } - - if (y > widget->allocation.height - AUTO_SCROLL_MARGIN) { - if (*y_scroll_delta != 0) { - /* Already trying to scroll because of being too close to - * the top edge -- must be the window is really narrow, - * don't autoscroll. - */ - return; - } - *y_scroll_delta = (float)(y - (widget->allocation.height - AUTO_SCROLL_MARGIN)); - } - - if (*x_scroll_delta == 0 && *y_scroll_delta == 0) { - /* no work */ - return; - } - - /* Adjust the scroll delta to the proper acceleration values depending on how far - * into the sroll margins we are. - * FIXME bugzilla.eazel.com 2486: - * we could use an exponential acceleration factor here for better feel - */ - if (*x_scroll_delta != 0) { - *x_scroll_delta /= AUTO_SCROLL_MARGIN; - *x_scroll_delta *= (MAX_AUTOSCROLL_DELTA - MIN_AUTOSCROLL_DELTA); - *x_scroll_delta += MIN_AUTOSCROLL_DELTA; - } - - if (*y_scroll_delta != 0) { - *y_scroll_delta /= AUTO_SCROLL_MARGIN; - *y_scroll_delta *= (MAX_AUTOSCROLL_DELTA - MIN_AUTOSCROLL_DELTA); - *y_scroll_delta += MIN_AUTOSCROLL_DELTA; - } - -} - - - -void -nautilus_drag_autoscroll_start (NautilusDragInfo *drag_info, - GtkWidget *widget, - GtkFunction callback, - gpointer user_data) -{ - if (nautilus_drag_autoscroll_in_scroll_region (widget)) { - if (drag_info->auto_scroll_timeout_id == 0) { - drag_info->waiting_to_autoscroll = TRUE; - drag_info->start_auto_scroll_in = eel_get_system_time() - + AUTOSCROLL_INITIAL_DELAY; - - drag_info->auto_scroll_timeout_id = gtk_timeout_add - (AUTOSCROLL_TIMEOUT_INTERVAL, - callback, - user_data); - } - } else { - if (drag_info->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (drag_info->auto_scroll_timeout_id); - drag_info->auto_scroll_timeout_id = 0; - } - } -} - -void -nautilus_drag_autoscroll_stop (NautilusDragInfo *drag_info) -{ - if (drag_info->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (drag_info->auto_scroll_timeout_id); - drag_info->auto_scroll_timeout_id = 0; - } -} - - -void -nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, char *keyword) -{ - GList *keywords, *word; - - g_return_if_fail (NAUTILUS_IS_FILE (file)); - g_return_if_fail (keyword != NULL); - - /* special case the erase emblem */ - if (strcmp (keyword, ERASE_KEYWORD) == 0) { - keywords = NULL; - } else { - keywords = nautilus_file_get_keywords (file); - word = g_list_find_custom (keywords, keyword, (GCompareFunc) strcmp); - if (word == NULL) { - keywords = g_list_append (keywords, g_strdup (keyword)); - } else { - keywords = g_list_remove_link (keywords, word); - g_free (word->data); - g_list_free_1 (word); - } - } - - nautilus_file_set_keywords (file, keywords); - eel_g_list_free_deep (keywords); -} diff --git a/libnautilus-extensions/nautilus-drag.h b/libnautilus-extensions/nautilus-drag.h deleted file mode 100644 index f25af7bb0..000000000 --- a/libnautilus-extensions/nautilus-drag.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* nautilus-drag.h - Common Drag & drop handling code shared by the icon container - and the list view. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com>, - Ettore Perazzoli <ettore@gnu.org> -*/ - -#ifndef NAUTILUS_DRAG_H -#define NAUTILUS_DRAG_H - -#include <gtk/gtkdnd.h> -#include "nautilus-file.h" - -/* a set of defines stolen from the nautilus-icon-dnd.c file */ -#define AUTOSCROLL_TIMEOUT_INTERVAL 100 - /* in milliseconds */ - -#define AUTOSCROLL_INITIAL_DELAY 750000 - /* in microseconds */ - -/* Item of the drag selection list */ -typedef struct { - char *uri; - gboolean got_icon_position; - int icon_x, icon_y; - int icon_width, icon_height; -} DragSelectionItem; - -/* Standard Drag & Drop types. */ -typedef enum { - NAUTILUS_ICON_DND_GNOME_ICON_LIST, - NAUTILUS_ICON_DND_URI_LIST, - NAUTILUS_ICON_DND_URL, - NAUTILUS_ICON_DND_COLOR, - NAUTILUS_ICON_DND_BGIMAGE, - NAUTILUS_ICON_DND_KEYWORD, - NAUTILUS_ICON_DND_TEXT -} NautilusIconDndTargetType; - -/* drag&drop-related information. */ -typedef struct { - GtkTargetList *target_list; - - /* Stuff saved at "receive data" time needed later in the drag. */ - gboolean got_drop_data_type; - NautilusIconDndTargetType data_type; - GtkSelectionData *selection_data; - - /* Start of the drag, in world coordinates. */ - gdouble start_x, start_y; - - /* List of DragSelectionItems, representing items being dragged, or NULL - * if data about them has not been received from the source yet. - */ - GList *selection_list; - - /* Stipple for drawing icon shadows during DnD. */ - GdkBitmap *stipple; - - /* has the drop occured ? */ - gboolean drop_occured; - - /* whether or not need to clean up the previous dnd data */ - gboolean need_to_destroy; - - /* autoscrolling during dragging */ - int auto_scroll_timeout_id; - gboolean waiting_to_autoscroll; - gint64 start_auto_scroll_in; - -} NautilusDragInfo; - - -/* Drag & Drop target names. */ -#define NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE "x-special/gnome-icon-list" -#define NAUTILUS_ICON_DND_URI_LIST_TYPE "text/uri-list" -#define NAUTILUS_ICON_DND_TEXT_TYPE "text/plain" -#define NAUTILUS_ICON_DND_URL_TYPE "_NETSCAPE_URL" -#define NAUTILUS_ICON_DND_COLOR_TYPE "application/x-color" -#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage" -#define NAUTILUS_ICON_DND_KEYWORD_TYPE "property/keyword" - -#define ERASE_KEYWORD "erase" - -typedef void (* NautilusDragEachSelectedItemDataGet) (const char *url, - int x, int y, int w, int h, - gpointer data); -typedef void (* NautilusDragEachSelectedItemIterator) (NautilusDragEachSelectedItemDataGet iteratee, - gpointer iterator_context, - gpointer data); - -void nautilus_drag_init (NautilusDragInfo *drag_info, - const GtkTargetEntry *drag_types, - int drag_type_count, - GdkBitmap *stipple); - -void nautilus_drag_finalize (NautilusDragInfo *drag_info); - - -DragSelectionItem *nautilus_drag_selection_item_new (void); -void nautilus_drag_destroy_selection_list (GList *selection_list); -GList *nautilus_drag_build_selection_list (GtkSelectionData *data); -gboolean nautilus_drag_items_local (const char *target_uri, - const GList *selection_list); -gboolean nautilus_drag_items_in_trash (const GList *selection_list); - -gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, - const char *item_uri); -gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item, - const GList *items); -void nautilus_drag_default_drop_action_for_icons (GdkDragContext *context, - const char *target_uri, - const GList *items, - int *default_action, - int *non_default_action); - -gboolean nautilus_drag_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint32 time, - gpointer container_context, - NautilusDragEachSelectedItemIterator each_selected_item_iterator); -int nautilus_drag_modifier_based_action (int default_action, - int non_default_action); - -GdkDragAction nautilus_drag_drop_action_ask (GdkDragAction possible_actions); - -gboolean nautilus_drag_autoscroll_in_scroll_region (GtkWidget *widget); -void nautilus_drag_autoscroll_calculate_delta (GtkWidget *widget, - float *x_scroll_delta, - float *y_scroll_delta); - -void nautilus_drag_autoscroll_start (NautilusDragInfo *drag_info, - GtkWidget *widget, - GtkFunction callback, - gpointer user_data); - -void nautilus_drag_autoscroll_stop (NautilusDragInfo *drag_info); - - -void nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, - char *keyword); - -#endif - diff --git a/libnautilus-extensions/nautilus-file-dnd.c b/libnautilus-extensions/nautilus-file-dnd.c new file mode 100644 index 000000000..fe559b2d1 --- /dev/null +++ b/libnautilus-extensions/nautilus-file-dnd.c @@ -0,0 +1,109 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-file-drag.c - Drag & drop handling code that operated on + NautilusFile objects. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler <pavel@eazel.com>, +*/ + +#include <config.h> +#include "nautilus-file-dnd.h" + +#include <eel/eel-glib-extensions.h> +#include <eel/eel-string.h> + +gboolean +nautilus_drag_can_accept_item (NautilusFile *drop_target_item, + const char *item_uri) +{ + if (nautilus_file_matches_uri (drop_target_item, item_uri)) { + /* can't accept itself */ + return FALSE; + } + + if (nautilus_file_is_directory (drop_target_item)) { + /* target is a directory, accept anything */ + return TRUE; + } + + /* All Nautilus links are assumed to be links to directories. + * Therefore, they all can accept drags, like all other + * directories to. As with other directories, there can be + * errors when the actual copy is attempted due to + * permissions. + */ + if (nautilus_file_is_nautilus_link (drop_target_item)) { + return TRUE; + } + + return FALSE; +} + +gboolean +nautilus_drag_can_accept_items (NautilusFile *drop_target_item, + const GList *items) +{ + int max; + + if (drop_target_item == NULL) + return FALSE; + + g_assert (NAUTILUS_IS_FILE (drop_target_item)); + + /* Iterate through selection checking if item will get accepted by the + * drop target. If more than 100 items selected, return an over-optimisic + * result + */ + for (max = 100; items != NULL && max >= 0; items = items->next, max--) { + if (!nautilus_drag_can_accept_item (drop_target_item, + ((DragSelectionItem *)items->data)->uri)) { + return FALSE; + } + } + + return TRUE; +} + +void +nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, char *keyword) +{ + GList *keywords, *word; + + g_return_if_fail (NAUTILUS_IS_FILE (file)); + g_return_if_fail (keyword != NULL); + + /* special case the erase emblem */ + if (strcmp (keyword, ERASE_KEYWORD) == 0) { + keywords = NULL; + } else { + keywords = nautilus_file_get_keywords (file); + word = g_list_find_custom (keywords, keyword, (GCompareFunc) strcmp); + if (word == NULL) { + keywords = g_list_append (keywords, g_strdup (keyword)); + } else { + keywords = g_list_remove_link (keywords, word); + g_free (word->data); + g_list_free_1 (word); + } + } + + nautilus_file_set_keywords (file, keywords); + eel_g_list_free_deep (keywords); +} diff --git a/libnautilus-extensions/nautilus-file-dnd.h b/libnautilus-extensions/nautilus-file-dnd.h new file mode 100644 index 000000000..484d5f643 --- /dev/null +++ b/libnautilus-extensions/nautilus-file-dnd.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* nautilus-file-drag.h - Drag & drop handling code that operated on + NautilusFile objects. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler <pavel@eazel.com>, +*/ + +#ifndef NAUTILUS_FILE_DND_H +#define NAUTILUS_FILE_DND_H + +#include <eel/eel-dnd.h> +#include <libnautilus-extensions/nautilus-file.h> + +gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, + const char *item_uri); +gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item, + const GList *items); +void nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, + char *keyword); + +#endif /* NAUTILUS_FILE_DND_H */ + diff --git a/libnautilus-extensions/nautilus-icon-dnd.c b/libnautilus-extensions/nautilus-icon-dnd.c index 61265e19b..6fcb48ad0 100644 --- a/libnautilus-extensions/nautilus-icon-dnd.c +++ b/libnautilus-extensions/nautilus-icon-dnd.c @@ -30,6 +30,9 @@ #include <config.h> #include "nautilus-icon-dnd.h" +#include "nautilus-file-dnd.h" +#include "nautilus-icon-private.h" +#include "nautilus-link.h" #include <eel/eel-background.h> #include <eel/eel-gdk-pixbuf-extensions.h> #include <eel/eel-glib-extensions.h> @@ -37,11 +40,9 @@ #include <eel/eel-graphic-effects.h> #include <eel/eel-gtk-extensions.h> #include <eel/eel-gtk-macros.h> -#include <eel/eel-vfs-extensions.h> -#include "nautilus-icon-private.h" -#include "nautilus-link.h" #include <eel/eel-stock-dialogs.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <gdk/gdkkeysyms.h> #include <gdk/gdkx.h> #include <gtk/gtkmain.h> @@ -91,19 +92,19 @@ static void set_drop_target (NautilusIconCo static GtkTargetEntry drag_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_TEXT_TYPE, 0, NAUTILUS_ICON_DND_TEXT } + { EEL_ICON_DND_GNOME_ICON_LIST_TYPE, 0, EEL_ICON_DND_GNOME_ICON_LIST }, + { EEL_ICON_DND_URI_LIST_TYPE, 0, EEL_ICON_DND_URI_LIST }, + { EEL_ICON_DND_URL_TYPE, 0, EEL_ICON_DND_URL }, + { EEL_ICON_DND_TEXT_TYPE, 0, EEL_ICON_DND_TEXT } }; static GtkTargetEntry drop_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }, - { NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }, - { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD } + { EEL_ICON_DND_GNOME_ICON_LIST_TYPE, 0, EEL_ICON_DND_GNOME_ICON_LIST }, + { EEL_ICON_DND_URI_LIST_TYPE, 0, EEL_ICON_DND_URI_LIST }, + { EEL_ICON_DND_URL_TYPE, 0, EEL_ICON_DND_URL }, + { EEL_ICON_DND_COLOR_TYPE, 0, EEL_ICON_DND_COLOR }, + { EEL_ICON_DND_BGIMAGE_TYPE, 0, EEL_ICON_DND_BGIMAGE }, + { EEL_ICON_DND_KEYWORD_TYPE, 0, EEL_ICON_DND_KEYWORD } }; static GtkTargetList *drop_types_list = NULL; @@ -208,7 +209,7 @@ set_shadow_position (GnomeCanvasItem *shadow, /* iteration glue struct */ typedef struct { gpointer iterator_context; - NautilusDragEachSelectedItemDataGet iteratee; + EelDragEachSelectedItemDataGet iteratee; gpointer iteratee_data; } IconGetDataBinderContext; @@ -284,7 +285,7 @@ nautilus_icon_container_each_selected_icon (NautilusIconContainer *container, * values to the iteratee */ static void -each_icon_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee, +each_icon_get_data_binder (EelDragEachSelectedItemDataGet iteratee, gpointer iterator_context, gpointer data) { IconGetDataBinderContext context; @@ -316,7 +317,7 @@ drag_data_get_callback (GtkWidget *widget, * the selection data in the right format. Pass it means to * iterate all the selected icons. */ - nautilus_drag_drag_data_get (widget, context, selection_data, + eel_drag_drag_data_get (widget, context, selection_data, info, time, widget, each_icon_get_data_binder); } @@ -353,7 +354,7 @@ nautilus_icon_container_dropped_icon_feedback (GtkWidget *widget, dnd_info = container->details->dnd_info; /* Delete old selection list. */ - nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (dnd_info->drag_info.selection_list); dnd_info->drag_info.selection_list = NULL; /* Delete old shadow if any. */ @@ -364,7 +365,7 @@ nautilus_icon_container_dropped_icon_feedback (GtkWidget *widget, } /* Build the selection list and the shadow. */ - dnd_info->drag_info.selection_list = nautilus_drag_build_selection_list (data); + dnd_info->drag_info.selection_list = eel_drag_build_selection_list (data); dnd_info->shadow = create_selection_shadow (container, dnd_info->drag_info.selection_list); nautilus_icon_container_position_shadow (container, x, y); } @@ -387,7 +388,7 @@ drag_data_received_callback (GtkWidget *widget, guint32 time, gpointer user_data) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; drag_info = &(NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->drag_info); @@ -395,20 +396,20 @@ drag_data_received_callback (GtkWidget *widget, drag_info->data_type = info; switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: nautilus_icon_container_dropped_icon_feedback (widget, data, x, y); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: - case NAUTILUS_ICON_DND_KEYWORD: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: + case EEL_ICON_DND_KEYWORD: + case EEL_ICON_DND_URI_LIST: /* Save the data so we can do the actual work on drop. */ g_assert (drag_info->selection_data == NULL); drag_info->selection_data = eel_gtk_selection_data_copy_deep (data); break; /* Netscape keeps sending us the data, even though we accept the first drag */ - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URL: if (drag_info->selection_data != NULL) { eel_gtk_selection_data_free_deep (drag_info->selection_data); drag_info->selection_data = eel_gtk_selection_data_copy_deep (data); @@ -427,32 +428,32 @@ drag_data_received_callback (GtkWidget *widget, if (drag_info->drop_occured) { switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: nautilus_icon_container_receive_dropped_icons (NAUTILUS_ICON_CONTAINER (widget), context, x, y); gtk_drag_finish (context, TRUE, FALSE, time); break; - case NAUTILUS_ICON_DND_COLOR: + case EEL_ICON_DND_COLOR: eel_background_receive_dropped_color (eel_get_widget_background (widget), widget, x, y, data); gtk_drag_finish (context, TRUE, FALSE, time); break; - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_BGIMAGE: receive_dropped_tile_image (NAUTILUS_ICON_CONTAINER (widget), data); gtk_drag_finish (context, FALSE, FALSE, time); break; - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: receive_dropped_keyword (NAUTILUS_ICON_CONTAINER (widget), (char*) data->data, x, y); gtk_drag_finish (context, FALSE, FALSE, time); break; - case NAUTILUS_ICON_DND_URI_LIST: - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URI_LIST: + case EEL_ICON_DND_URL: receive_dropped_uri_list (NAUTILUS_ICON_CONTAINER (widget), (char*) data->data, x, y); @@ -523,7 +524,7 @@ drag_end_callback (GtkWidget *widget, container = NAUTILUS_ICON_CONTAINER (widget); dnd_info = container->details->dnd_info; - nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (dnd_info->drag_info.selection_list); dnd_info->drag_info.selection_list = NULL; } @@ -587,12 +588,12 @@ nautilus_icon_container_selection_items_local (const NautilusIconContainer *cont container_uri_string = get_container_uri (container); if (eel_uri_is_trash (container_uri_string)) { - /* Special-case "trash:" because the nautilus_drag_items_local + /* Special-case "trash:" because the eel_drag_items_local * would not work for it. */ - result = nautilus_drag_items_in_trash (items); + result = eel_drag_items_in_trash (items); } else { - result = nautilus_drag_items_local (container_uri_string, items); + result = eel_drag_items_local (container_uri_string, items); } g_free (container_uri_string); @@ -677,7 +678,7 @@ auto_scroll_timeout_callback (gpointer data) container->details->dnd_info->drag_info.waiting_to_autoscroll = FALSE; - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); + eel_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); if (x_scroll_delta == 0 && y_scroll_delta == 0) { /* no work */ return TRUE; @@ -727,7 +728,7 @@ auto_scroll_timeout_callback (gpointer data) static void set_up_auto_scroll_if_needed (NautilusIconContainer *container) { - nautilus_drag_autoscroll_start (&container->details->dnd_info->drag_info, + eel_drag_autoscroll_start (&container->details->dnd_info->drag_info, GTK_WIDGET (container), auto_scroll_timeout_callback, container); @@ -736,7 +737,7 @@ set_up_auto_scroll_if_needed (NautilusIconContainer *container) static void stop_auto_scroll (NautilusIconContainer *container) { - nautilus_drag_autoscroll_stop (&container->details->dnd_info->drag_info); + eel_drag_autoscroll_stop (&container->details->dnd_info->drag_info); } static gboolean @@ -976,7 +977,7 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container, } else { action = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK; } - context->action = nautilus_drag_drop_action_ask (action); + context->action = eel_drag_drop_action_ask (action); } if (context->action > 0) { @@ -1003,7 +1004,7 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container, } g_free (drop_target); - nautilus_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list); container->details->dnd_info->drag_info.selection_list = NULL; } @@ -1033,7 +1034,7 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, /* case out on the type of object being dragged */ switch (container->details->dnd_info->drag_info.data_type) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: if (container->details->dnd_info->drag_info.selection_list == NULL) { *default_action = 0; *non_default_action = 0; @@ -1046,14 +1047,14 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, *non_default_action = 0; return; } - nautilus_drag_default_drop_action_for_icons (context, drop_target, + eel_drag_default_drop_action_for_icons (context, drop_target, container->details->dnd_info->drag_info.selection_list, default_action, non_default_action); g_free (drop_target); break; /* handle emblems by setting the action if we're over an object */ - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: if (icon == NULL) { *default_action = 0; *non_default_action = 0; @@ -1065,8 +1066,8 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, break; /* handle colors and backgrounds by setting the action if we're over the background */ - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: if (icon == NULL) { *default_action = context->suggested_action; *non_default_action = context->suggested_action; @@ -1077,8 +1078,8 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, break; - case NAUTILUS_ICON_DND_URI_LIST: - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URI_LIST: + case EEL_ICON_DND_URL: *default_action = context->suggested_action; *non_default_action = context->suggested_action; break; @@ -1118,7 +1119,7 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, g_assert (NAUTILUS_IS_ICON_CONTAINER (container)); if ((container->details->dnd_info->drag_info.selection_list == NULL) - && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD)) { + && (container->details->dnd_info->drag_info.data_type != EEL_ICON_DND_KEYWORD)) { return; } @@ -1136,7 +1137,7 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, /* Find if target icon accepts our drop. */ if (icon != NULL - && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD) + && (container->details->dnd_info->drag_info.data_type != EEL_ICON_DND_KEYWORD) && !nautilus_drag_can_accept_items (nautilus_file_get ( nautilus_icon_container_get_icon_uri (container, icon)), @@ -1193,7 +1194,7 @@ nautilus_icon_dnd_init (NautilusIconContainer *container, container->details->dnd_info = g_new0 (NautilusIconDndInfo, 1); - nautilus_drag_init (&container->details->dnd_info->drag_info, + eel_drag_init (&container->details->dnd_info->drag_info, drag_types, EEL_N_ELEMENTS (drag_types), stipple); /* Set up the widget as a drag destination. @@ -1238,7 +1239,7 @@ nautilus_icon_dnd_fini (NautilusIconContainer *container) gtk_object_destroy (GTK_OBJECT (container->details->dnd_info->shadow)); } - nautilus_drag_finalize (&container->details->dnd_info->drag_info); + eel_drag_finalize (&container->details->dnd_info->drag_info); } void @@ -1317,7 +1318,7 @@ drag_motion_callback (GtkWidget *widget, /* set the right drop action, choose based on modifier key state */ - resulting_action = nautilus_drag_modifier_based_action (default_action, + resulting_action = eel_drag_modifier_based_action (default_action, non_default_action); gdk_drag_status (context, resulting_action, time); diff --git a/libnautilus-extensions/nautilus-icon-dnd.h b/libnautilus-extensions/nautilus-icon-dnd.h index 2e25fca48..5dd83cc44 100644 --- a/libnautilus-extensions/nautilus-icon-dnd.h +++ b/libnautilus-extensions/nautilus-icon-dnd.h @@ -29,14 +29,12 @@ #define NAUTILUS_ICON_DND_H #include "nautilus-icon-container.h" -#include "nautilus-drag.h" - - +#include <eel/eel-dnd.h> /* DnD-related information. */ typedef struct { /* inherited drag info context */ - NautilusDragInfo drag_info; + EelDragInfo drag_info; /* Shadow for the icons being dragged. */ GnomeCanvasItem *shadow; diff --git a/libnautilus-extensions/nautilus-list-column-title.c b/libnautilus-extensions/nautilus-list-column-title.c deleted file mode 100644 index 26fff3a31..000000000 --- a/libnautilus-extensions/nautilus-list-column-title.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - - nautilus-list-column-title.c: List column title widget for interacting with list columns - - Copyright (C) 2000 Eazel, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com> - -*/ - -#include <config.h> -#include "nautilus-list-column-title.h" - -#include <eel/eel-gtk-macros.h> -#include <eel/eel-gdk-extensions.h> - -#include "nautilus-list.h" - -#include <gdk/gdk.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gtk/gtkmain.h> - -#include <libgnomeui/gnome-pixmap.h> - -#include <eel/eel-gdk-pixbuf-extensions.h> - -#include <string.h> - -/* these are from GtkCList, for now we need to copy them here - * eventually the target list should be able to describe the values - */ - -enum { - /* this defines the base grid spacing */ - CELL_SPACING = 1, - - /* added the horizontal space at the beginning and end of a row */ - COLUMN_INSET = 3, - - /* from GtkButton */ - CHILD_SPACING = 1, - - /* the width of the column resize windows */ - DRAG_WIDTH = 6 -}; - -static const char * down_xpm[] = { - "6 5 2 1", - " c None", - ". c #000000", - "......", - " ", - " .... ", - " ", - " .. " -}; - -static const char * up_xpm[] = { - "6 5 2 1", - " c None", - ". c #000000", - " .. ", - " ", - " .... ", - " ", - "......" -}; - -#define COLUMN_TITLE_THEME_STYLE_NAME "menu" - -struct NautilusListColumnTitleDetails -{ - /* gc for blitting sort order pixmaps, lazily allocated */ - GdkGC *copy_area_gc; - - /* sort order indicator pixmaps, lazily allocated */ - GdkPixmap *up_indicator_pixmap; - GdkBitmap *up_indicator_mask; - GdkPixmap *down_indicator_pixmap; - GdkBitmap *down_indicator_mask; - - /* offscreen drawing idle handler id*/ - guint offscreen_drawing_idle; - - int tracking_column_resize; - /* index of the column we are currently tracking or -1 */ - int tracking_column_prelight; - /* index of the column we are currently rolling over or -1 */ - int tracking_column_press; - /* index of the column we are currently pressing or -1 */ - - int last_tracking_x; - /* last horizontal track point so we can only resize when needed */ - gboolean resize_cursor_on; - -}; - -static void nautilus_list_column_title_initialize_class (gpointer klass); -static void nautilus_list_column_title_initialize (gpointer object, gpointer klass); -static void nautilus_list_column_title_paint (GtkWidget *widget, GtkWidget *draw_target, GdkDrawable *target_drawable, GdkRectangle *area); -static void nautilus_list_column_title_draw (GtkWidget *widget, GdkRectangle *box); -static void nautilus_list_column_title_buffered_draw (GtkWidget *widget); -static void nautilus_list_column_title_queue_buffered_draw(GtkWidget *widget); -static gboolean nautilus_list_column_title_expose (GtkWidget *widget, GdkEventExpose *event); -static void nautilus_list_column_title_realize (GtkWidget *widget); -static void nautilus_list_column_title_finalize (GtkObject *object); -static void nautilus_list_column_title_request (GtkWidget *widget, GtkRequisition *requisition); - -static gboolean nautilus_list_column_title_motion (GtkWidget *widget, GdkEventMotion *event); -static gboolean nautilus_list_column_title_leave (GtkWidget *widget, GdkEventCrossing *event); - -static gboolean nautilus_list_column_title_button_press (GtkWidget *widget, GdkEventButton *event); -static gboolean nautilus_list_column_title_button_release (GtkWidget *widget, GdkEventButton *event); - - -EEL_DEFINE_CLASS_BOILERPLATE (NautilusListColumnTitle, nautilus_list_column_title, GTK_TYPE_BIN) -/* generates nautilus_list_column_title_get_type */ - -static void -nautilus_list_column_title_initialize_class (gpointer klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - object_class->finalize = nautilus_list_column_title_finalize; - widget_class->draw = nautilus_list_column_title_draw; - widget_class->expose_event = nautilus_list_column_title_expose; - widget_class->realize = nautilus_list_column_title_realize; - widget_class->size_request = nautilus_list_column_title_request; - widget_class->motion_notify_event = nautilus_list_column_title_motion; - widget_class->leave_notify_event = nautilus_list_column_title_leave; - widget_class->button_press_event = nautilus_list_column_title_button_press; - widget_class->button_release_event = nautilus_list_column_title_button_release; -} - -NautilusListColumnTitle * -nautilus_list_column_title_new (void) -{ - return NAUTILUS_LIST_COLUMN_TITLE - (gtk_widget_new (nautilus_list_column_title_get_type (), NULL)); -} - -static void -nautilus_list_column_title_initialize (gpointer object, gpointer klass) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(object); - column_title->details = g_new0 (NautilusListColumnTitleDetails, 1); - - /* copy_gc, up/down indicators get allocated lazily when needed */ - column_title->details->copy_area_gc = NULL; - column_title->details->up_indicator_pixmap = NULL; - column_title->details->up_indicator_mask = NULL; - column_title->details->down_indicator_pixmap = NULL; - column_title->details->down_indicator_mask = NULL; - - column_title->details->offscreen_drawing_idle = 0; - - column_title->details->resize_cursor_on = FALSE; - column_title->details->tracking_column_resize = -1; - column_title->details->tracking_column_prelight = -1; - column_title->details->tracking_column_press = -1; - column_title->details->last_tracking_x = -1; - - GTK_WIDGET_UNSET_FLAGS (object, GTK_NO_WINDOW); -} - -static void -nautilus_list_column_title_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - int attributes_mask; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - /* ask for expose events */ - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width; - attributes.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width; - attributes.width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2; - attributes.height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_KEY_PRESS_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - /* give ourselves a background window */ - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); -} - -static void -nautilus_list_column_title_finalize (GtkObject *object) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(object); - - if (column_title->details->up_indicator_pixmap != NULL) { - gdk_pixmap_unref (column_title->details->up_indicator_pixmap); - column_title->details->up_indicator_pixmap = NULL; - } - if (column_title->details->up_indicator_mask != NULL) { - gdk_bitmap_unref (column_title->details->up_indicator_mask); - column_title->details->up_indicator_mask = NULL; - } - if (column_title->details->down_indicator_pixmap != NULL) { - gdk_pixmap_unref (column_title->details->down_indicator_pixmap); - column_title->details->down_indicator_pixmap = NULL; - } - if (column_title->details->down_indicator_mask != NULL) { - gdk_bitmap_unref (column_title->details->down_indicator_mask); - column_title->details->down_indicator_mask = NULL; - } - - if (column_title->details->offscreen_drawing_idle != 0) { - gtk_idle_remove (column_title->details->offscreen_drawing_idle); - column_title->details->offscreen_drawing_idle = 0; - } - - if (column_title->details->copy_area_gc != NULL) { - gdk_gc_destroy (column_title->details->copy_area_gc); - } - - g_free (column_title->details); - - EEL_CALL_PARENT (GTK_OBJECT_CLASS, finalize, (object)); -} - -static void -nautilus_list_column_title_request (GtkWidget *widget, GtkRequisition *requisition) -{ - /* size requisition: make sure we have at least a minimal height */ - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (requisition != NULL); - - requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + - widget->style->klass->xthickness) * 2; - requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + - widget->style->klass->ythickness) * 2; - - - if (GTK_BIN (widget)->child && GTK_WIDGET_VISIBLE (GTK_BIN (widget)->child)) { - GtkRequisition child_requisition; - - gtk_widget_size_request (GTK_BIN (widget)->child, &child_requisition); - - requisition->width += child_requisition.width; - requisition->height += child_requisition.height; - - requisition->height = MIN (requisition->height, 10); - } -} - -static const char * -get_column_label_at (GtkWidget *column_title, int index) -{ - NautilusCList *parent_clist; - - parent_clist = NAUTILUS_CLIST (column_title->parent); - - return parent_clist->column[index].title; -} - -static void -get_column_frame_at(GtkWidget *column_title, int index, GdkRectangle *result) -{ - NautilusCList *parent_clist; - parent_clist = NAUTILUS_CLIST (column_title->parent); - - *result = parent_clist->column_title_area; - result->x = parent_clist->column[index].area.x - COLUMN_INSET; - result->y = 0; - result->width = parent_clist->column[index].area.width - + CELL_SPACING + 2 * COLUMN_INSET - 1; -} - -static void -load_up_indicator (const char **xpm_data, - GdkPixmap **indicator_pixmap, GdkBitmap **indicator_mask) -{ - GdkPixbuf *pixbuf; - - /* sanity */ - *indicator_pixmap = NULL; - *indicator_mask = NULL; - - pixbuf = gdk_pixbuf_new_from_xpm_data (xpm_data); - - /* can't load, theoretically, we should always be able to load, - * but we'll be a good coder and catch possible errors */ - if (pixbuf == NULL) { - g_warning ("Cannot load up/down indicator, should never happen"); - return; - } - - gdk_pixbuf_render_pixmap_and_mask (pixbuf, indicator_pixmap, indicator_mask, EEL_STANDARD_ALPHA_THRESHHOLD); - - gdk_pixbuf_unref (pixbuf); -} - -static void -get_sort_indicator (GtkWidget *widget, gboolean ascending, - GdkPixmap **indicator_pixmap, GdkBitmap **indicator_mask) -{ - /* return the sort order pixmap for a given sort direction - * allocate the pixmap first time around - */ - NautilusListColumnTitle *column_title; - - g_return_if_fail (indicator_pixmap != NULL); - g_return_if_fail (indicator_mask != NULL); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - if (ascending) { - if (column_title->details->up_indicator_pixmap == NULL) { - g_assert (column_title->details->up_indicator_mask == NULL); - - load_up_indicator (up_xpm, - &column_title->details->up_indicator_pixmap, - &column_title->details->up_indicator_mask); - } - *indicator_pixmap = column_title->details->up_indicator_pixmap; - *indicator_mask = column_title->details->up_indicator_mask; - } else { - if (column_title->details->down_indicator_pixmap == NULL) { - g_assert (column_title->details->down_indicator_mask == NULL); - - load_up_indicator (down_xpm, - &column_title->details->down_indicator_pixmap, - &column_title->details->down_indicator_mask); - } - *indicator_pixmap = column_title->details->down_indicator_pixmap; - *indicator_mask = column_title->details->down_indicator_mask; - } -} - -/* Add more truncation modes, optimize for performance, move to nautilus-gdk-extensions */ -static char * -truncate_string (const char *string, GdkFont *font, int width, int *final_width) -{ - int current_width; - int ellipsis_width; - int length; - int trimmed_length; - char *result; - - length = strlen (string); - current_width = gdk_text_width (font, string, length); - if (current_width <= width) { - /* trivial case, already fits fine */ - if (final_width != NULL) { - *final_width = current_width; - } - return g_strdup (string); - } - - ellipsis_width = gdk_string_width (font, "..."); - if (ellipsis_width > width) { - /* we can't fit anything */ - if (final_width != NULL) { - *final_width = 0; - } - return g_strdup (""); - } - - width -= ellipsis_width; - - for (trimmed_length = length - 1; trimmed_length >= 0; trimmed_length--) { - current_width = gdk_text_width (font, string, trimmed_length); - if (current_width <= width) - break; - } - result = (char *) g_malloc (trimmed_length + 3 + 1); - strncpy (result, string, trimmed_length); - strcpy (result + trimmed_length, "..."); - - if (final_width != NULL) { - *final_width = current_width + ellipsis_width; - } - - return result; -} - -/* FIXME bugzilla.eazel.com 615: - * Some of these magic numbers could be replaced with some more dynamic values - */ -enum { - CELL_TITLE_INSET = 3, - TITLE_BASELINE_OFFSET = 6, - SORT_ORDER_INDICATOR_WIDTH = 10, - SORT_INDICATOR_X_OFFSET = 6, - SORT_INDICATOR_Y_OFFSET = 3 -}; - -static void -nautilus_list_column_title_paint (GtkWidget *widget, GtkWidget *draw_target, - GdkDrawable *target_drawable, GdkRectangle *area) -{ - NautilusListColumnTitle *column_title; - NautilusCList *parent_clist; - int index; - - g_assert (NAUTILUS_CLIST (widget->parent) != NULL); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - GdkRectangle cell_rectangle; - GdkRectangle cell_redraw_area; - const char *cell_label; - int text_x_offset; - int text_x_available_end; - int sort_indicator_x_offset; - GdkPixmap *sort_indicator_pixmap; - GdkBitmap *sort_indicator_mask; - gboolean right_justified; - - sort_indicator_x_offset = 0; - sort_indicator_pixmap = NULL; - sort_indicator_mask = NULL; - right_justified = (parent_clist->column[index].justification == GTK_JUSTIFY_RIGHT); - - /* pick the ascending/descending sort indicator if needed */ - if (index == parent_clist->sort_column) { - get_sort_indicator (widget, - parent_clist->sort_type == GTK_SORT_ASCENDING, - &sort_indicator_pixmap, - &sort_indicator_mask); - } - - get_column_frame_at (widget, index, &cell_rectangle); - gdk_rectangle_intersect (&cell_rectangle, area, &cell_redraw_area); - - if (cell_redraw_area.width == 0 || cell_redraw_area.height == 0) { - /* no work, go on to the next */ - continue; - } - - cell_label = get_column_label_at (widget, index); - - /* FIXME bugzilla.eazel.com 616: - * add support for center justification - */ - - text_x_offset = cell_rectangle.x + CELL_TITLE_INSET; - text_x_available_end = cell_rectangle.x + cell_rectangle.width - 2 * CELL_TITLE_INSET; - - /* Paint the column tiles as rectangles using "menu" (COLUMN_TITLE_THEME_STYLE_NAME). - * Style buttons as used by GtkCList produce round corners in some themes. - * Eventually we might consider having a separate style for column titles. - */ - gtk_paint_box (widget->style, target_drawable, - column_title->details->tracking_column_prelight == index ? - GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, - column_title->details->tracking_column_press == index - ? GTK_SHADOW_IN : GTK_SHADOW_OUT, - area, draw_target, COLUMN_TITLE_THEME_STYLE_NAME, - cell_rectangle.x, cell_rectangle.y, - cell_rectangle.width, cell_rectangle.height); - - - /* Draw the sort indicator if needed */ - if (sort_indicator_pixmap != NULL) { - int y_offset; - - if (right_justified) { - sort_indicator_x_offset = cell_rectangle.x + SORT_INDICATOR_X_OFFSET; - text_x_offset = sort_indicator_x_offset + CELL_TITLE_INSET - + SORT_ORDER_INDICATOR_WIDTH ; - } else { - sort_indicator_x_offset = cell_rectangle.x + cell_rectangle.width - - SORT_INDICATOR_X_OFFSET - SORT_ORDER_INDICATOR_WIDTH; - text_x_available_end = sort_indicator_x_offset - CELL_TITLE_INSET; - } - y_offset = cell_rectangle.y + cell_rectangle.height / 2 - - SORT_INDICATOR_Y_OFFSET; - - /* allocate the sort indicator copy gc first time around */ - if (column_title->details->copy_area_gc == NULL) { - column_title->details->copy_area_gc = gdk_gc_new (widget->window); - gdk_gc_set_function (column_title->details->copy_area_gc, GDK_COPY); - } - /* move the pixmap clip mask and origin to the right spot in the gc */ - gdk_gc_set_clip_mask (column_title->details->copy_area_gc, - sort_indicator_mask); - gdk_gc_set_clip_origin (column_title->details->copy_area_gc, sort_indicator_x_offset, y_offset); - - - gdk_draw_pixmap (target_drawable, column_title->details->copy_area_gc, - sort_indicator_pixmap, 0, 0, sort_indicator_x_offset, y_offset, - -1, -1); - } - - if (cell_label) { - char *truncated_label; - int truncanted_width; - GdkRectangle temporary; - - /* Extend the redraw area vertically to contain the entire cell - * -- seems like if I don't do this, for short exposed areas no text - * will get drawn. - * This happens when the title is half off-screen and you move it up by a pixel or two. - * If you move it up faster, it gets redrawn properly. - */ - cell_redraw_area.y = cell_rectangle.y; - cell_redraw_area.height = cell_rectangle.height; - - /* Clip a little more than the cell rectangle to - * not have the text draw over the cell broder. - */ - temporary = cell_rectangle; - /* Eeeek: magic numbers */ - eel_rectangle_inset (&temporary, 2, 2); - gdk_rectangle_intersect (&cell_redraw_area, &temporary, &cell_redraw_area); - - truncated_label = truncate_string (cell_label, widget->style->font, - text_x_available_end - text_x_offset, &truncanted_width); - - if (right_justified) { - text_x_offset = text_x_available_end - truncanted_width; - } - - gtk_paint_string (widget->style, target_drawable, GTK_STATE_NORMAL, - &cell_redraw_area, draw_target, "label", - text_x_offset, - cell_rectangle.y + cell_rectangle.height - TITLE_BASELINE_OFFSET, - truncated_label); - g_free (truncated_label); - } - } -} - -static void -nautilus_list_column_title_draw (GtkWidget *widget, GdkRectangle *area) -{ - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (area != NULL); - - if (!GTK_WIDGET_DRAWABLE (widget)) { - return; - } - - nautilus_list_column_title_paint (widget, widget, widget->window, area); -} - -static void -nautilus_list_column_title_buffered_draw (GtkWidget *widget) -{ - /* draw using an offscreen_pixmap */ - GdkRectangle redraw_area; - NautilusListColumnTitle *column_title; - GdkPixmap *offscreen_pixmap; - GdkGC *offscreen_blitting_gc; - - /* don't do anything if not drawable */ - if ( ! GTK_WIDGET_DRAWABLE (widget)) { - return; - } - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - redraw_area.x = 0; - redraw_area.y = 0; - redraw_area.width = widget->allocation.width; - redraw_area.height = widget->allocation.height; - - /* allocate a new offscreen_pixmap */ - offscreen_pixmap = gdk_pixmap_new (widget->window, - redraw_area.width, - redraw_area.height, -1); - - /* Erase the offscreen background. - * We are using the GtkStyle call to draw the background - this is a tiny bit - * less efficient but gives us the convenience of setting up the right colors and - * gc for the style we are using to blit the column titles. - */ - gtk_paint_box (widget->style, offscreen_pixmap, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - &redraw_area, widget, - COLUMN_TITLE_THEME_STYLE_NAME, - redraw_area.x, redraw_area.y, - redraw_area.width, redraw_area.height); - - /* render the column titles into the offscreen */ - nautilus_list_column_title_paint (widget, widget, - offscreen_pixmap, &redraw_area); - - /* allocate a gc to blit the offscreen */ - offscreen_blitting_gc = gdk_gc_new (widget->window); - - /* blit the offscreen into the real view */ - gdk_draw_pixmap (widget->window, offscreen_blitting_gc, - offscreen_pixmap, 0, 0, 0, 0, -1, -1); - - gdk_pixmap_unref (offscreen_pixmap); - gdk_gc_destroy (offscreen_blitting_gc); -} - -/* Do all buffered drawing in an idle, this means it's only done after all - * events have been processed and thus we don't do it unneccessairly */ -static gboolean -offscreen_drawing_idle_handler (gpointer data) -{ - GtkWidget *widget; - NautilusListColumnTitle *column_title; - - g_assert (GTK_IS_WIDGET (data)); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (data)); - - widget = GTK_WIDGET (data); - column_title = NAUTILUS_LIST_COLUMN_TITLE (data); - - nautilus_list_column_title_buffered_draw (widget); - - column_title->details->offscreen_drawing_idle = 0; - - return FALSE; -} - -/* queue a buffered_draw to be called later after all other events - * are processed. Increasing performance and reducing memory load. */ -static void -nautilus_list_column_title_queue_buffered_draw (GtkWidget *widget) -{ - NautilusListColumnTitle *column_title; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE (widget); - - if (column_title->details->offscreen_drawing_idle == 0) { - column_title->details->offscreen_drawing_idle = - gtk_idle_add (offscreen_drawing_idle_handler, widget); - } -} - -static gboolean -nautilus_list_column_title_expose (GtkWidget *widget, GdkEventExpose *event) -{ - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (event != NULL); - - if (!GTK_WIDGET_DRAWABLE (widget)) { - return FALSE; - } - - nautilus_list_column_title_paint (widget, widget, widget->window, &event->area); - - return FALSE; -} - -static int -in_column_rect (GtkWidget *widget, int x, int y) -{ - /* return the index of the column we hit or -1 */ - - NautilusCList *parent_clist; - int index; - - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - /* hit testing for column resizing */ - GdkRectangle cell_rectangle; - - get_column_frame_at (widget, index, &cell_rectangle); - - /* inset by a pixel so that you have to move past the border - * to be considered inside the rect - * nautilus_list_column_title_leave depends on this - */ - eel_rectangle_inset (&cell_rectangle, 1, 0); - - - if (eel_rectangle_contains (&cell_rectangle, x, y)) - return index; - } - - return -1; -} - -static int -in_resize_rect (GtkWidget *widget, int x, int y) -{ - /* return the index of the resize rect of a column we hit or -1 */ - - NautilusCList *parent_clist; - int index; - - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - /* hit testing for column resizing */ - GdkRectangle resize_rectangle; - - get_column_frame_at (widget, index, &resize_rectangle); - - eel_rectangle_inset (&resize_rectangle, 1, 0); - - resize_rectangle.x = resize_rectangle.x + resize_rectangle.width - DRAG_WIDTH / 2; - resize_rectangle.width = DRAG_WIDTH; - - if (eel_rectangle_contains (&resize_rectangle, x, y)) - return index; - } - - return -1; -} - -static void -show_hide_resize_cursor_if_needed (GtkWidget *widget, gboolean on) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - if (on == column_title->details->resize_cursor_on) - /* already set right */ - return; - - if (on) { - /* switch to a resize cursor */ - GdkCursor *cursor; - - cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_destroy (cursor); - } else - /* restore to old cursor */ - gdk_window_set_cursor (widget->window, NULL); - - column_title->details->resize_cursor_on = on; -} - -static gboolean -track_prelight (GtkWidget *widget, int mouse_x, int mouse_y) -{ - NautilusListColumnTitle *column_title; - int over_column; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - /* see if we need to update the prelight state of a column */ - over_column = in_column_rect (widget, mouse_x, mouse_y); - - if (column_title->details->tracking_column_resize != -1) { - /* resizing a column, don't prelight */ - over_column = -1; - } - - if (column_title->details->tracking_column_press != -1) { - /* pressing a column, don't prelight */ - over_column = -1; - } - - if (column_title->details->tracking_column_prelight == over_column) { - /* no change */ - return FALSE; - } - - /* update state and tell callers to redraw */ - column_title->details->tracking_column_prelight = over_column; - - return TRUE; -} - -static gboolean -nautilus_list_column_title_motion (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - int mouse_x, mouse_y; - gboolean title_update_needed; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - title_update_needed = FALSE; - - gdk_window_get_pointer (widget->window, &mouse_x, &mouse_y, NULL); - - if (column_title->details->tracking_column_resize != -1) { - /* we are currently tracking a column */ - if (column_title->details->last_tracking_x != mouse_x) { - /* mouse did move horizontally since last time */ - column_title->details->last_tracking_x = mouse_x; - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track, - (parent_list, column_title->details->tracking_column_resize)); - title_update_needed = TRUE; - } - } else { - /* make sure we are showing the right cursor */ - show_hide_resize_cursor_if_needed (widget, - in_resize_rect (widget, mouse_x, mouse_y) != -1); - } - - /* see if we need to update the prelight state of a column */ - title_update_needed |= track_prelight (widget, mouse_x, mouse_y); - - if (title_update_needed) { - nautilus_list_column_title_queue_buffered_draw (widget); - } - - return TRUE; -} - -static gboolean -nautilus_list_column_title_leave (GtkWidget *widget, GdkEventCrossing *event) -{ - NautilusListColumnTitle *column_title; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - /* see if we need to update the prelight state of a column */ - if (column_title->details->tracking_column_prelight != -1) { - column_title->details->tracking_column_prelight = -1; - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - } - nautilus_list_column_title_queue_buffered_draw (widget); - return TRUE; -} - -static gboolean -nautilus_list_column_title_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - int grab_result; - - g_assert (event != NULL); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - g_assert (event->type != GDK_BUTTON_PRESS - || NAUTILUS_LIST_COLUMN_TITLE(widget)->details->tracking_column_resize == -1); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - - - if (event->type == GDK_BUTTON_PRESS) { - int resized_column; - int clicked_column; - - resized_column = in_resize_rect (widget, (int)event->x, (int)event->y); - clicked_column = in_column_rect (widget, (int)event->x, (int)event->y); - - if (resized_column != -1) { - GdkCursor *cursor; - - /* during the drag, use the resize cursor */ - cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - - /* grab the pointer events so that we get them even when - * the mouse tracks out of the widget window - */ - grab_result = gdk_pointer_grab (widget->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON1_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - NULL, cursor, event->time); - gdk_cursor_destroy (cursor); - - if (grab_result != 0) { - /* failed to grab the pointer, give up - * - * The grab results are not very well documented - * looks like they may be Success, GrabSuccess, AlreadyGrabbed - * or anything else the low level X calls in gdk_pointer_grab - * decide to return. - */ - return FALSE; - } - - /* set up new state */ - column_title->details->tracking_column_resize = resized_column; - column_title->details->tracking_column_prelight = -1; - - /* FIXME bugzilla.eazel.com 617: - * use a "resized" state here ? - */ - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - - /* start column resize tracking */ - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track_start, - (parent_list, resized_column)); - - return FALSE; - } - - if (clicked_column != -1) { - /* clicked a column, draw the pressed column title */ - column_title->details->tracking_column_prelight = -1; - column_title->details->tracking_column_press = clicked_column; - gtk_widget_set_state (widget, GTK_STATE_ACTIVE); - - /* grab the pointer events so that we get release events even when - * the mouse tracks out of the widget window - */ - grab_result = gdk_pointer_grab (widget->window, FALSE, - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time); - - if (grab_result != 0) { - /* failed to grab the pointer, give up */ - return FALSE; - } - - nautilus_list_column_title_queue_buffered_draw (widget); - } - - } - - return FALSE; -} - -static gboolean -nautilus_list_column_title_button_release (GtkWidget *widget, GdkEventButton *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - - g_assert (event != NULL); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - - /* let go of all the pointer events */ - if ((column_title->details->tracking_column_resize != -1 - || column_title->details->tracking_column_press != -1) - && gdk_pointer_is_grabbed ()) - gdk_pointer_ungrab (event->time); - - if (column_title->details->tracking_column_resize != -1) { - - /* end column resize tracking */ - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track_end, - (parent_list, column_title->details->tracking_column_resize)); - column_title->details->tracking_column_resize = -1; - - } else if (column_title->details->tracking_column_press != -1) { - - /* column title press -- change the sort order */ - gtk_signal_emit_by_name (GTK_OBJECT (parent_list), "click_column", - column_title->details->tracking_column_press); - /* end press tracking */ - column_title->details->tracking_column_press = -1; - } - - track_prelight (widget, (int)event->x, (int)event->y); - gtk_widget_set_state (widget, - column_title->details->tracking_column_prelight != -1 ? - GTK_STATE_PRELIGHT : GTK_STATE_NORMAL); - - nautilus_list_column_title_queue_buffered_draw (widget); - - return FALSE; -} diff --git a/libnautilus-extensions/nautilus-list-column-title.h b/libnautilus-extensions/nautilus-list-column-title.h deleted file mode 100644 index 5c069800b..000000000 --- a/libnautilus-extensions/nautilus-list-column-title.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - - nautilus-list-column-title.h: List column title widget for interacting with list columns - - Copyright (C) 2000 Eazel, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com> - -*/ - -#ifndef __NAUTILUS_LIST_COLUMN_TITLE__ -#define __NAUTILUS_LIST_COLUMN_TITLE__ - -#include <gdk/gdktypes.h> -#include <gtk/gtkwidget.h> -#include <gtk/gtkbin.h> -#include <gtk/gtkenums.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define NAUTILUS_TYPE_LIST_COLUMN_TITLE \ - (nautilus_list_column_title_get_type ()) -#define NAUTILUS_LIST_COLUMN_TITLE(obj) \ - (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_LIST_COLUMN_TITLE, NautilusListColumnTitle)) -#define NAUTILUS_LIST_COLUMN_TITLE_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_LIST_COLUMN_TITLE, NautilusListColumnTitleClass)) -#define NAUTILUS_IS_LIST_COLUMN_TITLE(obj) \ - (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_LIST_COLUMN_TITLE)) -#define NAUTILUS_IS_LIST_COLUMN_TITLE_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_LIST_COLUMN_TITLE)) - -typedef struct NautilusListColumnTitle NautilusListColumnTitle; -typedef struct NautilusListColumnTitleClass NautilusListColumnTitleClass; -typedef struct NautilusListColumnTitleDetails NautilusListColumnTitleDetails; - - -struct NautilusListColumnTitle -{ - GtkBin bin; - NautilusListColumnTitleDetails *details; -}; - -struct NautilusListColumnTitleClass -{ - GtkBinClass parent_class; -}; - -GtkType nautilus_list_column_title_get_type (void); -NautilusListColumnTitle *nautilus_list_column_title_new (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __NAUTILUS_LIST_COLUMN_TITLE__ */ diff --git a/libnautilus-extensions/nautilus-list.c b/libnautilus-extensions/nautilus-list.c deleted file mode 100644 index abb14a5ee..000000000 --- a/libnautilus-extensions/nautilus-list.c +++ /dev/null @@ -1,3732 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-list.c: Enhanced version of GtkCList for Nautilus. - - Copyright (C) 1999, 2000 Free Software Foundation - Copyright (C) 2000, 2001 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Federico Mena <federico@nuclecu.unam.mx>, - Ettore Perazzoli <ettore@gnu.org>, - John Sullivan <sullivan@eazel.com>, - Pavel Cisler <pavel@eazel.com> - */ - -#include <config.h> -#include "nautilus-list.h" - -#include <ctype.h> -#include <string.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdk.h> -#include <gtk/gtkbindings.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkenums.h> -#include <gtk/gtkmain.h> -#include <glib.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-background.h> -#include <eel/eel-graphic-effects.h> -#include <libnautilus-extensions/nautilus-drag.h> -#include <eel/eel-gdk-extensions.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-glib-extensions.h> -#include <eel/eel-gtk-extensions.h> -#include <eel/eel-gtk-macros.h> -#include <libnautilus-extensions/nautilus-list-column-title.h> - -/* Timeout for making the row currently selected for keyboard operation visible. - * Unlike in nautilus-icon-container, there appear to be no adverse effects from - * making this 0. - */ -#define KEYBOARD_ROW_REVEAL_TIMEOUT 0 - -/* FIXME bugzilla.eazel.com 2573: This constant and much of the code surrounding its use was copied from - * nautilus-icon-container; they should share code instead. - */ -#define CONTEXT_MENU_TIMEOUT_INTERVAL 500 - -#define NO_BUTTON 0 -#define ACTION_BUTTON 1 -#define CONTEXTUAL_MENU_BUTTON 3 - -#define CLIST_UNFROZEN(clist) nautilus_clist_check_unfrozen (clist) - -struct NautilusListDetails -{ - /* Single click mode ? */ - gboolean single_click_mode; - - /* Anti-aliased mode ? */ - gboolean anti_aliased_mode; - - /* The anchor row for range selections */ - int anchor_row; - - /* Mouse information saved on button press */ - int dnd_press_button; - int dnd_press_x, dnd_press_y; - int button_down_row; - guint32 button_down_time; - - /* Timeout used to make a selected row fully visible after a short - * period of time. (The timeout is needed to make sure - * double-clicking still works, and to optimize holding down arrow key.) - */ - guint keyboard_row_reveal_timer_id; - int keyboard_row_to_reveal; - - /* Typeahead state */ - char *type_select_pattern; - gint64 last_typeselect_time; - - /* Signal IDs that we sometimes want to block. */ - guint select_row_signal_id; - guint unselect_row_signal_id; - - /* Drag state */ - NautilusDragInfo *drag_info; - gboolean drag_started; - gboolean rejects_dropped_icons; - - guint context_menu_timeout_id; - - /* Delayed selection information */ - gboolean dnd_select_pending; - guint dnd_select_pending_state; - - /* Targets for drag data */ - GtkTargetList *target_list; - - NautilusCListRow *drag_prelight_row; - - GtkWidget *title; - - /* Rendering state */ - GdkGC *cell_lighter_background; - GdkGC *cell_darker_background; - GdkGC *cell_selected_lighter_background; - GdkGC *cell_selected_darker_background; - GdkGC *cell_divider_color; - GdkGC *selection_light_color; - GdkGC *selection_medium_color; - GdkGC *selection_main_color; - GdkGC *text_color; - GdkGC *selected_text_color; - GdkGC *link_text_color; - - /* Need RGB background values when compositing images */ - guint32 cell_lighter_background_rgb; - guint32 cell_darker_background_rgb; - guint32 cell_selected_lighter_background_rgb; - guint32 cell_selected_darker_background_rgb; - guint32 selection_light_color_rgb; - guint32 selection_medium_color_rgb; - guint32 selection_main_color_rgb; - - gboolean alternate_row_colors; - gulong background_color_offset, selection_color_offset; -}; - -/* maximum amount of milliseconds the mouse button is allowed to stay down and still be considered a click */ -#define MAX_CLICK_TIME 1500 - -/* horizontal space between images in a pixbuf list cell */ -#define PIXBUF_LIST_SPACING 2 - -/* Some #defines stolen from gtkclist.c that we need for other stolen code. */ - -/* minimum allowed width of a column */ -#define COLUMN_MIN_WIDTH 5 - -/* this defines the base grid spacing */ -#define CELL_SPACING 1 - -/* added the horizontal space at the beginning and end of a row */ -#define COLUMN_INSET 3 - -/* the width of the column resize windows */ -#define DRAG_WIDTH 6 - -/* gives the left pixel of the given column in context of - * the clist's hoffset */ -#define COLUMN_LEFT_XPIXEL(clist, colnum) ((clist)->column[(colnum)].area.x + \ - (clist)->hoffset) - -/* gives the top pixel of the given row in context of - * the clist's voffset */ -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) - -/* returns the row index from a y pixel location in the - * context of the clist's voffset */ -#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ - ((clist)->row_height + CELL_SPACING)) - -/* returns the GList item for the nth row */ -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -/* returns the total height of the list */ -#define LIST_HEIGHT(clist) (((clist)->row_height * ((clist)->rows)) + \ - (CELL_SPACING * ((clist)->rows + 1))) - -enum { - CONTEXT_CLICK_SELECTION, - CONTEXT_CLICK_BACKGROUND, - ACTIVATE, - SELECTION_CHANGED, - SELECT_MATCHING_NAME, - SELECT_PREVIOUS_NAME, - SELECT_NEXT_NAME, - HANDLE_DROPPED_ITEMS, - HANDLE_DRAGGED_ITEMS, - GET_DEFAULT_ACTION, - GET_DRAG_PIXBUF, - GET_SORT_COLUMN_INDEX, - LAST_SIGNAL -}; - -static GtkTargetEntry nautilus_list_dnd_target_table[] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }, - { NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }, - { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD } -}; - -static GtkTargetList *nautilus_list_dnd_target_list = NULL; - -static void activate_row (NautilusList *list, - int row); -static int get_cell_horizontal_start_position (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - int content_width); -static void nautilus_list_initialize_class (NautilusListClass *class); -static void nautilus_list_initialize (NautilusList *list); -static void nautilus_list_destroy (GtkObject *object); -static int nautilus_list_button_press (GtkWidget *widget, - GdkEventButton *event); -static int nautilus_list_button_release (GtkWidget *widget, - GdkEventButton *event); -static int nautilus_list_motion (GtkWidget *widget, - GdkEventMotion *event); -static void nautilus_list_drag_end (GtkWidget *widget, - GdkDragContext *context); -static void nautilus_list_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean nautilus_list_drag_motion (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time); -static gboolean nautilus_list_drag_drop (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time); -static void nautilus_list_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - GtkSelectionData *data, - guint info, - guint time); -static void nautilus_list_clear_keyboard_focus (NautilusList *list); -static void nautilus_list_draw_focus (GtkWidget *widget); -static int nautilus_list_key_press (GtkWidget *widget, - GdkEventKey *event); -static void nautilus_list_unselect_all (NautilusCList *clist); -static void nautilus_list_select_all (NautilusCList *clist); -static void schedule_keyboard_row_reveal (NautilusList *list, - int row); -static void unschedule_keyboard_row_reveal (NautilusList *list); -static void emit_selection_changed (NautilusList *clist); -static void nautilus_list_clear (NautilusCList *clist); -static void nautilus_list_draw (GtkWidget *widget, - GdkRectangle *area); -static int nautilus_list_expose (GtkWidget *widget, - GdkEventExpose *event); -static void draw_rows (NautilusCList *clist, - GdkRectangle *area); -static void draw_row (NautilusCList *list, - GdkRectangle *area, - int row_index, - NautilusCListRow *row); -static void draw_all (NautilusCList *clist); -static void nautilus_list_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void nautilus_list_realize (GtkWidget *widget); -static void nautilus_list_unrealize (GtkWidget *widget); -static gboolean nautilus_list_set_cell_contents (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -static void nautilus_list_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void nautilus_list_resize_column (NautilusCList *widget, - int column_index, - int width); -static void nautilus_list_column_resize_track_start (GtkWidget *widget, - int column_index); -static void nautilus_list_column_resize_track (GtkWidget *widget, - int column_index); -static void nautilus_list_column_resize_track_end (GtkWidget *widget, - int column_index); -static gboolean row_set_selected (NautilusList *list, - int row_index, - NautilusCListRow *row, - gboolean select); -static gboolean select_row_unselect_others (NautilusList *list, - int row_to_select); -static void nautilus_list_flush_typeselect_state (NautilusList *container); -static int insert_row (NautilusCList *list, - int row, - char *text[]); -static void nautilus_list_ensure_drag_data (NautilusList *list, - GdkDragContext *context, - guint32 time); -static void nautilus_list_start_auto_scroll (NautilusList *list); -static void nautilus_list_stop_auto_scroll (NautilusList *list); - -static void unref_gcs (NautilusList *list); - - -EEL_DEFINE_CLASS_BOILERPLATE (NautilusList, nautilus_list, NAUTILUS_TYPE_CLIST) - -static guint list_signals[LAST_SIGNAL]; - -static GtkTargetEntry drag_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL } -}; - - -/* Standard class initialization function */ -static void -nautilus_list_initialize_class (NautilusListClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - NautilusCListClass *clist_class; - NautilusListClass *list_class; - - GtkBindingSet *clist_binding_set; - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - clist_class = (NautilusCListClass *) klass; - list_class = (NautilusListClass *) klass; - - list_signals[CONTEXT_CLICK_SELECTION] = - gtk_signal_new ("context_click_selection", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, context_click_selection), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[CONTEXT_CLICK_BACKGROUND] = - gtk_signal_new ("context_click_background", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, context_click_background), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[ACTIVATE] = - gtk_signal_new ("activate", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, activate), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[SELECT_MATCHING_NAME] = - gtk_signal_new ("select_matching_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_matching_name), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING, 0); - list_signals[SELECT_PREVIOUS_NAME] = - gtk_signal_new ("select_previous_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_previous_name), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[SELECT_NEXT_NAME] = - gtk_signal_new ("select_next_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_next_name), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[HANDLE_DRAGGED_ITEMS] = - gtk_signal_new ("handle_dragged_items", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, handle_dragged_items), - eel_gtk_marshal_BOOL__INT_POINTER_INT_INT_UINT, - GTK_TYPE_BOOL, - 5, - GTK_TYPE_INT, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[HANDLE_DROPPED_ITEMS] = - gtk_signal_new ("handle_dropped_items", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, handle_dropped_items), - eel_gtk_marshal_NONE__INT_POINTER_INT_INT_UINT, - GTK_TYPE_NONE, 5, - GTK_TYPE_INT, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[GET_DEFAULT_ACTION] = - gtk_signal_new ("get_default_action", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_default_action), - eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_INT_INT_UINT, - GTK_TYPE_NONE, 7, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[GET_DRAG_PIXBUF] = - gtk_signal_new ("get_drag_pixbuf", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_drag_pixbuf), - eel_gtk_marshal_POINTER__INT, - GTK_TYPE_POINTER, 1, - GTK_TYPE_INT); - list_signals[GET_SORT_COLUMN_INDEX] = - gtk_signal_new ("get_sort_column_index", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_sort_column_index), - eel_gtk_marshal_INT__NONE, - GTK_TYPE_INT, 0); - - gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL); - - /* Turn off the GtkCList key bindings that we want unbound. - * We only need to do this for the keys that we don't handle - * in nautilus_list_key_press. These extra ones are turned off - * to avoid inappropriate GtkCList code and to standardize the - * keyboard behavior in Nautilus. - */ - clist_binding_set = gtk_binding_set_by_class (clist_class); - - /* Use Control-A for Select All, not Control-/ */ - gtk_binding_entry_clear (clist_binding_set, - '/', - GDK_CONTROL_MASK); - /* Don't use Control-\ for Unselect All (maybe invent Nautilus - * standard for this?) */ - gtk_binding_entry_clear (clist_binding_set, - '\\', - GDK_CONTROL_MASK); - /* Hide GtkCList's weird extend-selection-from-keyboard stuff. - * Users can use control-navigation and control-space to create - * extended selections. - */ - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | GDK_CONTROL_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | GDK_CONTROL_MASK); - - list_class->column_resize_track_start = nautilus_list_column_resize_track_start; - list_class->column_resize_track = nautilus_list_column_resize_track; - list_class->column_resize_track_end = nautilus_list_column_resize_track_end; - - clist_class->clear = nautilus_list_clear; - clist_class->draw_row = draw_row; - clist_class->draw_rows = draw_rows; - clist_class->draw_all = draw_all; - clist_class->insert_row = insert_row; - clist_class->resize_column = nautilus_list_resize_column; - clist_class->set_cell_contents = nautilus_list_set_cell_contents; - clist_class->select_all = nautilus_list_select_all; - clist_class->unselect_all = nautilus_list_unselect_all; - - widget_class->button_press_event = nautilus_list_button_press; - widget_class->button_release_event = nautilus_list_button_release; - widget_class->motion_notify_event = nautilus_list_motion; - - widget_class->draw = nautilus_list_draw; - widget_class->expose_event = nautilus_list_expose; - widget_class->draw_focus = nautilus_list_draw_focus; - widget_class->key_press_event = nautilus_list_key_press; - widget_class->style_set = nautilus_list_style_set; - widget_class->realize = nautilus_list_realize; - widget_class->unrealize = nautilus_list_unrealize; - widget_class->size_request = nautilus_list_size_request; - - object_class->destroy = nautilus_list_destroy; -} - -static gboolean -event_state_modifies_selection (guint event_state) -{ - return (event_state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0; -} - -void -nautilus_list_set_single_click_mode (NautilusList *list, - gboolean single_click_mode) -{ - list->details->single_click_mode = single_click_mode; - gtk_widget_queue_draw (GTK_WIDGET (list)); -} - -void -nautilus_list_set_anti_aliased_mode (NautilusList *list, - gboolean anti_aliased_mode) -{ - list->details->anti_aliased_mode = anti_aliased_mode; - gtk_widget_queue_draw (GTK_WIDGET (list)); -} - -gboolean -nautilus_list_is_anti_aliased (NautilusList *list) -{ - return list->details->anti_aliased_mode; -} - - -void -nautilus_list_initialize_dnd (NautilusList *list) -{ - g_assert (list->details->drag_info == NULL); - g_assert (!GTK_WIDGET_REALIZED (list)); - - list->details->drag_info = g_new0 (NautilusDragInfo, 1); - - nautilus_drag_init (list->details->drag_info, drag_types, - EEL_N_ELEMENTS (drag_types), NULL); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_end", - GTK_SIGNAL_FUNC (nautilus_list_drag_end), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_leave", - GTK_SIGNAL_FUNC (nautilus_list_drag_leave), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_motion", - GTK_SIGNAL_FUNC (nautilus_list_drag_motion), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_drop", - GTK_SIGNAL_FUNC (nautilus_list_drag_drop), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_data_received", - GTK_SIGNAL_FUNC (nautilus_list_drag_data_received), - list); - - - /* Get ready to accept some dragged stuff. */ - gtk_drag_dest_set (GTK_WIDGET (list), - 0, - nautilus_list_dnd_target_table, - EEL_N_ELEMENTS (nautilus_list_dnd_target_table), - GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK - | GDK_ACTION_ASK); - -} - -/* Standard object initialization function */ -static void -nautilus_list_initialize (NautilusList *list) -{ - list->details = g_new0 (NautilusListDetails, 1); - list->details->anchor_row = -1; - - list->details->drag_prelight_row = NULL; - - list->details->alternate_row_colors = TRUE; - list->details->background_color_offset = G_STRUCT_OFFSET (GtkStyle, bg[GTK_STATE_NORMAL]); - list->details->selection_color_offset = G_STRUCT_OFFSET (GtkStyle, bg[GTK_STATE_SELECTED]); - - /* GtkCList does not specify pointer motion by default */ - gtk_widget_add_events (GTK_WIDGET (list), GDK_POINTER_MOTION_MASK); - - /* Emit "selection changed" signal when parent class changes selection */ - list->details->select_row_signal_id = gtk_signal_connect (GTK_OBJECT (list), - "select_row", - emit_selection_changed, - list); - list->details->unselect_row_signal_id = gtk_signal_connect (GTK_OBJECT (list), - "unselect_row", - emit_selection_changed, - list); - - gtk_widget_push_composite_child (); - list->details->title = GTK_WIDGET (nautilus_list_column_title_new()); - gtk_widget_pop_composite_child (); - - list->details->type_select_pattern = NULL; - list->details->last_typeselect_time = G_GINT64_CONSTANT(0); -} - -static void -nautilus_list_destroy (GtkObject *object) -{ - NautilusList *list; - - list = NAUTILUS_LIST (object); - - if (list->details->drag_info != NULL) { - nautilus_drag_finalize (list->details->drag_info); - } - - unschedule_keyboard_row_reveal (list); - - EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); - - unref_gcs (list); - - g_free (list->details->type_select_pattern); - - /* Must do this after calling the parent, because GtkCList calls - * the clear method, which must have a valid details pointer. - */ - g_free (list->details); -} - -static void -emit_selection_changed (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); -} - -static void -activate_row_data_list (NautilusList *list, GList *activate_list) -{ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[ACTIVATE], - activate_list); -} - -static void -activate_selected_rows (NautilusList *list) -{ - GList *selection; - - selection = nautilus_list_get_selection (list); - activate_row_data_list (list, selection); - g_list_free (selection); -} - -static void -activate_row (NautilusList *list, int row) -{ - GList *singleton_list; - - singleton_list = NULL; - singleton_list = g_list_append (NULL, nautilus_clist_get_row_data (NAUTILUS_CLIST (list), row)); - activate_row_data_list (list, singleton_list); - g_list_free (singleton_list); -} - -gboolean -nautilus_list_is_row_selected (NautilusList *list, int row) -{ - NautilusCListRow *elem; - - g_return_val_if_fail (row >= 0, FALSE); - g_return_val_if_fail (row < NAUTILUS_CLIST (list)->rows, FALSE); - - elem = g_list_nth (NAUTILUS_CLIST (list)->row_list, row)->data; - - return elem->state == GTK_STATE_SELECTED; -} - -/* Selects the rows between the anchor to the specified row, inclusive. - * Returns TRUE if selection changed. */ -static gboolean -select_range (NautilusList *list, int row) -{ - int min, max; - int i; - gboolean selection_changed; - - selection_changed = FALSE; - - if (list->details->anchor_row == -1) { - list->details->anchor_row = row; - } - - if (row < list->details->anchor_row) { - min = row; - max = list->details->anchor_row; - } else { - min = list->details->anchor_row; - max = row; - } - - for (i = min; i <= max; i++) { - selection_changed |= row_set_selected (list, i, NULL, TRUE); - } - - return selection_changed; -} - -/* Handles row selection according to the specified modifier state */ -static void -select_row_from_mouse (NautilusList *list, int row, guint state) -{ - int range, additive; - gboolean should_select_row; - gboolean selection_changed; - - selection_changed = FALSE; - - range = (state & GDK_SHIFT_MASK) != 0; - additive = (state & GDK_CONTROL_MASK) != 0; - - nautilus_list_clear_keyboard_focus (list); - - if (!additive) { - selection_changed |= select_row_unselect_others (list, -1); - } - - if (range) { - selection_changed |= select_range (list, row); - } else { - should_select_row = !additive || !nautilus_list_is_row_selected (list, row); - selection_changed |= row_set_selected (list, row, NULL, should_select_row); - list->details->anchor_row = row; - } - - if (selection_changed) { - emit_selection_changed (list); - } -} - -/* - * row_set_selected: - * - * Select or unselect a row. Return TRUE if selection has changed. - * Does not emit the SELECTION_CHANGED signal; it's up to the caller - * to handle that. - * - * @list: The NautilusList in question. - * @row: index of row number to select or unselect. - * @row: NautilusCListRow pointer for given list. Passing this avoids - * expensive lookup. If it's NULL, it will be looked up in this function. - * @select: TRUE if row should be selected, FALSE otherwise. - * - * Return Value: TRUE if selection has changed, FALSE otherwise. - */ -static gboolean -row_set_selected (NautilusList *list, int row_index, NautilusCListRow *row, gboolean select) -{ - g_assert (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows); - - if (row == NULL) { - row = ROW_ELEMENT (NAUTILUS_CLIST (list), row_index)->data; - } - - if (select == (row->state == GTK_STATE_SELECTED)) { - return FALSE; - } - - /* Block signal handlers so we can make sure the selection-changed - * signal gets sent only once. - */ - gtk_signal_handler_block (GTK_OBJECT(list), - list->details->select_row_signal_id); - gtk_signal_handler_block (GTK_OBJECT(list), - list->details->unselect_row_signal_id); - - if (select) { - nautilus_clist_select_row (NAUTILUS_CLIST (list), row_index, -1); - } else { - nautilus_clist_unselect_row (NAUTILUS_CLIST (list), row_index, -1); - } - - gtk_signal_handler_unblock (GTK_OBJECT(list), - list->details->select_row_signal_id); - gtk_signal_handler_unblock (GTK_OBJECT(list), - list->details->unselect_row_signal_id); - - return TRUE; -} - -/** - * select_row_unselect_others: - * - * Change the selected rows as necessary such that only - * the given row remains selected. - * - * @list: The NautilusList in question. - * @row_to_select: The row number to leave selected. Use -1 to leave - * no row selected. - * - * Return value: TRUE if the selection changed; FALSE otherwise. - */ -static gboolean -select_row_unselect_others (NautilusList *list, int row_to_select) -{ - GList *p; - int row_index; - gboolean selection_changed; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), FALSE); - - selection_changed = FALSE; - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; p != NULL; p = p->next, ++row_index) { - selection_changed |= row_set_selected (list, row_index, p->data, row_index == row_to_select); - } - - return selection_changed; -} - -static void -nautilus_list_unselect_all (NautilusCList *clist) -{ - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - if (select_row_unselect_others (NAUTILUS_LIST (clist), -1)) { - emit_selection_changed (NAUTILUS_LIST (clist)); - } -} - -static void -nautilus_list_select_all (NautilusCList *clist) -{ - GList *p; - int row_index; - gboolean selection_changed; - - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - selection_changed = FALSE; - for (p = clist->row_list, row_index = 0; p != NULL; p = p->next, ++row_index) { - selection_changed |= row_set_selected (NAUTILUS_LIST (clist), row_index, p->data, TRUE); - } - - if (selection_changed) { - emit_selection_changed (NAUTILUS_LIST (clist)); - } -} - -typedef struct { - NautilusList *list; - GdkEventButton *event; -} ContextMenuParameters; - -static ContextMenuParameters * -context_menu_parameters_new (NautilusList *list, - GdkEventButton *event) -{ - ContextMenuParameters *parameters; - - parameters = g_new (ContextMenuParameters, 1); - parameters->list = list; - parameters->event = (GdkEventButton *)(gdk_event_copy ((GdkEvent *)event)); - - return parameters; -} - -static void -context_menu_parameters_free (ContextMenuParameters *parameters) -{ - gdk_event_free ((GdkEvent *)parameters->event); - g_free (parameters); -} - -static gboolean -show_context_menu_callback (void *cast_to_parameters) -{ - ContextMenuParameters *parameters; - - parameters = (ContextMenuParameters *)cast_to_parameters; - - g_assert (NAUTILUS_IS_LIST (parameters->list)); - - /* FIXME bugzilla.eazel.com 2574: - * Need to handle case where button has already been released, - * a la NautilusIconContainer code? - */ - - gtk_timeout_remove (parameters->list->details->context_menu_timeout_id); - - /* Context menu applies to all selected items. The only - * odd case is if this click deselected the item under - * the mouse, but at least the behavior is consistent. - */ - gtk_signal_emit (GTK_OBJECT (parameters->list), - list_signals[CONTEXT_CLICK_SELECTION], - parameters->event); - - context_menu_parameters_free (parameters); - - return TRUE; -} - -/* Our handler for button_press events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusList *list; - NautilusCList *clist; - int on_row; - int row_index, column_index; - int retval; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - retval = FALSE; - - if (!GTK_WIDGET_HAS_FOCUS (widget)) { - gtk_widget_grab_focus (widget); - } - - - /* Forget the typeahead state. */ - nautilus_list_flush_typeselect_state (list); - - if (event->window != clist->clist_window) - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, button_press_event, (widget, event)); - - on_row = nautilus_clist_get_selection_info (clist, event->x, event->y, &row_index, &column_index); - list->details->button_down_time = event->time; - list->details->drag_started = FALSE; - - list->details->button_down_row = -1; - - switch (event->type) { - case GDK_BUTTON_PRESS: - - if (event->button == CONTEXTUAL_MENU_BUTTON && !on_row) { - gtk_signal_emit (GTK_OBJECT (list), - list_signals[CONTEXT_CLICK_BACKGROUND], - event); - - retval = TRUE; - } else if (event->button == ACTION_BUTTON || event->button == CONTEXTUAL_MENU_BUTTON) { - if (on_row) { - - if (event->button == CONTEXTUAL_MENU_BUTTON) { - /* after a timeout we will decide if this is a - * context menu click or a drag start - */ - list->details->context_menu_timeout_id = gtk_timeout_add ( - CONTEXT_MENU_TIMEOUT_INTERVAL, - show_context_menu_callback, - context_menu_parameters_new (list, event)); - } - - /* Save the clicked row_index for DnD and single-click activate */ - - list->details->button_down_row = row_index; - - /* Save the mouse info for DnD */ - - list->details->dnd_press_button = event->button; - list->details->dnd_press_x = event->x; - list->details->dnd_press_y = event->y; - - /* Handle selection */ - - if ((nautilus_list_is_row_selected (list, row_index) - && !event_state_modifies_selection (event->state)) - || ((event->state & GDK_CONTROL_MASK) - && !(event->state & GDK_SHIFT_MASK))) { - /* don't change selection just yet, wait for - * possible drag - */ - list->details->dnd_select_pending = TRUE; - list->details->dnd_select_pending_state = event->state; - } - - if (!list->details->dnd_select_pending) { - select_row_from_mouse (list, row_index, event->state); - } - } else { - nautilus_clist_unselect_all (clist); - } - - retval = TRUE; - } - - break; - - case GDK_2BUTTON_PRESS: - if (event->button == ACTION_BUTTON) { - list->details->dnd_select_pending = FALSE; - list->details->dnd_select_pending_state = 0; - - if (on_row && !list->details->single_click_mode) { - /* We'll just eat the 2nd click if in single-click mode. */ - activate_selected_rows (list); - } - - retval = TRUE; - break; - } - - default: - break; - } - - return retval; -} - -/* Our handler for button_release events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_button_release (GtkWidget *widget, GdkEventButton *event) -{ - NautilusList *list; - NautilusCList *clist; - NautilusCListRow *row; - int on_row; - int row_index, column_index; - GtkStyle *style; - int text_x, text_width; - int retval; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - retval = FALSE; - - if (event->window != clist->clist_window) - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, button_release_event, (widget, event)); - - on_row = nautilus_clist_get_selection_info (clist, event->x, event->y, &row_index, &column_index); - - if (event->button != ACTION_BUTTON && event->button != CONTEXTUAL_MENU_BUTTON) - return FALSE; - - if (on_row) { - /* Clean up after abortive drag-and-drop attempt (since user can't - * reorder list view items, releasing mouse in list view cancels - * drag-and-drop possibility). - */ - if (list->details->dnd_select_pending) { - /* If clicked on a selected item, don't change selection - * (unless perhaps if modifiers were used) - */ - if (!nautilus_list_is_row_selected (list, row_index) - || event_state_modifies_selection (list->details->dnd_select_pending_state)) { - select_row_from_mouse (list, - list->details->button_down_row, - list->details->dnd_select_pending_state); - } - - list->details->dnd_select_pending = FALSE; - list->details->dnd_select_pending_state = 0; - } - - if (event->button == CONTEXTUAL_MENU_BUTTON && !list->details->drag_started) { - /* Right click, drag never happened, immediately show context menu */ - gtk_timeout_remove (list->details->context_menu_timeout_id); - gtk_signal_emit (GTK_OBJECT (list), - list_signals[CONTEXT_CLICK_SELECTION], - event); - } - - /* - * Activate on single click if not extending selection, mouse hasn't moved to - * a different row, not too much time has passed, and this is a link-type cell. - */ - if (event->button == ACTION_BUTTON && - list->details->single_click_mode && - !event_state_modifies_selection (event->state)) { - int elapsed_time = event->time - list->details->button_down_time; - - if (elapsed_time < MAX_CLICK_TIME && list->details->button_down_row == row_index) { - row = ROW_ELEMENT (clist, row_index)->data; - if (row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT) { - /* One final test. Check whether the click was in the - * horizontal bounds of the displayed text. - */ - nautilus_list_get_cell_style (list, row, GTK_STATE_NORMAL, row_index, column_index, &style, NULL, NULL, NULL); - text_width = gdk_string_width (style->font, NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - text_x = get_cell_horizontal_start_position (clist, row, column_index, text_width); - if (event->x >= text_x && event->x <= text_x + text_width) { - /* Note that we activate only the clicked-on item, - * not all selected items. This is because the UI - * feedback makes it clear that you're clicking on - * a link to activate that link, rather than activating - * the whole selection. - */ - activate_row (list, row_index); - } - } - } - } - - retval = TRUE; - } - - list->details->dnd_press_button = NO_BUTTON; - list->details->dnd_press_x = 0; - list->details->dnd_press_y = 0; - list->details->drag_started = FALSE; - - return retval; -} - -static void -nautilus_list_clear_keyboard_focus (NautilusList *list) -{ - if (NAUTILUS_CLIST (list)->focus_row >= 0) { - gtk_widget_draw_focus (GTK_WIDGET (list)); - } - - NAUTILUS_CLIST (list)->focus_row = -1; -} - -static void -nautilus_list_set_keyboard_focus (NautilusList *list, int row_index) -{ - g_assert (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows); - - if (row_index == NAUTILUS_CLIST (list)->focus_row) { - return; - } - - nautilus_list_clear_keyboard_focus (list); - - NAUTILUS_CLIST (list)->focus_row = row_index; - - gtk_widget_draw_focus (GTK_WIDGET (list)); -} - -static void -nautilus_list_keyboard_move_to (NautilusList *list, int row_index, GdkEventKey *event) -{ - NautilusCList *clist; - - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (row_index >= 0 || row_index < NAUTILUS_CLIST (list)->rows); - - clist = NAUTILUS_CLIST (list); - - if (event != NULL && (event->state & GDK_MOD1_MASK) != 0) { - /* Move the keyboard focus. */ - nautilus_list_set_keyboard_focus (list, row_index); - } else { - /* Select row_index and get rid of special keyboard focus. */ - nautilus_list_clear_keyboard_focus (list); - if (select_row_unselect_others (list, row_index)) { - emit_selection_changed (list); - } - } - - schedule_keyboard_row_reveal (list, row_index); -} - -void -nautilus_list_select_row (NautilusList *list, int row_index) -{ - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (row_index >= 0); - - if (row_index >= NAUTILUS_CLIST (list)->rows) - row_index = NAUTILUS_CLIST (list)->rows - 1; - - nautilus_list_keyboard_move_to (list, row_index, NULL); -} - -static gboolean -keyboard_row_reveal_timeout_callback (gpointer data) -{ - NautilusList *list; - int row_index; - - GDK_THREADS_ENTER (); - - list = NAUTILUS_LIST (data); - row_index = list->details->keyboard_row_to_reveal; - - if (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows) { - /* Only reveal the icon if it's still the keyboard - * focus or if it's still selected. Someone originally - * thought we should cancel this reveal if the user - * manages to sneak a direct scroll in before the - * timeout fires, but we later realized this wouldn't - * actually be an improvement (see bugzilla.eazel.com - * 612). - */ - if (row_index == NAUTILUS_CLIST (list)->focus_row - || nautilus_list_is_row_selected (list, row_index)) { - nautilus_list_reveal_row (list, row_index); - } - list->details->keyboard_row_reveal_timer_id = 0; - } - - GDK_THREADS_LEAVE (); - - return FALSE; -} - -static void -unschedule_keyboard_row_reveal (NautilusList *list) -{ - if (list->details->keyboard_row_reveal_timer_id != 0) { - gtk_timeout_remove (list->details->keyboard_row_reveal_timer_id); - } -} - -static void -schedule_keyboard_row_reveal (NautilusList *list, int row_index) -{ - unschedule_keyboard_row_reveal (list); - - list->details->keyboard_row_to_reveal = row_index; - list->details->keyboard_row_reveal_timer_id - = gtk_timeout_add (KEYBOARD_ROW_REVEAL_TIMEOUT, - keyboard_row_reveal_timeout_callback, - list); -} - -void -nautilus_list_reveal_row (NautilusList *list, int row_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - g_return_if_fail (row_index >= 0 && row_index < NAUTILUS_CLIST (list) ->rows); - - clist = NAUTILUS_CLIST (list); - - if (ROW_TOP_YPIXEL (clist, row_index) + clist->row_height > - clist->clist_window_height) { - nautilus_clist_moveto (clist, row_index, -1, 1, 0); - } else if (ROW_TOP_YPIXEL (clist, row_index) < 0) { - nautilus_clist_moveto (clist, row_index, -1, 0, 0); - } -} - -static void -nautilus_list_keyboard_navigation_key_press (NautilusList *list, GdkEventKey *event, - GtkScrollType scroll_type, gboolean jump_to_end) -{ - NautilusCList *clist; - int start_row; - int destination_row; - int rows_per_page; - - g_assert (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - if (scroll_type == GTK_SCROLL_JUMP) { - destination_row = (jump_to_end ? - clist->rows - 1 : - 0); - } else { - /* Choose the row to start with. - * If we have a keyboard focus, start with it. - * If there's a selection, use the selected row farthest toward the end. - */ - - if (clist->focus_row >= 0) { - start_row = clist->focus_row; - } else { - start_row = (scroll_type == GTK_SCROLL_STEP_FORWARD - || scroll_type == GTK_SCROLL_PAGE_FORWARD ? - nautilus_list_get_last_selected_row (list) : - nautilus_list_get_first_selected_row (list)); - } - - /* If there's no row to start with, select the row farthest toward the end. - * If there is a row to start with, select the next row in the arrow direction. - */ - if (start_row < 0) { - destination_row = (scroll_type == GTK_SCROLL_STEP_FORWARD - || scroll_type == GTK_SCROLL_PAGE_FORWARD - ? 0 : clist->rows - 1); - } else if (scroll_type == GTK_SCROLL_STEP_FORWARD) { - destination_row = MIN (clist->rows - 1, start_row + 1); - } else if (scroll_type == GTK_SCROLL_STEP_BACKWARD) { - destination_row = MAX (0, start_row - 1); - } else { - g_assert (scroll_type == GTK_SCROLL_PAGE_FORWARD || GTK_SCROLL_PAGE_BACKWARD); - rows_per_page = (2 * clist->clist_window_height - - clist->row_height - CELL_SPACING) / - (2 * (clist->row_height + CELL_SPACING)); - - if (scroll_type == GTK_SCROLL_PAGE_FORWARD) { - destination_row = MIN (clist->rows - 1, - start_row + rows_per_page); - } else { - destination_row = MAX (0, - start_row - rows_per_page); - } - } - } - - nautilus_list_keyboard_move_to (list, destination_row, event); -} - -static void -nautilus_list_keyboard_home (NautilusList *list, GdkEventKey *event) -{ - /* Home selects the first row. - * Control-Home sets the keyboard focus to the first row. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_JUMP, FALSE); -} - -static void -nautilus_list_keyboard_end (NautilusList *list, GdkEventKey *event) -{ - /* End selects the last row. - * Control-End sets the keyboard focus to the last row. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_JUMP, TRUE); -} - -static void -nautilus_list_keyboard_up (NautilusList *list, GdkEventKey *event) -{ - /* Up selects the next higher row. - * Control-Up sets the keyboard focus to the next higher icon. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_STEP_BACKWARD, FALSE); -} - -static void -nautilus_list_keyboard_down (NautilusList *list, GdkEventKey *event) -{ - /* Down selects the next lower row. - * Control-Down sets the keyboard focus to the next lower icon. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_STEP_FORWARD, FALSE); -} - -static void -nautilus_list_keyboard_page_up (NautilusList *list, GdkEventKey *event) -{ - /* Page Up selects a row one screenful higher. - * Control-Page Up sets the keyboard focus to the row one screenful higher. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_PAGE_BACKWARD, FALSE); -} - -static void -nautilus_list_keyboard_page_down (NautilusList *list, GdkEventKey *event) -{ - /* Page Down selects a row one screenful lower. - * Control-Page Down sets the keyboard focus to the row one screenful lower. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_PAGE_FORWARD, FALSE); -} - -static void -nautilus_list_keyboard_space (NautilusList *list, GdkEventKey *event) -{ - if (event->state & GDK_MOD1_MASK) { - gtk_signal_emit_by_name (GTK_OBJECT (list), "toggle_focus_row"); - } -} - -static void -nautilus_list_activate_selected_items (NautilusList *list) -{ - int row_index; - - for (row_index = 0; row_index < NAUTILUS_CLIST (list)->rows; ++row_index) { - if (nautilus_list_is_row_selected (list, row_index)) { - activate_row (list, row_index); - } - } -} - -static void -nautilus_list_flush_typeselect_state (NautilusList *list) -{ - g_free (list->details->type_select_pattern); - list->details->type_select_pattern = NULL; - list->details->last_typeselect_time = G_GINT64_CONSTANT(0); -} - -enum { - NAUTILUS_TYPESELECT_FLUSH_DELAY = 1000000 - /* After this time the current typeselect buffer will be - * thrown away and the new pressed character will be made - * the the start of a new pattern. - */ -}; - -static gboolean -nautilus_list_handle_typeahead (NautilusList *list, const char *key_string) -{ - char *new_pattern; - gint64 now; - gint64 time_delta; - int key_string_length; - int index; - - g_assert (key_string != NULL); - g_assert (strlen (key_string) < 5); - - key_string_length = strlen (key_string); - - if (key_string_length == 0) { - /* can be an empty string if the modifier was held down, etc. */ - return FALSE; - } - - /* only handle if printable keys typed */ - for (index = 0; index < key_string_length; index++) { - if (!isprint (key_string[index])) { - return FALSE; - } - } - - /* find out how long since last character was typed */ - now = eel_get_system_time(); - time_delta = now - list->details->last_typeselect_time; - if (time_delta < 0 || time_delta > NAUTILUS_TYPESELECT_FLUSH_DELAY) { - /* the typeselect state is too old, start with a fresh one */ - g_free (list->details->type_select_pattern); - list->details->type_select_pattern = NULL; - } - - if (list->details->type_select_pattern != NULL) { - new_pattern = g_strconcat - (list->details->type_select_pattern, - key_string, NULL); - g_free (list->details->type_select_pattern); - } else { - new_pattern = g_strdup (key_string); - } - - list->details->type_select_pattern = new_pattern; - list->details->last_typeselect_time = now; - - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_MATCHING_NAME], new_pattern); - - return TRUE; -} - -static int -nautilus_list_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - NautilusList *list; - - list = NAUTILUS_LIST (widget); - - switch (event->keyval) { - case GDK_Home: - nautilus_list_keyboard_home (list, event); - break; - case GDK_End: - nautilus_list_keyboard_end (list, event); - break; - case GDK_Page_Up: - nautilus_list_keyboard_page_up (list, event); - break; - case GDK_Page_Down: - nautilus_list_keyboard_page_down (list, event); - break; - case GDK_Up: - nautilus_list_keyboard_up (list, event); - break; - case GDK_Down: - nautilus_list_keyboard_down (list, event); - break; - case GDK_space: - nautilus_list_keyboard_space (list, event); - break; - case GDK_Return: - nautilus_list_activate_selected_items (list); - break; - case GDK_Tab: - case GDK_ISO_Left_Tab: - if ((event->state & GDK_SHIFT_MASK) == 0) { - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_PREVIOUS_NAME]); - } else { - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_NEXT_NAME]); - } - break; - default: - /* Don't use Control or Alt keys for type-selecting, because they - * might be used for menus. - */ - if ((event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0 && - nautilus_list_handle_typeahead (list, event->string)) { - return TRUE; - } - - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, key_press_event, (widget, event)); - } - - return TRUE; -} - -static guint32 -eel_gdk_set_shifted_foreground_gc_color (GdkGC *gc, guint32 color, float shift_by) -{ - guint32 shifted_color; - - shifted_color = eel_rgb_shift_color (color, shift_by); - gdk_rgb_gc_set_foreground (gc, shifted_color); - - return shifted_color; -} - -static GdkGC * -eel_gdk_gc_copy (GdkGC *source, GdkWindow *window) -{ - GdkGC *result; - - result = gdk_gc_new (window); - gdk_gc_copy (result, source); - - /* reset some properties to be on the safe side */ - gdk_gc_set_function (result, GDK_COPY); - gdk_gc_set_fill (result, GDK_SOLID); - gdk_gc_set_clip_origin (result, 0, 0); - gdk_gc_set_clip_mask (result, NULL); - - return result; -} - -static void -nautilus_list_setup_style_colors (NautilusList *list) -{ - guint32 style_background_color; - guint32 selection_background_color; - GdkColor text_color; - - gdk_rgb_init(); - - style_background_color = eel_gdk_color_to_rgb - (G_STRUCT_MEMBER_P (GTK_WIDGET (list)->style, - list->details->background_color_offset)); - selection_background_color = eel_gdk_color_to_rgb - (G_STRUCT_MEMBER_P (GTK_WIDGET (list)->style, - list->details->selection_color_offset)); - - list->details->cell_lighter_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_lighter_background, - style_background_color, 1); - - list->details->cell_darker_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_darker_background, - style_background_color, 1.03); - - list->details->cell_selected_lighter_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_selected_lighter_background, - style_background_color, 1.04); - - list->details->cell_selected_darker_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_selected_darker_background, - style_background_color, 1.06); - - eel_gdk_set_shifted_foreground_gc_color (list->details->cell_divider_color, - style_background_color, 0.8); - - list->details->selection_main_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_main_color, - selection_background_color, 1); - - list->details->selection_medium_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_medium_color, - selection_background_color, 0.7); - - list->details->selection_light_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_light_color, - selection_background_color, 0.5); - - text_color = GTK_WIDGET (list)->style->fg[GTK_STATE_NORMAL]; - eel_gdk_gc_choose_foreground_color (list->details->text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_NORMAL]); - - text_color = GTK_WIDGET (list)->style->fg[GTK_STATE_SELECTED]; - eel_gdk_gc_choose_foreground_color (list->details->selected_text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_SELECTED]); - - text_color.red = 0; - text_color.green = 0; - text_color.blue = 65535; - eel_gdk_gc_choose_foreground_color (list->details->link_text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_NORMAL]); -} - -static void -unref_a_gc (GdkGC **gc) -{ - if (*gc != NULL) { - gdk_gc_unref (*gc); - *gc = NULL; - } -} - -static void -unref_gcs (NautilusList *list) -{ - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - unref_a_gc (&list->details->cell_lighter_background); - unref_a_gc (&list->details->cell_darker_background); - unref_a_gc (&list->details->cell_selected_lighter_background); - unref_a_gc (&list->details->cell_selected_darker_background); - unref_a_gc (&list->details->cell_divider_color); - unref_a_gc (&list->details->selection_light_color); - unref_a_gc (&list->details->selection_medium_color); - unref_a_gc (&list->details->selection_main_color); - unref_a_gc (&list->details->text_color); - unref_a_gc (&list->details->selected_text_color); - unref_a_gc (&list->details->link_text_color); -} - -static void -make_gcs_and_colors (NautilusList *list) -{ - GtkWidget *widget; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - g_return_if_fail (GTK_IS_WIDGET (list)); - - widget = GTK_WIDGET (list); - - /* First unref old gcs */ - unref_gcs (list); - - /* now setup new ones */ - list->details->cell_lighter_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_darker_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_selected_lighter_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_selected_darker_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_divider_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->selection_light_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - list->details->selection_medium_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - list->details->selection_main_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - - list->details->text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_NORMAL], widget->window); - list->details->selected_text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_SELECTED], widget->window); - list->details->link_text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_NORMAL], widget->window); - - nautilus_list_setup_style_colors (list); -} - -static void -nautilus_list_style_set (GtkWidget *widget, GtkStyle *previous_style) -{ - NautilusList *list; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - list = NAUTILUS_LIST (widget); - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, style_set, (widget, previous_style)); - - if (GTK_WIDGET_REALIZED (widget)) { - make_gcs_and_colors (list); - } -} - -static void -nautilus_list_realize (GtkWidget *widget) -{ - NautilusList *list; - NautilusCList *clist; - GtkWindow *window; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - - clist->column[0].button = list->details->title; - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget)); - - make_gcs_and_colors (list); - - if (list->details->title) { - gtk_widget_set_parent_window (list->details->title, clist->title_window); - gtk_widget_set_parent (list->details->title, GTK_WIDGET (clist)); - gtk_widget_show (list->details->title); - } - - /* make us the focused widget */ - g_assert (GTK_IS_WINDOW (gtk_widget_get_toplevel (widget))); - window = GTK_WINDOW (gtk_widget_get_toplevel (widget)); - gtk_window_set_focus (window, widget); -} - -static void -nautilus_list_unrealize (GtkWidget *widget) -{ - GtkWindow *window; - window = GTK_WINDOW (gtk_widget_get_toplevel (widget)); - gtk_window_set_focus (window, NULL); - - /* unref all the gcs we've created */ - unref_gcs (NAUTILUS_LIST (widget)); - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, unrealize, (widget)); -} - -/* this is here just temporarily */ -static int -list_requisition_width (NautilusCList *clist) -{ - int width = CELL_SPACING; - int i; - - for (i = clist->columns - 1; i >= 0; i--) { - if (!clist->column[i].visible) - continue; - - if (clist->column[i].width_set) - width += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET); - else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) - width += clist->column[i].button->requisition.width; - } - - return width; -} - - -static void -nautilus_list_size_request (GtkWidget *widget, GtkRequisition *requisition) -{ - /* stolen from gtk_clist - * make sure the proper title ammount is allocated for the column - * title view -- this would not otherwise be done because - * NautilusList depends the buttons being there when doing a size calculation - */ - NautilusList *list; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - g_return_if_fail (requisition != NULL); - - clist = NAUTILUS_CLIST (widget); - list = NAUTILUS_LIST (widget); - - requisition->width = 0; - requisition->height = 0; - - /* compute the size of the column title (title) area */ - clist->column_title_area.height = 0; - if (NAUTILUS_CLIST_SHOW_TITLES(clist) && list->details->title) { - GtkRequisition child_requisition; - - gtk_widget_size_request (list->details->title, - &child_requisition); - - child_requisition.height = 20; - /* for now */ - - clist->column_title_area.height = - MAX (clist->column_title_area.height, - child_requisition.height); - } - - requisition->width += (widget->style->klass->xthickness + - GTK_CONTAINER (widget)->border_width) * 2; - requisition->height += (clist->column_title_area.height + - (widget->style->klass->ythickness + - GTK_CONTAINER (widget)->border_width) * 2); - - - requisition->width += list_requisition_width (clist); - requisition->height += LIST_HEIGHT (clist); -} - -static int -new_column_width (NautilusCList *clist, int column_index, int *x) -{ - int xthickness = GTK_WIDGET (clist)->style->klass->xthickness; - int width; - int cx; - int dx; - int last_column; - - /* first translate the x position from widget->window - * to clist->clist_window */ - cx = *x - xthickness; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--); - - /* calculate new column width making sure it doesn't end up - * less than the minimum width */ - dx = (COLUMN_LEFT_XPIXEL (clist, column_index) + COLUMN_INSET + - (column_index < last_column) * CELL_SPACING); - width = cx - dx; - - if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width)) { - width = MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width); - cx = dx + width; - *x = cx + xthickness; - } else if (clist->column[column_index].max_width >= COLUMN_MIN_WIDTH && - width > clist->column[column_index].max_width) { - width = clist->column[column_index].max_width; - cx = dx + clist->column[column_index].max_width; - *x = cx + xthickness; - } - - if (cx < 0 || cx > clist->clist_window_width) - *x = -1; - - return width; -} - -static void -size_allocate_columns (NautilusCList *clist, gboolean block_resize) -{ - int xoffset = CELL_SPACING + COLUMN_INSET; - int last_column; - int i; - - /* find last visible column and calculate correct column width */ - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - if (last_column < 0) - return; - - for (i = 0; i <= last_column; i++) { - if (!clist->column[i].visible) - continue; - - clist->column[i].area.x = xoffset; - if (clist->column[i].width_set) { - if (!block_resize && NAUTILUS_CLIST_SHOW_TITLES(clist) && - clist->column[i].auto_resize && clist->column[i].button) { - int width; - - width = (clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - - if (width > clist->column[i].width) - nautilus_clist_set_column_width (clist, i, width); - } - - clist->column[i].area.width = clist->column[i].width; - xoffset += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET); - } else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) { - clist->column[i].area.width = - clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET)); - xoffset += clist->column[i].button->requisition.width; - } - } - - clist->column[last_column].area.width - += MAX (0, clist->clist_window_width + COLUMN_INSET - xoffset); -} - -static void -size_allocate_title_buttons (NautilusCList *clist) -{ - GtkAllocation button_allocation; - int last_column; - int last_button = 0; - int i; - - button_allocation.x = clist->hoffset; - button_allocation.y = 0; - button_allocation.width = 0; - button_allocation.height = clist->column_title_area.height; - - /* find last visible column */ - for (last_column = clist->columns - 1; last_column >= 0; last_column--) - if (clist->column[last_column].visible) - break; - - for (i = 0; i < last_column; i++) { - if (!clist->column[i].visible) { - last_button = i + 1; - gdk_window_hide (clist->column[i].window); - continue; - } - - button_allocation.width += (clist->column[i].area.width + - CELL_SPACING + 2 * COLUMN_INSET); - - if (!clist->column[i + 1].button) { - gdk_window_hide (clist->column[i].window); - continue; - } - - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - button_allocation.x += button_allocation.width; - button_allocation.width = 0; - - last_button = i + 1; - } - - button_allocation.width += (clist->column[last_column].area.width + - 2 * (CELL_SPACING + COLUMN_INSET)); - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - -} - -static void -nautilus_list_draw_focus (GtkWidget *widget) -{ - GdkGCValues saved_values; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - if (!GTK_WIDGET_DRAWABLE (widget) || !GTK_WIDGET_CAN_FOCUS (widget)) { - return; - } - - clist = NAUTILUS_CLIST (widget); - if (clist->focus_row < 0) { - return; - } - - gdk_gc_get_values (clist->xor_gc, &saved_values); - - gdk_gc_set_stipple (clist->xor_gc, eel_stipple_bitmap ()); - gdk_gc_set_fill (clist->xor_gc, GDK_STIPPLED); - - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, ROW_TOP_YPIXEL(clist, clist->focus_row), - clist->clist_window_width - 1, - clist->row_height - 1); - /* Resetting the stipple to the saved value causes death - * deep in Bonobo X handling, believe it or not. Fortunately - * we don't need to. - */ - gdk_gc_set_fill (clist->xor_gc, saved_values.fill); -} - -static int -selected_column_index (NautilusList *list) -{ - int column; - - column = 2; - gtk_signal_emit_by_name (GTK_OBJECT (list), "get_sort_column_index", &column); - return column; -} - -static void -get_column_background (NautilusList *list, GdkGC **selected, GdkGC **plain) -{ - *plain = list->details->cell_lighter_background; - *selected = list->details->cell_selected_lighter_background; -} - -void -nautilus_list_get_cell_style (NautilusList *list, NautilusCListRow *row, - int state, int row_index, int column_index, GtkStyle **style, - GdkGC **fg_gc, GdkGC **bg_gc, guint32 *bg_rgb) -{ - gboolean lighter_row; - - lighter_row = (list->details->alternate_row_colors - ? (row_index % 2) != 0 : TRUE); - - if (style) { - *style = GTK_WIDGET (list)->style; - } - - if (state == GTK_STATE_SELECTED) { - if (fg_gc != NULL) { - *fg_gc = GTK_WIDGET (list)->style->fg_gc[state]; - } - if (bg_gc != NULL) { - if (column_index == selected_column_index (list)) { - *bg_gc = list->details->selection_medium_color; - } else { - *bg_gc = list->details->selection_light_color; - } - } - if (bg_rgb != NULL) { - if (column_index == selected_column_index (list)) { - *bg_rgb = list->details->selection_medium_color_rgb; - } else { - *bg_rgb = list->details->selection_light_color_rgb; - } - } - - - return; - } - - if (fg_gc != NULL) { - *fg_gc = GTK_WIDGET (list)->style->fg_gc[state]; - } - - if (bg_gc != NULL) { - if (column_index == selected_column_index (list)) { - if (lighter_row) { - *bg_gc = list->details->cell_selected_lighter_background; - } else { - *bg_gc = list->details->cell_selected_darker_background; - } - } else { - if (lighter_row) { - *bg_gc = list->details->cell_lighter_background; - } else { - *bg_gc = list->details->cell_darker_background; - } - } - } - if (bg_rgb != NULL) { - if (column_index == selected_column_index (list)) { - if (lighter_row) { - *bg_rgb = list->details->cell_selected_lighter_background_rgb; - } else { - *bg_rgb = list->details->cell_selected_darker_background_rgb; - } - } else { - if (lighter_row) { - *bg_rgb = list->details->cell_lighter_background_rgb; - } else { - *bg_rgb = list->details->cell_darker_background_rgb; - } - } - } -} - -void -nautilus_list_set_alternate_row_colors (NautilusList *list, - gboolean state) -{ - list->details->alternate_row_colors = state; -} - -void -nautilus_list_set_background_color_offsets (NautilusList *list, - long background_offset, - long selection_offset) -{ - g_return_if_fail (background_offset < 0 - || (gulong) background_offset < sizeof (GtkStyle)); - g_return_if_fail (selection_offset < 0 - || (gulong) selection_offset < sizeof (GtkStyle)); - - if (background_offset >= 0) { - list->details->background_color_offset = background_offset; - } - if (selection_offset >= 0) { - list->details->selection_color_offset = selection_offset; - } -} - -int -nautilus_list_draw_cell_pixbuf (NautilusList *list, GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, guint32 bg_rgb, - GdkPixbuf *pixbuf, int x, int y) -{ - GdkRectangle image_rectangle; - GdkRectangle intersect_rectangle; - GdkPixbuf *composited; - - image_rectangle.width = gdk_pixbuf_get_width (pixbuf); - image_rectangle.height = gdk_pixbuf_get_height (pixbuf); - image_rectangle.x = x; - image_rectangle.y = y; - - if (!gdk_rectangle_intersect (clip_rectangle, &image_rectangle, &intersect_rectangle)) { - return x; - } - - if (list && nautilus_list_is_anti_aliased (list)) { - /* Composite a version of the pixbuf with the background color */ - composited = gdk_pixbuf_composite_color_simple (pixbuf, - image_rectangle.width, - image_rectangle.height, - GDK_INTERP_BILINEAR, - 255, 64, - bg_rgb, bg_rgb); - if (composited == NULL) { - return x; - } - - gdk_pixbuf_render_to_drawable (composited, window, fg_gc, - intersect_rectangle.x - x, - intersect_rectangle.y - y, - image_rectangle.x, image_rectangle.y, - intersect_rectangle.width, - intersect_rectangle.height, - GDK_RGB_DITHER_MAX, 0, 0); - - gdk_pixbuf_unref (composited); - - } else { - - gdk_pixbuf_render_to_drawable_alpha (pixbuf, window, - intersect_rectangle.x - x, - intersect_rectangle.y - y, - image_rectangle.x, image_rectangle.y, - intersect_rectangle.width, - intersect_rectangle.height, - GDK_PIXBUF_ALPHA_BILEVEL, - EEL_STANDARD_ALPHA_THRESHHOLD, - GDK_RGB_DITHER_MAX, 0, 0); - } - - return x + intersect_rectangle.width; -} - -/** - * get_cell_horizontal_start_position: - * - * Get the leftmost x value at which the contents of this cell are painted. - * - * @clist: The list in question. - * @row: The row data structure for the target cell. - * @column_index: The column of the target cell. - * @content_width: The already-computed width of the cell contents. - * - * Return value: x value at which the contents of this cell are painted. - */ -static int -get_cell_horizontal_start_position (NautilusCList *clist, NautilusCListRow *row, int column_index, int content_width) -{ - int initial_offset; - - initial_offset = clist->column[column_index].area.x + - clist->hoffset + - row->cell[column_index].horizontal; - - switch (clist->column[column_index].justification) { - case GTK_JUSTIFY_LEFT: - return initial_offset; - case GTK_JUSTIFY_RIGHT: - return initial_offset + clist->column[column_index].area.width - content_width; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - default: - return initial_offset + (clist->column[column_index].area.width - content_width)/2; - } -} - -static int -last_column_index (NautilusCList *clist) -{ - int result; - for (result = clist->columns - 1; - result >= 0 && !clist->column[result].visible; - result--) { - } - - return result; -} - -void -nautilus_list_get_cell_rectangle (NautilusList *list, int row_index, int column_index, GdkRectangle *result) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - result->x = clist->column[column_index].area.x + clist->hoffset; - result->y = ROW_TOP_YPIXEL (clist, row_index); - result->width = clist->column[column_index].area.width; - result->height = clist->row_height; -} - -static void -get_cell_greater_rectangle (GdkRectangle *cell_rect, GdkRectangle *result, - gboolean last_column) -{ - *result = *cell_rect; - result->x -= COLUMN_INSET + CELL_SPACING; - result->width += 2 * COLUMN_INSET + CELL_SPACING; - if (last_column) { - result->width += CELL_SPACING; - } -} - -static void -draw_cell (NautilusCList *clist, GdkRectangle *area, int row_index, int column_index, - NautilusCListRow *row) -{ - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - GdkGC *text_gc; - guint32 bg_rgb; - - GList *p; - - int width; - int height; - int pixbuf_width; - int offset = 0; - int baseline; - int row_center_offset; - - GdkRectangle cell_rectangle; - GdkRectangle erase_rectangle; - GdkRectangle intersect_rectangle; - - if (!clist->column[column_index].visible) { - return; - } - - nautilus_list_get_cell_style (NAUTILUS_LIST(clist), row, row->state, row_index, - column_index, &style, &fg_gc, &bg_gc, &bg_rgb); - nautilus_list_get_cell_rectangle (NAUTILUS_LIST (clist), row_index, column_index, &cell_rectangle); - get_cell_greater_rectangle (&cell_rectangle, &erase_rectangle, - column_index == last_column_index (clist)); - - /* do we have anything do draw? */ - if (area && !gdk_rectangle_intersect (area, &erase_rectangle, &intersect_rectangle)) { - return; - } - - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - erase_rectangle.x, erase_rectangle.y, - erase_rectangle.width, erase_rectangle.height); - - /* calculate real width for column justification */ - width = 0; - height = 0; - - switch ((NautilusCellType)row->cell[column_index].type) { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - width = gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - break; - case NAUTILUS_CELL_PIXBUF: - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf); - break; - case NAUTILUS_CELL_PIXTEXT: - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf); - width = (pixbuf_width + - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->spacing + - gdk_string_width (style->font, NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->text)); - break; - case NAUTILUS_CELL_PIXBUF_LIST: - for (p = NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs; - p != NULL; p = p->next) { - if (width != 0) { - width += PIXBUF_LIST_SPACING; - } - width += gdk_pixbuf_get_width (p->data); - } - break; - case NAUTILUS_CELL_EMPTY: - case NAUTILUS_CELL_WIDGET: - return; - } - - offset = get_cell_horizontal_start_position (clist, row, column_index, width); - - /* Draw Text and/or Pixbuf */ - switch ((NautilusCellType) row->cell[column_index].type) { - case NAUTILUS_CELL_PIXBUF: { - NautilusList *list = NAUTILUS_LIST (clist); - GdkPixbuf *src_pixbuf, *dark_pixbuf; - - if (list->details->drag_prelight_row == row) { - - src_pixbuf = NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf; - - if (src_pixbuf != NULL) { - /* Create darkened pixbuf */ - dark_pixbuf = eel_create_darkened_pixbuf (src_pixbuf, - 0.8 * 255, - 0.8 * 255); - if (dark_pixbuf != NULL) { - nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - dark_pixbuf, offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - - gdk_pixbuf_unref (dark_pixbuf); - } - } - } else { - nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf, - offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - } - break; - } - - case NAUTILUS_CELL_PIXTEXT: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf, - offset, - cell_rectangle.y + row->cell[column_index].vertical+ - (cell_rectangle.height - height) / 2); - offset += NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->spacing; - /* fall through */ - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (style != GTK_WIDGET (clist)->style) { - row_center_offset = (((clist->row_height - style->font->ascent - - style->font->descent - 1) / 2) + 1.5 + - style->font->ascent); - } else { - row_center_offset = clist->row_center_offset; - } - baseline = cell_rectangle.y + row_center_offset + row->cell[column_index].vertical; - - if (row->state != GTK_STATE_NORMAL) { - text_gc = NAUTILUS_LIST (clist)->details->selected_text_color; - } else if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT - && NAUTILUS_LIST (clist)->details->single_click_mode) { - /* For link text cells, draw with blue link-like color and use underline. */ - text_gc = NAUTILUS_LIST (clist)->details->link_text_color; - } else { - text_gc = NAUTILUS_LIST (clist)->details->text_color; - } - - gdk_gc_set_clip_rectangle (text_gc, &cell_rectangle); - - gdk_draw_string (clist->clist_window, style->font, text_gc, - offset, - baseline, - ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_PIXTEXT) ? - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->text : - NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - - if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT - && NAUTILUS_LIST (clist)->details->single_click_mode) { - gdk_draw_line (clist->clist_window, text_gc, - offset, baseline + 1, - offset + width, baseline + 1); - } - - gdk_gc_set_clip_rectangle (text_gc, NULL); - break; - - case NAUTILUS_CELL_PIXBUF_LIST: { - guint pixbuf_width; - guint ellipsis_width; - - ellipsis_width = gdk_string_width (style->font, "..."); - - for (p = NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs; p != NULL; p = p->next) { - pixbuf_width = gdk_pixbuf_get_width (p->data); - - if ((p->next != NULL && (int) (pixbuf_width + ellipsis_width) >= - cell_rectangle.x + cell_rectangle.width - offset) - || ((int) pixbuf_width >= cell_rectangle.x + cell_rectangle.width - offset)) { - /* Not enough room for this icon & ellipsis, just draw ellipsis. */ - - gdk_draw_string (clist->clist_window, style->font, fg_gc, - offset, - cell_rectangle.y + cell_rectangle.height/2, - "..."); - - break; - } - - height = gdk_pixbuf_get_height (p->data); - - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, - &cell_rectangle, - fg_gc, bg_rgb, p->data, - offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - - offset += PIXBUF_LIST_SPACING; - } - break; - } - case NAUTILUS_CELL_EMPTY: - case NAUTILUS_CELL_WIDGET: - break; - } -} - -static void -draw_row (NautilusCList *clist, GdkRectangle *area, int row_index, NautilusCListRow *row) -{ - GtkWidget *widget; - GdkRectangle row_rectangle; - GdkRectangle extended_row_rectangle; - GdkRectangle intersect_rectangle; - int colum_index; - - g_return_if_fail (clist != NULL); - - /* bail now if we arn't drawable yet */ - if (!GTK_WIDGET_DRAWABLE (clist) || row_index < 0 || row_index >= clist->rows) { - return; - } - - widget = GTK_WIDGET (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup - */ - if (!row) { - row = ROW_ELEMENT (clist, row_index)->data; - } - - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row_index); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; - - /* rectangle of the entire row including spacing above and below the row */ - extended_row_rectangle.x = 0; - extended_row_rectangle.y = row_rectangle.y - CELL_SPACING; - extended_row_rectangle.width = row_rectangle.width; - extended_row_rectangle.height = row_rectangle.height + CELL_SPACING; - - if (row->state == GTK_STATE_NORMAL) { - if (row->fg_set) { - gdk_gc_set_foreground (clist->fg_gc, &row->foreground); - } - if (row->bg_set) { - gdk_gc_set_foreground (clist->bg_gc, &row->background); - } - } - - intersect_rectangle = extended_row_rectangle; - /* check if we have something to draw */ - if (area && !gdk_rectangle_intersect (area, &extended_row_rectangle, &intersect_rectangle)) { - return; - } - - - /* iterate and draw all the columns (row cells) and draw their contents */ - for (colum_index = 0; colum_index < clist->columns; colum_index++) { - draw_cell (clist, area, row_index, colum_index, row); - } - - /* draw the row spacer */ - gdk_draw_rectangle (clist->clist_window, - NAUTILUS_LIST (clist)->details->cell_divider_color, - TRUE, - intersect_rectangle.x, - extended_row_rectangle.y, - intersect_rectangle.width, - CELL_SPACING); - gdk_draw_rectangle (clist->clist_window, - NAUTILUS_LIST (clist)->details->cell_divider_color, - TRUE, - intersect_rectangle.x, - row_rectangle.y + row_rectangle.height, - intersect_rectangle.width, - CELL_SPACING); - - /* draw focus rectangle */ - if (clist->focus_row == row_index - && GTK_WIDGET_CAN_FOCUS (widget) && GTK_WIDGET_HAS_FOCUS (widget)) { - if (!area) { - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - } else if (gdk_rectangle_intersect (area, &row_rectangle, &intersect_rectangle)) { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } - } -} - -static void -rectangle_intersect (const GdkRectangle *source1, const GdkRectangle *source2, GdkRectangle *result) -{ - /* convenience call that returns result with defined values even if sources are disjucnt */ - if (!gdk_rectangle_intersect ((GdkRectangle *)source1, (GdkRectangle *)source2, result)) { - result->width = 0; - result->height = 0; - } -} - -static void -nautilus_list_clear_from_row (NautilusList *list, int row_index, - GdkRectangle *area) -{ - NautilusCList *clist; - GdkRectangle clip_area, tmp; - GdkRectangle first_column_plain_rectangle, selected_column_rectangle, - second_column_plain_rectangle; - GdkGC *selected_column_gc; - GdkGC *plain_column_gc; - - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (area); - - clist = NAUTILUS_CLIST (list); - - /* calculate the area we need to erase */ - clip_area = *area; - clip_area.y = ROW_TOP_YPIXEL (clist, row_index); - if (clip_area.y < 0) { - clip_area.y = 0; - } - if (clip_area.y - area->y < area->height) { - clip_area.height = area->height - (clip_area.y - area->y); - } else { - clip_area.height = 0; - } - - if (clip_area.height <= 0) { - /* nothing visible to erase */ - return; - } - - /* calculate the rectangle for the selected column */ - nautilus_list_get_cell_rectangle (list, 0, selected_column_index (list), &tmp); - get_cell_greater_rectangle (&tmp, &tmp, - selected_column_index (list) == last_column_index (clist)); - tmp.y = clip_area.y; - tmp.height = clip_area.height; - - rectangle_intersect (&clip_area, &tmp, &selected_column_rectangle); - - /* calculate the first rectangle */ - tmp = clip_area; - if (selected_column_rectangle.x > tmp.x) { - tmp.width = selected_column_rectangle.x - tmp.x; - } else { - tmp.width = selected_column_rectangle.x - tmp.x; - } - rectangle_intersect (&clip_area, &tmp, &first_column_plain_rectangle); - - - /* calculate the last rectangle */ - tmp = clip_area; - tmp.x = selected_column_rectangle.x + selected_column_rectangle.width; - rectangle_intersect (&clip_area, &tmp, &second_column_plain_rectangle); - - /* get the colors for drawing */ - get_column_background (list, &selected_column_gc, &plain_column_gc); - - /* draw the first column if non-empty */ - if (first_column_plain_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, plain_column_gc, TRUE, - first_column_plain_rectangle.x, first_column_plain_rectangle.y, - first_column_plain_rectangle.width, first_column_plain_rectangle.height); - } - /* draw the selected column if non-empty */ - if (selected_column_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, selected_column_gc, TRUE, - selected_column_rectangle.x, selected_column_rectangle.y, - selected_column_rectangle.width, selected_column_rectangle.height); - } - /* draw the last column if non-empty */ - if (second_column_plain_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, plain_column_gc, TRUE, - second_column_plain_rectangle.x, second_column_plain_rectangle.y, - second_column_plain_rectangle.width, second_column_plain_rectangle.height); - } -} - -static void -draw_rows (NautilusCList *clist, GdkRectangle *area) -{ - GList *list; - int row_index; - int first_row; - int last_row; - - g_assert (area != NULL); - - if (clist->row_height == 0 || !GTK_WIDGET_DRAWABLE (clist)) { - return; - } - - first_row = ROW_FROM_YPIXEL (clist, area->y); - last_row = ROW_FROM_YPIXEL (clist, area->y + area->height); - - /* this is a small special case which exposes the bottom cell line - * on the last row -- it might go away if I change the wall the cell - * spacings are drawn - */ - if (clist->rows == first_row) { - first_row--; - } - - list = ROW_ELEMENT (clist, first_row); - for (row_index = first_row; row_index <= last_row ; row_index++) { - if (list == NULL) { - break; - } - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, - draw_row, (clist, area, row_index, list->data)); - list = list->next; - } - - nautilus_list_clear_from_row (NAUTILUS_LIST (clist), - row_index, area); -} - -static void -draw_all (NautilusCList *clist) -{ - GdkRectangle area; - area.x = 0; - area.y = 0; - area.width = clist->clist_window_width; - area.height = clist->clist_window_height; - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, &area)); -} - -static void -nautilus_list_draw (GtkWidget *widget, GdkRectangle *area) -{ - NautilusCList *clist; - NautilusList *list; - - g_assert (NAUTILUS_IS_LIST (widget)); - g_assert (area != NULL); - - clist = NAUTILUS_CLIST (widget); - list = NAUTILUS_LIST (widget); - - nautilus_list_setup_style_colors (NAUTILUS_LIST (widget)); - - if (GTK_WIDGET_DRAWABLE (widget)) { - int border_width; - border_width = GTK_CONTAINER (widget)->border_width; - gdk_window_clear_area (widget->window, - area->x - border_width, - area->y - border_width, - area->width, area->height); - - gtk_draw_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, clist->shadow_type, - 0, 0, - clist->clist_window_width + - (2 * widget->style->klass->xthickness), - clist->clist_window_height + - (2 * widget->style->klass->ythickness) + - clist->column_title_area.height); - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, area)); - - /* Draw the title if it exists */ - if (list->details->title) { - GdkRectangle draw_area; - - if (gtk_widget_intersect (list->details->title, - area, &draw_area)) { - gtk_widget_draw (list->details->title, &draw_area); - } - } - } -} - -static int -nautilus_list_expose (GtkWidget *widget, GdkEventExpose *event) -{ - NautilusCList *clist; - - g_assert (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - nautilus_list_setup_style_colors (NAUTILUS_LIST (widget)); - - if (GTK_WIDGET_DRAWABLE (widget)) { - - gtk_draw_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, clist->shadow_type, - 0, 0, - clist->clist_window_width + - (2 * widget->style->klass->xthickness), - clist->clist_window_height + - (2 * widget->style->klass->ythickness) + - clist->column_title_area.height); - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, - (clist, &event->area)); - } - - return FALSE; -} - -static void -nautilus_list_resize_column (NautilusCList *clist, int column_index, int width) -{ - /* override resize column to invalidate the title */ - NautilusList *list; - - list = NAUTILUS_LIST (clist); - - gtk_widget_queue_draw (list->details->title); - - EEL_CALL_PARENT (NAUTILUS_CLIST_CLASS, resize_column, (clist, column_index, width)); -} - - -/** - * nautilus_list_mark_cell_as_link: - * - * Mark a text cell as a link cell. Link cells are drawn differently, - * and activate rather than select on single-click. The cell must - * be a text cell (not a pixbuf cell or one of the other types). - * - * @list: The NautilusList in question. - * @column_index: The column of the desired cell. - * @row: The row of the desired cell. - */ -void -nautilus_list_mark_cell_as_link (NautilusList *list, - int row_index, - int column_index) -{ - NautilusCListRow *row; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - g_return_if_fail (row_index >= 0 && row_index < clist->rows); - g_return_if_fail (column_index >= 0 && column_index < clist->columns); - - row = ROW_ELEMENT (clist, row_index)->data; - - /* - * We only support changing text cells to links. Maybe someday - * we'll support pixbuf or pixtext link cells too. - */ - g_return_if_fail ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_TEXT); - - row->cell[column_index].type = NAUTILUS_CELL_LINK_TEXT; -} - - -static gboolean -nautilus_list_set_cell_contents (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - gboolean result; - - /* - * Note that we don't do the auto_resize bracketing here that's done - * in the parent class. It would require copying over huge additional - * chunks of code. We might decide we need that someday, but the - * chances seem larger that we'll switch away from CList first. - */ - - /* Clean up old data, which parent class doesn't know about. */ - if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_PIXBUF_LIST) { - eel_gdk_pixbuf_list_free (NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs); - } - - result = EEL_CALL_PARENT_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, set_cell_contents, - (clist, row, column_index, type, text, spacing, pixbuf)); - - if ((NautilusCellType)type == NAUTILUS_CELL_PIXBUF_LIST) { - row->cell[column_index].type = NAUTILUS_CELL_PIXBUF_LIST; - /* Hideously, we concealed our list of pixbufs in the pixbuf parameter. */ - NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs = (GList *)pixbuf; - } - - return result; -} - -static void -set_list_cell (NautilusList *list, - int row_index, int column_index, - NautilusCellType type, - gpointer data) -{ - NautilusCList *clist; - NautilusCListRow *row; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - if (row_index < 0 || row_index >= clist->rows) { - return; - } - - if (column_index < 0 || column_index >= clist->columns) { - return; - } - - row = ROW_ELEMENT (clist, row_index)->data; - - /* - * We have to go through the set_cell_contents bottleneck, which only - * allows expected parameter types. Since our pixbuf is not an - * expected parameter type, we have to sneak it in by casting it into - * one of the expected parameters. - */ - if (EEL_CALL_METHOD_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, clist, set_cell_contents, - (clist, row, column_index, type, NULL, 0, data))) { - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist) - && nautilus_clist_row_is_visible (clist, row_index) != GTK_VISIBILITY_NONE) { - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_row, - (clist, NULL, row_index, row)); - } - } -} - -static gpointer -get_list_cell (NautilusList *list, - int row_index, int column_index, - NautilusCellType type) -{ - NautilusCList *clist; - NautilusCListRow *row; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), NULL); - - clist = NAUTILUS_CLIST (list); - - if (row_index < 0 || row_index >= clist->rows) { - return NULL; - } - - if (column_index < 0 || column_index >= clist->columns) { - return NULL; - } - - row = ROW_ELEMENT (clist, row_index)->data; - - if (row->cell[column_index].type == type) { - return NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf; - } - - return NULL; -} - -/** - * nautilus_list_set_pixbuf_list: - * - * Set the contents of a cell to a list of similarly-sized GdkPixbufs. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - * @pixbufs: A GList of GdkPixbufs. - */ -void -nautilus_list_set_pixbuf_list (NautilusList *list, - int row_index, - int column_index, - GList *pixbufs) -{ - set_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF_LIST, pixbufs); -} - -/** - * nautilus_list_set_pixbuf: - * - * Similar to nautilus_list_set_pixbuf_list, but with a single pixbuf. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - * @pixbuf: A GdkPixbuf. - */ -void -nautilus_list_set_pixbuf (NautilusList *list, - int row_index, - int column_index, - GdkPixbuf *pixbuf) -{ - set_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF, pixbuf); -} - -/** - * nautilus_list_get_pixbuf: - * - * Return the pixbuf stored in the specified position, or a null pointer - * if the cell isn't a pixbuf. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - */ -GdkPixbuf * -nautilus_list_get_pixbuf (NautilusList *list, - int row_index, - int column_index) -{ - return get_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF); -} - -static void -nautilus_list_track_new_column_width (NautilusCList *clist, int column_index, int new_width) -{ - NautilusList *list; - GdkRectangle area; - - list = NAUTILUS_LIST (clist); - - /* pin new_width to min and max values */ - if (new_width < MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width)) - new_width = MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width); - if (clist->column[column_index].max_width >= 0 && - new_width > clist->column[column_index].max_width) - new_width = clist->column[column_index].max_width; - - /* check to see if the pinned value is still different */ - if (clist->column[column_index].width == new_width) - return; - - /* set the new width */ - clist->column[column_index].width = new_width; - clist->column[column_index].width_set = TRUE; - - size_allocate_columns (clist, TRUE); - size_allocate_title_buttons (clist); - - /* redraw the invalid columns */ - if (CLIST_UNFROZEN (clist)) { - area = clist->column_title_area; - area.x = clist->column[column_index].area.x; - area.height += clist->clist_window_height; - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, &area)); - } -} - -static void -nautilus_list_drag_start (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusList *list; - GdkDragContext *context; - GdkPixbuf *pixbuf; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - list = NAUTILUS_LIST (widget); - - if (list->details->drag_info == NULL) { - return; - } - - list->details->drag_started = TRUE; - list->details->dnd_select_pending = FALSE; - /* reinit from last dnd if there was one */ - list->details->drag_info->got_drop_data_type = FALSE; - nautilus_drag_destroy_selection_list (list->details->drag_info->selection_list); - list->details->drag_info->selection_list = NULL; - - context = gtk_drag_begin (widget, list->details->drag_info->target_list, - list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON - ? GDK_ACTION_ASK - : GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK, - list->details->dnd_press_button, - (GdkEvent *) event); - - pixbuf = NULL; - gtk_signal_emit (GTK_OBJECT (list), list_signals[GET_DRAG_PIXBUF], - list->details->button_down_row, &pixbuf); - - if (pixbuf != NULL) { - /* FIXME: We can do better than 10,10. */ - eel_drag_set_icon_pixbuf (context, pixbuf, 10, 10); - - gdk_pixbuf_unref (pixbuf); - } -} - -/* Our handler for motion_notify events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_motion (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusList *list; - NautilusCList *clist; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - - if (event->window != clist->clist_window) { - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, motion_notify_event, (widget, event)); - } - - if (!((list->details->dnd_press_button == ACTION_BUTTON && (event->state & GDK_BUTTON1_MASK)) - || (list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON && (event->state & GDK_BUTTON3_MASK)))) - return FALSE; - - /* This is the same threshold value that is used in gtkdnd.c */ - - if (MAX (abs (list->details->dnd_press_x - event->x), - abs (list->details->dnd_press_y - event->y)) <= 3) { - return FALSE; - } - - - if (list->details->button_down_row < 0) { - /* We didn't hit a row, just blank space */ - return FALSE; - } - - g_assert (list->details->button_down_row < clist->rows); - if (!list->details->drag_started) { - if (list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON) { - gtk_timeout_remove (list->details->context_menu_timeout_id); - } - nautilus_list_drag_start (widget, event); - } - - return TRUE; -} - -void -nautilus_list_column_resize_track_start (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - clist->drag_pos = column_index; -} - -void -nautilus_list_column_resize_track (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - int x; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - gtk_widget_get_pointer (widget, &x, NULL); - nautilus_list_track_new_column_width (clist, column_index, - new_column_width (clist, column_index, &x)); -} - -void -nautilus_list_column_resize_track_end (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - clist->drag_pos = -1; -} - -/* FIXME bugzilla.eazel.com 7445: Needs to become a shared function */ -static void -get_data_on_first_target_we_support (GtkWidget *widget, GdkDragContext *context, guint32 time) -{ - GList *target; - - if (nautilus_list_dnd_target_list == NULL) - nautilus_list_dnd_target_list = gtk_target_list_new (nautilus_list_dnd_target_table, - EEL_N_ELEMENTS (nautilus_list_dnd_target_table)); - - for (target = context->targets; target != NULL; target = target->next) { - guint dummy_info; - GdkAtom target_atom = GPOINTER_TO_UINT (target->data); - - if (gtk_target_list_find (nautilus_list_dnd_target_list, - target_atom, - &dummy_info)) { - gtk_drag_get_data (GTK_WIDGET (widget), context, - target_atom, - time); - break; - } - } -} - - -static void -nautilus_list_ensure_drag_data (NautilusList *list, - GdkDragContext *context, - guint32 time) -{ - if (!list->details->drag_info->got_drop_data_type) { - get_data_on_first_target_we_support (GTK_WIDGET (list), context, time); - } -} - -static void -nautilus_list_drag_end (GtkWidget *widget, GdkDragContext *context) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - drag_info->got_drop_data_type = FALSE; - nautilus_drag_destroy_selection_list (list->details->drag_info->selection_list); - list->details->drag_info->selection_list = NULL; - -} - -static void -nautilus_list_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - nautilus_list_stop_auto_scroll (NAUTILUS_LIST (list)); - - nautilus_list_set_drag_prelight_row (list, -1); -} - -gboolean -nautilus_list_rejects_dropped_icons (NautilusList *list) -{ - return list->details->rejects_dropped_icons; -} - -void -nautilus_list_set_rejects_dropped_icons (NautilusList *list, gboolean new_value) -{ - list->details->rejects_dropped_icons = new_value; -} - -static void -nautilus_list_get_drop_action (NautilusList *list, - GdkDragContext *context, - int x, int y, - int *default_action, - int *non_default_action) -{ - NautilusDragInfo *drag_info; - - drag_info = NAUTILUS_LIST (list)->details->drag_info; - - /* FIXME bugzilla.eazel.com 2569: Too much code copied from nautilus-icon-dnd.c. - * Need to share more. - */ - - if (!drag_info->got_drop_data_type) { - /* drag_data_received didn't get called yet */ - return; - } - - /* get those actions from a subclass of this object */ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[GET_DEFAULT_ACTION], - default_action, - non_default_action, - context, - drag_info->selection_list, - x, y, - drag_info->data_type); - -} - - -static void -nautilus_list_real_scroll (NautilusList *list, float delta_x, float delta_y) -{ - GtkAdjustment *hadj, *vadj; - - hadj = nautilus_clist_get_hadjustment (NAUTILUS_CLIST (list)); - vadj = nautilus_clist_get_vadjustment (NAUTILUS_CLIST (list)); - - eel_gtk_adjustment_set_value (hadj, hadj->value + (int)delta_x); - eel_gtk_adjustment_set_value (vadj, vadj->value + (int)delta_y); - -} - -static int -auto_scroll_timeout_callback (gpointer data) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - GtkWidget *widget; - float x_scroll_delta, y_scroll_delta; - - g_assert (NAUTILUS_IS_LIST (data)); - widget = GTK_WIDGET (data); - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - if (drag_info->waiting_to_autoscroll - && drag_info->start_auto_scroll_in > eel_get_system_time()) { - /* not yet */ - return TRUE; - } - - drag_info->waiting_to_autoscroll = FALSE; - - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); - - nautilus_list_real_scroll (list, x_scroll_delta, y_scroll_delta); - - return TRUE; -} - -static void -nautilus_list_start_auto_scroll (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - - nautilus_drag_autoscroll_start (list->details->drag_info, - GTK_WIDGET (list), - auto_scroll_timeout_callback, - list); -} - -static void -nautilus_list_stop_auto_scroll (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - - nautilus_drag_autoscroll_stop (list->details->drag_info); -} - -static void -nautilus_list_prelight_if_necessary (NautilusList *list, GdkDragContext *context, - int x, int y, guint time) -{ - gboolean is_prelight_necessary; - - /* should we prelight the current row ? */ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[HANDLE_DRAGGED_ITEMS], - context->action, - list->details->drag_info->selection_list, - x, y, - list->details->drag_info->data_type, - &is_prelight_necessary); - - if (is_prelight_necessary) { - nautilus_list_set_drag_prelight_row (list, y); - } else { - nautilus_list_set_drag_prelight_row (list, -1); - } -} - - -static gboolean -nautilus_list_drag_motion (GtkWidget *widget, GdkDragContext *context, - int x, int y, guint time) -{ - NautilusList *list; - int default_action, non_default_action, resulting_action; - - list = NAUTILUS_LIST (widget); - - nautilus_list_ensure_drag_data (list, context, time); - - nautilus_list_start_auto_scroll (NAUTILUS_LIST (widget)); - - default_action = 0; - non_default_action = 0; - - nautilus_list_get_drop_action (list, context, x, y, &default_action, &non_default_action); - resulting_action = nautilus_drag_modifier_based_action (default_action, non_default_action); - - gdk_drag_status (context, resulting_action, time); - - nautilus_list_prelight_if_necessary (list, context, x, y, time); - - return TRUE; -} - -static gboolean -nautilus_list_drag_drop (GtkWidget *widget, GdkDragContext *context, - int x, int y, guint time) -{ - NautilusList *list; - - list = NAUTILUS_LIST (widget); - - /* make sure that drag_data_received is going to be called - after this event and will do the actual actions */ - list->details->drag_info->drop_occured = TRUE; - get_data_on_first_target_we_support (widget, context, time); - - return FALSE; -} - -static void -nautilus_list_receive_dropped_icons (NautilusList *list, - int action, - GtkSelectionData *data, - int x, int y, guint info) -{ - NautilusDragInfo *drag_info; - GList *selected_items; - - g_assert (NAUTILUS_IS_LIST (list)); - drag_info = list->details->drag_info; - - /* Put selection list in local variable and NULL the global one - * so it doesn't get munged in a modal popup-menu event loop - * in the handle_dropped_item handler. - */ - selected_items = drag_info->selection_list; - drag_info->selection_list = NULL; - gtk_signal_emit (GTK_OBJECT (list), list_signals[HANDLE_DROPPED_ITEMS], - action, selected_items, x, y, info); - nautilus_drag_destroy_selection_list (selected_items); -} - -static void -nautilus_list_receive_dropped_keyword (NautilusList *list, - int action, - GtkSelectionData *data, - int x, int y, - guint info) -{ - GList *emblems; - - emblems = g_list_prepend (NULL, (char *)data->data); - - gtk_signal_emit (GTK_OBJECT (list), - list_signals[HANDLE_DROPPED_ITEMS], - action, emblems, x, y, info); - - g_list_free (emblems); -} - - - -static void -nautilus_list_drag_data_received (GtkWidget *widget, GdkDragContext *context, - int x, int y, GtkSelectionData *data, - guint info, guint time) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - - if (!drag_info->got_drop_data_type) { - - drag_info->data_type = info; - drag_info->got_drop_data_type = TRUE; - drag_info->selection_data = data; - - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); - break; - case NAUTILUS_ICON_DND_URI_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); - break; - case NAUTILUS_ICON_DND_COLOR: - break; - case NAUTILUS_ICON_DND_BGIMAGE: - break; - case NAUTILUS_ICON_DND_KEYWORD: - break; - default: - break; - } - } - - if (drag_info->drop_occured) { - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - nautilus_list_receive_dropped_icons - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_URI_LIST: - nautilus_list_receive_dropped_icons - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_COLOR: - eel_background_receive_dropped_color - (eel_get_widget_background (widget), - widget, x, y, data); - nautilus_list_setup_style_colors (NAUTILUS_LIST (list)); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_BGIMAGE: - eel_background_receive_dropped_background_image - (eel_get_widget_background (widget), - (char *)data->data); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_KEYWORD: - nautilus_list_receive_dropped_keyword - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - default: - gtk_drag_finish (context, FALSE, FALSE, time); - break; - } - - - drag_info->drop_occured = FALSE; - drag_info->got_drop_data_type = FALSE; - } -} - - - -/* Our handler for the clear signal of the clist. We have to reset the anchor - * to null. - */ -static void -nautilus_list_clear (NautilusCList *clist) -{ - NautilusList *list; - - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - list = NAUTILUS_LIST (clist); - list->details->anchor_row = -1; - - EEL_CALL_PARENT (NAUTILUS_CLIST_CLASS, clear, (clist)); -} - - -/** - * nautilus_list_new_with_titles: - * @columns: The number of columns in the list - * @titles: The titles for the columns - * - * Return value: The newly-created file list. - **/ -GtkWidget * -nautilus_list_new_with_titles (int columns, const char * const *titles) -{ - NautilusList *list; - - list = NAUTILUS_LIST (gtk_type_new (nautilus_list_get_type ())); - nautilus_clist_construct (NAUTILUS_CLIST (list), columns, NULL); - if (titles) { - NautilusCList *clist; - int index; - - clist = NAUTILUS_CLIST(list); - - for (index = 0; index < columns; index++) { - clist->column[index].title = g_strdup (titles[index]); - } - } - - nautilus_clist_set_selection_mode (NAUTILUS_CLIST (list), - GTK_SELECTION_MULTIPLE); - - return GTK_WIDGET (list); -} - -NautilusCListRow * -nautilus_list_row_at (NautilusList *list, int y) -{ - NautilusCList *clist; - int row_index, column_index; - - clist = NAUTILUS_CLIST (list); - y -= (GTK_CONTAINER (list)->border_width + - GTK_WIDGET (list)->style->klass->ythickness + - clist->column_title_area.height); - - if (!nautilus_clist_get_selection_info (clist, 10, y, &row_index, &column_index)) { - return NULL; - } - - return g_list_nth (clist->row_list, row_index)->data; -} - -GList * -nautilus_list_get_selection (NautilusList *list) -{ - GList *retval; - GList *p; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), NULL); - - retval = NULL; - for (p = NAUTILUS_CLIST (list)->row_list; p != NULL; p = p->next) { - NautilusCListRow *row; - - row = p->data; - if (row->state == GTK_STATE_SELECTED) - retval = g_list_prepend (retval, row->data); - } - - return retval; -} - -void -nautilus_list_set_selection (NautilusList *list, GList *selection) -{ - gboolean selection_changed; - GHashTable *hash; - GList *p; - int i; - NautilusCListRow *row; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - selection_changed = FALSE; - - hash = g_hash_table_new (NULL, NULL); - for (p = selection; p != NULL; p = p->next) { - g_hash_table_insert (hash, p->data, p->data); - } - - for (p = NAUTILUS_CLIST (list)->row_list, i = 0; p != NULL; p = p->next, i++) { - row = p->data; - selection_changed |= row_set_selected (list, i, row, g_hash_table_lookup (hash, row->data) != NULL); - } - - g_hash_table_destroy (hash); - - if (selection_changed) { - emit_selection_changed (list); - } -} - -void -nautilus_list_each_selected_row (NautilusList *list, NautilusEachRowFunction function, - gpointer data) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_assert (NAUTILUS_IS_LIST (list)); - - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; p != NULL; p = p->next, row_index++) { - row = p->data; - if (row->state != GTK_STATE_SELECTED) - continue; - - if (!function(row, row_index, data)) - return; - } -} - -/** - * nautilus_list_get_first_selected_row: - * - * Get the index of the first selected row, or -1 if no rows are selected. - * @list: Any NautilusList - **/ -int -nautilus_list_get_first_selected_row (NautilusList *list) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), -1); - - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; - p != NULL; - p = p->next, ++row_index) { - row = p->data; - if (row->state == GTK_STATE_SELECTED) - return row_index; - } - - return -1; -} - -/** - * nautilus_list_get_last_selected_row: - * - * Get the index of the last selected row, or -1 if no rows are selected. - * @list: Any GtkCList - **/ -int -nautilus_list_get_last_selected_row (NautilusList *list) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), -1); - - for (p = NAUTILUS_CLIST (list)->row_list_end, row_index = NAUTILUS_CLIST (list)->rows - 1; p != NULL; p = p->prev, --row_index) { - row = p->data; - if (row->state == GTK_STATE_SELECTED) { - return row_index; - } - } - - return -1; -} - -/* Workaround for a bug in GtkCList's insert_row. - * It sets the focus row to 0 if there is exactly one row, - * even if there was no focus on entry. - * Although this works for focus, there may still be a problem - * with selection. - */ -static int -insert_row (NautilusCList *list, int row_index, char *text[]) -{ - gboolean had_focus; - int result; - - had_focus = list->focus_row != -1; - - result = EEL_CALL_PARENT_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, insert_row, (list, row_index, text)); - - if (!had_focus) { - list->focus_row = -1; - } - - return result; -} - - -void -nautilus_list_set_drag_prelight_row (NautilusList *list, int y) -{ - NautilusCList *clist; - NautilusCListRow *row, *last_row; - GdkRectangle rect; - int row_index; - - clist = NAUTILUS_CLIST (list); - - row = NULL; - - if (y >= 0) { - row = nautilus_list_row_at (list, y); - } - - if (row != list->details->drag_prelight_row) { - last_row = list->details->drag_prelight_row; - list->details->drag_prelight_row = row; - - /* Redraw old cell */ - if (last_row != NULL) { - row_index = g_list_index (clist->row_list, last_row); - nautilus_list_get_cell_rectangle (list, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (list), &rect); - } - - /* Draw new cell */ - if (list->details->drag_prelight_row != NULL) { - row_index = g_list_index (clist->row_list, list->details->drag_prelight_row); - nautilus_list_get_cell_rectangle (list, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (list), &rect); - } - } -} - -void -nautilus_list_get_initial_drag_offset (NautilusList *list, int *x, int *y) -{ - *x = list->details->dnd_press_x;// + NAUTILUS_CLIST (list)->hoffset; - *y = list->details->dnd_press_y;// + NAUTILUS_CLIST (list)->voffset; -} - diff --git a/libnautilus-extensions/nautilus-list.h b/libnautilus-extensions/nautilus-list.h deleted file mode 100644 index b9d43d588..000000000 --- a/libnautilus-extensions/nautilus-list.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-list.h: Enhanced version of GtkCList for Nautilus. - - Copyright (C) 1999, 2000 Free Software Foundation - Copyright (C) 2000, 2001 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Federico Mena <federico@nuclecu.unam.mx>, - Ettore Perazzoli <ettore@gnu.org>, - John Sullivan <sullivan@eazel.com>, - Pavel Cisler <pavel@eazel.com> - */ - -#ifndef NAUTILUS_LIST_H -#define NAUTILUS_LIST_H - -#include <libgnome/gnome-defs.h> -#include <cut-n-paste-code/widgets/nautilusclist/nautilusclist.h> - -/* This class was originally derived from the GtkFList class in gmc. - */ - -/* It is sad that we have to do this. GtkCList's behavior is so broken that we - * have to override all the event handlers and implement our own selection - * behavior. Sigh. -Federico - */ - -/* pointer casting for cells */ -#define NAUTILUS_CELL_PIXBUF_LIST(cell) ((NautilusCellPixbufList *) &(cell)) -/* no #define for NAUTILUS_CELL_LINK_TEXT, use GTK_CELL_TEXT instead */ - -/* returns the GList item for the nth row */ -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -typedef struct NautilusCellPixbufList NautilusCellPixbufList; -/* no struct for NautilusCellLinkText, use GtkCellText instead */ - -/* Since the info in each cell must fit in the GtkCell struct that CList defines, - * we disguise ours in the GtkCellWidget format, with our pixbufs list where - * the widget would be. - */ -struct NautilusCellPixbufList -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - GList *pixbufs; /* list of GdkPixbuf * */ -}; - -#define NAUTILUS_TYPE_LIST (nautilus_list_get_type ()) -#define NAUTILUS_LIST(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_LIST, NautilusList)) -#define NAUTILUS_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_LIST, NautilusListClass)) -#define NAUTILUS_IS_LIST(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_LIST)) -#define NAUTILUS_IS_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_LIST)) - -typedef struct NautilusList NautilusList; -typedef struct NautilusListClass NautilusListClass; -typedef struct NautilusListDetails NautilusListDetails; - -struct NautilusList { - NautilusCList clist; - NautilusListDetails *details; -}; - -struct NautilusListClass { - NautilusCListClass parent_class; - - /* Signal: invoke the popup menu for selected items */ - void (* context_click_selection) (NautilusList *list, - GdkEventButton *event); - - /* Signal: invoke the popup menu for empty areas */ - void (* context_click_background) (NautilusList *list, - GdkEventButton *event); - - /* Signal: announce that one or more items have been activated. */ - void (* activate) (NautilusList *list, GList *row_data_list); - - /* Signal: selection has changed */ - void (* selection_changed) (NautilusList *list); - - /* column resize tracking calls */ - void (* column_resize_track_start) (GtkWidget *widget, int column); - void (* column_resize_track) (GtkWidget *widget, int column); - void (* column_resize_track_end) (GtkWidget *widget, int column); - void (* select_matching_name) (GtkWidget *widget, const char *); - void (* select_previous_name) (GtkWidget *widget); - void (* select_next_name) (GtkWidget *widget); - GdkPixbuf (* get_drag_pixbuf) (NautilusList *list, int row_index); - int (* get_sort_column_index) (NautilusList *list); - - /* dnd handling. defer the semantics of dnd to the application side, not nautilus-list */ - gboolean (* handle_dragged_items) (GtkWidget *widget, - int action, - GList *drop_data, - int x, - int y, - guint info); - void (* handle_dropped_items) (GtkWidget *widget, - int action, - GList *drop_data, - int x, - int y, - guint info); - void (* get_default_action) (GtkWidget *widget, - int *default_action, - int *non_default_action, - GdkDragContext *context, - GList *drop_data, - int x, - int y, - guint info); - -}; - -typedef gboolean (* NautilusEachRowFunction) (NautilusCListRow *, int, gpointer); - -GtkType nautilus_list_get_type (void); -GtkWidget * nautilus_list_new_with_titles (int columns, - const char * const *titles); -void nautilus_list_initialize_dnd (NautilusList *list); -GList * nautilus_list_get_selection (NautilusList *list); -void nautilus_list_set_selection (NautilusList *list, - GList *selection); -void nautilus_list_reveal_row (NautilusList *list, - int row); -gboolean nautilus_list_is_row_selected (NautilusList *list, - int row); -void nautilus_list_get_cell_rectangle (NautilusList *clist, - int row_index, - int column_index, - GdkRectangle *result); -void nautilus_list_set_pixbuf_list (NautilusList *list, - gint row, - gint column, - GList *pixbufs); -void nautilus_list_set_pixbuf (NautilusList *list, - int row_index, - int column_index, - GdkPixbuf *pixbuf); -GdkPixbuf *nautilus_list_get_pixbuf (NautilusList *list, - int row_index, - int column_index); -void nautilus_list_mark_cell_as_link (NautilusList *list, - gint row, - gint column); -void nautilus_list_set_single_click_mode (NautilusList *list, - gboolean single_click_mode); -void nautilus_list_select_row (NautilusList *list, - int row); -NautilusCListRow *nautilus_list_row_at (NautilusList *list, - int y); -int nautilus_list_get_first_selected_row (NautilusList *list); -int nautilus_list_get_last_selected_row (NautilusList *list); -void nautilus_list_each_selected_row (NautilusList *list, - NautilusEachRowFunction function, - gpointer data); -gboolean nautilus_list_rejects_dropped_icons (NautilusList *list); -void nautilus_list_set_rejects_dropped_icons (NautilusList *list, - gboolean new_value); -void nautilus_list_set_drag_prelight_row (NautilusList *list, - int y); -void nautilus_list_get_initial_drag_offset (NautilusList *list, - int *x, - int *y); - -void nautilus_list_set_anti_aliased_mode (NautilusList *list, - gboolean anti_aliased_mode); -gboolean nautilus_list_is_anti_aliased (NautilusList *list); - -int nautilus_list_draw_cell_pixbuf (NautilusList *list, - GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, - guint32 bg_rgb, - GdkPixbuf *pixbuf, - int x, - int y); -void nautilus_list_get_cell_style (NautilusList *list, - NautilusCListRow *row, - int state, - int row_index, - int column_index, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc, - guint32 *bg_rgb); -void nautilus_list_set_alternate_row_colors (NautilusList *list, - gboolean state); -void nautilus_list_set_background_color_offsets (NautilusList *list, - long background_offset, - long selection_offset); - -#endif /* NAUTILUS_LIST_H */ - - - - - diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am index 733834e09..aec8b8514 100644 --- a/libnautilus-private/Makefile.am +++ b/libnautilus-private/Makefile.am @@ -27,7 +27,6 @@ INCLUDES = \ dependency_static_libs = \ $(top_builddir)/cut-n-paste-code/widgets/e-paned/libe-paned.la \ - $(top_builddir)/cut-n-paste-code/widgets/nautilusclist/libnautilusclist.la \ $(top_builddir)/cut-n-paste-code/widgets/gimphwrapbox/libgtkhwrapbox.la \ $(NULL) @@ -67,7 +66,6 @@ libnautilus_extensions_la_SOURCES = \ nautilus-audio-player.c \ nautilus-bonobo-extensions.c \ nautilus-bookmark.c \ - nautilus-ctree.c \ nautilus-customization-data.c \ nautilus-dateedit-extensions.c \ nautilus-default-file-icon.c \ @@ -77,11 +75,11 @@ libnautilus_extensions_la_SOURCES = \ nautilus-directory-metafile.c \ nautilus-directory.c \ nautilus-drag-window.c \ - nautilus-drag.c \ nautilus-druid-page-eazel.c \ nautilus-druid.c \ nautilus-entry.c \ nautilus-file-changes-queue.c \ + nautilus-file-dnd.c \ nautilus-file-operations-progress.c \ nautilus-file-operations.c \ nautilus-file-utilities.c \ @@ -100,8 +98,6 @@ libnautilus_extensions_la_SOURCES = \ nautilus-lib-self-check-functions.c \ nautilus-link-set.c \ nautilus-link.c \ - nautilus-list-column-title.c \ - nautilus-list.c \ nautilus-medusa-support.c \ nautilus-merged-directory.c \ nautilus-metafile-factory.c \ @@ -139,7 +135,6 @@ noinst_HEADERS = \ nautilus-bonobo-extensions.h \ nautilus-bookmark.h \ nautilus-cdrom-extensions.h \ - nautilus-ctree.h \ nautilus-customization-data.h \ nautilus-dateedit-extensions.h \ nautilus-default-file-icon.h \ @@ -150,12 +145,12 @@ noinst_HEADERS = \ nautilus-directory-private.h \ nautilus-directory.h \ nautilus-drag-window.h \ - nautilus-drag.h \ nautilus-druid-page-eazel.h \ nautilus-druid.h \ nautilus-entry.h \ nautilus-file-attributes.h \ nautilus-file-changes-queue.h \ + nautilus-file-dnd.h \ nautilus-file-operations-progress.h \ nautilus-file-operations.h \ nautilus-file-private.h \ @@ -178,8 +173,6 @@ noinst_HEADERS = \ nautilus-lib-self-check-functions.h \ nautilus-link-set.h \ nautilus-link.h \ - nautilus-list-column-title.h \ - nautilus-list.h \ nautilus-medusa-support.h \ nautilus-merged-directory.h \ nautilus-metadata.h \ diff --git a/libnautilus-private/nautilus-ctree.c b/libnautilus-private/nautilus-ctree.c deleted file mode 100644 index 029f04128..000000000 --- a/libnautilus-private/nautilus-ctree.c +++ /dev/null @@ -1,6125 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald, - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * NautilusCTree widget for GTK+ - * Copyright (C) 1998 Lars Hamann and Stefan Jeske - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - - -#include <config.h> -#include "nautilus-ctree.h" - -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkx.h> -#include <gdk/gdkx.h> -#include <gtk/gtkbindings.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkmain.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-graphic-effects.h> -#include <eel/eel-gtk-extensions.h> -#include <stdlib.h> -#include <string.h> - -#define PM_SIZE 8 -#define TAB_SIZE (PM_SIZE + 6) -#define CELL_SPACING 1 -#define CLIST_OPTIMUM_SIZE 64 -#define COLUMN_INSET 3 -#define DRAG_WIDTH 6 - -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) -#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ - ((clist)->row_height + CELL_SPACING)) -#define COLUMN_LEFT_XPIXEL(clist, col) ((clist)->column[(col)].area.x \ - + (clist)->hoffset) -#define COLUMN_LEFT(clist, column) ((clist)->column[(column)].area.x) - -static inline gint -COLUMN_FROM_XPIXEL (NautilusCList * clist, - gint x) -{ - gint i, cx; - - for (i = 0; i < clist->columns; i++) - if (clist->column[i].visible) - { - cx = clist->column[i].area.x + clist->hoffset; - - if (x >= (cx - (COLUMN_INSET + CELL_SPACING)) && - x <= (cx + clist->column[i].area.width + COLUMN_INSET)) - return i; - } - - /* no match */ - return -1; -} - -#define NAUTILUS_CLIST_CLASS_FW(_widget_) NAUTILUS_CLIST_CLASS (((GtkObject*) (_widget_))->klass) -#define CLIST_UNFROZEN(clist) nautilus_clist_check_unfrozen (clist) -#define CLIST_REFRESH(clist) G_STMT_START { \ - if (CLIST_UNFROZEN (clist)) \ - NAUTILUS_CLIST_CLASS_FW (clist)->refresh (clist); \ -} G_STMT_END - - -enum { - ARG_0, - ARG_N_COLUMNS, - ARG_TREE_COLUMN, - ARG_INDENT, - ARG_SPACING, - ARG_SHOW_STUB, - ARG_LINE_STYLE -}; - - -static void nautilus_ctree_class_init (NautilusCTreeClass *klass); -static void nautilus_ctree_init (NautilusCTree *ctree); -static void nautilus_ctree_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_ctree_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void nautilus_ctree_realize (GtkWidget *widget); -static void nautilus_ctree_unrealize (GtkWidget *widget); -static gint nautilus_ctree_button_press (GtkWidget *widget, - GdkEventButton *event); -static gboolean nautilus_ctree_event (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); -static void ctree_attach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void ctree_detach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static gint nautilus_ctree_draw_expander (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - GtkStyle *style, - GdkRectangle *clip_rectangle, - gint x); -static gint nautilus_ctree_draw_lines (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style); -static void draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row); -static void draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos); -static void tree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -static gboolean set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -static void set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -static NautilusCTreeRow *row_new (NautilusCTree *ctree); -static void row_delete (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row); -static void tree_delete (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_delete_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void real_clear (NautilusCList *clist); -static void tree_update_level (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void real_select_all (NautilusCList *clist); -static void real_unselect_all (NautilusCList *clist); -static void tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void tree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -static void tree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void change_focus_row_expansion (NautilusCTree *ctree, - NautilusCTreeExpansionType expansion); -static void real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event); -static void real_tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void real_tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void real_tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node); -static void real_tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node); -static void real_tree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); -static void real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row); -static void real_tree_activate_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -static void nautilus_ctree_link (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gboolean update_focus_row); -static void nautilus_ctree_unlink (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean update_focus_row); -static NautilusCTreeNode * nautilus_ctree_last_visible (NautilusCTree *ctree, - NautilusCTreeNode *node); -static gboolean ctree_is_hot_spot (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint row, - gint x, - gint y); -static void tree_sort (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static void fake_unselect_all (NautilusCList *clist, - gint row); -static GList * selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element); -static void resync_selection (NautilusCList *clist, - GdkEvent *event); -static void real_undo_selection (NautilusCList *clist); -static void select_row_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -static gint real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]); -static void real_remove_row (NautilusCList *clist, - gint row); -static void real_sort_list (NautilusCList *clist); -static void cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition); -static void column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width); -static void auto_resize_columns (NautilusCList *clist); - - -static gboolean check_drag (NautilusCTree *ctree, - NautilusCTreeNode *drag_source, - NautilusCTreeNode *drag_target, - NautilusCListDragPos insert_pos); -static void nautilus_ctree_drag_begin (GtkWidget *widget, - GdkDragContext *context); -static gint nautilus_ctree_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time); -static void nautilus_ctree_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint32 time); -static void remove_grab (NautilusCList *clist); -static void drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info); - - -enum -{ - TREE_SELECT_ROW, - TREE_UNSELECT_ROW, - TREE_EXPAND, - TREE_COLLAPSE, - TREE_MOVE, - CHANGE_FOCUS_ROW_EXPANSION, - TREE_ACTIVATE_ROW, - LAST_SIGNAL -}; - -static NautilusCListClass *parent_class = NULL; -static GtkContainerClass *container_class = NULL; -static guint ctree_signals[LAST_SIGNAL] = {0}; - - -GtkType -nautilus_ctree_get_type (void) -{ - static GtkType ctree_type = 0; - - if (!ctree_type) - { - static const GtkTypeInfo ctree_info = - { - "NautilusCTree", - sizeof (NautilusCTree), - sizeof (NautilusCTreeClass), - (GtkClassInitFunc) nautilus_ctree_class_init, - (GtkObjectInitFunc) nautilus_ctree_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - ctree_type = gtk_type_unique (NAUTILUS_TYPE_LIST, &ctree_info); - } - - return ctree_type; -} - -static void -nautilus_ctree_class_init (NautilusCTreeClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - NautilusCListClass *clist_class; - GtkBindingSet *binding_set; - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - container_class = (GtkContainerClass *) klass; - clist_class = (NautilusCListClass *) klass; - - parent_class = gtk_type_class (NAUTILUS_TYPE_LIST); - container_class = gtk_type_class (GTK_TYPE_CONTAINER); - - gtk_object_add_arg_type ("NautilusCTree::n_columns", - GTK_TYPE_UINT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_N_COLUMNS); - gtk_object_add_arg_type ("NautilusCTree::tree_column", - GTK_TYPE_UINT, - GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, - ARG_TREE_COLUMN); - gtk_object_add_arg_type ("NautilusCTree::indent", - GTK_TYPE_UINT, - GTK_ARG_READWRITE, - ARG_INDENT); - gtk_object_add_arg_type ("NautilusCTree::spacing", - GTK_TYPE_UINT, - GTK_ARG_READWRITE, - ARG_SPACING); - gtk_object_add_arg_type ("NautilusCTree::show_stub", - GTK_TYPE_BOOL, - GTK_ARG_READWRITE, - ARG_SHOW_STUB); - object_class->set_arg = nautilus_ctree_set_arg; - object_class->get_arg = nautilus_ctree_get_arg; - - ctree_signals[TREE_SELECT_ROW] = - gtk_signal_new ("tree_select_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_select_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - ctree_signals[TREE_UNSELECT_ROW] = - gtk_signal_new ("tree_unselect_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_unselect_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - ctree_signals[TREE_EXPAND] = - gtk_signal_new ("tree_expand", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_expand), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); - ctree_signals[TREE_COLLAPSE] = - gtk_signal_new ("tree_collapse", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_collapse), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); - ctree_signals[TREE_MOVE] = - gtk_signal_new ("tree_move", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_move), - gtk_marshal_NONE__POINTER_POINTER_POINTER, - GTK_TYPE_NONE, 3, GTK_TYPE_CTREE_NODE, - GTK_TYPE_CTREE_NODE, GTK_TYPE_CTREE_NODE); - ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] = - gtk_signal_new ("change_focus_row_expansion", - GTK_RUN_LAST | GTK_RUN_ACTION, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, - change_focus_row_expansion), - gtk_marshal_NONE__ENUM, - GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_EXPANSION_TYPE); - ctree_signals[TREE_ACTIVATE_ROW] = - gtk_signal_new ("tree_activate_row", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusCTreeClass, tree_activate_row), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, ctree_signals, LAST_SIGNAL); - - widget_class->realize = nautilus_ctree_realize; - widget_class->unrealize = nautilus_ctree_unrealize; - widget_class->button_press_event = nautilus_ctree_button_press; - - widget_class->drag_begin = nautilus_ctree_drag_begin; - widget_class->drag_motion = nautilus_ctree_drag_motion; - widget_class->drag_data_received = nautilus_ctree_drag_data_received; - - clist_class->select_row = real_select_row; - clist_class->unselect_row = real_unselect_row; - clist_class->row_move = real_row_move; - clist_class->undo_selection = real_undo_selection; - clist_class->resync_selection = resync_selection; - clist_class->selection_find = selection_find; - clist_class->click_column = NULL; - clist_class->draw_row = draw_row; - clist_class->draw_drag_highlight = draw_drag_highlight; - clist_class->clear = real_clear; - clist_class->select_all = real_select_all; - clist_class->unselect_all = real_unselect_all; - clist_class->fake_unselect_all = fake_unselect_all; - clist_class->insert_row = real_insert_row; - clist_class->remove_row = real_remove_row; - clist_class->sort_list = real_sort_list; - clist_class->set_cell_contents = set_cell_contents; - clist_class->cell_size_request = cell_size_request; - - klass->tree_select_row = real_tree_select; - klass->tree_unselect_row = real_tree_unselect; - klass->tree_expand = real_tree_expand; - klass->tree_collapse = real_tree_collapse; - klass->tree_move = real_tree_move; - klass->change_focus_row_expansion = change_focus_row_expansion; - klass->tree_activate_row = real_tree_activate_row; - - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, - '+', GDK_SHIFT_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Add, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_EXPAND); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Add, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - '-', 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Subtract, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_COLLAPSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Subtract, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE); - gtk_binding_entry_add_signal (binding_set, - '=', 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Multiply, 0, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, NAUTILUS_CTREE_EXPANSION_TOGGLE); - gtk_binding_entry_add_signal (binding_set, - GDK_KP_Multiply, GDK_CONTROL_MASK, - "change_focus_row_expansion", 1, - GTK_TYPE_ENUM, - NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE); -} - -static void -nautilus_ctree_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCTree *ctree; - - ctree = NAUTILUS_CTREE (object); - - switch (arg_id) - { - case ARG_N_COLUMNS: /* construct-only arg, only set when !GTK_CONSTRUCTED */ - if (ctree->tree_column) - nautilus_ctree_construct (ctree, - MAX (1, GTK_VALUE_UINT (*arg)), - ctree->tree_column, NULL); - else - NAUTILUS_CLIST (ctree)->columns = MAX (1, GTK_VALUE_UINT (*arg)); - break; - case ARG_TREE_COLUMN: /* construct-only arg, only set when !GTK_CONSTRUCTED */ - if (NAUTILUS_CLIST (ctree)->columns) - nautilus_ctree_construct (ctree, - NAUTILUS_CLIST (ctree)->columns, - MAX (1, GTK_VALUE_UINT (*arg)), - NULL); - else - ctree->tree_column = MAX (1, GTK_VALUE_UINT (*arg)); - break; - case ARG_INDENT: - nautilus_ctree_set_indent (ctree, GTK_VALUE_UINT (*arg)); - break; - case ARG_SPACING: - nautilus_ctree_set_spacing (ctree, GTK_VALUE_UINT (*arg)); - break; - case ARG_SHOW_STUB: - nautilus_ctree_set_show_stub (ctree, GTK_VALUE_BOOL (*arg)); - break; - case ARG_LINE_STYLE: - nautilus_ctree_set_line_style (ctree, GTK_VALUE_ENUM (*arg)); - break; - default: - break; - } -} - -static void -nautilus_ctree_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) -{ - NautilusCTree *ctree; - - ctree = NAUTILUS_CTREE (object); - - switch (arg_id) - { - case ARG_N_COLUMNS: - GTK_VALUE_UINT (*arg) = NAUTILUS_CLIST (ctree)->columns; - break; - case ARG_TREE_COLUMN: - GTK_VALUE_UINT (*arg) = ctree->tree_column; - break; - case ARG_INDENT: - GTK_VALUE_UINT (*arg) = ctree->tree_indent; - break; - case ARG_SPACING: - GTK_VALUE_UINT (*arg) = ctree->tree_spacing; - break; - case ARG_SHOW_STUB: - GTK_VALUE_BOOL (*arg) = ctree->show_stub; - break; - case ARG_LINE_STYLE: - GTK_VALUE_ENUM (*arg) = ctree->line_style; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static void -nautilus_ctree_init (NautilusCTree *ctree) -{ - NautilusCList *clist; - - NAUTILUS_CLIST_SET_FLAG (ctree, CLIST_DRAW_DRAG_RECT); - NAUTILUS_CLIST_SET_FLAG (ctree, CLIST_DRAW_DRAG_LINE); - - clist = NAUTILUS_CLIST (ctree); - - ctree->tree_indent = 20; - ctree->tree_spacing = 5; - ctree->tree_column = 0; - ctree->line_style = NAUTILUS_CTREE_LINES_NONE; - ctree->drag_compare = NULL; - ctree->show_stub = TRUE; - ctree->prelight_node = NULL; - - clist->button_actions[0] |= NAUTILUS_BUTTON_EXPANDS; - - /* Some random GNOME luser wants trees to look `normal' */ - nautilus_list_set_alternate_row_colors (NAUTILUS_LIST (ctree), FALSE); - nautilus_list_set_background_color_offsets (NAUTILUS_LIST (ctree), - G_STRUCT_OFFSET (GtkStyle, - base[GTK_STATE_NORMAL]), -1); - - gtk_signal_connect (GTK_OBJECT (ctree), "event", - GTK_SIGNAL_FUNC (nautilus_ctree_event), ctree); -} - -static void -ctree_attach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style) - NAUTILUS_CTREE_ROW (node)->row.style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.style, clist->clist_window); - - if (NAUTILUS_CTREE_ROW (node)->row.fg_set || NAUTILUS_CTREE_ROW (node)->row.bg_set) - { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (ctree)); - if (NAUTILUS_CTREE_ROW (node)->row.fg_set) - gdk_color_alloc (colormap, &(NAUTILUS_CTREE_ROW (node)->row.foreground)); - if (NAUTILUS_CTREE_ROW (node)->row.bg_set) - gdk_color_alloc (colormap, &(NAUTILUS_CTREE_ROW (node)->row.background)); - } - - for (i = 0; i < clist->columns; i++) - if (NAUTILUS_CTREE_ROW (node)->row.cell[i].style) - NAUTILUS_CTREE_ROW (node)->row.cell[i].style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.cell[i].style, - clist->clist_window); -} - -static void -ctree_detach_styles (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.style); - for (i = 0; i < clist->columns; i++) - if (NAUTILUS_CTREE_ROW (node)->row.cell[i].style) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.cell[i].style); -} - -static void -nautilus_ctree_realize (GtkWidget *widget) -{ - NautilusCTree *ctree; - NautilusCList *clist; - GdkGCValues values; - NautilusCTreeNode *node; - NautilusCTreeNode *child; - gint i; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - - GTK_WIDGET_CLASS (parent_class)->realize (widget); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - node = NAUTILUS_CTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) - { - if (!NAUTILUS_CTREE_ROW (node)->is_leaf && !NAUTILUS_CTREE_ROW (node)->expanded) - for (child = NAUTILUS_CTREE_ROW (node)->children; - child != NULL; - child = NAUTILUS_CTREE_ROW (child)->sibling) - nautilus_ctree_pre_recursive (ctree, child, ctree_attach_styles, NULL); - node = NAUTILUS_CTREE_NODE_NEXT (node); - } - - values.foreground = widget->style->fg[GTK_STATE_NORMAL]; - values.background = widget->style->base[GTK_STATE_NORMAL]; - values.subwindow_mode = GDK_INCLUDE_INFERIORS; - values.line_style = GDK_LINE_SOLID; - ctree->lines_gc = gdk_gc_new_with_values (NAUTILUS_CLIST(widget)->clist_window, - &values, - GDK_GC_FOREGROUND | - GDK_GC_BACKGROUND | - GDK_GC_SUBWINDOW | - GDK_GC_LINE_STYLE); - - if (ctree->line_style == NAUTILUS_CTREE_LINES_DOTTED) - { - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, None, None); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - } -} - -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -static gint -nautilus_ctree_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) -{ - GdkEventMotion *motion; - int press_row, press_column, row; - NautilusCTree *tree; - NautilusCTreeNode *node, *old_node; - NautilusCTreeRow *ctree_row; - NautilusCList *clist; - gint x, y; - GdkModifierType button; - - tree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - /* Do prelighting */ - if (event->type == GDK_MOTION_NOTIFY) { - motion = (GdkEventMotion *) event; - - /* Get node that we are over */ - row = nautilus_clist_get_selection_info (clist, motion->x, motion->y, &press_row, &press_column); - if (row <= 0) { - return FALSE; - } - - ctree_row = ROW_ELEMENT (clist, press_row)->data; - if (ctree_row == NULL) { - return FALSE; - } - - node = nautilus_ctree_find_node_ptr (tree, ctree_row); - if (node == NULL) { - return FALSE; - } - - /* Cancel prelighting if we have a button pressed */ - gdk_window_get_pointer (widget->window, &x, &y, &button); - if ((button & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK | GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)) != 0) { - if (nautilus_ctree_is_hot_spot (tree, motion->x, motion->y)) { - /* Handle moving in and out of hotspot while mouse is down */ - if (!ctree_row->in_hotspot) { - ctree_row->in_hotspot = TRUE; - nautilus_ctree_draw_node (tree, node); - } - } else { - if (ctree_row->in_hotspot) { - ctree_row->in_hotspot = FALSE; - nautilus_ctree_draw_node (tree, node); - } - } - - /* Remove prelighting */ - if (tree->prelight_node != NULL) { - old_node = tree->prelight_node; - tree->prelight_node = NULL; - nautilus_ctree_draw_node (tree, old_node); - } - return FALSE; - } - - if (nautilus_ctree_is_hot_spot (tree, motion->x, motion->y)) { - if (node != tree->prelight_node) { - /* Redraw old prelit node and save and draw new highlight */ - old_node = tree->prelight_node; - tree->prelight_node = node; - nautilus_ctree_draw_node (tree, old_node); - nautilus_ctree_draw_node (tree, tree->prelight_node); - } - } else if (tree->prelight_node != NULL) { - /* End prelighting of last expander */ - old_node = tree->prelight_node; - tree->prelight_node = NULL; - nautilus_ctree_draw_node (tree, old_node); - } - } - - return FALSE; -} - -static void -nautilus_ctree_unrealize (GtkWidget *widget) -{ - NautilusCTree *ctree; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - - GTK_WIDGET_CLASS (parent_class)->unrealize (widget); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - if (GTK_WIDGET_REALIZED (widget)) - { - NautilusCTreeNode *node; - NautilusCTreeNode *child; - gint i; - - node = NAUTILUS_CTREE_NODE (clist->row_list); - for (i = 0; i < clist->rows; i++) - { - if (!NAUTILUS_CTREE_ROW (node)->is_leaf && - !NAUTILUS_CTREE_ROW (node)->expanded) - for (child = NAUTILUS_CTREE_ROW (node)->children; - child != NULL; - child = NAUTILUS_CTREE_ROW (child)->sibling) - nautilus_ctree_pre_recursive(ctree, child, ctree_detach_styles, NULL); - node = NAUTILUS_CTREE_NODE_NEXT (node); - } - } - - gdk_gc_destroy (ctree->lines_gc); -} - -static gint -nautilus_ctree_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusCTree *ctree; - NautilusCList *clist; - gint button_actions; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - button_actions = clist->button_actions[event->button - 1]; - - if (button_actions == NAUTILUS_BUTTON_IGNORED) { - return FALSE; - } - - if (event->window == clist->clist_window) - { - NautilusCTreeNode *work; - gint x; - gint y; - gint row; - gint column; - - x = event->x; - y = event->y; - - if (!nautilus_clist_get_selection_info (clist, x, y, &row, &column)) { - return FALSE; - } - - work = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - - if (button_actions & NAUTILUS_BUTTON_EXPANDS && - (!NAUTILUS_CTREE_ROW (work)->is_leaf && - ctree_is_hot_spot (ctree, work, row, x, y))) - { - if (NAUTILUS_CTREE_ROW (work)->expanded) { - nautilus_ctree_collapse (ctree, work); - } else { - nautilus_ctree_expand (ctree, work); - } - return FALSE; - } else if (event->type == GDK_2BUTTON_PRESS) { - /* double-click on a row = "activate" */ - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_ACTIVATE_ROW], - work, column); - } - } - - return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); -} - -static void -draw_drag_highlight (NautilusCList *clist, - NautilusCListRow *dest_row, - gint dest_row_number, - NautilusCListDragPos drag_pos) -{ - NautilusCTree *ctree; - GdkPoint points[4]; - gint level; - gint i; - gint y = 0; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - level = ((NautilusCTreeRow *)(dest_row))->level; - - y = ROW_TOP_YPIXEL (clist, dest_row_number) - 1; - - switch (drag_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - break; - case NAUTILUS_CLIST_DRAG_AFTER: - y += clist->row_height + 1; - case NAUTILUS_CLIST_DRAG_BEFORE: - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - if (ctree->tree_column > 0) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, 0), y, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column - 1)+ - clist->column[ctree->tree_column - 1].area.width, - y); - - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - - (ctree->tree_indent - PM_SIZE) / 2, y, - GTK_WIDGET (ctree)->allocation.width, y); - break; - case GTK_JUSTIFY_RIGHT: - if (ctree->tree_column < clist->columns - 1) - gdk_draw_line (clist->clist_window, clist->xor_gc, - COLUMN_LEFT_XPIXEL(clist, ctree->tree_column + 1), - y, - COLUMN_LEFT_XPIXEL(clist, clist->columns - 1) + - clist->column[clist->columns - 1].area.width, y); - - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - + clist->column[ctree->tree_column].area.width - - ctree->tree_indent * level + - (ctree->tree_indent - PM_SIZE) / 2, y); - break; - } - else - gdk_draw_line (clist->clist_window, clist->xor_gc, - 0, y, clist->clist_window_width, y); - break; - case NAUTILUS_CLIST_DRAG_INTO: - y = ROW_TOP_YPIXEL (clist, dest_row_number) + clist->row_height; - - if (clist->column[ctree->tree_column].visible) - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) + - ctree->tree_indent * level - (ctree->tree_indent - PM_SIZE) / 2; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - - if (ctree->tree_column > 0) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, - ctree->tree_column - 1) + - clist->column[ctree->tree_column - 1].area.width ; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, points[i+1].x, - points[i+1].y); - } - break; - case GTK_JUSTIFY_RIGHT: - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column) - - ctree->tree_indent * level + (ctree->tree_indent - PM_SIZE) / 2 + - clist->column[ctree->tree_column].area.width; - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = 0; - points[1].y = points[0].y; - points[2].x = 0; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - - if (ctree->tree_column < clist->columns - 1) - { - points[0].x = COLUMN_LEFT_XPIXEL(clist, ctree->tree_column +1); - points[0].y = y; - points[3].x = points[0].x; - points[3].y = y - clist->row_height - 1; - points[1].x = clist->clist_window_width - 1; - points[1].y = points[0].y; - points[2].x = points[1].x; - points[2].y = points[3].y; - - for (i = 0; i < 3; i++) - gdk_draw_line (clist->clist_window, clist->xor_gc, - points[i].x, points[i].y, - points[i+1].x, points[i+1].y); - } - break; - } - else - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, y - clist->row_height, - clist->clist_window_width - 1, clist->row_height); - break; - } -} - -static NautilusCTreeRow * -nautilus_ctree_row_at (NautilusCTree *ctree, int y) -{ - int row_index, column_index; - - y -= (GTK_CONTAINER (ctree)->border_width + - GTK_WIDGET (ctree)->style->klass->ythickness + - NAUTILUS_CLIST (ctree)->column_title_area.height); - - if (!nautilus_clist_get_selection_info (NAUTILUS_CLIST (ctree), 10, y, &row_index, &column_index)) { - return NULL; - } - - return g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row_index)->data; -} - - -static void -get_cell_rectangle (NautilusCList *clist, int row_index, int column_index, GdkRectangle *result) -{ - result->x = clist->column[column_index].area.x + clist->hoffset; - result->y = ROW_TOP_YPIXEL (clist, row_index); - result->width = clist->column[column_index].area.width; - result->height = clist->row_height; -} - - -void -nautilus_ctree_set_prelight (NautilusCTree *ctree, - int y) -{ - NautilusCList *clist; - NautilusCTreeRow *row, *last_row; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - row = NULL; - - if (y >= 0) { - row = nautilus_ctree_row_at (ctree, y); - } - - if (row != ctree->dnd_prelighted_row) { - last_row = ctree->dnd_prelighted_row; - ctree->dnd_prelighted_row = row; - - { - GdkRectangle rect; - int row_index; - /* Redraw old cell */ - if (last_row != NULL) { - row_index = g_list_index (clist->row_list, last_row); - get_cell_rectangle (clist, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (clist), &rect); - } - - /* Draw new cell */ - if (ctree->dnd_prelighted_row != NULL) { - row_index = g_list_index (clist->row_list, ctree->dnd_prelighted_row); - get_cell_rectangle (clist, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (clist), &rect); - } - } - } -} - -static gint -nautilus_ctree_draw_expander (NautilusCTree *ctree, NautilusCTreeRow *ctree_row, GtkStyle *style, - GdkRectangle *clip_rectangle, gint x) -{ - NautilusCList *clist; - GdkPoint points[3]; - gint justification_factor; - gint y; - NautilusCTreeNode *node; - - clist = NAUTILUS_CLIST (ctree); - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) - justification_factor = -1; - else - justification_factor = 1; - - y = (clip_rectangle->y + (clip_rectangle->height - PM_SIZE) / 2 - (clip_rectangle->height + 1) % 2); - - if (ctree_row->is_leaf) { - return x + justification_factor * (PM_SIZE + 3); - } - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], clip_rectangle); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], clip_rectangle); - - if (ctree_row->expanded) - { - points[0].x = x; - points[0].y = y + (PM_SIZE + 2) / 6; - points[1].x = points[0].x + justification_factor * (PM_SIZE + 2); - points[1].y = points[0].y; - points[2].x = (points[0].x + justification_factor * (PM_SIZE + 2) / 2); - points[2].y = y + 2 * (PM_SIZE + 2) / 3; - } else { - points[0].x = x + justification_factor * ((PM_SIZE + 2) / 6 + 2); - points[0].y = y - 1; - points[1].x = points[0].x; - points[1].y = points[0].y + (PM_SIZE + 2); - points[2].x = (points[0].x + justification_factor * (2 * (PM_SIZE + 2) / 3 - 1)); - points[2].y = points[0].y + (PM_SIZE + 2) / 2; - } - - gdk_draw_polygon (clist->clist_window, style->base_gc[GTK_STATE_NORMAL], TRUE, points, 3); - if (ctree_row->mouse_down) { - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], !ctree_row->in_hotspot, points, 3); - } else { - node = nautilus_ctree_find_node_ptr (ctree, ctree_row); - if (node != NULL) { - if (node == ctree->prelight_node) { - /* Draw prelight state */ - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], FALSE, points, 3); - } else { - gdk_draw_polygon (clist->clist_window, style->fg_gc[GTK_STATE_NORMAL], TRUE, points, 3); - } - } - } - - x += justification_factor * (PM_SIZE + 3); - - gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL); - gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL); - - return x; -} - -static gint -nautilus_ctree_draw_lines (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row, - gint row, - gint column, - gint state, - GdkRectangle *clip_rectangle, - GdkRectangle *cell_rectangle, - GdkRectangle *crect, - GdkRectangle *area, - GtkStyle *style) -{ - NautilusCList *clist; - NautilusCTreeNode *node; - NautilusCTreeNode *parent; - GdkRectangle tree_rectangle; - GdkRectangle tc_rectangle; - GdkGC *bg_gc; - gint offset; - gint offset_x; - gint offset_y; - gint xcenter; - gint ycenter; - gint next_level; - gint column_right; - gint column_left; - gint justify_right; - gint justification_factor; - - clist = NAUTILUS_CLIST (ctree); - ycenter = clip_rectangle->y + (clip_rectangle->height / 2); - justify_right = (clist->column[column].justification == GTK_JUSTIFY_RIGHT); - - if (justify_right) - { - offset = (clip_rectangle->x + clip_rectangle->width - 1 - - ctree->tree_indent * (ctree_row->level - 1)); - justification_factor = -1; - } - else - { - offset = clip_rectangle->x + ctree->tree_indent * (ctree_row->level - 1); - justification_factor = 1; - } - - switch (ctree->line_style) - { - case NAUTILUS_CTREE_LINES_NONE: - break; - case NAUTILUS_CTREE_LINES_TABBED: - xcenter = offset + justification_factor * TAB_SIZE; - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - CELL_SPACING); - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter; - tree_rectangle.width = column_right - xcenter; - } - else - { - tree_rectangle.x = column_left; - tree_rectangle.width = xcenter - column_left; - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - { - offset += justification_factor * 3; - break; - } - } - - gdk_gc_set_clip_rectangle (ctree->lines_gc, crect); - - next_level = ctree_row->level; - - if (!ctree_row->sibling || (ctree_row->children && ctree_row->expanded)) - { - node = nautilus_ctree_find_node_ptr (ctree, ctree_row); - if (NAUTILUS_CTREE_NODE_NEXT (node)) - next_level = NAUTILUS_CTREE_ROW (NAUTILUS_CTREE_NODE_NEXT (node))->level; - else - next_level = 0; - } - - if (ctree->tree_indent > 0) - { - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if ((justify_right && xcenter < column_left) || - (!justify_right && xcenter > column_right)) - { - node = NAUTILUS_CTREE_ROW (node)->parent; - continue; - } - - tree_rectangle.y = cell_rectangle->y; - tree_rectangle.height = cell_rectangle->height; - if (justify_right) - { - tree_rectangle.x = MAX (xcenter - ctree->tree_indent + 1, - column_left); - tree_rectangle.width = MIN (xcenter - column_left, - ctree->tree_indent); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - ctree->tree_indent); - } - - if (!area || gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &NAUTILUS_CTREE_ROW (node)->row.background); - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - if (next_level > NAUTILUS_CTREE_ROW (node)->level) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, crect->y, - xcenter, crect->y + crect->height); - else - { - gint width; - - offset_x = MIN (ctree->tree_indent, 2 * TAB_SIZE); - width = offset_x / 2 + offset_x % 2; - - parent = NAUTILUS_CTREE_ROW (node)->parent; - - tree_rectangle.y = ycenter; - tree_rectangle.height = (cell_rectangle->y - ycenter + - cell_rectangle->height); - - if (justify_right) - { - tree_rectangle.x = MAX(xcenter + 1 - width, column_left); - tree_rectangle.width = MIN (xcenter + 1 - column_left, - width); - } - else - { - tree_rectangle.x = xcenter; - tree_rectangle.width = MIN (column_right - xcenter, - width); - } - - if (!area || - gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - { - if (parent) - { - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (parent)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, - &NAUTILUS_CTREE_ROW (parent)->row.background); - } - else if (state == GTK_STATE_SELECTED) - bg_gc = style->base_gc[state]; - else - bg_gc = GTK_WIDGET (clist)->style->base_gc[state]; - - if (!area) - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else - gdk_draw_rectangle (clist->clist_window, - bg_gc, TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &NAUTILUS_CTREE_ROW (node)->row, - state, row, column, NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground - (clist->bg_gc, &NAUTILUS_CTREE_ROW (node)->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - xcenter - (justify_right * offset_x), - cell_rectangle->y, - offset_x, clist->row_height, - (180 + (justify_right * 90)) * 64, 90 * 64); - gdk_gc_set_clip_rectangle (bg_gc, NULL); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y, xcenter, ycenter); - - if (justify_right) - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter - offset_x, cell_rectangle->y, - offset_x, clist->row_height, - 270 * 64, 90 * 64); - else - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - xcenter, cell_rectangle->y, - offset_x, clist->row_height, - 180 * 64, 90 * 64); - } - node = NAUTILUS_CTREE_ROW (node)->parent; - } - } - - if (state != GTK_STATE_SELECTED) - { - tree_rectangle.y = clip_rectangle->y; - tree_rectangle.height = clip_rectangle->height; - tree_rectangle.width = COLUMN_INSET + CELL_SPACING + - MIN (clist->column[ctree->tree_column].area.width + COLUMN_INSET, - TAB_SIZE); - - if (justify_right) - tree_rectangle.x = MAX (xcenter + 1, column_left); - else - tree_rectangle.x = column_left; - - if (!area) - gdk_draw_rectangle (clist->clist_window, - GTK_WIDGET - (ctree)->style->base_gc[GTK_STATE_NORMAL], - TRUE, - tree_rectangle.x, - tree_rectangle.y, - tree_rectangle.width, - tree_rectangle.height); - else if (gdk_rectangle_intersect (area, &tree_rectangle, - &tc_rectangle)) - gdk_draw_rectangle (clist->clist_window, - GTK_WIDGET - (ctree)->style->base_gc[GTK_STATE_NORMAL], - TRUE, - tc_rectangle.x, - tc_rectangle.y, - tc_rectangle.width, - tc_rectangle.height); - } - - xcenter = offset + (justification_factor * ctree->tree_indent / 2); - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), - &ctree_row->row, state, row, column, - NULL, NULL, &bg_gc, NULL); - if (bg_gc == clist->bg_gc) - gdk_gc_set_foreground (clist->bg_gc, &ctree_row->row.background); - - gdk_gc_set_clip_rectangle (bg_gc, crect); - if (ctree_row->is_leaf) - { - GdkPoint points[6]; - - points[0].x = offset + justification_factor * TAB_SIZE; - points[0].y = cell_rectangle->y; - - points[1].x = points[0].x - justification_factor * 4; - points[1].y = points[0].y; - - points[2].x = points[1].x - justification_factor * 2; - points[2].y = points[1].y + 3; - - points[3].x = points[2].x; - points[3].y = points[2].y + clist->row_height - 5; - - points[4].x = points[3].x + justification_factor * 2; - points[4].y = points[3].y + 3; - - points[5].x = points[4].x + justification_factor * 4; - points[5].y = points[4].y; - - gdk_draw_polygon (clist->clist_window, bg_gc, TRUE, points, 6); - gdk_draw_lines (clist->clist_window, ctree->lines_gc, points, 6); - } - else - { - gdk_draw_arc (clist->clist_window, bg_gc, TRUE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - gdk_draw_arc (clist->clist_window, ctree->lines_gc, FALSE, - offset - (justify_right * 2 * TAB_SIZE), - cell_rectangle->y, - 2 * TAB_SIZE, clist->row_height, - (90 + (180 * justify_right)) * 64, 180 * 64); - } - gdk_gc_set_clip_rectangle (bg_gc, NULL); - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - - offset += justification_factor * 3; - break; - default: - xcenter = offset + justification_factor * PM_SIZE / 2; - - if (area) - { - tree_rectangle.y = crect->y; - tree_rectangle.height = crect->height; - - if (justify_right) - { - tree_rectangle.x = xcenter - PM_SIZE / 2 - 2; - tree_rectangle.width = (clip_rectangle->x + - clip_rectangle->width -tree_rectangle.x); - } - else - { - tree_rectangle.x = clip_rectangle->x + PM_SIZE / 2; - tree_rectangle.width = (xcenter + PM_SIZE / 2 + 2 - - clip_rectangle->x); - } - - if (!gdk_rectangle_intersect (area, &tree_rectangle, &tc_rectangle)) - break; - } - - offset_x = 1; - offset_y = 0; - if (ctree->line_style == NAUTILUS_CTREE_LINES_DOTTED) - { - offset_x += abs((clip_rectangle->x + clist->hoffset) % 2); - offset_y = abs((cell_rectangle->y + clist->voffset) % 2); - } - - clip_rectangle->y--; - clip_rectangle->height++; - gdk_gc_set_clip_rectangle (ctree->lines_gc, clip_rectangle); - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, - (ctree->show_stub || clist->row_list->data != ctree_row) ? - cell_rectangle->y + offset_y : ycenter, - xcenter, - (ctree_row->sibling) ? crect->y +crect->height : ycenter); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter + (justification_factor * offset_x), ycenter, - xcenter + (justification_factor * (PM_SIZE / 2 + 2)), - ycenter); - - node = ctree_row->parent; - while (node) - { - xcenter -= (justification_factor * ctree->tree_indent); - - if (NAUTILUS_CTREE_ROW (node)->sibling) - gdk_draw_line (clist->clist_window, ctree->lines_gc, - xcenter, cell_rectangle->y + offset_y, - xcenter, crect->y + crect->height); - node = NAUTILUS_CTREE_ROW (node)->parent; - } - gdk_gc_set_clip_rectangle (ctree->lines_gc, NULL); - clip_rectangle->y++; - clip_rectangle->height--; - break; - } - return offset; -} - -static void -draw_row (NautilusCList *clist, - GdkRectangle *area, - gint row, - NautilusCListRow *clist_row) -{ - GtkWidget *widget; - NautilusCTree *ctree; - GdkRectangle *rect; - GdkRectangle *crect; - GdkRectangle row_rectangle; - GdkRectangle cell_rectangle; - GdkRectangle clip_rectangle; - GdkRectangle intersect_rectangle; - gint last_column; - gint column_left = 0; - gint column_right = 0; - gint offset = 0; - gint state; - gint i; - - g_return_if_fail (clist != NULL); - - /* bail now if we arn't drawable yet */ - if (!GTK_WIDGET_DRAWABLE (clist) || row < 0 || row >= clist->rows) - return; - - widget = GTK_WIDGET (clist); - ctree = NAUTILUS_CTREE (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup */ - if (!clist_row) - clist_row = (g_list_nth (clist->row_list, row))->data; - - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; - - /* rectangle of the cell spacing above the row */ - cell_rectangle.x = 0; - cell_rectangle.y = row_rectangle.y - CELL_SPACING; - cell_rectangle.width = row_rectangle.width; - cell_rectangle.height = CELL_SPACING; - - /* rectangle used to clip drawing operations, its y and height - * positions only need to be set once, so we set them once here. - * the x and width are set withing the drawing loop below once per - * column */ - clip_rectangle.y = row_rectangle.y; - clip_rectangle.height = row_rectangle.height; - - if (clist_row->state == GTK_STATE_NORMAL) - { - if (clist_row->fg_set) - gdk_gc_set_foreground (clist->fg_gc, &clist_row->foreground); - if (clist_row->bg_set) - gdk_gc_set_foreground (clist->bg_gc, &clist_row->background); - } - - state = clist_row->state; - - gdk_gc_set_foreground (ctree->lines_gc, - &widget->style->fg[clist_row->state]); - - /* draw the cell borders */ - if (area) - { - rect = &intersect_rectangle; - crect = &intersect_rectangle; - - if (gdk_rectangle_intersect (area, &cell_rectangle, crect)) - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - else - { - rect = &clip_rectangle; - crect = &cell_rectangle; - - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - } - - /* horizontal black lines */ - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) - { - - column_right = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) + - clist->column[ctree->tree_column].area.width + - COLUMN_INSET); - column_left = (COLUMN_LEFT_XPIXEL (clist, ctree->tree_column) - - COLUMN_INSET - (ctree->tree_column != 0) * CELL_SPACING); - - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - offset = (column_left + ctree->tree_indent * - (((NautilusCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (offset + TAB_SIZE, column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - offset = (column_right - 1 - ctree->tree_indent * - (((NautilusCTreeRow *)clist_row)->level - 1)); - - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (offset - TAB_SIZE, column_left), - cell_rectangle.y); - break; - } - } - - /* the last row has to clear its bottom cell spacing too */ - if (clist_row == clist->row_list_end->data) - { - cell_rectangle.y += clist->row_height + CELL_SPACING; - - if (!area || gdk_rectangle_intersect (area, &cell_rectangle, crect)) - { - gdk_draw_rectangle (clist->clist_window, - widget->style->base_gc[GTK_STATE_ACTIVE], TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* horizontal black lines */ - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) - { - switch (clist->column[ctree->tree_column].justification) - { - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - case GTK_JUSTIFY_LEFT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - MIN (column_left + TAB_SIZE + COLUMN_INSET + - (((NautilusCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_right), - cell_rectangle.y, - clist->clist_window_width, cell_rectangle.y); - break; - case GTK_JUSTIFY_RIGHT: - gdk_draw_line (clist->clist_window, ctree->lines_gc, - -1, cell_rectangle.y, - MAX (column_right - TAB_SIZE - 1 - - COLUMN_INSET - - (((NautilusCTreeRow *)clist_row)->level > 1) * - MIN (ctree->tree_indent / 2, TAB_SIZE), - column_left - 1), cell_rectangle.y); - break; - } - } - } - } - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - /* iterate and draw all the columns (row cells) and draw their contents */ - for (i = 0; i < clist->columns; i++) - { - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - guint bg_rgb; - - gint width; - gint height; - gint pixbuf_width; - gint string_width; - gint old_offset; - gint row_center_offset; - - if (!clist->column[i].visible) - continue; - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), clist_row, state, row, i, - &style, &fg_gc, &bg_gc, &bg_rgb); - - /* calculate clipping region */ - clip_rectangle.x = clist->column[i].area.x + clist->hoffset; - clip_rectangle.width = clist->column[i].area.width; - - cell_rectangle.x = clip_rectangle.x - COLUMN_INSET - CELL_SPACING; - cell_rectangle.width = (clip_rectangle.width + 2 * COLUMN_INSET + - (1 + (i == last_column)) * CELL_SPACING); - cell_rectangle.y = clip_rectangle.y; - cell_rectangle.height = clip_rectangle.height; - - string_width = 0; - pixbuf_width = 0; - height = 0; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - { - if (i != ctree->tree_column) - continue; - } - else - { - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - crect->x, crect->y, crect->width, crect->height); - - /* calculate real width for column justification */ - switch (clist_row->cell[i].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - width = gdk_string_width - (style->font, NAUTILUS_CELL_TEXT (clist_row->cell[i])->text); - break; - case NAUTILUS_CELL_PIXBUF: - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf); - width = pixbuf_width; - break; - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - { - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf); - } - - width = pixbuf_width; - - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text) - { - string_width = gdk_string_width - (style->font, NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text); - width += string_width; - } - - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text && - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - width += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - - if (i == ctree->tree_column) - width += (ctree->tree_indent * - ((NautilusCTreeRow *)clist_row)->level); - break; - default: - continue; - break; - } - - switch (clist->column[i].justification) - { - case GTK_JUSTIFY_LEFT: - offset = clip_rectangle.x + clist_row->cell[i].horizontal; - break; - case GTK_JUSTIFY_RIGHT: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - clip_rectangle.width - width); - break; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - offset = (clip_rectangle.x + clist_row->cell[i].horizontal + - (clip_rectangle.width / 2) - (width / 2)); - break; - }; - - if (i != ctree->tree_column) - { - offset += clist_row->cell[i].horizontal; - switch (clist_row->cell[i].type) - { - case NAUTILUS_CELL_PIXBUF: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXBUF (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - break; - case NAUTILUS_CELL_PIXTEXT: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &clip_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - offset += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - case NAUTILUS_CELL_TEXT: - row_center_offset = ((clist->row_height - - (style->font->ascent - + style->font->descent)) / 2 - + style->font->ascent); - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_string - (clist->clist_window, style->font, fg_gc, - offset, - row_rectangle.y + row_center_offset + - clist_row->cell[i].vertical, - (clist_row->cell[i].type == NAUTILUS_CELL_PIXTEXT) ? - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text : - NAUTILUS_CELL_TEXT (clist_row->cell[i])->text); - gdk_gc_set_clip_rectangle (fg_gc, NULL); - break; - default: - break; - } - continue; - } - } - - if (bg_gc == clist->bg_gc) - gdk_gc_set_background (ctree->lines_gc, &clist_row->background); - - /* draw ctree->tree_column */ - cell_rectangle.y -= CELL_SPACING; - cell_rectangle.height += CELL_SPACING; - - if (area && !gdk_rectangle_intersect (area, &cell_rectangle, - &intersect_rectangle)) - continue; - - /* draw lines */ - offset = nautilus_ctree_draw_lines (ctree, (NautilusCTreeRow *)clist_row, row, i, - state, &clip_rectangle, &cell_rectangle, - crect, area, style); - - /* draw expander */ - offset = nautilus_ctree_draw_expander (ctree, (NautilusCTreeRow *)clist_row, - style, &clip_rectangle, offset); - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= ctree->tree_spacing; - else - offset += ctree->tree_spacing; - - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - offset -= (pixbuf_width + clist_row->cell[i].horizontal); - else - offset += clist_row->cell[i].horizontal; - - old_offset = offset; - if (height > 0) { - GdkPixbuf *src_pixbuf, *dark_pixbuf; - - if (((NautilusCListRow *)ctree->dnd_prelighted_row) == clist_row) { - - src_pixbuf = NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf; - - if (src_pixbuf != NULL) { - /* Create darkened pixbuf */ - dark_pixbuf = eel_create_darkened_pixbuf (src_pixbuf, - 0.8 * 255, - 0.8 * 255); - if (dark_pixbuf != NULL) { - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - dark_pixbuf, offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - gdk_pixbuf_unref (dark_pixbuf); - } - } - } else { - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), - clist->clist_window, &clip_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf, - offset, - clip_rectangle.y + clist_row->cell[i].vertical + - (clip_rectangle.height - height) / 2); - - - } - } - - if (string_width) - { - if (clist->column[i].justification == GTK_JUSTIFY_RIGHT) - { - offset = (old_offset - string_width); - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset -= NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - } - else - { - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->pixbuf) - offset += NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->spacing; - } - - row_center_offset = ((clist->row_height - - (style->font->ascent - + style->font->descent)) / 2 - + style->font->ascent); - - gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle); - gdk_draw_string (clist->clist_window, style->font, fg_gc, offset, - row_rectangle.y + row_center_offset + - clist_row->cell[i].vertical, - NAUTILUS_CELL_PIXTEXT (clist_row->cell[i])->text); - } - gdk_gc_set_clip_rectangle (fg_gc, NULL); - } - - /* draw focus rectangle */ - if (clist->focus_row == row && - GTK_WIDGET_CAN_FOCUS (widget) && GTK_WIDGET_HAS_FOCUS (widget)) - { - if (!area) - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - else if (gdk_rectangle_intersect (area, &row_rectangle, - &intersect_rectangle)) - { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } - } -} - -void -nautilus_ctree_draw_node (NautilusCTree *ctree, NautilusCTreeNode *node) -{ - if (ctree == NULL || node == NULL) { - return; - } - - tree_draw_node (ctree, node); -} - -static void -tree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && nautilus_ctree_is_viewable (ctree, node)) - { - NautilusCTreeNode *work; - gint num = 0; - - work = NAUTILUS_CTREE_NODE (clist->row_list); - while (work && work != node) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - num++; - } - - if (work && nautilus_clist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE) { - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row - (clist, NULL, num, NAUTILUS_CLIST_ROW ((GList *) node)); - } - } -} - -static NautilusCTreeNode * -nautilus_ctree_last_visible (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeNode *work; - - if (!node) - return NULL; - - work = NAUTILUS_CTREE_ROW (node)->children; - - if (!work || !NAUTILUS_CTREE_ROW (node)->expanded) - return node; - - while (NAUTILUS_CTREE_ROW (work)->sibling) - work = NAUTILUS_CTREE_ROW (work)->sibling; - - return nautilus_ctree_last_visible (ctree, work); -} - -static void -nautilus_ctree_link (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gboolean update_focus_row) -{ - NautilusCList *clist; - GList *list_end; - GList *list; - GList *work; - gboolean visible = FALSE; - gint rows = 0; - - if (sibling) - g_return_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent); - g_return_if_fail (node != NULL); - g_return_if_fail (node != sibling); - g_return_if_fail (node != parent); - - clist = NAUTILUS_CLIST (ctree); - - if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - for (rows = 1, list_end = (GList *)node; list_end->next; - list_end = list_end->next) - rows++; - - NAUTILUS_CTREE_ROW (node)->parent = parent; - NAUTILUS_CTREE_ROW (node)->sibling = sibling; - - if (!parent || (parent && (nautilus_ctree_is_viewable (ctree, parent) && - NAUTILUS_CTREE_ROW (parent)->expanded))) - { - visible = TRUE; - clist->rows += rows; - } - - if (parent) - work = (GList *)(NAUTILUS_CTREE_ROW (parent)->children); - else - work = clist->row_list; - - if (sibling) - { - if (work != (GList *)sibling) - { - while (NAUTILUS_CTREE_ROW (work)->sibling != sibling) - work = (GList *)(NAUTILUS_CTREE_ROW (work)->sibling); - NAUTILUS_CTREE_ROW (work)->sibling = node; - } - - if (sibling == NAUTILUS_CTREE_NODE (clist->row_list)) - clist->row_list = (GList *) node; - if (NAUTILUS_CTREE_NODE_PREV (sibling) && - NAUTILUS_CTREE_NODE_NEXT (NAUTILUS_CTREE_NODE_PREV (sibling)) == sibling) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (sibling); - list->next = (GList *)node; - } - - list = (GList *)node; - list->prev = (GList *)NAUTILUS_CTREE_NODE_PREV (sibling); - list_end->next = (GList *)sibling; - list = (GList *)sibling; - list->prev = list_end; - if (parent && NAUTILUS_CTREE_ROW (parent)->children == sibling) - NAUTILUS_CTREE_ROW (parent)->children = node; - } - else - { - if (work) - { - /* find sibling */ - while (NAUTILUS_CTREE_ROW (work)->sibling) - work = (GList *)(NAUTILUS_CTREE_ROW (work)->sibling); - NAUTILUS_CTREE_ROW (work)->sibling = node; - - /* find last visible child of sibling */ - work = (GList *) nautilus_ctree_last_visible (ctree, - NAUTILUS_CTREE_NODE (work)); - - list_end->next = work->next; - if (work->next) - list = work->next->prev = list_end; - work->next = (GList *)node; - list = (GList *)node; - list->prev = work; - } - else - { - if (parent) - { - NAUTILUS_CTREE_ROW (parent)->children = node; - list = (GList *)node; - list->prev = (GList *)parent; - if (NAUTILUS_CTREE_ROW (parent)->expanded) - { - list_end->next = (GList *)NAUTILUS_CTREE_NODE_NEXT (parent); - if (NAUTILUS_CTREE_NODE_NEXT(parent)) - { - list = (GList *)NAUTILUS_CTREE_NODE_NEXT (parent); - list->prev = list_end; - } - list = (GList *)parent; - list->next = (GList *)node; - } - else - list_end->next = NULL; - } - else - { - clist->row_list = (GList *)node; - list = (GList *)node; - list->prev = NULL; - list_end->next = NULL; - } - } - } - - nautilus_ctree_pre_recursive (ctree, node, tree_update_level, NULL); - - if (clist->row_list_end == NULL || - clist->row_list_end->next == (GList *)node) - clist->row_list_end = list_end; - - if (visible && update_focus_row) - { - gint pos; - - pos = g_list_position (clist->row_list, (GList *)node); - - if (pos <= clist->focus_row) - { - clist->focus_row += rows; - clist->undo_anchor = clist->focus_row; - } - } -} - -static void -nautilus_ctree_unlink (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean update_focus_row) -{ - NautilusCList *clist; - gint rows; - gint level; - gint visible; - NautilusCTreeNode *work; - NautilusCTreeNode *parent; - GList *list; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (update_focus_row && clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - visible = nautilus_ctree_is_viewable (ctree, node); - - /* clist->row_list_end unlinked ? */ - if (visible && - (NAUTILUS_CTREE_NODE_NEXT (node) == NULL || - (NAUTILUS_CTREE_ROW (node)->children && - nautilus_ctree_is_ancestor (ctree, node, - NAUTILUS_CTREE_NODE (clist->row_list_end))))) - clist->row_list_end = (GList *) (NAUTILUS_CTREE_NODE_PREV (node)); - - /* update list */ - rows = 0; - level = NAUTILUS_CTREE_ROW (node)->level; - work = NAUTILUS_CTREE_NODE_NEXT (node); - while (work && NAUTILUS_CTREE_ROW (work)->level > level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - rows++; - } - - if (visible) - { - clist->rows -= (rows + 1); - - if (update_focus_row) - { - gint pos; - - pos = g_list_position (clist->row_list, (GList *)node); - if (pos + rows < clist->focus_row) - clist->focus_row -= (rows + 1); - else if (pos <= clist->focus_row) - { - if (!NAUTILUS_CTREE_ROW (node)->sibling) - clist->focus_row = MAX (pos - 1, 0); - else - clist->focus_row = pos; - - clist->focus_row = MIN (clist->focus_row, clist->rows - 1); - } - clist->undo_anchor = clist->focus_row; - } - } - - if (work) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (work); - list->next = NULL; - list = (GList *)work; - list->prev = (GList *)NAUTILUS_CTREE_NODE_PREV (node); - } - - if (NAUTILUS_CTREE_NODE_PREV (node) && - NAUTILUS_CTREE_NODE_NEXT (NAUTILUS_CTREE_NODE_PREV (node)) == node) - { - list = (GList *)NAUTILUS_CTREE_NODE_PREV (node); - list->next = (GList *)work; - } - - /* update tree */ - parent = NAUTILUS_CTREE_ROW (node)->parent; - if (parent) - { - if (NAUTILUS_CTREE_ROW (parent)->children == node) - { - NAUTILUS_CTREE_ROW (parent)->children = NAUTILUS_CTREE_ROW (node)->sibling; - if (NAUTILUS_CTREE_ROW (parent)->is_leaf) - nautilus_ctree_collapse (ctree, parent); - } - else - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_ROW (parent)->children; - while (NAUTILUS_CTREE_ROW (sibling)->sibling != node) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - NAUTILUS_CTREE_ROW (sibling)->sibling = NAUTILUS_CTREE_ROW (node)->sibling; - } - } - else - { - if (clist->row_list == (GList *)node) - clist->row_list = (GList *) (NAUTILUS_CTREE_ROW (node)->sibling); - else - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - while (NAUTILUS_CTREE_ROW (sibling)->sibling != node) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - NAUTILUS_CTREE_ROW (sibling)->sibling = NAUTILUS_CTREE_ROW (node)->sibling; - } - } -} - -static void -real_row_move (NautilusCList *clist, - gint source_row, - gint dest_row) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - return; - - if (source_row < 0 || source_row >= clist->rows || - dest_row < 0 || dest_row >= clist->rows || - source_row == dest_row) - return; - - ctree = NAUTILUS_CTREE (clist); - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, source_row)); - - if (source_row < dest_row) - { - NautilusCTreeNode *work; - - dest_row++; - work = NAUTILUS_CTREE_ROW (node)->children; - - while (work && NAUTILUS_CTREE_ROW (work)->level > NAUTILUS_CTREE_ROW (node)->level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - dest_row++; - } - - if (dest_row > clist->rows) - dest_row = clist->rows; - } - - if (dest_row < clist->rows) - { - NautilusCTreeNode *sibling; - - sibling = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, dest_row)); - nautilus_ctree_move (ctree, node, NAUTILUS_CTREE_ROW (sibling)->parent, sibling); - } - else - nautilus_ctree_move (ctree, node, NULL, NULL); -} - -static void -real_tree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (node != NULL); - g_return_if_fail (!new_sibling || - NAUTILUS_CTREE_ROW (new_sibling)->parent == new_parent); - - if (new_parent && NAUTILUS_CTREE_ROW (new_parent)->is_leaf) - return; - - /* new_parent != child of child */ - for (work = new_parent; work; work = NAUTILUS_CTREE_ROW (work)->parent) - if (work == node) - return; - - clist = NAUTILUS_CLIST (ctree); - - visible = nautilus_ctree_is_viewable (ctree, node); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (new_parent == NAUTILUS_CTREE_ROW (node)->parent) - return; - - if (new_parent) - new_sibling = NAUTILUS_CTREE_ROW (new_parent)->children; - else - new_sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (new_sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (new_sibling)) > 0) - new_sibling = NAUTILUS_CTREE_ROW (new_sibling)->sibling; - } - - if (new_parent == NAUTILUS_CTREE_ROW (node)->parent && - new_sibling == NAUTILUS_CTREE_ROW (node)->sibling) - return; - - nautilus_clist_freeze (clist); - - work = NULL; - if (nautilus_ctree_is_viewable (ctree, node) || - nautilus_ctree_is_viewable (ctree, new_sibling)) - work = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row)); - - nautilus_ctree_unlink (ctree, node, FALSE); - nautilus_ctree_link (ctree, node, new_parent, new_sibling, FALSE); - - if (work) - { - while (work && !nautilus_ctree_is_viewable (ctree, work)) - work = NAUTILUS_CTREE_ROW (work)->parent; - clist->focus_row = g_list_position (clist->row_list, (GList *)work); - clist->undo_anchor = clist->focus_row; - CLIST_REFRESH (clist); - } - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist) && - (visible || nautilus_ctree_is_viewable (ctree, node))) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - nautilus_clist_optimal_column_width (clist, ctree->tree_column)); - - nautilus_clist_thaw (clist); -} - -static void -change_focus_row_expansion (NautilusCTree *ctree, - NautilusCTreeExpansionType action) -{ - NautilusCList *clist; - NautilusCTreeNode *node; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (ctree)) - return; - - if (!(node = - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row))) || - NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - switch (action) - { - case NAUTILUS_CTREE_EXPANSION_EXPAND: - nautilus_ctree_expand (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE: - nautilus_ctree_expand_recursive (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_COLLAPSE: - nautilus_ctree_collapse (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE: - nautilus_ctree_collapse_recursive (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_TOGGLE: - nautilus_ctree_toggle_expansion (ctree, node); - break; - case NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE: - nautilus_ctree_toggle_expansion_recursive (ctree, node); - break; - } -} - -static void -real_tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - GtkRequisition requisition; - gboolean visible; - gint level; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->expanded || NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - NAUTILUS_CTREE_ROW (node)->expanded = TRUE; - level = NAUTILUS_CTREE_ROW (node)->level; - - visible = nautilus_ctree_is_viewable (ctree, node); - /* get cell width if tree_column is auto resized */ - if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, &requisition); - - /* unref/unset closed pixbuf */ - if (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf); - - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = NULL; - } - - /* set/ref opened pixbuf */ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_opened) - { - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = - gdk_pixbuf_ref (NAUTILUS_CTREE_ROW (node)->pixbuf_opened); - } - - - work = NAUTILUS_CTREE_ROW (node)->children; - if (work) - { - GList *list = (GList *)work; - gint *cell_width = NULL; - gint tmp = 0; - gint row; - gint i; - - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - cell_width = g_new0 (gint, clist->columns); - if (clist->column[ctree->tree_column].auto_resize) - cell_width[ctree->tree_column] = requisition.width; - - while (work) - { - /* search maximum cell widths of auto_resize columns */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (work)->row, i, &requisition); - cell_width[i] = MAX (requisition.width, cell_width[i]); - } - - list = (GList *)work; - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - } - else - while (work) - { - list = (GList *)work; - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - - list->next = (GList *)NAUTILUS_CTREE_NODE_NEXT (node); - - if (NAUTILUS_CTREE_NODE_NEXT (node)) - { - GList *tmp_list; - - tmp_list = (GList *)NAUTILUS_CTREE_NODE_NEXT (node); - tmp_list->prev = list; - } - else - clist->row_list_end = list; - - list = (GList *)node; - list->next = (GList *)(NAUTILUS_CTREE_ROW (node)->children); - - if (visible) - { - /* resize auto_resize columns if needed */ - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize && - cell_width[i] > clist->column[i].width) - nautilus_clist_set_column_width (clist, i, cell_width[i]); - g_free (cell_width); - - /* update focus_row position */ - row = g_list_position (clist->row_list, (GList *)node); - if (row < clist->focus_row) - clist->focus_row += tmp; - - clist->rows += tmp; - CLIST_REFRESH (clist); - } - } - else if (visible && clist->column[ctree->tree_column].auto_resize) - /* resize tree_column if needed */ - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, - requisition.width); - - tree_draw_node (ctree, node); -} - -static void -real_tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *work; - GtkRequisition requisition; - gboolean visible; - gint level; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || !NAUTILUS_CTREE_ROW (node)->expanded || - NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - NAUTILUS_CTREE_ROW (node)->expanded = FALSE; - level = NAUTILUS_CTREE_ROW (node)->level; - - visible = nautilus_ctree_is_viewable (ctree, node); - /* get cell width if tree_column is auto resized */ - if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, &requisition); - - /* unref/unset opened pixbuf */ - if (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf); - - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = NULL; - } - - /* set/ref closed pixbuf */ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_closed) - { - NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf = - gdk_pixbuf_ref (NAUTILUS_CTREE_ROW (node)->pixbuf_closed); - } - - work = NAUTILUS_CTREE_ROW (node)->children; - if (work) - { - gint tmp = 0; - gint row; - GList *list; - - while (work && NAUTILUS_CTREE_ROW (work)->level > level) - { - work = NAUTILUS_CTREE_NODE_NEXT (work); - tmp++; - } - - if (work) - { - list = (GList *)node; - list->next = (GList *)work; - list = (GList *)NAUTILUS_CTREE_NODE_PREV (work); - list->next = NULL; - list = (GList *)work; - list->prev = (GList *)node; - } - else - { - list = (GList *)node; - list->next = NULL; - clist->row_list_end = (GList *)node; - } - - if (visible) - { - /* resize auto_resize columns if needed */ - auto_resize_columns (clist); - - row = g_list_position (clist->row_list, (GList *)node); - if (row < clist->focus_row) - clist->focus_row -= tmp; - clist->rows -= tmp; - CLIST_REFRESH (clist); - } - } - else if (visible && clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - /* resize tree_column if needed */ - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, ctree->tree_column, - requisition.width); - - tree_draw_node (ctree, node); -} - -static void -column_auto_resize (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - gint old_width) -{ - /* resize column if needed for auto_resize */ - GtkRequisition requisition; - - if (!clist->column[column].auto_resize || - NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - return; - - if (clist_row) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - else - requisition.width = 0; - - if (requisition.width > clist->column[column].width) - nautilus_clist_set_column_width (clist, column, requisition.width); - else if (requisition.width < old_width && - old_width == clist->column[column].width) - { - GList *list; - gint new_width; - - /* run a "nautilus_clist_optimal_column_width" but break, if - * the column doesn't shrink */ - if (NAUTILUS_CLIST_SHOW_TITLES (clist) && clist->column[column].button) - new_width = (clist->column[column].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - else - new_width = 0; - - for (list = clist->row_list; list; list = list->next) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, NAUTILUS_CLIST_ROW (list), column, &requisition); - new_width = MAX (new_width, requisition.width); - if (new_width == clist->column[column].width) - break; - } - if (new_width < clist->column[column].width) - nautilus_clist_set_column_width (clist, column, new_width); - } -} - -static void -auto_resize_columns (NautilusCList *clist) -{ - gint i; - - if (NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - return; - - for (i = 0; i < clist->columns; i++) - column_auto_resize (clist, NULL, i, clist->column[i].width); -} - -static void -cell_size_request (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - GtkRequisition *requisition) -{ - NautilusCTree *ctree; - GtkStyle *style; - gint width; - gint height; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - g_return_if_fail (requisition != NULL); - - ctree = NAUTILUS_CTREE (clist); - - nautilus_list_get_cell_style (NAUTILUS_LIST (clist), clist_row, - GTK_STATE_NORMAL, 0, column, - &style, NULL, NULL, NULL); - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - requisition->width = - gdk_string_width (style->font, NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - requisition->height = style->font->ascent + style->font->descent; - break; - - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) { - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - width += NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing; - } else { - width = height = 0; - } - - requisition->width = width + gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - requisition->height = MAX (style->font->ascent + style->font->descent, height); - - if (column == ctree->tree_column) { - requisition->width += (ctree->tree_spacing + ctree->tree_indent * - (((NautilusCTreeRow *) clist_row)->level - 1)); - requisition->width += PM_SIZE + 3; - } - - if (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) { - requisition->width += 3; - } - break; - - case NAUTILUS_CELL_PIXBUF: - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - requisition->width = width; - requisition->height = height; - break; - - default: - requisition->width = 0; - requisition->height = 0; - break; - } - - requisition->width += clist_row->cell[column].horizontal; - requisition->height += clist_row->cell[column].vertical; -} - -static gboolean -set_cell_contents (NautilusCList *clist, - NautilusCListRow *clist_row, - gint column, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - gboolean visible = FALSE; - NautilusCTree *ctree; - GtkRequisition requisition; - - g_return_val_if_fail (NAUTILUS_IS_CTREE (clist), FALSE); - g_return_val_if_fail (clist_row != NULL, FALSE); - - ctree = NAUTILUS_CTREE (clist); - - if (type == clist_row->cell[column].type) - { - switch (type) - { - case NAUTILUS_CELL_EMPTY: - return FALSE; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf == NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf) - return FALSE; - break; - case NAUTILUS_CELL_PIXTEXT: - if (pixbuf == NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) - { - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text == NULL) - { - if (text == NULL) - return FALSE; - } - else - { - if (text != NULL && strcmp (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text, text) == 0) - return FALSE; - } - } - break; - case NAUTILUS_CELL_WIDGET: - /* unimplemented */ - break; - case NAUTILUS_CELL_PIXBUF_LIST: - /* handled at the higher level */ - break; - } - } - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - NautilusCTreeNode *parent; - - parent = ((NautilusCTreeRow *)clist_row)->parent; - if (!parent || (parent && NAUTILUS_CTREE_ROW (parent)->expanded && - nautilus_ctree_is_viewable (ctree, parent))) - { - visible = TRUE; - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request (clist, clist_row, - column, &requisition); - } - } - - switch (clist_row->cell[column].type) - { - case NAUTILUS_CELL_EMPTY: - break; - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - g_free (NAUTILUS_CELL_TEXT (clist_row->cell[column])->text); - break; - case NAUTILUS_CELL_PIXBUF: - gdk_pixbuf_unref (NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf); - break; - case NAUTILUS_CELL_PIXTEXT: - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text) - g_free (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text); - if (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf) - { - gdk_pixbuf_unref - (NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf); - } - break; - case NAUTILUS_CELL_WIDGET: - /* unimplimented */ - break; - - default: - break; - } - - clist_row->cell[column].type = NAUTILUS_CELL_EMPTY; - if (column == ctree->tree_column && type != NAUTILUS_CELL_EMPTY) - type = NAUTILUS_CELL_PIXTEXT; - - switch (type) - { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (text) - { - clist_row->cell[column].type = NAUTILUS_CELL_TEXT; - NAUTILUS_CELL_TEXT (clist_row->cell[column])->text = g_strdup (text); - } - break; - case NAUTILUS_CELL_PIXBUF: - if (pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXBUF; - NAUTILUS_CELL_PIXBUF (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - case NAUTILUS_CELL_PIXTEXT: - if (column == ctree->tree_column) - { - if (pixbuf) - pixbuf = gdk_pixbuf_ref (pixbuf); - clist_row->cell[column].type = NAUTILUS_CELL_PIXTEXT; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text = g_strdup (text); - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing = spacing; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf = pixbuf; - } - else if (text && pixbuf) - { - clist_row->cell[column].type = NAUTILUS_CELL_PIXTEXT; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->text = g_strdup (text); - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->spacing = spacing; - NAUTILUS_CELL_PIXTEXT (clist_row->cell[column])->pixbuf = gdk_pixbuf_ref (pixbuf); - } - break; - default: - break; - } - - if (visible && clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - column_auto_resize (clist, clist_row, column, requisition.width); - - return TRUE; -} - -static void -set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - if (NAUTILUS_CTREE_ROW (node)->pixbuf_opened) - { - gdk_pixbuf_unref (NAUTILUS_CTREE_ROW (node)->pixbuf_opened); - } - if (NAUTILUS_CTREE_ROW (node)->pixbuf_closed) - { - gdk_pixbuf_unref (NAUTILUS_CTREE_ROW (node)->pixbuf_closed); - } - - NAUTILUS_CTREE_ROW (node)->pixbuf_opened = NULL; - NAUTILUS_CTREE_ROW (node)->pixbuf_closed = NULL; - - if (pixbuf_closed) - { - NAUTILUS_CTREE_ROW (node)->pixbuf_closed = gdk_pixbuf_ref (pixbuf_closed); - } - if (pixbuf_opened) - { - NAUTILUS_CTREE_ROW (node)->pixbuf_opened = gdk_pixbuf_ref (pixbuf_opened); - } - - NAUTILUS_CTREE_ROW (node)->is_leaf = is_leaf; - NAUTILUS_CTREE_ROW (node)->expanded = (is_leaf) ? FALSE : expanded; - - if (NAUTILUS_CTREE_ROW (node)->expanded) - nautilus_ctree_node_set_pixtext (ctree, node, ctree->tree_column, - text, spacing, pixbuf_opened); - else - nautilus_ctree_node_set_pixtext (ctree, node, ctree->tree_column, - text, spacing, pixbuf_closed); -} - -static void -tree_delete (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - tree_unselect (ctree, node, NULL); - row_delete (ctree, NAUTILUS_CTREE_ROW (node)); - g_list_free_1 ((GList *)node); -} - -static void -tree_delete_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - row_delete (ctree, NAUTILUS_CTREE_ROW (node)); - g_list_free_1 ((GList *)node); -} - -static void -tree_update_level (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node) - return; - - if (NAUTILUS_CTREE_ROW (node)->parent) - NAUTILUS_CTREE_ROW (node)->level = - NAUTILUS_CTREE_ROW (NAUTILUS_CTREE_ROW (node)->parent)->level + 1; - else - NAUTILUS_CTREE_ROW (node)->level = 1; -} - -static void -tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED && - NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_SELECT_ROW], - node, -1); -} - -static void -tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_UNSELECT_ROW], - node, -1); -} - -static void -tree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && !NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -static void -tree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (node && NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); -} - -static void -tree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - if (node && NAUTILUS_CTREE_ROW (node)->level == depth) - nautilus_ctree_collapse_recursive (ctree, node); -} - -static void -tree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node) - return; - - if (NAUTILUS_CTREE_ROW (node)->expanded) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); - else - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -static NautilusCTreeRow * -row_new (NautilusCTree *ctree) -{ - NautilusCList *clist; - NautilusCTreeRow *ctree_row; - int i; - - clist = NAUTILUS_CLIST (ctree); - ctree_row = g_chunk_new (NautilusCTreeRow, clist->row_mem_chunk); - ctree_row->row.cell = g_chunk_new (NautilusCell, clist->cell_mem_chunk); - - for (i = 0; i < clist->columns; i++) { - ctree_row->row.cell[i].type = NAUTILUS_CELL_EMPTY; - ctree_row->row.cell[i].vertical = 0; - ctree_row->row.cell[i].horizontal = 0; - ctree_row->row.cell[i].style = NULL; - } - - NAUTILUS_CELL_PIXTEXT (ctree_row->row.cell[ctree->tree_column])->text = NULL; - - ctree_row->row.fg_set = FALSE; - ctree_row->row.bg_set = FALSE; - ctree_row->row.style = NULL; - ctree_row->row.selectable = TRUE; - ctree_row->row.state = GTK_STATE_NORMAL; - ctree_row->row.data = NULL; - ctree_row->row.destroy = NULL; - - ctree_row->level = 0; - ctree_row->expanded = FALSE; - ctree_row->parent = NULL; - ctree_row->sibling = NULL; - ctree_row->children = NULL; - ctree_row->pixbuf_closed = NULL; - ctree_row->pixbuf_opened = NULL; - ctree_row->mouse_down = FALSE; - ctree_row->in_hotspot = FALSE; - - return ctree_row; -} - -static void -row_delete (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row) -{ - NautilusCList *clist; - gint i; - - clist = NAUTILUS_CLIST (ctree); - - for (i = 0; i < clist->columns; i++) - { - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(ctree_row->row), i, NAUTILUS_CELL_EMPTY, NULL, 0, NULL); - if (ctree_row->row.cell[i].style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (ctree_row->row.cell[i].style); - gtk_style_unref (ctree_row->row.cell[i].style); - } - } - - if (ctree_row->row.style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (ctree_row->row.style); - gtk_style_unref (ctree_row->row.style); - } - - if (ctree_row->pixbuf_closed) - { - gdk_pixbuf_unref (ctree_row->pixbuf_closed); - } - - if (ctree_row->pixbuf_opened) - { - gdk_pixbuf_unref (ctree_row->pixbuf_opened); - } - - if (ctree_row->row.destroy) - { - GtkDestroyNotify dnotify = ctree_row->row.destroy; - gpointer ddata = ctree_row->row.data; - - ctree_row->row.destroy = NULL; - ctree_row->row.data = NULL; - - dnotify (ddata); - } - - g_mem_chunk_free (clist->cell_mem_chunk, ctree_row->row.cell); - g_mem_chunk_free (clist->row_mem_chunk, ctree_row); -} - -static void -real_tree_activate_row (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - /* don't care */ -} - -static void -real_select_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - GList *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if ((node = g_list_nth (clist->row_list, row)) && - NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_SELECT_ROW], - node, column); -} - -static void -real_unselect_row (NautilusCList *clist, - gint row, - gint column, - GdkEvent *event) -{ - GList *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if ((node = g_list_nth (clist->row_list, row))) - gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_UNSELECT_ROW], - node, column); -} - -static void -real_tree_select (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - NautilusCList *clist; - GList *list; - NautilusCTreeNode *sel_row; - gboolean node_selected; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED || - !NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - clist = NAUTILUS_CLIST (ctree); - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - - node_selected = FALSE; - list = clist->selection; - - while (list) - { - sel_row = list->data; - list = list->next; - - if (node == sel_row) - node_selected = TRUE; - else - gtk_signal_emit (GTK_OBJECT (ctree), - ctree_signals[TREE_UNSELECT_ROW], sel_row, column); - } - - if (node_selected) - return; - - default: - break; - } - - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - - if (!clist->selection) - { - clist->selection = g_list_append (clist->selection, node); - clist->selection_end = clist->selection; - } - else - clist->selection_end = g_list_append (clist->selection_end, node)->next; - - tree_draw_node (ctree, node); -} - -static void -real_tree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (!node || NAUTILUS_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->selection_end && clist->selection_end->data == node) - clist->selection_end = clist->selection_end->prev; - - clist->selection = g_list_remove (clist->selection, node); - - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - - tree_draw_node (ctree, node); -} - -static void -select_row_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - if (!node || NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED || - !NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - NAUTILUS_CLIST (ctree)->undo_unselection = - g_list_prepend (NAUTILUS_CLIST (ctree)->undo_unselection, node); - nautilus_ctree_select (ctree, node); -} - -static void -real_select_all (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - switch (clist->selection_mode) - { - case GTK_SELECTION_SINGLE: - case GTK_SELECTION_BROWSE: - return; - - case GTK_SELECTION_EXTENDED: - nautilus_clist_freeze (clist); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor_state = GTK_STATE_SELECTED; - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - - for (node = NAUTILUS_CTREE_NODE (clist->row_list); node; - node = NAUTILUS_CTREE_NODE_NEXT (node)) - nautilus_ctree_pre_recursive (ctree, node, select_row_recursive, NULL); - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); - break; - - case GTK_SELECTION_MULTIPLE: - nautilus_ctree_select_recursive (ctree, NULL); - break; - - default: - /* do nothing */ - break; - } -} - -static void -real_unselect_all (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *node; - GList *list; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - switch (clist->selection_mode) - { - case GTK_SELECTION_BROWSE: - if (clist->focus_row >= 0) - { - nautilus_ctree_select - (ctree, - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row))); - return; - } - break; - - case GTK_SELECTION_EXTENDED: - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - clist->anchor = -1; - clist->drag_pos = -1; - clist->undo_anchor = clist->focus_row; - break; - - default: - break; - } - - list = clist->selection; - - while (list) - { - node = list->data; - list = list->next; - nautilus_ctree_unselect (ctree, node); - } -} - -static gboolean -ctree_is_hot_spot (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint row, - gint x, - gint y) -{ - NautilusCTreeRow *tree_row; - NautilusCList *clist; - NautilusCellPixText *cell; - gint xl; - gint yu; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - clist = NAUTILUS_CLIST (ctree); - - if (!clist->column[ctree->tree_column].visible) { - return FALSE; - } - - tree_row = NAUTILUS_CTREE_ROW (node); - - cell = NAUTILUS_CELL_PIXTEXT(tree_row->row.cell[ctree->tree_column]); - - yu = (ROW_TOP_YPIXEL (clist, row) + (clist->row_height - PM_SIZE) / 2 - (clist->row_height - 1) % 2); - - if (clist->column[ctree->tree_column].justification == GTK_JUSTIFY_RIGHT) { - xl = (clist->column[ctree->tree_column].area.x + - clist->column[ctree->tree_column].area.width - 1 + clist->hoffset - - (tree_row->level - 1) * ctree->tree_indent - PM_SIZE - - (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) * 3); - } else { - xl = (clist->column[ctree->tree_column].area.x + clist->hoffset + - (tree_row->level - 1) * ctree->tree_indent + - (ctree->line_style == NAUTILUS_CTREE_LINES_TABBED) * 3); - } - - return (x >= xl - 3 && x <= xl + 3 + PM_SIZE && y >= yu - 3 && y <= yu + PM_SIZE + 3); -} - -/*********************************************************** - *********************************************************** - *** Public interface *** - *********************************************************** - ***********************************************************/ - - -/*********************************************************** - * Creation, insertion, deletion * - ***********************************************************/ - -void -nautilus_ctree_construct (NautilusCTree *ctree, - gint columns, - gint tree_column, - gchar *titles[]) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (GTK_OBJECT_CONSTRUCTED (ctree) == FALSE); - - clist = NAUTILUS_CLIST (ctree); - - clist->row_mem_chunk = g_mem_chunk_new ("ctree row mem chunk", - sizeof (NautilusCTreeRow), - sizeof (NautilusCTreeRow) - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - clist->cell_mem_chunk = g_mem_chunk_new ("ctree cell mem chunk", - sizeof (NautilusCell) * columns, - sizeof (NautilusCell) * columns - * CLIST_OPTIMUM_SIZE, - G_ALLOC_AND_FREE); - - ctree->tree_column = tree_column; - - nautilus_clist_construct (clist, columns, titles); -} - -GtkWidget * -nautilus_ctree_new_with_titles (gint columns, - gint tree_column, - gchar *titles[]) -{ - GtkWidget *widget; - - g_return_val_if_fail (columns > 0, NULL); - g_return_val_if_fail (tree_column >= 0 && tree_column < columns, NULL); - - widget = GTK_WIDGET (gtk_type_new (NAUTILUS_TYPE_CTREE)); - nautilus_ctree_construct (NAUTILUS_CTREE (widget), columns, tree_column, titles); - - return widget; -} - -GtkWidget * -nautilus_ctree_new (gint columns, - gint tree_column) -{ - return nautilus_ctree_new_with_titles (columns, tree_column, NULL); -} - -static gint -real_insert_row (NautilusCList *clist, - gint row, - gchar *text[]) -{ - NautilusCTreeNode *parent = NULL; - NautilusCTreeNode *sibling; - NautilusCTreeNode *node; - - g_return_val_if_fail (clist != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CTREE (clist), -1); - - sibling = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - if (sibling) - parent = NAUTILUS_CTREE_ROW (sibling)->parent; - - node = nautilus_ctree_insert_node (NAUTILUS_CTREE (clist), parent, sibling, text, 5, - NULL, NULL, TRUE, FALSE); - - if (NAUTILUS_CLIST_AUTO_SORT (clist) || !sibling) - return g_list_position (clist->row_list, (GList *) node); - - return row; -} - -NautilusCTreeNode * -nautilus_ctree_insert_node (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gchar *text[], - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - NautilusCList *clist; - NautilusCTreeRow *new_row; - NautilusCTreeNode *node; - GList *list; - gint i; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - if (sibling) { - g_return_val_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent, NULL); - } - - if (parent && NAUTILUS_CTREE_ROW (parent)->is_leaf) { - return NULL; - } - - clist = NAUTILUS_CLIST (ctree); - - /* create the row */ - new_row = row_new (ctree); - list = g_list_alloc (); - list->data = new_row; - node = NAUTILUS_CTREE_NODE (list); - - if (text) - for (i = 0; i < clist->columns; i++) - if (text[i] && i != ctree->tree_column) - NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(new_row->row), i, NAUTILUS_CELL_TEXT, text[i], 0, NULL); - - set_node_info (ctree, node, text ? - text[ctree->tree_column] : NULL, spacing, pixbuf_closed, - pixbuf_opened, is_leaf, expanded); - - /* sorted insertion */ - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (sibling)) > 0) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - - } - - nautilus_ctree_link (ctree, node, parent, sibling, TRUE); - - if (text && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist) && - nautilus_ctree_is_viewable (ctree, node)) - { - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - column_auto_resize (clist, &(new_row->row), i, 0); - } - - if (clist->rows == 1) - { - clist->focus_row = 0; - if (clist->selection_mode == GTK_SELECTION_BROWSE) - nautilus_ctree_select (ctree, node); - } - - - CLIST_REFRESH (clist); - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_insert_gnode (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - GNode *gnode, - NautilusCTreeGNodeFunc func, - gpointer data) -{ - NautilusCList *clist; - NautilusCTreeNode *cnode = NULL; - NautilusCTreeNode *child = NULL; - NautilusCTreeNode *new_child; - GList *list; - GNode *work; - guint depth = 1; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (gnode != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - if (sibling) - g_return_val_if_fail (NAUTILUS_CTREE_ROW (sibling)->parent == parent, NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (parent) - depth = NAUTILUS_CTREE_ROW (parent)->level + 1; - - list = g_list_alloc (); - list->data = row_new (ctree); - cnode = NAUTILUS_CTREE_NODE (list); - - nautilus_clist_freeze (clist); - - set_node_info (ctree, cnode, "", 0, NULL, NULL, TRUE, FALSE); - - if (!func (ctree, depth, gnode, cnode, data)) - { - tree_delete_row (ctree, cnode, NULL); - return NULL; - } - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling && clist->compare - (clist, NAUTILUS_CTREE_ROW (cnode), NAUTILUS_CTREE_ROW (sibling)) > 0) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - } - - nautilus_ctree_link (ctree, cnode, parent, sibling, TRUE); - - for (work = g_node_last_child (gnode); work; work = work->prev) - { - new_child = nautilus_ctree_insert_gnode (ctree, cnode, child, - work, func, data); - if (new_child) - child = new_child; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); - - return cnode; -} - -GNode * -nautilus_ctree_export_to_gnode (NautilusCTree *ctree, - GNode *parent, - GNode *sibling, - NautilusCTreeNode *node, - NautilusCTreeGNodeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - GNode *gnode; - gint depth; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - if (sibling) - { - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (sibling->parent == parent, NULL); - } - - gnode = g_node_new (NULL); - depth = g_node_depth (parent) + 1; - - if (!func (ctree, depth, gnode, node, data)) - { - g_node_destroy (gnode); - return NULL; - } - - if (parent) - g_node_insert_before (parent, sibling, gnode); - - if (!NAUTILUS_CTREE_ROW (node)->is_leaf) - { - GNode *new_sibling = NULL; - - for (work = NAUTILUS_CTREE_ROW (node)->children; work; - work = NAUTILUS_CTREE_ROW (work)->sibling) - new_sibling = nautilus_ctree_export_to_gnode (ctree, gnode, new_sibling, - work, func, data); - - g_node_reverse_children (gnode); - } - - return gnode; -} - -static void -real_remove_row (NautilusCList *clist, - gint row) -{ - NautilusCTreeNode *node; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, row)); - - if (node) - nautilus_ctree_remove_node (NAUTILUS_CTREE (clist), node); -} - -void -nautilus_ctree_remove_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (node) - { - gboolean visible; - - visible = nautilus_ctree_is_viewable (ctree, node); - nautilus_ctree_unlink (ctree, node, TRUE); - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_delete), - NULL); - if (clist->selection_mode == GTK_SELECTION_BROWSE && !clist->selection && - clist->focus_row >= 0) - nautilus_clist_select_row (clist, clist->focus_row, -1); - - auto_resize_columns (clist); - } - else - nautilus_clist_clear (clist); - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -static void -real_clear (NautilusCList *clist) -{ - NautilusCTree *ctree; - NautilusCTreeNode *work; - NautilusCTreeNode *ptr; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - ctree = NAUTILUS_CTREE (clist); - - /* remove all rows */ - work = NAUTILUS_CTREE_NODE (clist->row_list); - clist->row_list = NULL; - clist->row_list_end = NULL; - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - while (work) - { - ptr = work; - work = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive (ctree, ptr, NAUTILUS_CTREE_FUNC (tree_delete_row), - NULL); - } - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - - parent_class->clear (clist); -} - - -/*********************************************************** - * Generic recursive functions, querying / finding tree * - * information * - ***********************************************************/ - - -void -nautilus_ctree_post_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (node) - work = NAUTILUS_CTREE_ROW (node)->children; - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive (ctree, work, func, data); - work = tmp; - } - - if (node) - func (ctree, node, data); -} - -void -nautilus_ctree_post_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (depth < 0) - { - nautilus_ctree_post_recursive (ctree, node, func, data); - return; - } - - if (node) - work = NAUTILUS_CTREE_ROW (node)->children; - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - if (work && NAUTILUS_CTREE_ROW (work)->level <= depth) - { - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_post_recursive_to_depth (ctree, work, depth, func, data); - work = tmp; - } - } - - if (node && NAUTILUS_CTREE_ROW (node)->level <= depth) - func (ctree, node, data); -} - -void -nautilus_ctree_pre_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (node) - { - work = NAUTILUS_CTREE_ROW (node)->children; - func (ctree, node, data); - } - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_pre_recursive (ctree, work, func, data); - work = tmp; - } -} - -void -nautilus_ctree_pre_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data) -{ - NautilusCTreeNode *work; - NautilusCTreeNode *tmp; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (func != NULL); - - if (depth < 0) - { - nautilus_ctree_pre_recursive (ctree, node, func, data); - return; - } - - if (node) - { - work = NAUTILUS_CTREE_ROW (node)->children; - if (NAUTILUS_CTREE_ROW (node)->level <= depth) - func (ctree, node, data); - } - else - work = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - if (work && NAUTILUS_CTREE_ROW (work)->level <= depth) - { - while (work) - { - tmp = NAUTILUS_CTREE_ROW (work)->sibling; - nautilus_ctree_pre_recursive_to_depth (ctree, work, depth, func, data); - work = tmp; - } - } -} - -gboolean -nautilus_ctree_is_viewable (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeRow *work; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - work = NAUTILUS_CTREE_ROW (node); - - while (work->parent && NAUTILUS_CTREE_ROW (work->parent)->expanded) - work = NAUTILUS_CTREE_ROW (work->parent); - - if (!work->parent) - return TRUE; - - return FALSE; -} - -NautilusCTreeNode * -nautilus_ctree_last (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - if (!node) - return NULL; - - while (NAUTILUS_CTREE_ROW (node)->sibling) - node = NAUTILUS_CTREE_ROW (node)->sibling; - - if (NAUTILUS_CTREE_ROW (node)->children) - return nautilus_ctree_last (ctree, NAUTILUS_CTREE_ROW (node)->children); - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_find_node_ptr (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row) -{ - NautilusCTreeNode *node; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (ctree_row != NULL, FALSE); - - if (ctree_row->parent) - node = NAUTILUS_CTREE_ROW (ctree_row->parent)->children; - else - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (NAUTILUS_CTREE_ROW (node) != ctree_row) - node = NAUTILUS_CTREE_ROW (node)->sibling; - - return node; -} - -NautilusCTreeNode * -nautilus_ctree_node_nth (NautilusCTree *ctree, - int row) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - if ((row < 0) || (row >= NAUTILUS_CLIST(ctree)->rows)) - return NULL; - - return NAUTILUS_CTREE_NODE (g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row)); -} - -gboolean -nautilus_ctree_find (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child) -{ - if (!child) - return FALSE; - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (node == child) - return TRUE; - if (NAUTILUS_CTREE_ROW (node)->children) - { - if (nautilus_ctree_find (ctree, NAUTILUS_CTREE_ROW (node)->children, child)) - return TRUE; - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return FALSE; -} - -gboolean -nautilus_ctree_is_ancestor (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child) -{ - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - g_return_val_if_fail (node != NULL, FALSE); - - if (NAUTILUS_CTREE_ROW (node)->children) - return nautilus_ctree_find (ctree, NAUTILUS_CTREE_ROW (node)->children, child); - - return FALSE; -} - -NautilusCTreeNode * -nautilus_ctree_find_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCTreeNode *work; - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (NAUTILUS_CTREE_ROW (node)->row.data == data) - return node; - if (NAUTILUS_CTREE_ROW (node)->children && - (work = nautilus_ctree_find_by_row_data - (ctree, NAUTILUS_CTREE_ROW (node)->children, data))) - return work; - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return NULL; -} - -GList * -nautilus_ctree_find_all_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - GList *list = NULL; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - /* if node == NULL then look in the whole tree */ - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (NAUTILUS_CTREE_ROW (node)->row.data == data) - list = g_list_append (list, node); - - if (NAUTILUS_CTREE_ROW (node)->children) - { - GList *sub_list; - - sub_list = nautilus_ctree_find_all_by_row_data (ctree, - NAUTILUS_CTREE_ROW - (node)->children, - data); - list = g_list_concat (list, sub_list); - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return list; -} - -NautilusCTreeNode * -nautilus_ctree_find_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func) -{ - NautilusCTreeNode *work; - - g_return_val_if_fail (func != NULL, NULL); - - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (!func (NAUTILUS_CTREE_ROW (node)->row.data, data)) - return node; - if (NAUTILUS_CTREE_ROW (node)->children && - (work = nautilus_ctree_find_by_row_data_custom - (ctree, NAUTILUS_CTREE_ROW (node)->children, data, func))) - return work; - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return NULL; -} - -GList * -nautilus_ctree_find_all_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func) -{ - GList *list = NULL; - - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (func != NULL, NULL); - - /* if node == NULL then look in the whole tree */ - if (!node) - node = NAUTILUS_CTREE_NODE (NAUTILUS_CLIST (ctree)->row_list); - - while (node) - { - if (!func (NAUTILUS_CTREE_ROW (node)->row.data, data)) - list = g_list_append (list, node); - - if (NAUTILUS_CTREE_ROW (node)->children) - { - GList *sub_list; - - sub_list = nautilus_ctree_find_all_by_row_data_custom (ctree, - NAUTILUS_CTREE_ROW - (node)->children, - data, - func); - list = g_list_concat (list, sub_list); - } - node = NAUTILUS_CTREE_ROW (node)->sibling; - } - return list; -} - -gboolean -nautilus_ctree_is_hot_spot (NautilusCTree *ctree, - gint x, - gint y) -{ - NautilusCTreeNode *node; - gint column; - gint row; - - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - - if (nautilus_clist_get_selection_info (NAUTILUS_CLIST (ctree), x, y, &row, &column)) { - if ((node = NAUTILUS_CTREE_NODE(g_list_nth (NAUTILUS_CLIST (ctree)->row_list, row)))) { - return ctree_is_hot_spot (ctree, node, row, x, y); - } - } - - return FALSE; -} - - -/*********************************************************** - * Tree signals : move, expand, collapse, (un)select * - ***********************************************************/ - - -void -nautilus_ctree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_MOVE], node, - new_parent, new_sibling); -} - -void -nautilus_ctree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node); -} - -void -nautilus_ctree_expand_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_expand), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_expand_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive_to_depth (ctree, node, depth, - NAUTILUS_CTREE_FUNC (tree_expand), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node); -} - -void -nautilus_ctree_collapse_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_collapse), NULL); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - nautilus_clist_set_column_width (clist, i, - nautilus_clist_optimal_column_width (clist, i)); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - nautilus_ctree_post_recursive_to_depth (ctree, node, depth, - NAUTILUS_CTREE_FUNC (tree_collapse_to_depth), - GINT_TO_POINTER (depth)); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_AUTO_RESIZE_BLOCKED); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - nautilus_clist_set_column_width (clist, i, - nautilus_clist_optimal_column_width (clist, i)); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - tree_toggle_expansion (ctree, node, NULL); -} - -void -nautilus_ctree_toggle_expansion_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (node && NAUTILUS_CTREE_ROW (node)->is_leaf) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_toggle_expansion), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_select (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_SELECT_ROW], - node, -1); -} - -void -nautilus_ctree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_UNSELECT_ROW], - node, -1); -} - -void -nautilus_ctree_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - nautilus_ctree_real_select_recursive (ctree, node, TRUE); -} - -void -nautilus_ctree_unselect_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - nautilus_ctree_real_select_recursive (ctree, node, FALSE); -} - -void -nautilus_ctree_real_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint state) -{ - NautilusCList *clist; - gboolean thaw = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - if ((state && - (clist->selection_mode == GTK_SELECTION_BROWSE || - clist->selection_mode == GTK_SELECTION_SINGLE)) || - (!state && clist->selection_mode == GTK_SELECTION_BROWSE)) - return; - - if (CLIST_UNFROZEN (clist) && (!node || nautilus_ctree_is_viewable (ctree, node))) - { - nautilus_clist_freeze (clist); - thaw = TRUE; - } - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (state) - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_select), NULL); - else - nautilus_ctree_post_recursive (ctree, node, - NAUTILUS_CTREE_FUNC (tree_unselect), NULL); - - CLIST_REFRESH (clist); - if (thaw) - nautilus_clist_thaw (clist); -} - - -/*********************************************************** - * Analogons of NautilusCList functions * - ***********************************************************/ - - -void -nautilus_ctree_node_set_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW(node)->row), column, NAUTILUS_CELL_TEXT, - text, 0, NULL)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf *pixbuf) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - g_return_if_fail (pixbuf != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW (node)->row), column, NAUTILUS_CELL_PIXBUF, - NULL, 0, pixbuf)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - if (column != ctree->tree_column) - g_return_if_fail (pixbuf != NULL); - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CLIST_CLASS_FW (clist)->set_cell_contents - (clist, &(NAUTILUS_CTREE_ROW (node)->row), column, NAUTILUS_CELL_PIXTEXT, - text, spacing, pixbuf)) - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded) -{ - gboolean old_leaf; - gboolean old_expanded; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - old_leaf = NAUTILUS_CTREE_ROW (node)->is_leaf; - old_expanded = NAUTILUS_CTREE_ROW (node)->expanded; - - if (is_leaf && NAUTILUS_CTREE_ROW (node)->children) - { - NautilusCTreeNode *work; - NautilusCTreeNode *ptr; - - work = NAUTILUS_CTREE_ROW (node)->children; - while (work) - { - ptr = work; - work = NAUTILUS_CTREE_ROW(work)->sibling; - nautilus_ctree_remove_node (ctree, ptr); - } - } - - set_node_info (ctree, node, text, spacing, pixbuf_closed, - pixbuf_opened, is_leaf, expanded); - - if (!is_leaf && !old_leaf) - { - NAUTILUS_CTREE_ROW (node)->expanded = old_expanded; - if (expanded && !old_expanded) - nautilus_ctree_expand (ctree, node); - else if (!expanded && old_expanded) - nautilus_ctree_collapse (ctree, node); - } - - NAUTILUS_CTREE_ROW (node)->expanded = (is_leaf) ? FALSE : expanded; - - if (NAUTILUS_CLIST_AUTO_SORT (NAUTILUS_CLIST (ctree)) - && NAUTILUS_CTREE_ROW (node)->parent != NULL) - { - nautilus_ctree_sort_single_node (ctree, NAUTILUS_CTREE_ROW (node)->parent); - } -} - -void -nautilus_ctree_node_set_shift (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gint vertical, - gint horizontal) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, column, &requisition); - } - - NAUTILUS_CTREE_ROW (node)->row.cell[column].vertical = vertical; - NAUTILUS_CTREE_ROW (node)->row.cell[column].horizontal = horizontal; - - if (visible) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, - column, requisition.width); - - tree_draw_node (ctree, node); -} - -static void -remove_grab (NautilusCList *clist) -{ - if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (clist)) - { - gtk_grab_remove (GTK_WIDGET (clist)); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - - if (clist->htimer) - { - gtk_timeout_remove (clist->htimer); - clist->htimer = 0; - } - - if (clist->vtimer) - { - gtk_timeout_remove (clist->vtimer); - clist->vtimer = 0; - } -} - -void -nautilus_ctree_node_set_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean selectable) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (selectable == NAUTILUS_CTREE_ROW (node)->row.selectable) - return; - - NAUTILUS_CTREE_ROW (node)->row.selectable = selectable; - - if (!selectable && NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (clist->anchor >= 0 && - clist->selection_mode == GTK_SELECTION_EXTENDED) - { - clist->drag_button = 0; - remove_grab (clist); - - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - } - nautilus_ctree_unselect (ctree, node); - } -} - -gboolean -nautilus_ctree_node_get_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (node != NULL, FALSE); - - return NAUTILUS_CTREE_ROW (node)->row.selectable; -} - -NautilusCellType -nautilus_ctree_node_get_cell_type (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_val_if_fail (ctree != NULL, -1); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), -1); - g_return_val_if_fail (node != NULL, -1); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return -1; - - return NAUTILUS_CTREE_ROW (node)->row.cell[column].type; -} - -gint -nautilus_ctree_node_get_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_TEXT - && NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_LINK_TEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_TEXT (NAUTILUS_CTREE_ROW (node)->row.cell[column])->text; - - return 1; -} - -gint -nautilus_ctree_node_get_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf **pixbuf) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_PIXBUF) - return 0; - - if (pixbuf) - *pixbuf = NAUTILUS_CELL_PIXBUF (NAUTILUS_CTREE_ROW(node)->row.cell[column])->pixbuf; - - return 1; -} - -gint -nautilus_ctree_node_get_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return 0; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].type != NAUTILUS_CELL_PIXTEXT) - return 0; - - if (text) - *text = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW (node)->row.cell[column])->text; - if (spacing) - *spacing = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW - (node)->row.cell[column])->spacing; - if (pixbuf) - *pixbuf = NAUTILUS_CELL_PIXTEXT (NAUTILUS_CTREE_ROW - (node)->row.cell[column])->pixbuf; - - return 1; -} - -gint -nautilus_ctree_get_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf_closed, - GdkPixbuf **pixbuf_opened, - gboolean *is_leaf, - gboolean *expanded) -{ - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), 0); - g_return_val_if_fail (node != NULL, 0); - - if (text) - *text = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->text; - if (spacing) - *spacing = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->spacing; - if (pixbuf_closed) - *pixbuf_closed = NAUTILUS_CTREE_ROW (node)->pixbuf_closed; - if (pixbuf_opened) - *pixbuf_opened = NAUTILUS_CTREE_ROW (node)->pixbuf_opened; - if (is_leaf) - *is_leaf = NAUTILUS_CTREE_ROW (node)->is_leaf; - if (expanded) - *expanded = NAUTILUS_CTREE_ROW (node)->expanded; - - return 1; -} - -void -nautilus_ctree_node_set_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GtkStyle *style) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible = FALSE; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (column < 0 || column >= clist->columns) - return; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style == style) - return; - - if (clist->column[column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible) - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, column, &requisition); - } - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - gtk_style_unref (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - } - - NAUTILUS_CTREE_ROW (node)->row.cell[column].style = style; - - if (NAUTILUS_CTREE_ROW (node)->row.cell[column].style) - { - gtk_style_ref (NAUTILUS_CTREE_ROW (node)->row.cell[column].style); - - if (GTK_WIDGET_REALIZED (ctree)) - NAUTILUS_CTREE_ROW (node)->row.cell[column].style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.cell[column].style, - clist->clist_window); - } - - if (visible) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, column, - requisition.width); - - tree_draw_node (ctree, node); -} - -GtkStyle * -nautilus_ctree_node_get_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - - if (column < 0 || column >= NAUTILUS_CLIST (ctree)->columns) - return NULL; - - return NAUTILUS_CTREE_ROW (node)->row.cell[column].style; -} - -void -nautilus_ctree_node_set_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - GtkStyle *style) -{ - NautilusCList *clist; - GtkRequisition requisition; - gboolean visible; - gint *old_width = NULL; - gint i; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - clist = NAUTILUS_CLIST (ctree); - - if (NAUTILUS_CTREE_ROW (node)->row.style == style) - return; - - visible = nautilus_ctree_is_viewable (ctree, node); - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - old_width = g_new (gint, clist->columns); - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - { - NAUTILUS_CLIST_CLASS_FW (clist)->cell_size_request - (clist, &NAUTILUS_CTREE_ROW (node)->row, i, &requisition); - old_width[i] = requisition.width; - } - } - - if (NAUTILUS_CTREE_ROW (node)->row.style) - { - if (GTK_WIDGET_REALIZED (ctree)) - gtk_style_detach (NAUTILUS_CTREE_ROW (node)->row.style); - gtk_style_unref (NAUTILUS_CTREE_ROW (node)->row.style); - } - - NAUTILUS_CTREE_ROW (node)->row.style = style; - - if (NAUTILUS_CTREE_ROW (node)->row.style) - { - gtk_style_ref (NAUTILUS_CTREE_ROW (node)->row.style); - - if (GTK_WIDGET_REALIZED (ctree)) - NAUTILUS_CTREE_ROW (node)->row.style = - gtk_style_attach (NAUTILUS_CTREE_ROW (node)->row.style, - clist->clist_window); - } - - if (visible && !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - for (i = 0; i < clist->columns; i++) - if (clist->column[i].auto_resize) - column_auto_resize (clist, &NAUTILUS_CTREE_ROW (node)->row, i, - old_width[i]); - g_free (old_width); - } - tree_draw_node (ctree, node); -} - -GtkStyle * -nautilus_ctree_node_get_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - g_return_val_if_fail (node != NULL, NULL); - - return NAUTILUS_CTREE_ROW (node)->row.style; -} - -void -nautilus_ctree_node_set_foreground (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (color) - { - NAUTILUS_CTREE_ROW (node)->row.foreground = *color; - NAUTILUS_CTREE_ROW (node)->row.fg_set = TRUE; - if (GTK_WIDGET_REALIZED (ctree)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), - &NAUTILUS_CTREE_ROW (node)->row.foreground); - } - else - NAUTILUS_CTREE_ROW (node)->row.fg_set = FALSE; - - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_background (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - if (color) - { - NAUTILUS_CTREE_ROW (node)->row.background = *color; - NAUTILUS_CTREE_ROW (node)->row.bg_set = TRUE; - if (GTK_WIDGET_REALIZED (ctree)) - gdk_color_alloc (gtk_widget_get_colormap (GTK_WIDGET (ctree)), - &NAUTILUS_CTREE_ROW (node)->row.background); - } - else - NAUTILUS_CTREE_ROW (node)->row.bg_set = FALSE; - - tree_draw_node (ctree, node); -} - -void -nautilus_ctree_node_set_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - nautilus_ctree_node_set_row_data_full (ctree, node, data, NULL); -} - -void -nautilus_ctree_node_set_row_data_full (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GtkDestroyNotify destroy) -{ - GtkDestroyNotify dnotify; - gpointer ddata; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (node != NULL); - - dnotify = NAUTILUS_CTREE_ROW (node)->row.destroy; - ddata = NAUTILUS_CTREE_ROW (node)->row.data; - - NAUTILUS_CTREE_ROW (node)->row.data = data; - NAUTILUS_CTREE_ROW (node)->row.destroy = destroy; - - if (dnotify) - dnotify (ddata); -} - -gpointer -nautilus_ctree_node_get_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - g_return_val_if_fail (ctree != NULL, NULL); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), NULL); - - return node ? NAUTILUS_CTREE_ROW (node)->row.data : NULL; -} - -void -nautilus_ctree_node_moveto (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gfloat row_align, - gfloat col_align) -{ - gint row = -1; - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - while (node && !nautilus_ctree_is_viewable (ctree, node)) - node = NAUTILUS_CTREE_ROW (node)->parent; - - if (node) - row = g_list_position (clist->row_list, (GList *)node); - - nautilus_clist_moveto (clist, row, column, row_align, col_align); -} - -GtkVisibility nautilus_ctree_node_is_visible (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - gint row; - - g_return_val_if_fail (ctree != NULL, 0); - g_return_val_if_fail (node != NULL, 0); - - row = g_list_position (NAUTILUS_CLIST (ctree)->row_list, (GList*) node); - return nautilus_clist_row_is_visible (NAUTILUS_CLIST (ctree), row); -} - - -/*********************************************************** - * NautilusCTree specific functions * - ***********************************************************/ - -void -nautilus_ctree_set_indent (NautilusCTree *ctree, - gint indent) -{ - NautilusCList *clist; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (indent >= 0); - - if (indent == ctree->tree_indent) - return; - - clist = NAUTILUS_CLIST (ctree); - ctree->tree_indent = indent; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - nautilus_clist_optimal_column_width (clist, ctree->tree_column)); - else - CLIST_REFRESH (clist); -} - -void -nautilus_ctree_set_spacing (NautilusCTree *ctree, - gint spacing) -{ - NautilusCList *clist; - gint old_spacing; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - g_return_if_fail (spacing >= 0); - - if (spacing == ctree->tree_spacing) - return; - - clist = NAUTILUS_CLIST (ctree); - - old_spacing = ctree->tree_spacing; - ctree->tree_spacing = spacing; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - nautilus_clist_set_column_width (clist, ctree->tree_column, - clist->column[ctree->tree_column].width + - spacing - old_spacing); - else - CLIST_REFRESH (clist); -} - -void -nautilus_ctree_set_show_stub (NautilusCTree *ctree, - gboolean show_stub) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - show_stub = show_stub != FALSE; - - if (show_stub != ctree->show_stub) - { - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - ctree->show_stub = show_stub; - - if (CLIST_UNFROZEN (clist) && clist->rows && - nautilus_clist_row_is_visible (clist, 0) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row - (clist, NULL, 0, NAUTILUS_CLIST_ROW (clist->row_list)); - } -} - -void -nautilus_ctree_set_line_style (NautilusCTree *ctree, - NautilusCTreeLineStyle line_style) -{ - NautilusCList *clist; - NautilusCTreeLineStyle old_style; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - if (line_style == ctree->line_style) - return; - - clist = NAUTILUS_CLIST (ctree); - - old_style = ctree->line_style; - ctree->line_style = line_style; - - if (clist->column[ctree->tree_column].auto_resize && - !NAUTILUS_CLIST_AUTO_RESIZE_BLOCKED (clist)) - { - if (old_style == NAUTILUS_CTREE_LINES_TABBED) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width - 3); - else if (line_style == NAUTILUS_CTREE_LINES_TABBED) - nautilus_clist_set_column_width - (clist, ctree->tree_column, - clist->column[ctree->tree_column].width + 3); - } - - if (GTK_WIDGET_REALIZED (ctree)) - { - switch (line_style) - { - case NAUTILUS_CTREE_LINES_SOLID: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - None, None); - break; - case NAUTILUS_CTREE_LINES_DOTTED: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, - GDK_LINE_ON_OFF_DASH, None, None); - gdk_gc_set_dashes (ctree->lines_gc, 0, "\1\1", 2); - break; - case NAUTILUS_CTREE_LINES_TABBED: - if (GTK_WIDGET_REALIZED (ctree)) - gdk_gc_set_line_attributes (ctree->lines_gc, 1, GDK_LINE_SOLID, - None, None); - break; - case NAUTILUS_CTREE_LINES_NONE: - break; - default: - return; - } - CLIST_REFRESH (clist); - } -} - -/*********************************************************** - * Tree sorting functions * - ***********************************************************/ - - -static void -tree_sort (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data) -{ - NautilusCTreeNode *list_start; - NautilusCTreeNode *cmp; - NautilusCTreeNode *work; - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - if (node) - list_start = NAUTILUS_CTREE_ROW (node)->children; - else - list_start = NAUTILUS_CTREE_NODE (clist->row_list); - - while (list_start) - { - cmp = list_start; - work = NAUTILUS_CTREE_ROW (cmp)->sibling; - while (work) - { - if (clist->sort_type == GTK_SORT_ASCENDING) - { - if (clist->compare - (clist, NAUTILUS_CTREE_ROW (work), NAUTILUS_CTREE_ROW (cmp)) < 0) - cmp = work; - } - else - { - if (clist->compare - (clist, NAUTILUS_CTREE_ROW (work), NAUTILUS_CTREE_ROW (cmp)) > 0) - cmp = work; - } - work = NAUTILUS_CTREE_ROW (work)->sibling; - } - if (cmp == list_start) - list_start = NAUTILUS_CTREE_ROW (cmp)->sibling; - else - { - nautilus_ctree_unlink (ctree, cmp, FALSE); - nautilus_ctree_link (ctree, cmp, node, list_start, FALSE); - } - } -} - -void -nautilus_ctree_sort_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *focus_node = NULL; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (!node || (node && nautilus_ctree_is_viewable (ctree, node))) - focus_node = - NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, clist->focus_row)); - - nautilus_ctree_post_recursive (ctree, node, NAUTILUS_CTREE_FUNC (tree_sort), NULL); - - if (!node) - tree_sort (ctree, NULL, NULL); - - if (focus_node) - { - clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node); - clist->undo_anchor = clist->focus_row; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -static void -real_sort_list (NautilusCList *clist) -{ - nautilus_ctree_sort_recursive (NAUTILUS_CTREE (clist), NULL); -} - -void -nautilus_ctree_sort_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCList *clist; - NautilusCTreeNode *focus_node = NULL; - - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (clist->selection_mode == GTK_SELECTION_EXTENDED) - { - NAUTILUS_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL); - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - } - - if (!node || (node && nautilus_ctree_is_viewable (ctree, node))) - focus_node = NAUTILUS_CTREE_NODE - (g_list_nth (clist->row_list, clist->focus_row)); - - tree_sort (ctree, node, NULL); - - if (focus_node) - { - clist->focus_row = g_list_position (clist->row_list,(GList *)focus_node); - clist->undo_anchor = clist->focus_row; - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -void -nautilus_ctree_sort_single_node (NautilusCTree *ctree, - NautilusCTreeNode *node) -{ - NautilusCTreeNode *sibling, *parent; - NautilusCList *clist; - - clist = NAUTILUS_CLIST (ctree); - - nautilus_clist_freeze (clist); - - if (NAUTILUS_CLIST_AUTO_SORT (clist)) - { - parent = NAUTILUS_CTREE_ROW (node)->parent; - - if (parent) - sibling = NAUTILUS_CTREE_ROW (parent)->children; - else - sibling = NAUTILUS_CTREE_NODE (clist->row_list); - - while (sibling - && (sibling == node || clist->compare (clist, NAUTILUS_CTREE_ROW (node), NAUTILUS_CTREE_ROW (sibling)) > 0)) - sibling = NAUTILUS_CTREE_ROW (sibling)->sibling; - - nautilus_ctree_unlink (ctree, node, TRUE); - nautilus_ctree_link (ctree, node, parent, sibling, TRUE); - } - - CLIST_REFRESH (clist); - nautilus_clist_thaw (clist); -} - -/************************************************************************/ - -static void -fake_unselect_all (NautilusCList *clist, - gint row) -{ - GList *list; - GList *focus_node = NULL; - - if (row >= 0 && (focus_node = g_list_nth (clist->row_list, row))) - { - if (NAUTILUS_CTREE_ROW (focus_node)->row.state == GTK_STATE_NORMAL && - NAUTILUS_CTREE_ROW (focus_node)->row.selectable) - { - NAUTILUS_CTREE_ROW (focus_node)->row.state = GTK_STATE_SELECTED; - - if (CLIST_UNFROZEN (clist) && - nautilus_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, - NAUTILUS_CLIST_ROW (focus_node)); - } - } - - clist->undo_selection = clist->selection; - clist->selection = NULL; - clist->selection_end = NULL; - - for (list = clist->undo_selection; list; list = list->next) - { - if (list->data == focus_node) - continue; - - NAUTILUS_CTREE_ROW ((GList *)(list->data))->row.state = GTK_STATE_NORMAL; - tree_draw_node (NAUTILUS_CTREE (clist), NAUTILUS_CTREE_NODE (list->data)); - } -} - -static GList * -selection_find (NautilusCList *clist, - gint row_number, - GList *row_list_element) -{ - return g_list_find (clist->selection, row_list_element); -} - -static void -resync_selection (NautilusCList *clist, GdkEvent *event) -{ - NautilusCTree *ctree; - GList *list; - NautilusCTreeNode *node; - gint i; - gint e; - gint row; - gboolean unselect; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (clist->anchor < 0 || clist->drag_pos < 0) - return; - - ctree = NAUTILUS_CTREE (clist); - - clist->freeze_count++; - - i = MIN (clist->anchor, clist->drag_pos); - e = MAX (clist->anchor, clist->drag_pos); - - if (clist->undo_selection) - { - list = clist->selection; - clist->selection = clist->undo_selection; - clist->selection_end = g_list_last (clist->selection); - clist->undo_selection = list; - list = clist->selection; - - while (list) - { - node = list->data; - list = list->next; - - unselect = TRUE; - - if (nautilus_ctree_is_viewable (ctree, node)) - { - row = g_list_position (clist->row_list, (GList *)node); - if (row >= i && row <= e) - unselect = FALSE; - } - if (unselect && NAUTILUS_CTREE_ROW (node)->row.selectable) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = g_list_prepend (clist->undo_selection, - node); - } - } - } - - if (clist->anchor < clist->drag_pos) - { - for (node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, i)); i <= e; - i++, node = NAUTILUS_CTREE_NODE_NEXT (node)) - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - { - if (g_list_find (clist->selection, node)) - { - if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = - g_list_prepend (clist->undo_selection, node); - } - } - else if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, node); - } - } - } - else - { - for (node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, e)); i <= e; - e--, node = NAUTILUS_CTREE_NODE_PREV (node)) - if (NAUTILUS_CTREE_ROW (node)->row.selectable) - { - if (g_list_find (clist->selection, node)) - { - if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED; - nautilus_ctree_unselect (ctree, node); - clist->undo_selection = - g_list_prepend (clist->undo_selection, node); - } - } - else if (NAUTILUS_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED) - { - NAUTILUS_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL; - clist->undo_unselection = - g_list_prepend (clist->undo_unselection, node); - } - } - } - - clist->undo_unselection = g_list_reverse (clist->undo_unselection); - for (list = clist->undo_unselection; list; list = list->next) - nautilus_ctree_select (ctree, list->data); - - clist->anchor = -1; - clist->drag_pos = -1; - - if (!CLIST_UNFROZEN (clist)) - clist->freeze_count--; -} - -static void -real_undo_selection (NautilusCList *clist) -{ - NautilusCTree *ctree; - GList *work; - - g_return_if_fail (clist != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (clist)); - - if (clist->selection_mode != GTK_SELECTION_EXTENDED) - return; - - if (!(clist->undo_selection || clist->undo_unselection)) - { - nautilus_clist_unselect_all (clist); - return; - } - - ctree = NAUTILUS_CTREE (clist); - - for (work = clist->undo_selection; work; work = work->next) - if (NAUTILUS_CTREE_ROW (work->data)->row.selectable) - nautilus_ctree_select (ctree, NAUTILUS_CTREE_NODE (work->data)); - - for (work = clist->undo_unselection; work; work = work->next) - if (NAUTILUS_CTREE_ROW (work->data)->row.selectable) - nautilus_ctree_unselect (ctree, NAUTILUS_CTREE_NODE (work->data)); - - if (GTK_WIDGET_HAS_FOCUS (clist) && clist->focus_row != clist->undo_anchor) - { - gtk_widget_draw_focus (GTK_WIDGET (clist)); - clist->focus_row = clist->undo_anchor; - gtk_widget_draw_focus (GTK_WIDGET (clist)); - } - else - clist->focus_row = clist->undo_anchor; - - clist->undo_anchor = -1; - - g_list_free (clist->undo_selection); - g_list_free (clist->undo_unselection); - clist->undo_selection = NULL; - clist->undo_unselection = NULL; - - if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height > - clist->clist_window_height) - nautilus_clist_moveto (clist, clist->focus_row, -1, 1, 0); - else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0) - nautilus_clist_moveto (clist, clist->focus_row, -1, 0, 0); - -} - -void -nautilus_ctree_set_drag_compare_func (NautilusCTree *ctree, - NautilusCTreeCompareDragFunc cmp_func) -{ - g_return_if_fail (ctree != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (ctree)); - - ctree->drag_compare = cmp_func; -} - -static gboolean -check_drag (NautilusCTree *ctree, - NautilusCTreeNode *drag_source, - NautilusCTreeNode *drag_target, - NautilusCListDragPos insert_pos) -{ - g_return_val_if_fail (ctree != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (ctree), FALSE); - - if (drag_source && drag_source != drag_target && - (!NAUTILUS_CTREE_ROW (drag_source)->children || - !nautilus_ctree_is_ancestor (ctree, drag_source, drag_target))) - { - switch (insert_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - return FALSE; - case NAUTILUS_CLIST_DRAG_AFTER: - if (NAUTILUS_CTREE_ROW (drag_target)->sibling != drag_source) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - NAUTILUS_CTREE_ROW (drag_target)->parent, - NAUTILUS_CTREE_ROW(drag_target)->sibling)); - break; - case NAUTILUS_CLIST_DRAG_BEFORE: - if (NAUTILUS_CTREE_ROW (drag_source)->sibling != drag_target) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - NAUTILUS_CTREE_ROW (drag_target)->parent, - drag_target)); - break; - case NAUTILUS_CLIST_DRAG_INTO: - if (!NAUTILUS_CTREE_ROW (drag_target)->is_leaf && - NAUTILUS_CTREE_ROW (drag_target)->children != drag_source) - return (!ctree->drag_compare || - ctree->drag_compare (ctree, - drag_source, - drag_target, - NAUTILUS_CTREE_ROW (drag_target)->children)); - break; - } - } - return FALSE; -} - - - -/************************************/ -static void -drag_dest_info_destroy (gpointer data) -{ - NautilusCListDestInfo *info = data; - - g_free (info); -} - -static void -drag_dest_cell (NautilusCList *clist, - gint x, - gint y, - NautilusCListDestInfo *dest_info) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (clist); - - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - - y -= (GTK_CONTAINER (widget)->border_width + - widget->style->klass->ythickness + clist->column_title_area.height); - dest_info->cell.row = ROW_FROM_YPIXEL (clist, y); - - if (dest_info->cell.row >= clist->rows) - { - dest_info->cell.row = clist->rows - 1; - y = ROW_TOP_YPIXEL (clist, dest_info->cell.row) + clist->row_height; - } - if (dest_info->cell.row < -1) - dest_info->cell.row = -1; - - x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness; - dest_info->cell.column = COLUMN_FROM_XPIXEL (clist, x); - - if (dest_info->cell.row >= 0) - { - gint y_delta; - gint h = 0; - - y_delta = y - ROW_TOP_YPIXEL (clist, dest_info->cell.row); - - if (NAUTILUS_CLIST_DRAW_DRAG_RECT(clist) && - !NAUTILUS_CTREE_ROW (g_list_nth (clist->row_list, - dest_info->cell.row))->is_leaf) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_INTO; - h = clist->row_height / 4; - } - else if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - h = clist->row_height / 2; - } - - if (NAUTILUS_CLIST_DRAW_DRAG_LINE(clist)) - { - if (y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_BEFORE; - else if (clist->row_height - y_delta < h) - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_AFTER; - } - } -} - -static void -nautilus_ctree_drag_begin (GtkWidget *widget, - GdkDragContext *context) -{ - NautilusCList *clist; - NautilusCTree *ctree; - gboolean use_icons; - GdkPixbuf *pixbuf; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - g_return_if_fail (context != NULL); - - clist = NAUTILUS_CLIST (widget); - ctree = NAUTILUS_CTREE (widget); - - use_icons = NAUTILUS_CLIST_USE_DRAG_ICONS (clist); - NAUTILUS_CLIST_UNSET_FLAG (clist, CLIST_USE_DRAG_ICONS); - GTK_WIDGET_CLASS (parent_class)->drag_begin (widget, context); - - if (use_icons) - { - NautilusCTreeNode *node; - - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_USE_DRAG_ICONS); - node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - clist->click_cell.row)); - if (node) - { - pixbuf = NAUTILUS_CELL_PIXTEXT - (NAUTILUS_CTREE_ROW (node)->row.cell[ctree->tree_column])->pixbuf; - if (pixbuf) - { - eel_drag_set_icon_pixbuf (context, pixbuf, -2, -2); - return; - } - } - gtk_drag_set_icon_default (context); - } -} - -static gint -nautilus_ctree_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time) -{ - NautilusCList *clist; - NautilusCTree *ctree; - NautilusCListDestInfo new_info; - NautilusCListDestInfo *dest_info; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (NAUTILUS_IS_CTREE (widget), FALSE); - - clist = NAUTILUS_CLIST (widget); - ctree = NAUTILUS_CTREE (widget); - - dest_info = g_dataset_get_data (context, "nautilus-clist-drag-dest"); - - if (!dest_info) - { - dest_info = g_new (NautilusCListDestInfo, 1); - - dest_info->cell.row = -1; - dest_info->cell.column = -1; - dest_info->insert_pos = NAUTILUS_CLIST_DRAG_NONE; - - g_dataset_set_data_full (context, "nautilus-clist-drag-dest", dest_info, - drag_dest_info_destroy); - } - - drag_dest_cell (clist, x, y, &new_info); - - if (NAUTILUS_CLIST_REORDERABLE (clist)) - { - GList *list; - GdkAtom atom = gdk_atom_intern ("nautilus-clist-drag-reorder", FALSE); - - list = context->targets; - while (list) - { - if (atom == GPOINTER_TO_UINT (list->data)) - break; - list = list->next; - } - - if (list) - { - NautilusCTreeNode *drag_source; - NautilusCTreeNode *drag_target; - - drag_source = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - clist->click_cell.row)); - drag_target = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - new_info.cell.row)); - - if (gtk_drag_get_source_widget (context) != widget || - !check_drag (ctree, drag_source, drag_target, - new_info.insert_pos)) - { - if (dest_info->cell.row < 0) - { - gdk_drag_status (context, GDK_ACTION_DEFAULT, time); - return FALSE; - } - return TRUE; - } - - if (new_info.cell.row != dest_info->cell.row || - (new_info.cell.row == dest_info->cell.row && - dest_info->insert_pos != new_info.insert_pos)) - { - if (dest_info->cell.row >= 0) - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, - g_list_nth (clist->row_list, dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - - NAUTILUS_CLIST_CLASS_FW (clist)->draw_drag_highlight - (clist, - g_list_nth (clist->row_list, dest_info->cell.row)->data, - dest_info->cell.row, dest_info->insert_pos); - - gdk_drag_status (context, context->suggested_action, time); - } - return TRUE; - } - } - - dest_info->insert_pos = new_info.insert_pos; - dest_info->cell.row = new_info.cell.row; - dest_info->cell.column = new_info.cell.column; - return TRUE; -} - -static void -nautilus_ctree_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint32 time) -{ - NautilusCTree *ctree; - NautilusCList *clist; - - g_return_if_fail (widget != NULL); - g_return_if_fail (NAUTILUS_IS_CTREE (widget)); - g_return_if_fail (context != NULL); - g_return_if_fail (selection_data != NULL); - - ctree = NAUTILUS_CTREE (widget); - clist = NAUTILUS_CLIST (widget); - - if (NAUTILUS_CLIST_REORDERABLE (clist) && - gtk_drag_get_source_widget (context) == widget && - selection_data->target == - gdk_atom_intern ("nautilus-clist-drag-reorder", FALSE) && - selection_data->format == GTK_TYPE_POINTER && - selection_data->length == sizeof (NautilusCListCellInfo)) - { - NautilusCListCellInfo *source_info; - - source_info = (NautilusCListCellInfo *)(selection_data->data); - if (source_info) - { - NautilusCListDestInfo dest_info; - NautilusCTreeNode *source_node; - NautilusCTreeNode *dest_node; - - drag_dest_cell (clist, x, y, &dest_info); - - source_node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - source_info->row)); - dest_node = NAUTILUS_CTREE_NODE (g_list_nth (clist->row_list, - dest_info.cell.row)); - - if (!source_node || !dest_node) - return; - - switch (dest_info.insert_pos) - { - case NAUTILUS_CLIST_DRAG_NONE: - break; - case NAUTILUS_CLIST_DRAG_INTO: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, dest_node, - NAUTILUS_CTREE_ROW (dest_node)->children); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - case NAUTILUS_CLIST_DRAG_BEFORE: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, - NAUTILUS_CTREE_ROW (dest_node)->parent, dest_node); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - case NAUTILUS_CLIST_DRAG_AFTER: - if (check_drag (ctree, source_node, dest_node, - dest_info.insert_pos)) - nautilus_ctree_move (ctree, source_node, - NAUTILUS_CTREE_ROW (dest_node)->parent, - NAUTILUS_CTREE_ROW (dest_node)->sibling); - g_dataset_remove_data (context, "nautilus-clist-drag-dest"); - break; - } - } - } -} diff --git a/libnautilus-private/nautilus-ctree.h b/libnautilus-private/nautilus-ctree.h deleted file mode 100644 index 1f7982874..000000000 --- a/libnautilus-private/nautilus-ctree.h +++ /dev/null @@ -1,441 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald - * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> - * - * NautilusCTree widget for GTK+ - * Copyright (C) 1998 Lars Hamann and Stefan Jeske - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef NAUTILUS_CTREE_H -#define NAUTILUS_CTREE_H - -#include "nautilus-list.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define NAUTILUS_TYPE_CTREE (nautilus_ctree_get_type ()) -#define NAUTILUS_CTREE(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_CTREE, NautilusCTree)) -#define NAUTILUS_CTREE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_CTREE, NautilusCTreeClass)) -#define NAUTILUS_IS_CTREE(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_CTREE)) -#define NAUTILUS_IS_CTREE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_CTREE)) - -#define NAUTILUS_CTREE_ROW(_node_) ((NautilusCTreeRow *)(((GList *)(_node_))->data)) -#define NAUTILUS_CTREE_NODE(_node_) ((NautilusCTreeNode *)((_node_))) -#define NAUTILUS_CTREE_NODE_NEXT(_nnode_) ((NautilusCTreeNode *)(((GList *)(_nnode_))->next)) -#define NAUTILUS_CTREE_NODE_PREV(_pnode_) ((NautilusCTreeNode *)(((GList *)(_pnode_))->prev)) -#define NAUTILUS_CTREE_FUNC(_func_) ((NautilusCTreeFunc)(_func_)) - -typedef enum -{ - NAUTILUS_CTREE_POS_BEFORE, - NAUTILUS_CTREE_POS_AS_CHILD, - NAUTILUS_CTREE_POS_AFTER -} NautilusCTreePos; - -typedef enum -{ - NAUTILUS_CTREE_LINES_NONE, - NAUTILUS_CTREE_LINES_SOLID, - NAUTILUS_CTREE_LINES_DOTTED, - NAUTILUS_CTREE_LINES_TABBED -} NautilusCTreeLineStyle; - -typedef enum -{ - NAUTILUS_CTREE_EXPANDER_TRIANGLE -} NautilusCTreeExpanderStyle; - -typedef enum -{ - NAUTILUS_CTREE_EXPANSION_EXPAND, - NAUTILUS_CTREE_EXPANSION_EXPAND_RECURSIVE, - NAUTILUS_CTREE_EXPANSION_COLLAPSE, - NAUTILUS_CTREE_EXPANSION_COLLAPSE_RECURSIVE, - NAUTILUS_CTREE_EXPANSION_TOGGLE, - NAUTILUS_CTREE_EXPANSION_TOGGLE_RECURSIVE -} NautilusCTreeExpansionType; - -typedef struct _NautilusCTree NautilusCTree; -typedef struct _NautilusCTreeClass NautilusCTreeClass; -typedef struct _NautilusCTreeRow NautilusCTreeRow; -typedef struct _NautilusCTreeNode NautilusCTreeNode; - -typedef void (*NautilusCTreeFunc) (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); - -typedef gboolean (*NautilusCTreeGNodeFunc) (NautilusCTree *ctree, - guint depth, - GNode *gnode, - NautilusCTreeNode *cnode, - gpointer data); - -typedef gboolean (*NautilusCTreeCompareDragFunc) (NautilusCTree *ctree, - NautilusCTreeNode *source_node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); - -struct _NautilusCTree -{ - NautilusList list; - - GdkGC *lines_gc; - - gint tree_indent; - gint tree_spacing; - gint tree_column; - - guint line_style : 2; - guint show_stub : 1; - - NautilusCTreeNode *prelight_node; - - NautilusCTreeRow *dnd_prelighted_row; - - NautilusCTreeCompareDragFunc drag_compare; -}; - -struct _NautilusCTreeClass -{ - NautilusListClass parent_class; - - void (*tree_select_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); - void (*tree_unselect_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); - void (*tree_expand) (NautilusCTree *ctree, - NautilusCTreeNode *node); - void (*tree_collapse) (NautilusCTree *ctree, - NautilusCTreeNode *node); - void (*tree_move) (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); - void (*change_focus_row_expansion) (NautilusCTree *ctree, - NautilusCTreeExpansionType action); - void (*tree_activate_row) (NautilusCTree *ctree, - NautilusCTreeNode *row, - gint column); -}; - -struct _NautilusCTreeRow -{ - NautilusCListRow row; - - NautilusCTreeNode *parent; - NautilusCTreeNode *sibling; - NautilusCTreeNode *children; - - GdkPixbuf *pixbuf_closed; - GdkPixbuf *pixbuf_opened; - - guint16 level; - - guint is_leaf : 1; - guint expanded : 1; - - gboolean mouse_down; - gboolean in_hotspot; - -}; - -struct _NautilusCTreeNode { - GList list; -}; - - -/*********************************************************** - * Creation, insertion, deletion * - ***********************************************************/ - -GtkType nautilus_ctree_get_type (void); -void nautilus_ctree_construct (NautilusCTree *ctree, - gint columns, - gint tree_column, - gchar *titles[]); -GtkWidget * nautilus_ctree_new_with_titles (gint columns, - gint tree_column, - gchar *titles[]); -GtkWidget * nautilus_ctree_new (gint columns, - gint tree_column); -NautilusCTreeNode * nautilus_ctree_insert_node (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - gchar *text[], - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -void nautilus_ctree_remove_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_insert_gnode (NautilusCTree *ctree, - NautilusCTreeNode *parent, - NautilusCTreeNode *sibling, - GNode *gnode, - NautilusCTreeGNodeFunc func, - gpointer data); -GNode * nautilus_ctree_export_to_gnode (NautilusCTree *ctree, - GNode *parent, - GNode *sibling, - NautilusCTreeNode *node, - NautilusCTreeGNodeFunc func, - gpointer data); - -/*********************************************************** - * Generic recursive functions, querying / finding tree * - * information * - ***********************************************************/ - -void nautilus_ctree_post_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_post_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_pre_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeFunc func, - gpointer data); -void nautilus_ctree_pre_recursive_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth, - NautilusCTreeFunc func, - gpointer data); -gboolean nautilus_ctree_is_viewable (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_last (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCTreeNode * nautilus_ctree_find_node_ptr (NautilusCTree *ctree, - NautilusCTreeRow *ctree_row); -NautilusCTreeNode * nautilus_ctree_node_nth (NautilusCTree *ctree, - int row); -gboolean nautilus_ctree_find (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child); -gboolean nautilus_ctree_is_ancestor (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *child); -NautilusCTreeNode * nautilus_ctree_find_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -/* returns a GList of all NautilusCTreeNodes with row->data == data. */ -GList * nautilus_ctree_find_all_by_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -NautilusCTreeNode * nautilus_ctree_find_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func); -/* returns a GList of all NautilusCTreeNodes with row->data == data. */ -GList * nautilus_ctree_find_all_by_row_data_custom (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GCompareFunc func); -gboolean nautilus_ctree_is_hot_spot (NautilusCTree *ctree, - gint x, - gint y); - -/*********************************************************** - * Tree signals : move, expand, collapse, (un)select * - ***********************************************************/ - -void nautilus_ctree_move (NautilusCTree *ctree, - NautilusCTreeNode *node, - NautilusCTreeNode *new_parent, - NautilusCTreeNode *new_sibling); -void nautilus_ctree_expand (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_expand_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_expand_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -void nautilus_ctree_collapse (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_collapse_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_collapse_to_depth (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint depth); -void nautilus_ctree_toggle_expansion (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_toggle_expansion_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_select (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_unselect (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_unselect_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_real_select_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint state); -void nautilus_ctree_draw_node (NautilusCTree *ctree, - NautilusCTreeNode *node); - -/*********************************************************** - * Analogons of GtkCList functions * - ***********************************************************/ - -void nautilus_ctree_node_set_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text); -void nautilus_ctree_node_set_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf *pixbuf); -void nautilus_ctree_node_set_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -void nautilus_ctree_set_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf_closed, - GdkPixbuf *pixbuf_opened, - gboolean is_leaf, - gboolean expanded); -void nautilus_ctree_node_set_shift (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gint vertical, - gint horizontal); -void nautilus_ctree_node_set_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node, - gboolean selectable); -gboolean nautilus_ctree_node_get_selectable (NautilusCTree *ctree, - NautilusCTreeNode *node); -NautilusCellType nautilus_ctree_node_get_cell_type (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -gint nautilus_ctree_node_get_text (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text); -gint nautilus_ctree_node_get_pixbuf (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GdkPixbuf **pixbuf); -gint nautilus_ctree_node_get_pixtext (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf); -gint nautilus_ctree_get_node_info (NautilusCTree *ctree, - NautilusCTreeNode *node, - gchar **text, - guint8 *spacing, - GdkPixbuf **pixbuf_closed, - GdkPixbuf **pixbuf_opened, - gboolean *is_leaf, - gboolean *expanded); - -void nautilus_ctree_set_prelight (NautilusCTree *ctree, - int y); - -void nautilus_ctree_node_set_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - GtkStyle *style); -GtkStyle * nautilus_ctree_node_get_row_style (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_node_set_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - GtkStyle *style); -GtkStyle * nautilus_ctree_node_get_cell_style (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column); -void nautilus_ctree_node_set_foreground (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color); -void nautilus_ctree_node_set_background (NautilusCTree *ctree, - NautilusCTreeNode *node, - GdkColor *color); -void nautilus_ctree_node_set_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data); -void nautilus_ctree_node_set_row_data_full (NautilusCTree *ctree, - NautilusCTreeNode *node, - gpointer data, - GtkDestroyNotify destroy); -gpointer nautilus_ctree_node_get_row_data (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_node_moveto (NautilusCTree *ctree, - NautilusCTreeNode *node, - gint column, - gfloat row_align, - gfloat col_align); -GtkVisibility nautilus_ctree_node_is_visible (NautilusCTree *ctree, - NautilusCTreeNode *node); - -/*********************************************************** - * NautilusCTree specific functions * - ***********************************************************/ - -void nautilus_ctree_set_indent (NautilusCTree *ctree, - gint indent); -void nautilus_ctree_set_spacing (NautilusCTree *ctree, - gint spacing); -void nautilus_ctree_set_show_stub (NautilusCTree *ctree, - gboolean show_stub); -void nautilus_ctree_set_line_style (NautilusCTree *ctree, - NautilusCTreeLineStyle line_style); -void nautilus_ctree_set_drag_compare_func (NautilusCTree *ctree, - NautilusCTreeCompareDragFunc cmp_func); - -/*********************************************************** - * Tree sorting functions * - ***********************************************************/ - -void nautilus_ctree_sort_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_sort_single_node (NautilusCTree *ctree, - NautilusCTreeNode *node); -void nautilus_ctree_sort_recursive (NautilusCTree *ctree, - NautilusCTreeNode *node); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* NAUTILUS_CTREE_H */ diff --git a/libnautilus-private/nautilus-drag.c b/libnautilus-private/nautilus-drag.c deleted file mode 100644 index e609993b3..000000000 --- a/libnautilus-private/nautilus-drag.c +++ /dev/null @@ -1,688 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-drag.c - Common Drag & drop handling code shared by the icon container - and the list view. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com>, - Ettore Perazzoli <ettore@gnu.org> -*/ - -#include <config.h> -#include "nautilus-drag.h" - -#include "nautilus-link.h" -#include <eel/eel-glib-extensions.h> -#include <eel/eel-string.h> -#include <eel/eel-vfs-extensions.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-popup-menu.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomevfs/gnome-vfs-find-directory.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-types.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-utils.h> -#include <stdio.h> -#include <string.h> - -#define NAUTILUS_COMMAND_SPECIFIER "command:" - -void -nautilus_drag_init (NautilusDragInfo *drag_info, - const GtkTargetEntry *drag_types, int drag_type_count, - GdkBitmap *stipple) -{ - drag_info->target_list = gtk_target_list_new (drag_types, - drag_type_count); - - if (stipple != NULL) { - drag_info->stipple = gdk_bitmap_ref (stipple); - } - - drag_info->drop_occured = FALSE; - drag_info->need_to_destroy = FALSE; -} - -void -nautilus_drag_finalize (NautilusDragInfo *drag_info) -{ - gtk_target_list_unref (drag_info->target_list); - nautilus_drag_destroy_selection_list (drag_info->selection_list); - - if (drag_info->stipple != NULL) { - gdk_bitmap_unref (drag_info->stipple); - } - - g_free (drag_info); -} - - -/* Functions to deal with DragSelectionItems. */ - -DragSelectionItem * -nautilus_drag_selection_item_new (void) -{ - return g_new0 (DragSelectionItem, 1); -} - -static void -drag_selection_item_destroy (DragSelectionItem *item) -{ - g_free (item->uri); - g_free (item); -} - -void -nautilus_drag_destroy_selection_list (GList *list) -{ - GList *p; - - if (list == NULL) - return; - - for (p = list; p != NULL; p = p->next) - drag_selection_item_destroy (p->data); - - g_list_free (list); -} - -GList * -nautilus_drag_build_selection_list (GtkSelectionData *data) -{ - GList *result; - const guchar *p, *oldp; - int size; - - result = NULL; - oldp = data->data; - size = data->length; - - while (size > 0) { - DragSelectionItem *item; - guint len; - - /* The list is in the form: - - name\rx:y:width:height\r\n - - The geometry information after the first \r is optional. */ - - /* 1: Decode name. */ - - p = memchr (oldp, '\r', size); - if (p == NULL) { - break; - } - - item = nautilus_drag_selection_item_new (); - - len = p - oldp; - - item->uri = g_malloc (len + 1); - memcpy (item->uri, oldp, len); - item->uri[len] = 0; - - p++; - if (*p == '\n' || *p == '\0') { - result = g_list_prepend (result, item); - if (p == 0) { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "missing newline character."); - break; - } else { - oldp = p + 1; - continue; - } - } - - size -= p - oldp; - oldp = p; - - /* 2: Decode geometry information. */ - - item->got_icon_position = sscanf (p, "%d:%d:%d:%d%*s", - &item->icon_x, &item->icon_y, - &item->icon_width, &item->icon_height) == 4; - if (!item->got_icon_position) { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "invalid icon position specification."); - } - - result = g_list_prepend (result, item); - - p = memchr (p, '\r', size); - if (p == NULL || p[1] != '\n') { - g_warning ("Invalid x-special/gnome-icon-list data received: " - "missing newline character."); - if (p == NULL) { - break; - } - } else { - p += 2; - } - - size -= p - oldp; - oldp = p; - } - - return result; -} - - -gboolean -nautilus_drag_items_local (const char *target_uri_string, const GList *selection_list) -{ - /* check if the first item on the list has target_uri_string as a parent - * FIXME: - * we should really test each item but that would be slow for large selections - * and currently dropped items can only be from the same container - */ - GnomeVFSURI *target_uri; - GnomeVFSURI *item_uri; - gboolean result; - - /* must have at least one item */ - g_assert (selection_list); - - result = FALSE; - - target_uri = gnome_vfs_uri_new (target_uri_string); - - /* get the parent URI of the first item in the selection */ - item_uri = gnome_vfs_uri_new (((DragSelectionItem *)selection_list->data)->uri); - result = gnome_vfs_uri_is_parent (target_uri, item_uri, FALSE); - - gnome_vfs_uri_unref (item_uri); - gnome_vfs_uri_unref (target_uri); - - return result; -} - -gboolean -nautilus_drag_items_in_trash (const GList *selection_list) -{ - /* check if the first item on the list is in trash. - * FIXME: - * we should really test each item but that would be slow for large selections - * and currently dropped items can only be from the same container - */ - return eel_uri_is_in_trash (((DragSelectionItem *)selection_list->data)->uri); -} - -gboolean -nautilus_drag_can_accept_item (NautilusFile *drop_target_item, - const char *item_uri) -{ - if (nautilus_file_matches_uri (drop_target_item, item_uri)) { - /* can't accept itself */ - return FALSE; - } - - if (nautilus_file_is_directory (drop_target_item)) { - /* target is a directory, accept anything */ - return TRUE; - } - - /* All Nautilus links are assumed to be links to directories. - * Therefore, they all can accept drags, like all other - * directories to. As with other directories, there can be - * errors when the actual copy is attempted due to - * permissions. - */ - if (nautilus_file_is_nautilus_link (drop_target_item)) { - return TRUE; - } - - return FALSE; -} - -gboolean -nautilus_drag_can_accept_items (NautilusFile *drop_target_item, - const GList *items) -{ - int max; - - if (drop_target_item == NULL) - return FALSE; - - g_assert (NAUTILUS_IS_FILE (drop_target_item)); - - /* Iterate through selection checking if item will get accepted by the - * drop target. If more than 100 items selected, return an over-optimisic - * result - */ - for (max = 100; items != NULL && max >= 0; items = items->next, max--) { - if (!nautilus_drag_can_accept_item (drop_target_item, - ((DragSelectionItem *)items->data)->uri)) { - return FALSE; - } - } - - return TRUE; -} - -void -nautilus_drag_default_drop_action_for_icons (GdkDragContext *context, - const char *target_uri_string, const GList *items, - int *default_action, int *non_default_action) -{ - gboolean same_fs; - GnomeVFSURI *target_uri; - GnomeVFSURI *dropped_uri; - GdkDragAction actions; - GnomeVFSResult result; - - if (target_uri_string == NULL) { - *default_action = 0; - *non_default_action = 0; - return; - } - - actions = context->actions & (GDK_ACTION_MOVE | GDK_ACTION_COPY); - if (actions == 0) { - /* We can't use copy or move, just go with the suggested action. - * - * Note: it would be more correct to only choose between move - * and copy if both are specified in context->actions. - * There is a problem in gtk-dnd.c though where context->actions - * gets set only to copy when Control is held down, despite the - * fact that bot copy and move were requested. - * - */ - *default_action = context->suggested_action; - *non_default_action = context->suggested_action; - return; - } - - /* Check for trash URI. We do a find_directory for any Trash directory. */ - if (eel_uri_is_trash (target_uri_string)) { - result = gnome_vfs_find_directory (NULL, GNOME_VFS_DIRECTORY_KIND_TRASH, - &target_uri, FALSE, FALSE, 0777); - if (result != GNOME_VFS_OK) { - *default_action = 0; - *non_default_action = 0; - return; - } - - /* Only move to Trash */ - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_MOVE; - return; - - } else if (eel_str_has_prefix (target_uri_string, NAUTILUS_COMMAND_SPECIFIER)) { - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_MOVE; - return; - } else { - target_uri = gnome_vfs_uri_new (target_uri_string); - } - - if (target_uri == NULL) { - *default_action = 0; - *non_default_action = 0; - return; - } - - /* Compare the first dropped uri with the target uri for same fs match. */ - dropped_uri = gnome_vfs_uri_new (((DragSelectionItem *)items->data)->uri); - same_fs = TRUE; - - gnome_vfs_check_same_fs_uris (dropped_uri, target_uri, &same_fs); - gnome_vfs_uri_unref (dropped_uri); - gnome_vfs_uri_unref (target_uri); - - if (same_fs) { - *default_action = GDK_ACTION_MOVE; - *non_default_action = GDK_ACTION_COPY; - } else { - *default_action = GDK_ACTION_COPY; - *non_default_action = GDK_ACTION_MOVE; - } -} - -/* Encode a "x-special/gnome-icon-list" selection. - Along with the URIs of the dragged files, this encodes - the location and size of each icon relative to the cursor. -*/ -static void -add_one_gnome_icon_list (const char *uri, int x, int y, int w, int h, - gpointer data) -{ - GString *result = (GString *)data; - char *s; - - s = g_strdup_printf ("%s\r%d:%d:%hu:%hu\r\n", - uri, x, y, w, h); - - g_string_append (result, s); - g_free (s); -} - -/* Encode a "text/uri-list" selection. */ -static void -add_one_uri_list (const char *uri, int x, int y, int w, int h, - gpointer data) -{ - GString *result = (GString *)data; - g_string_append (result, uri); - g_string_append (result, "\r\n"); -} - -/* Encode a "_NETSCAPE_URL_" selection. - * As far as I can tell, Netscape is expecting a single - * URL to be returned. I cannot discover a way to construct - * a list to be returned that Netscape can understand. - * GMC also fails to do this as well. - */ -static void -add_one_netscape_url_list (const char *url, int x, int y, int w, int h, gpointer data) -{ - GString *result = (GString *)data; - if (result->len == 0) { - g_string_append (result, url); - } -} - -/* Encode a "text/path" selection. */ -static void -add_one_path_list (const char *uri, int x, int y, int w, int h, gpointer data) -{ - GString *result = (GString *)data; - char *local_path; - - g_return_if_fail (uri != NULL); - - local_path = gnome_vfs_get_local_path_from_uri (uri); - if (local_path == NULL) - return; - - g_string_append (result, local_path); - g_string_append (result, "\r\n"); - g_free (local_path); -} - - -/* Common function for drag_data_get_callback calls. - * Returns FALSE if it doesn't handle drag data - */ -gboolean -nautilus_drag_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint32 time, - gpointer container_context, - NautilusDragEachSelectedItemIterator each_selected_item_iterator) -{ - GString *result; - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_gnome_icon_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_URI_LIST: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_uri_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_TEXT: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_path_list, container_context, result); - break; - - case NAUTILUS_ICON_DND_URL: - result = g_string_new (NULL); - each_selected_item_iterator (add_one_netscape_url_list, container_context, result); - break; - - default: - return FALSE; - } - - gtk_selection_data_set (selection_data, - selection_data->target, - 8, result->str, result->len); - - return TRUE; -} - -int -nautilus_drag_modifier_based_action (int default_action, int non_default_action) -{ - GdkModifierType modifiers; - gdk_window_get_pointer (NULL, NULL, NULL, &modifiers); - - if ((modifiers & GDK_CONTROL_MASK) != 0) { - return non_default_action; - } else if ((modifiers & GDK_SHIFT_MASK) != 0) { - return GDK_ACTION_LINK; - } else if ((modifiers & GDK_MOD1_MASK) != 0) { - return GDK_ACTION_ASK; - } - - return default_action; -} - -/* The menu of DnD actions */ -static GnomeUIInfo menu_items[] = { - GNOMEUIINFO_ITEM_NONE (N_("_Move here"), NULL, NULL), - GNOMEUIINFO_ITEM_NONE (N_("_Copy here"), NULL, NULL), - GNOMEUIINFO_ITEM_NONE (N_("_Link here"), NULL, NULL), - GNOMEUIINFO_SEPARATOR, - GNOMEUIINFO_ITEM_NONE (N_("Cancel"), NULL, NULL), - GNOMEUIINFO_END -}; - -/* Pops up a menu of actions to perform on dropped files */ -GdkDragAction -nautilus_drag_drop_action_ask (GdkDragAction actions) -{ - GtkWidget *menu; - int action; - - /* Create the menu and set the sensitivity of the items based on the - * allowed actions. - */ - menu = gnome_popup_menu_new (menu_items); - - gtk_widget_set_sensitive (menu_items[0].widget, (actions & GDK_ACTION_MOVE) != 0); - gtk_widget_set_sensitive (menu_items[1].widget, (actions & GDK_ACTION_COPY) != 0); - gtk_widget_set_sensitive (menu_items[2].widget, (actions & GDK_ACTION_LINK) != 0); - - switch (gnome_popup_menu_do_popup_modal (menu, NULL, NULL, NULL, NULL)) { - case 0: - action = GDK_ACTION_MOVE; - break; - case 1: - action = GDK_ACTION_COPY; - break; - case 2: - action = GDK_ACTION_LINK; - break; - default: - action = 0; - } - - gtk_widget_destroy (menu); - - return action; -} - -#define AUTO_SCROLL_MARGIN 20 - /* drag this close to the view edge to start auto scroll*/ - -#define MIN_AUTOSCROLL_DELTA 5 - /* the smallest amount of auto scroll used when we just enter the autoscroll - * margin - */ - -#define MAX_AUTOSCROLL_DELTA 50 - /* the largest amount of auto scroll used when we are right over the view - * edge - */ - - - -gboolean -nautilus_drag_autoscroll_in_scroll_region (GtkWidget *widget) -{ - float x_scroll_delta, y_scroll_delta; - - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); - - return x_scroll_delta != 0 || y_scroll_delta != 0; -} - - -void -nautilus_drag_autoscroll_calculate_delta (GtkWidget *widget, float *x_scroll_delta, float *y_scroll_delta) -{ - int x, y; - - g_assert (GTK_IS_WIDGET (widget)); - - gdk_window_get_pointer (widget->window, &x, &y, NULL); - - /* Find out if we are anywhere close to the tree view edges - * to see if we need to autoscroll. - */ - *x_scroll_delta = 0; - *y_scroll_delta = 0; - - if (x < AUTO_SCROLL_MARGIN) { - *x_scroll_delta = (float)(x - AUTO_SCROLL_MARGIN); - } - - if (x > widget->allocation.width - AUTO_SCROLL_MARGIN) { - if (*x_scroll_delta != 0) { - /* Already trying to scroll because of being too close to - * the top edge -- must be the window is really short, - * don't autoscroll. - */ - return; - } - *x_scroll_delta = (float)(x - (widget->allocation.width - AUTO_SCROLL_MARGIN)); - } - - if (y < AUTO_SCROLL_MARGIN) { - *y_scroll_delta = (float)(y - AUTO_SCROLL_MARGIN); - } - - if (y > widget->allocation.height - AUTO_SCROLL_MARGIN) { - if (*y_scroll_delta != 0) { - /* Already trying to scroll because of being too close to - * the top edge -- must be the window is really narrow, - * don't autoscroll. - */ - return; - } - *y_scroll_delta = (float)(y - (widget->allocation.height - AUTO_SCROLL_MARGIN)); - } - - if (*x_scroll_delta == 0 && *y_scroll_delta == 0) { - /* no work */ - return; - } - - /* Adjust the scroll delta to the proper acceleration values depending on how far - * into the sroll margins we are. - * FIXME bugzilla.eazel.com 2486: - * we could use an exponential acceleration factor here for better feel - */ - if (*x_scroll_delta != 0) { - *x_scroll_delta /= AUTO_SCROLL_MARGIN; - *x_scroll_delta *= (MAX_AUTOSCROLL_DELTA - MIN_AUTOSCROLL_DELTA); - *x_scroll_delta += MIN_AUTOSCROLL_DELTA; - } - - if (*y_scroll_delta != 0) { - *y_scroll_delta /= AUTO_SCROLL_MARGIN; - *y_scroll_delta *= (MAX_AUTOSCROLL_DELTA - MIN_AUTOSCROLL_DELTA); - *y_scroll_delta += MIN_AUTOSCROLL_DELTA; - } - -} - - - -void -nautilus_drag_autoscroll_start (NautilusDragInfo *drag_info, - GtkWidget *widget, - GtkFunction callback, - gpointer user_data) -{ - if (nautilus_drag_autoscroll_in_scroll_region (widget)) { - if (drag_info->auto_scroll_timeout_id == 0) { - drag_info->waiting_to_autoscroll = TRUE; - drag_info->start_auto_scroll_in = eel_get_system_time() - + AUTOSCROLL_INITIAL_DELAY; - - drag_info->auto_scroll_timeout_id = gtk_timeout_add - (AUTOSCROLL_TIMEOUT_INTERVAL, - callback, - user_data); - } - } else { - if (drag_info->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (drag_info->auto_scroll_timeout_id); - drag_info->auto_scroll_timeout_id = 0; - } - } -} - -void -nautilus_drag_autoscroll_stop (NautilusDragInfo *drag_info) -{ - if (drag_info->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (drag_info->auto_scroll_timeout_id); - drag_info->auto_scroll_timeout_id = 0; - } -} - - -void -nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, char *keyword) -{ - GList *keywords, *word; - - g_return_if_fail (NAUTILUS_IS_FILE (file)); - g_return_if_fail (keyword != NULL); - - /* special case the erase emblem */ - if (strcmp (keyword, ERASE_KEYWORD) == 0) { - keywords = NULL; - } else { - keywords = nautilus_file_get_keywords (file); - word = g_list_find_custom (keywords, keyword, (GCompareFunc) strcmp); - if (word == NULL) { - keywords = g_list_append (keywords, g_strdup (keyword)); - } else { - keywords = g_list_remove_link (keywords, word); - g_free (word->data); - g_list_free_1 (word); - } - } - - nautilus_file_set_keywords (file, keywords); - eel_g_list_free_deep (keywords); -} diff --git a/libnautilus-private/nautilus-drag.h b/libnautilus-private/nautilus-drag.h deleted file mode 100644 index f25af7bb0..000000000 --- a/libnautilus-private/nautilus-drag.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* nautilus-drag.h - Common Drag & drop handling code shared by the icon container - and the list view. - - Copyright (C) 2000 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com>, - Ettore Perazzoli <ettore@gnu.org> -*/ - -#ifndef NAUTILUS_DRAG_H -#define NAUTILUS_DRAG_H - -#include <gtk/gtkdnd.h> -#include "nautilus-file.h" - -/* a set of defines stolen from the nautilus-icon-dnd.c file */ -#define AUTOSCROLL_TIMEOUT_INTERVAL 100 - /* in milliseconds */ - -#define AUTOSCROLL_INITIAL_DELAY 750000 - /* in microseconds */ - -/* Item of the drag selection list */ -typedef struct { - char *uri; - gboolean got_icon_position; - int icon_x, icon_y; - int icon_width, icon_height; -} DragSelectionItem; - -/* Standard Drag & Drop types. */ -typedef enum { - NAUTILUS_ICON_DND_GNOME_ICON_LIST, - NAUTILUS_ICON_DND_URI_LIST, - NAUTILUS_ICON_DND_URL, - NAUTILUS_ICON_DND_COLOR, - NAUTILUS_ICON_DND_BGIMAGE, - NAUTILUS_ICON_DND_KEYWORD, - NAUTILUS_ICON_DND_TEXT -} NautilusIconDndTargetType; - -/* drag&drop-related information. */ -typedef struct { - GtkTargetList *target_list; - - /* Stuff saved at "receive data" time needed later in the drag. */ - gboolean got_drop_data_type; - NautilusIconDndTargetType data_type; - GtkSelectionData *selection_data; - - /* Start of the drag, in world coordinates. */ - gdouble start_x, start_y; - - /* List of DragSelectionItems, representing items being dragged, or NULL - * if data about them has not been received from the source yet. - */ - GList *selection_list; - - /* Stipple for drawing icon shadows during DnD. */ - GdkBitmap *stipple; - - /* has the drop occured ? */ - gboolean drop_occured; - - /* whether or not need to clean up the previous dnd data */ - gboolean need_to_destroy; - - /* autoscrolling during dragging */ - int auto_scroll_timeout_id; - gboolean waiting_to_autoscroll; - gint64 start_auto_scroll_in; - -} NautilusDragInfo; - - -/* Drag & Drop target names. */ -#define NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE "x-special/gnome-icon-list" -#define NAUTILUS_ICON_DND_URI_LIST_TYPE "text/uri-list" -#define NAUTILUS_ICON_DND_TEXT_TYPE "text/plain" -#define NAUTILUS_ICON_DND_URL_TYPE "_NETSCAPE_URL" -#define NAUTILUS_ICON_DND_COLOR_TYPE "application/x-color" -#define NAUTILUS_ICON_DND_BGIMAGE_TYPE "property/bgimage" -#define NAUTILUS_ICON_DND_KEYWORD_TYPE "property/keyword" - -#define ERASE_KEYWORD "erase" - -typedef void (* NautilusDragEachSelectedItemDataGet) (const char *url, - int x, int y, int w, int h, - gpointer data); -typedef void (* NautilusDragEachSelectedItemIterator) (NautilusDragEachSelectedItemDataGet iteratee, - gpointer iterator_context, - gpointer data); - -void nautilus_drag_init (NautilusDragInfo *drag_info, - const GtkTargetEntry *drag_types, - int drag_type_count, - GdkBitmap *stipple); - -void nautilus_drag_finalize (NautilusDragInfo *drag_info); - - -DragSelectionItem *nautilus_drag_selection_item_new (void); -void nautilus_drag_destroy_selection_list (GList *selection_list); -GList *nautilus_drag_build_selection_list (GtkSelectionData *data); -gboolean nautilus_drag_items_local (const char *target_uri, - const GList *selection_list); -gboolean nautilus_drag_items_in_trash (const GList *selection_list); - -gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, - const char *item_uri); -gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item, - const GList *items); -void nautilus_drag_default_drop_action_for_icons (GdkDragContext *context, - const char *target_uri, - const GList *items, - int *default_action, - int *non_default_action); - -gboolean nautilus_drag_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint32 time, - gpointer container_context, - NautilusDragEachSelectedItemIterator each_selected_item_iterator); -int nautilus_drag_modifier_based_action (int default_action, - int non_default_action); - -GdkDragAction nautilus_drag_drop_action_ask (GdkDragAction possible_actions); - -gboolean nautilus_drag_autoscroll_in_scroll_region (GtkWidget *widget); -void nautilus_drag_autoscroll_calculate_delta (GtkWidget *widget, - float *x_scroll_delta, - float *y_scroll_delta); - -void nautilus_drag_autoscroll_start (NautilusDragInfo *drag_info, - GtkWidget *widget, - GtkFunction callback, - gpointer user_data); - -void nautilus_drag_autoscroll_stop (NautilusDragInfo *drag_info); - - -void nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, - char *keyword); - -#endif - diff --git a/libnautilus-private/nautilus-file-dnd.c b/libnautilus-private/nautilus-file-dnd.c new file mode 100644 index 000000000..fe559b2d1 --- /dev/null +++ b/libnautilus-private/nautilus-file-dnd.c @@ -0,0 +1,109 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-file-drag.c - Drag & drop handling code that operated on + NautilusFile objects. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler <pavel@eazel.com>, +*/ + +#include <config.h> +#include "nautilus-file-dnd.h" + +#include <eel/eel-glib-extensions.h> +#include <eel/eel-string.h> + +gboolean +nautilus_drag_can_accept_item (NautilusFile *drop_target_item, + const char *item_uri) +{ + if (nautilus_file_matches_uri (drop_target_item, item_uri)) { + /* can't accept itself */ + return FALSE; + } + + if (nautilus_file_is_directory (drop_target_item)) { + /* target is a directory, accept anything */ + return TRUE; + } + + /* All Nautilus links are assumed to be links to directories. + * Therefore, they all can accept drags, like all other + * directories to. As with other directories, there can be + * errors when the actual copy is attempted due to + * permissions. + */ + if (nautilus_file_is_nautilus_link (drop_target_item)) { + return TRUE; + } + + return FALSE; +} + +gboolean +nautilus_drag_can_accept_items (NautilusFile *drop_target_item, + const GList *items) +{ + int max; + + if (drop_target_item == NULL) + return FALSE; + + g_assert (NAUTILUS_IS_FILE (drop_target_item)); + + /* Iterate through selection checking if item will get accepted by the + * drop target. If more than 100 items selected, return an over-optimisic + * result + */ + for (max = 100; items != NULL && max >= 0; items = items->next, max--) { + if (!nautilus_drag_can_accept_item (drop_target_item, + ((DragSelectionItem *)items->data)->uri)) { + return FALSE; + } + } + + return TRUE; +} + +void +nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, char *keyword) +{ + GList *keywords, *word; + + g_return_if_fail (NAUTILUS_IS_FILE (file)); + g_return_if_fail (keyword != NULL); + + /* special case the erase emblem */ + if (strcmp (keyword, ERASE_KEYWORD) == 0) { + keywords = NULL; + } else { + keywords = nautilus_file_get_keywords (file); + word = g_list_find_custom (keywords, keyword, (GCompareFunc) strcmp); + if (word == NULL) { + keywords = g_list_append (keywords, g_strdup (keyword)); + } else { + keywords = g_list_remove_link (keywords, word); + g_free (word->data); + g_list_free_1 (word); + } + } + + nautilus_file_set_keywords (file, keywords); + eel_g_list_free_deep (keywords); +} diff --git a/libnautilus-private/nautilus-file-dnd.h b/libnautilus-private/nautilus-file-dnd.h new file mode 100644 index 000000000..484d5f643 --- /dev/null +++ b/libnautilus-private/nautilus-file-dnd.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* nautilus-file-drag.h - Drag & drop handling code that operated on + NautilusFile objects. + + Copyright (C) 2000 Eazel, Inc. + + The Gnome Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Pavel Cisler <pavel@eazel.com>, +*/ + +#ifndef NAUTILUS_FILE_DND_H +#define NAUTILUS_FILE_DND_H + +#include <eel/eel-dnd.h> +#include <libnautilus-extensions/nautilus-file.h> + +gboolean nautilus_drag_can_accept_item (NautilusFile *drop_target_item, + const char *item_uri); +gboolean nautilus_drag_can_accept_items (NautilusFile *drop_target_item, + const GList *items); +void nautilus_drag_file_receive_dropped_keyword (NautilusFile *file, + char *keyword); + +#endif /* NAUTILUS_FILE_DND_H */ + diff --git a/libnautilus-private/nautilus-icon-dnd.c b/libnautilus-private/nautilus-icon-dnd.c index 61265e19b..6fcb48ad0 100644 --- a/libnautilus-private/nautilus-icon-dnd.c +++ b/libnautilus-private/nautilus-icon-dnd.c @@ -30,6 +30,9 @@ #include <config.h> #include "nautilus-icon-dnd.h" +#include "nautilus-file-dnd.h" +#include "nautilus-icon-private.h" +#include "nautilus-link.h" #include <eel/eel-background.h> #include <eel/eel-gdk-pixbuf-extensions.h> #include <eel/eel-glib-extensions.h> @@ -37,11 +40,9 @@ #include <eel/eel-graphic-effects.h> #include <eel/eel-gtk-extensions.h> #include <eel/eel-gtk-macros.h> -#include <eel/eel-vfs-extensions.h> -#include "nautilus-icon-private.h" -#include "nautilus-link.h" #include <eel/eel-stock-dialogs.h> #include <eel/eel-string.h> +#include <eel/eel-vfs-extensions.h> #include <gdk/gdkkeysyms.h> #include <gdk/gdkx.h> #include <gtk/gtkmain.h> @@ -91,19 +92,19 @@ static void set_drop_target (NautilusIconCo static GtkTargetEntry drag_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_TEXT_TYPE, 0, NAUTILUS_ICON_DND_TEXT } + { EEL_ICON_DND_GNOME_ICON_LIST_TYPE, 0, EEL_ICON_DND_GNOME_ICON_LIST }, + { EEL_ICON_DND_URI_LIST_TYPE, 0, EEL_ICON_DND_URI_LIST }, + { EEL_ICON_DND_URL_TYPE, 0, EEL_ICON_DND_URL }, + { EEL_ICON_DND_TEXT_TYPE, 0, EEL_ICON_DND_TEXT } }; static GtkTargetEntry drop_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }, - { NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }, - { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD } + { EEL_ICON_DND_GNOME_ICON_LIST_TYPE, 0, EEL_ICON_DND_GNOME_ICON_LIST }, + { EEL_ICON_DND_URI_LIST_TYPE, 0, EEL_ICON_DND_URI_LIST }, + { EEL_ICON_DND_URL_TYPE, 0, EEL_ICON_DND_URL }, + { EEL_ICON_DND_COLOR_TYPE, 0, EEL_ICON_DND_COLOR }, + { EEL_ICON_DND_BGIMAGE_TYPE, 0, EEL_ICON_DND_BGIMAGE }, + { EEL_ICON_DND_KEYWORD_TYPE, 0, EEL_ICON_DND_KEYWORD } }; static GtkTargetList *drop_types_list = NULL; @@ -208,7 +209,7 @@ set_shadow_position (GnomeCanvasItem *shadow, /* iteration glue struct */ typedef struct { gpointer iterator_context; - NautilusDragEachSelectedItemDataGet iteratee; + EelDragEachSelectedItemDataGet iteratee; gpointer iteratee_data; } IconGetDataBinderContext; @@ -284,7 +285,7 @@ nautilus_icon_container_each_selected_icon (NautilusIconContainer *container, * values to the iteratee */ static void -each_icon_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee, +each_icon_get_data_binder (EelDragEachSelectedItemDataGet iteratee, gpointer iterator_context, gpointer data) { IconGetDataBinderContext context; @@ -316,7 +317,7 @@ drag_data_get_callback (GtkWidget *widget, * the selection data in the right format. Pass it means to * iterate all the selected icons. */ - nautilus_drag_drag_data_get (widget, context, selection_data, + eel_drag_drag_data_get (widget, context, selection_data, info, time, widget, each_icon_get_data_binder); } @@ -353,7 +354,7 @@ nautilus_icon_container_dropped_icon_feedback (GtkWidget *widget, dnd_info = container->details->dnd_info; /* Delete old selection list. */ - nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (dnd_info->drag_info.selection_list); dnd_info->drag_info.selection_list = NULL; /* Delete old shadow if any. */ @@ -364,7 +365,7 @@ nautilus_icon_container_dropped_icon_feedback (GtkWidget *widget, } /* Build the selection list and the shadow. */ - dnd_info->drag_info.selection_list = nautilus_drag_build_selection_list (data); + dnd_info->drag_info.selection_list = eel_drag_build_selection_list (data); dnd_info->shadow = create_selection_shadow (container, dnd_info->drag_info.selection_list); nautilus_icon_container_position_shadow (container, x, y); } @@ -387,7 +388,7 @@ drag_data_received_callback (GtkWidget *widget, guint32 time, gpointer user_data) { - NautilusDragInfo *drag_info; + EelDragInfo *drag_info; drag_info = &(NAUTILUS_ICON_CONTAINER (widget)->details->dnd_info->drag_info); @@ -395,20 +396,20 @@ drag_data_received_callback (GtkWidget *widget, drag_info->data_type = info; switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: nautilus_icon_container_dropped_icon_feedback (widget, data, x, y); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: - case NAUTILUS_ICON_DND_KEYWORD: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: + case EEL_ICON_DND_KEYWORD: + case EEL_ICON_DND_URI_LIST: /* Save the data so we can do the actual work on drop. */ g_assert (drag_info->selection_data == NULL); drag_info->selection_data = eel_gtk_selection_data_copy_deep (data); break; /* Netscape keeps sending us the data, even though we accept the first drag */ - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URL: if (drag_info->selection_data != NULL) { eel_gtk_selection_data_free_deep (drag_info->selection_data); drag_info->selection_data = eel_gtk_selection_data_copy_deep (data); @@ -427,32 +428,32 @@ drag_data_received_callback (GtkWidget *widget, if (drag_info->drop_occured) { switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: nautilus_icon_container_receive_dropped_icons (NAUTILUS_ICON_CONTAINER (widget), context, x, y); gtk_drag_finish (context, TRUE, FALSE, time); break; - case NAUTILUS_ICON_DND_COLOR: + case EEL_ICON_DND_COLOR: eel_background_receive_dropped_color (eel_get_widget_background (widget), widget, x, y, data); gtk_drag_finish (context, TRUE, FALSE, time); break; - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_BGIMAGE: receive_dropped_tile_image (NAUTILUS_ICON_CONTAINER (widget), data); gtk_drag_finish (context, FALSE, FALSE, time); break; - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: receive_dropped_keyword (NAUTILUS_ICON_CONTAINER (widget), (char*) data->data, x, y); gtk_drag_finish (context, FALSE, FALSE, time); break; - case NAUTILUS_ICON_DND_URI_LIST: - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URI_LIST: + case EEL_ICON_DND_URL: receive_dropped_uri_list (NAUTILUS_ICON_CONTAINER (widget), (char*) data->data, x, y); @@ -523,7 +524,7 @@ drag_end_callback (GtkWidget *widget, container = NAUTILUS_ICON_CONTAINER (widget); dnd_info = container->details->dnd_info; - nautilus_drag_destroy_selection_list (dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (dnd_info->drag_info.selection_list); dnd_info->drag_info.selection_list = NULL; } @@ -587,12 +588,12 @@ nautilus_icon_container_selection_items_local (const NautilusIconContainer *cont container_uri_string = get_container_uri (container); if (eel_uri_is_trash (container_uri_string)) { - /* Special-case "trash:" because the nautilus_drag_items_local + /* Special-case "trash:" because the eel_drag_items_local * would not work for it. */ - result = nautilus_drag_items_in_trash (items); + result = eel_drag_items_in_trash (items); } else { - result = nautilus_drag_items_local (container_uri_string, items); + result = eel_drag_items_local (container_uri_string, items); } g_free (container_uri_string); @@ -677,7 +678,7 @@ auto_scroll_timeout_callback (gpointer data) container->details->dnd_info->drag_info.waiting_to_autoscroll = FALSE; - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); + eel_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); if (x_scroll_delta == 0 && y_scroll_delta == 0) { /* no work */ return TRUE; @@ -727,7 +728,7 @@ auto_scroll_timeout_callback (gpointer data) static void set_up_auto_scroll_if_needed (NautilusIconContainer *container) { - nautilus_drag_autoscroll_start (&container->details->dnd_info->drag_info, + eel_drag_autoscroll_start (&container->details->dnd_info->drag_info, GTK_WIDGET (container), auto_scroll_timeout_callback, container); @@ -736,7 +737,7 @@ set_up_auto_scroll_if_needed (NautilusIconContainer *container) static void stop_auto_scroll (NautilusIconContainer *container) { - nautilus_drag_autoscroll_stop (&container->details->dnd_info->drag_info); + eel_drag_autoscroll_stop (&container->details->dnd_info->drag_info); } static gboolean @@ -976,7 +977,7 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container, } else { action = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK; } - context->action = nautilus_drag_drop_action_ask (action); + context->action = eel_drag_drop_action_ask (action); } if (context->action > 0) { @@ -1003,7 +1004,7 @@ nautilus_icon_container_receive_dropped_icons (NautilusIconContainer *container, } g_free (drop_target); - nautilus_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list); + eel_drag_destroy_selection_list (container->details->dnd_info->drag_info.selection_list); container->details->dnd_info->drag_info.selection_list = NULL; } @@ -1033,7 +1034,7 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, /* case out on the type of object being dragged */ switch (container->details->dnd_info->drag_info.data_type) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: if (container->details->dnd_info->drag_info.selection_list == NULL) { *default_action = 0; *non_default_action = 0; @@ -1046,14 +1047,14 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, *non_default_action = 0; return; } - nautilus_drag_default_drop_action_for_icons (context, drop_target, + eel_drag_default_drop_action_for_icons (context, drop_target, container->details->dnd_info->drag_info.selection_list, default_action, non_default_action); g_free (drop_target); break; /* handle emblems by setting the action if we're over an object */ - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: if (icon == NULL) { *default_action = 0; *non_default_action = 0; @@ -1065,8 +1066,8 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, break; /* handle colors and backgrounds by setting the action if we're over the background */ - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: if (icon == NULL) { *default_action = context->suggested_action; *non_default_action = context->suggested_action; @@ -1077,8 +1078,8 @@ nautilus_icon_container_get_drop_action (NautilusIconContainer *container, break; - case NAUTILUS_ICON_DND_URI_LIST: - case NAUTILUS_ICON_DND_URL: + case EEL_ICON_DND_URI_LIST: + case EEL_ICON_DND_URL: *default_action = context->suggested_action; *non_default_action = context->suggested_action; break; @@ -1118,7 +1119,7 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, g_assert (NAUTILUS_IS_ICON_CONTAINER (container)); if ((container->details->dnd_info->drag_info.selection_list == NULL) - && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD)) { + && (container->details->dnd_info->drag_info.data_type != EEL_ICON_DND_KEYWORD)) { return; } @@ -1136,7 +1137,7 @@ nautilus_icon_dnd_update_drop_target (NautilusIconContainer *container, /* Find if target icon accepts our drop. */ if (icon != NULL - && (container->details->dnd_info->drag_info.data_type != NAUTILUS_ICON_DND_KEYWORD) + && (container->details->dnd_info->drag_info.data_type != EEL_ICON_DND_KEYWORD) && !nautilus_drag_can_accept_items (nautilus_file_get ( nautilus_icon_container_get_icon_uri (container, icon)), @@ -1193,7 +1194,7 @@ nautilus_icon_dnd_init (NautilusIconContainer *container, container->details->dnd_info = g_new0 (NautilusIconDndInfo, 1); - nautilus_drag_init (&container->details->dnd_info->drag_info, + eel_drag_init (&container->details->dnd_info->drag_info, drag_types, EEL_N_ELEMENTS (drag_types), stipple); /* Set up the widget as a drag destination. @@ -1238,7 +1239,7 @@ nautilus_icon_dnd_fini (NautilusIconContainer *container) gtk_object_destroy (GTK_OBJECT (container->details->dnd_info->shadow)); } - nautilus_drag_finalize (&container->details->dnd_info->drag_info); + eel_drag_finalize (&container->details->dnd_info->drag_info); } void @@ -1317,7 +1318,7 @@ drag_motion_callback (GtkWidget *widget, /* set the right drop action, choose based on modifier key state */ - resulting_action = nautilus_drag_modifier_based_action (default_action, + resulting_action = eel_drag_modifier_based_action (default_action, non_default_action); gdk_drag_status (context, resulting_action, time); diff --git a/libnautilus-private/nautilus-icon-dnd.h b/libnautilus-private/nautilus-icon-dnd.h index 2e25fca48..5dd83cc44 100644 --- a/libnautilus-private/nautilus-icon-dnd.h +++ b/libnautilus-private/nautilus-icon-dnd.h @@ -29,14 +29,12 @@ #define NAUTILUS_ICON_DND_H #include "nautilus-icon-container.h" -#include "nautilus-drag.h" - - +#include <eel/eel-dnd.h> /* DnD-related information. */ typedef struct { /* inherited drag info context */ - NautilusDragInfo drag_info; + EelDragInfo drag_info; /* Shadow for the icons being dragged. */ GnomeCanvasItem *shadow; diff --git a/libnautilus-private/nautilus-list-column-title.c b/libnautilus-private/nautilus-list-column-title.c deleted file mode 100644 index 26fff3a31..000000000 --- a/libnautilus-private/nautilus-list-column-title.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - - nautilus-list-column-title.c: List column title widget for interacting with list columns - - Copyright (C) 2000 Eazel, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com> - -*/ - -#include <config.h> -#include "nautilus-list-column-title.h" - -#include <eel/eel-gtk-macros.h> -#include <eel/eel-gdk-extensions.h> - -#include "nautilus-list.h" - -#include <gdk/gdk.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gtk/gtkmain.h> - -#include <libgnomeui/gnome-pixmap.h> - -#include <eel/eel-gdk-pixbuf-extensions.h> - -#include <string.h> - -/* these are from GtkCList, for now we need to copy them here - * eventually the target list should be able to describe the values - */ - -enum { - /* this defines the base grid spacing */ - CELL_SPACING = 1, - - /* added the horizontal space at the beginning and end of a row */ - COLUMN_INSET = 3, - - /* from GtkButton */ - CHILD_SPACING = 1, - - /* the width of the column resize windows */ - DRAG_WIDTH = 6 -}; - -static const char * down_xpm[] = { - "6 5 2 1", - " c None", - ". c #000000", - "......", - " ", - " .... ", - " ", - " .. " -}; - -static const char * up_xpm[] = { - "6 5 2 1", - " c None", - ". c #000000", - " .. ", - " ", - " .... ", - " ", - "......" -}; - -#define COLUMN_TITLE_THEME_STYLE_NAME "menu" - -struct NautilusListColumnTitleDetails -{ - /* gc for blitting sort order pixmaps, lazily allocated */ - GdkGC *copy_area_gc; - - /* sort order indicator pixmaps, lazily allocated */ - GdkPixmap *up_indicator_pixmap; - GdkBitmap *up_indicator_mask; - GdkPixmap *down_indicator_pixmap; - GdkBitmap *down_indicator_mask; - - /* offscreen drawing idle handler id*/ - guint offscreen_drawing_idle; - - int tracking_column_resize; - /* index of the column we are currently tracking or -1 */ - int tracking_column_prelight; - /* index of the column we are currently rolling over or -1 */ - int tracking_column_press; - /* index of the column we are currently pressing or -1 */ - - int last_tracking_x; - /* last horizontal track point so we can only resize when needed */ - gboolean resize_cursor_on; - -}; - -static void nautilus_list_column_title_initialize_class (gpointer klass); -static void nautilus_list_column_title_initialize (gpointer object, gpointer klass); -static void nautilus_list_column_title_paint (GtkWidget *widget, GtkWidget *draw_target, GdkDrawable *target_drawable, GdkRectangle *area); -static void nautilus_list_column_title_draw (GtkWidget *widget, GdkRectangle *box); -static void nautilus_list_column_title_buffered_draw (GtkWidget *widget); -static void nautilus_list_column_title_queue_buffered_draw(GtkWidget *widget); -static gboolean nautilus_list_column_title_expose (GtkWidget *widget, GdkEventExpose *event); -static void nautilus_list_column_title_realize (GtkWidget *widget); -static void nautilus_list_column_title_finalize (GtkObject *object); -static void nautilus_list_column_title_request (GtkWidget *widget, GtkRequisition *requisition); - -static gboolean nautilus_list_column_title_motion (GtkWidget *widget, GdkEventMotion *event); -static gboolean nautilus_list_column_title_leave (GtkWidget *widget, GdkEventCrossing *event); - -static gboolean nautilus_list_column_title_button_press (GtkWidget *widget, GdkEventButton *event); -static gboolean nautilus_list_column_title_button_release (GtkWidget *widget, GdkEventButton *event); - - -EEL_DEFINE_CLASS_BOILERPLATE (NautilusListColumnTitle, nautilus_list_column_title, GTK_TYPE_BIN) -/* generates nautilus_list_column_title_get_type */ - -static void -nautilus_list_column_title_initialize_class (gpointer klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - object_class->finalize = nautilus_list_column_title_finalize; - widget_class->draw = nautilus_list_column_title_draw; - widget_class->expose_event = nautilus_list_column_title_expose; - widget_class->realize = nautilus_list_column_title_realize; - widget_class->size_request = nautilus_list_column_title_request; - widget_class->motion_notify_event = nautilus_list_column_title_motion; - widget_class->leave_notify_event = nautilus_list_column_title_leave; - widget_class->button_press_event = nautilus_list_column_title_button_press; - widget_class->button_release_event = nautilus_list_column_title_button_release; -} - -NautilusListColumnTitle * -nautilus_list_column_title_new (void) -{ - return NAUTILUS_LIST_COLUMN_TITLE - (gtk_widget_new (nautilus_list_column_title_get_type (), NULL)); -} - -static void -nautilus_list_column_title_initialize (gpointer object, gpointer klass) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(object); - column_title->details = g_new0 (NautilusListColumnTitleDetails, 1); - - /* copy_gc, up/down indicators get allocated lazily when needed */ - column_title->details->copy_area_gc = NULL; - column_title->details->up_indicator_pixmap = NULL; - column_title->details->up_indicator_mask = NULL; - column_title->details->down_indicator_pixmap = NULL; - column_title->details->down_indicator_mask = NULL; - - column_title->details->offscreen_drawing_idle = 0; - - column_title->details->resize_cursor_on = FALSE; - column_title->details->tracking_column_resize = -1; - column_title->details->tracking_column_prelight = -1; - column_title->details->tracking_column_press = -1; - column_title->details->last_tracking_x = -1; - - GTK_WIDGET_UNSET_FLAGS (object, GTK_NO_WINDOW); -} - -static void -nautilus_list_column_title_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - int attributes_mask; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); - - /* ask for expose events */ - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width; - attributes.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width; - attributes.width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2; - attributes.height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK - | GDK_ENTER_NOTIFY_MASK - | GDK_LEAVE_NOTIFY_MASK - | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK - | GDK_POINTER_MOTION_MASK - | GDK_POINTER_MOTION_HINT_MASK - | GDK_KEY_PRESS_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - /* give ourselves a background window */ - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, widget); - - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); -} - -static void -nautilus_list_column_title_finalize (GtkObject *object) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(object); - - if (column_title->details->up_indicator_pixmap != NULL) { - gdk_pixmap_unref (column_title->details->up_indicator_pixmap); - column_title->details->up_indicator_pixmap = NULL; - } - if (column_title->details->up_indicator_mask != NULL) { - gdk_bitmap_unref (column_title->details->up_indicator_mask); - column_title->details->up_indicator_mask = NULL; - } - if (column_title->details->down_indicator_pixmap != NULL) { - gdk_pixmap_unref (column_title->details->down_indicator_pixmap); - column_title->details->down_indicator_pixmap = NULL; - } - if (column_title->details->down_indicator_mask != NULL) { - gdk_bitmap_unref (column_title->details->down_indicator_mask); - column_title->details->down_indicator_mask = NULL; - } - - if (column_title->details->offscreen_drawing_idle != 0) { - gtk_idle_remove (column_title->details->offscreen_drawing_idle); - column_title->details->offscreen_drawing_idle = 0; - } - - if (column_title->details->copy_area_gc != NULL) { - gdk_gc_destroy (column_title->details->copy_area_gc); - } - - g_free (column_title->details); - - EEL_CALL_PARENT (GTK_OBJECT_CLASS, finalize, (object)); -} - -static void -nautilus_list_column_title_request (GtkWidget *widget, GtkRequisition *requisition) -{ - /* size requisition: make sure we have at least a minimal height */ - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (requisition != NULL); - - requisition->width = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + - widget->style->klass->xthickness) * 2; - requisition->height = (GTK_CONTAINER (widget)->border_width + CHILD_SPACING + - widget->style->klass->ythickness) * 2; - - - if (GTK_BIN (widget)->child && GTK_WIDGET_VISIBLE (GTK_BIN (widget)->child)) { - GtkRequisition child_requisition; - - gtk_widget_size_request (GTK_BIN (widget)->child, &child_requisition); - - requisition->width += child_requisition.width; - requisition->height += child_requisition.height; - - requisition->height = MIN (requisition->height, 10); - } -} - -static const char * -get_column_label_at (GtkWidget *column_title, int index) -{ - NautilusCList *parent_clist; - - parent_clist = NAUTILUS_CLIST (column_title->parent); - - return parent_clist->column[index].title; -} - -static void -get_column_frame_at(GtkWidget *column_title, int index, GdkRectangle *result) -{ - NautilusCList *parent_clist; - parent_clist = NAUTILUS_CLIST (column_title->parent); - - *result = parent_clist->column_title_area; - result->x = parent_clist->column[index].area.x - COLUMN_INSET; - result->y = 0; - result->width = parent_clist->column[index].area.width - + CELL_SPACING + 2 * COLUMN_INSET - 1; -} - -static void -load_up_indicator (const char **xpm_data, - GdkPixmap **indicator_pixmap, GdkBitmap **indicator_mask) -{ - GdkPixbuf *pixbuf; - - /* sanity */ - *indicator_pixmap = NULL; - *indicator_mask = NULL; - - pixbuf = gdk_pixbuf_new_from_xpm_data (xpm_data); - - /* can't load, theoretically, we should always be able to load, - * but we'll be a good coder and catch possible errors */ - if (pixbuf == NULL) { - g_warning ("Cannot load up/down indicator, should never happen"); - return; - } - - gdk_pixbuf_render_pixmap_and_mask (pixbuf, indicator_pixmap, indicator_mask, EEL_STANDARD_ALPHA_THRESHHOLD); - - gdk_pixbuf_unref (pixbuf); -} - -static void -get_sort_indicator (GtkWidget *widget, gboolean ascending, - GdkPixmap **indicator_pixmap, GdkBitmap **indicator_mask) -{ - /* return the sort order pixmap for a given sort direction - * allocate the pixmap first time around - */ - NautilusListColumnTitle *column_title; - - g_return_if_fail (indicator_pixmap != NULL); - g_return_if_fail (indicator_mask != NULL); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - if (ascending) { - if (column_title->details->up_indicator_pixmap == NULL) { - g_assert (column_title->details->up_indicator_mask == NULL); - - load_up_indicator (up_xpm, - &column_title->details->up_indicator_pixmap, - &column_title->details->up_indicator_mask); - } - *indicator_pixmap = column_title->details->up_indicator_pixmap; - *indicator_mask = column_title->details->up_indicator_mask; - } else { - if (column_title->details->down_indicator_pixmap == NULL) { - g_assert (column_title->details->down_indicator_mask == NULL); - - load_up_indicator (down_xpm, - &column_title->details->down_indicator_pixmap, - &column_title->details->down_indicator_mask); - } - *indicator_pixmap = column_title->details->down_indicator_pixmap; - *indicator_mask = column_title->details->down_indicator_mask; - } -} - -/* Add more truncation modes, optimize for performance, move to nautilus-gdk-extensions */ -static char * -truncate_string (const char *string, GdkFont *font, int width, int *final_width) -{ - int current_width; - int ellipsis_width; - int length; - int trimmed_length; - char *result; - - length = strlen (string); - current_width = gdk_text_width (font, string, length); - if (current_width <= width) { - /* trivial case, already fits fine */ - if (final_width != NULL) { - *final_width = current_width; - } - return g_strdup (string); - } - - ellipsis_width = gdk_string_width (font, "..."); - if (ellipsis_width > width) { - /* we can't fit anything */ - if (final_width != NULL) { - *final_width = 0; - } - return g_strdup (""); - } - - width -= ellipsis_width; - - for (trimmed_length = length - 1; trimmed_length >= 0; trimmed_length--) { - current_width = gdk_text_width (font, string, trimmed_length); - if (current_width <= width) - break; - } - result = (char *) g_malloc (trimmed_length + 3 + 1); - strncpy (result, string, trimmed_length); - strcpy (result + trimmed_length, "..."); - - if (final_width != NULL) { - *final_width = current_width + ellipsis_width; - } - - return result; -} - -/* FIXME bugzilla.eazel.com 615: - * Some of these magic numbers could be replaced with some more dynamic values - */ -enum { - CELL_TITLE_INSET = 3, - TITLE_BASELINE_OFFSET = 6, - SORT_ORDER_INDICATOR_WIDTH = 10, - SORT_INDICATOR_X_OFFSET = 6, - SORT_INDICATOR_Y_OFFSET = 3 -}; - -static void -nautilus_list_column_title_paint (GtkWidget *widget, GtkWidget *draw_target, - GdkDrawable *target_drawable, GdkRectangle *area) -{ - NautilusListColumnTitle *column_title; - NautilusCList *parent_clist; - int index; - - g_assert (NAUTILUS_CLIST (widget->parent) != NULL); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - GdkRectangle cell_rectangle; - GdkRectangle cell_redraw_area; - const char *cell_label; - int text_x_offset; - int text_x_available_end; - int sort_indicator_x_offset; - GdkPixmap *sort_indicator_pixmap; - GdkBitmap *sort_indicator_mask; - gboolean right_justified; - - sort_indicator_x_offset = 0; - sort_indicator_pixmap = NULL; - sort_indicator_mask = NULL; - right_justified = (parent_clist->column[index].justification == GTK_JUSTIFY_RIGHT); - - /* pick the ascending/descending sort indicator if needed */ - if (index == parent_clist->sort_column) { - get_sort_indicator (widget, - parent_clist->sort_type == GTK_SORT_ASCENDING, - &sort_indicator_pixmap, - &sort_indicator_mask); - } - - get_column_frame_at (widget, index, &cell_rectangle); - gdk_rectangle_intersect (&cell_rectangle, area, &cell_redraw_area); - - if (cell_redraw_area.width == 0 || cell_redraw_area.height == 0) { - /* no work, go on to the next */ - continue; - } - - cell_label = get_column_label_at (widget, index); - - /* FIXME bugzilla.eazel.com 616: - * add support for center justification - */ - - text_x_offset = cell_rectangle.x + CELL_TITLE_INSET; - text_x_available_end = cell_rectangle.x + cell_rectangle.width - 2 * CELL_TITLE_INSET; - - /* Paint the column tiles as rectangles using "menu" (COLUMN_TITLE_THEME_STYLE_NAME). - * Style buttons as used by GtkCList produce round corners in some themes. - * Eventually we might consider having a separate style for column titles. - */ - gtk_paint_box (widget->style, target_drawable, - column_title->details->tracking_column_prelight == index ? - GTK_STATE_PRELIGHT : GTK_STATE_NORMAL, - column_title->details->tracking_column_press == index - ? GTK_SHADOW_IN : GTK_SHADOW_OUT, - area, draw_target, COLUMN_TITLE_THEME_STYLE_NAME, - cell_rectangle.x, cell_rectangle.y, - cell_rectangle.width, cell_rectangle.height); - - - /* Draw the sort indicator if needed */ - if (sort_indicator_pixmap != NULL) { - int y_offset; - - if (right_justified) { - sort_indicator_x_offset = cell_rectangle.x + SORT_INDICATOR_X_OFFSET; - text_x_offset = sort_indicator_x_offset + CELL_TITLE_INSET - + SORT_ORDER_INDICATOR_WIDTH ; - } else { - sort_indicator_x_offset = cell_rectangle.x + cell_rectangle.width - - SORT_INDICATOR_X_OFFSET - SORT_ORDER_INDICATOR_WIDTH; - text_x_available_end = sort_indicator_x_offset - CELL_TITLE_INSET; - } - y_offset = cell_rectangle.y + cell_rectangle.height / 2 - - SORT_INDICATOR_Y_OFFSET; - - /* allocate the sort indicator copy gc first time around */ - if (column_title->details->copy_area_gc == NULL) { - column_title->details->copy_area_gc = gdk_gc_new (widget->window); - gdk_gc_set_function (column_title->details->copy_area_gc, GDK_COPY); - } - /* move the pixmap clip mask and origin to the right spot in the gc */ - gdk_gc_set_clip_mask (column_title->details->copy_area_gc, - sort_indicator_mask); - gdk_gc_set_clip_origin (column_title->details->copy_area_gc, sort_indicator_x_offset, y_offset); - - - gdk_draw_pixmap (target_drawable, column_title->details->copy_area_gc, - sort_indicator_pixmap, 0, 0, sort_indicator_x_offset, y_offset, - -1, -1); - } - - if (cell_label) { - char *truncated_label; - int truncanted_width; - GdkRectangle temporary; - - /* Extend the redraw area vertically to contain the entire cell - * -- seems like if I don't do this, for short exposed areas no text - * will get drawn. - * This happens when the title is half off-screen and you move it up by a pixel or two. - * If you move it up faster, it gets redrawn properly. - */ - cell_redraw_area.y = cell_rectangle.y; - cell_redraw_area.height = cell_rectangle.height; - - /* Clip a little more than the cell rectangle to - * not have the text draw over the cell broder. - */ - temporary = cell_rectangle; - /* Eeeek: magic numbers */ - eel_rectangle_inset (&temporary, 2, 2); - gdk_rectangle_intersect (&cell_redraw_area, &temporary, &cell_redraw_area); - - truncated_label = truncate_string (cell_label, widget->style->font, - text_x_available_end - text_x_offset, &truncanted_width); - - if (right_justified) { - text_x_offset = text_x_available_end - truncanted_width; - } - - gtk_paint_string (widget->style, target_drawable, GTK_STATE_NORMAL, - &cell_redraw_area, draw_target, "label", - text_x_offset, - cell_rectangle.y + cell_rectangle.height - TITLE_BASELINE_OFFSET, - truncated_label); - g_free (truncated_label); - } - } -} - -static void -nautilus_list_column_title_draw (GtkWidget *widget, GdkRectangle *area) -{ - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (area != NULL); - - if (!GTK_WIDGET_DRAWABLE (widget)) { - return; - } - - nautilus_list_column_title_paint (widget, widget, widget->window, area); -} - -static void -nautilus_list_column_title_buffered_draw (GtkWidget *widget) -{ - /* draw using an offscreen_pixmap */ - GdkRectangle redraw_area; - NautilusListColumnTitle *column_title; - GdkPixmap *offscreen_pixmap; - GdkGC *offscreen_blitting_gc; - - /* don't do anything if not drawable */ - if ( ! GTK_WIDGET_DRAWABLE (widget)) { - return; - } - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - redraw_area.x = 0; - redraw_area.y = 0; - redraw_area.width = widget->allocation.width; - redraw_area.height = widget->allocation.height; - - /* allocate a new offscreen_pixmap */ - offscreen_pixmap = gdk_pixmap_new (widget->window, - redraw_area.width, - redraw_area.height, -1); - - /* Erase the offscreen background. - * We are using the GtkStyle call to draw the background - this is a tiny bit - * less efficient but gives us the convenience of setting up the right colors and - * gc for the style we are using to blit the column titles. - */ - gtk_paint_box (widget->style, offscreen_pixmap, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - &redraw_area, widget, - COLUMN_TITLE_THEME_STYLE_NAME, - redraw_area.x, redraw_area.y, - redraw_area.width, redraw_area.height); - - /* render the column titles into the offscreen */ - nautilus_list_column_title_paint (widget, widget, - offscreen_pixmap, &redraw_area); - - /* allocate a gc to blit the offscreen */ - offscreen_blitting_gc = gdk_gc_new (widget->window); - - /* blit the offscreen into the real view */ - gdk_draw_pixmap (widget->window, offscreen_blitting_gc, - offscreen_pixmap, 0, 0, 0, 0, -1, -1); - - gdk_pixmap_unref (offscreen_pixmap); - gdk_gc_destroy (offscreen_blitting_gc); -} - -/* Do all buffered drawing in an idle, this means it's only done after all - * events have been processed and thus we don't do it unneccessairly */ -static gboolean -offscreen_drawing_idle_handler (gpointer data) -{ - GtkWidget *widget; - NautilusListColumnTitle *column_title; - - g_assert (GTK_IS_WIDGET (data)); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (data)); - - widget = GTK_WIDGET (data); - column_title = NAUTILUS_LIST_COLUMN_TITLE (data); - - nautilus_list_column_title_buffered_draw (widget); - - column_title->details->offscreen_drawing_idle = 0; - - return FALSE; -} - -/* queue a buffered_draw to be called later after all other events - * are processed. Increasing performance and reducing memory load. */ -static void -nautilus_list_column_title_queue_buffered_draw (GtkWidget *widget) -{ - NautilusListColumnTitle *column_title; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE (widget); - - if (column_title->details->offscreen_drawing_idle == 0) { - column_title->details->offscreen_drawing_idle = - gtk_idle_add (offscreen_drawing_idle_handler, widget); - } -} - -static gboolean -nautilus_list_column_title_expose (GtkWidget *widget, GdkEventExpose *event) -{ - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (event != NULL); - - if (!GTK_WIDGET_DRAWABLE (widget)) { - return FALSE; - } - - nautilus_list_column_title_paint (widget, widget, widget->window, &event->area); - - return FALSE; -} - -static int -in_column_rect (GtkWidget *widget, int x, int y) -{ - /* return the index of the column we hit or -1 */ - - NautilusCList *parent_clist; - int index; - - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - /* hit testing for column resizing */ - GdkRectangle cell_rectangle; - - get_column_frame_at (widget, index, &cell_rectangle); - - /* inset by a pixel so that you have to move past the border - * to be considered inside the rect - * nautilus_list_column_title_leave depends on this - */ - eel_rectangle_inset (&cell_rectangle, 1, 0); - - - if (eel_rectangle_contains (&cell_rectangle, x, y)) - return index; - } - - return -1; -} - -static int -in_resize_rect (GtkWidget *widget, int x, int y) -{ - /* return the index of the resize rect of a column we hit or -1 */ - - NautilusCList *parent_clist; - int index; - - parent_clist = NAUTILUS_CLIST (widget->parent); - - for (index = 0; index < parent_clist->columns; index++) { - /* hit testing for column resizing */ - GdkRectangle resize_rectangle; - - get_column_frame_at (widget, index, &resize_rectangle); - - eel_rectangle_inset (&resize_rectangle, 1, 0); - - resize_rectangle.x = resize_rectangle.x + resize_rectangle.width - DRAG_WIDTH / 2; - resize_rectangle.width = DRAG_WIDTH; - - if (eel_rectangle_contains (&resize_rectangle, x, y)) - return index; - } - - return -1; -} - -static void -show_hide_resize_cursor_if_needed (GtkWidget *widget, gboolean on) -{ - NautilusListColumnTitle *column_title; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - if (on == column_title->details->resize_cursor_on) - /* already set right */ - return; - - if (on) { - /* switch to a resize cursor */ - GdkCursor *cursor; - - cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - gdk_window_set_cursor (widget->window, cursor); - gdk_cursor_destroy (cursor); - } else - /* restore to old cursor */ - gdk_window_set_cursor (widget->window, NULL); - - column_title->details->resize_cursor_on = on; -} - -static gboolean -track_prelight (GtkWidget *widget, int mouse_x, int mouse_y) -{ - NautilusListColumnTitle *column_title; - int over_column; - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - /* see if we need to update the prelight state of a column */ - over_column = in_column_rect (widget, mouse_x, mouse_y); - - if (column_title->details->tracking_column_resize != -1) { - /* resizing a column, don't prelight */ - over_column = -1; - } - - if (column_title->details->tracking_column_press != -1) { - /* pressing a column, don't prelight */ - over_column = -1; - } - - if (column_title->details->tracking_column_prelight == over_column) { - /* no change */ - return FALSE; - } - - /* update state and tell callers to redraw */ - column_title->details->tracking_column_prelight = over_column; - - return TRUE; -} - -static gboolean -nautilus_list_column_title_motion (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - int mouse_x, mouse_y; - gboolean title_update_needed; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - title_update_needed = FALSE; - - gdk_window_get_pointer (widget->window, &mouse_x, &mouse_y, NULL); - - if (column_title->details->tracking_column_resize != -1) { - /* we are currently tracking a column */ - if (column_title->details->last_tracking_x != mouse_x) { - /* mouse did move horizontally since last time */ - column_title->details->last_tracking_x = mouse_x; - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track, - (parent_list, column_title->details->tracking_column_resize)); - title_update_needed = TRUE; - } - } else { - /* make sure we are showing the right cursor */ - show_hide_resize_cursor_if_needed (widget, - in_resize_rect (widget, mouse_x, mouse_y) != -1); - } - - /* see if we need to update the prelight state of a column */ - title_update_needed |= track_prelight (widget, mouse_x, mouse_y); - - if (title_update_needed) { - nautilus_list_column_title_queue_buffered_draw (widget); - } - - return TRUE; -} - -static gboolean -nautilus_list_column_title_leave (GtkWidget *widget, GdkEventCrossing *event) -{ - NautilusListColumnTitle *column_title; - - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - - /* see if we need to update the prelight state of a column */ - if (column_title->details->tracking_column_prelight != -1) { - column_title->details->tracking_column_prelight = -1; - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - } - nautilus_list_column_title_queue_buffered_draw (widget); - return TRUE; -} - -static gboolean -nautilus_list_column_title_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - int grab_result; - - g_assert (event != NULL); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - g_assert (event->type != GDK_BUTTON_PRESS - || NAUTILUS_LIST_COLUMN_TITLE(widget)->details->tracking_column_resize == -1); - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - - - if (event->type == GDK_BUTTON_PRESS) { - int resized_column; - int clicked_column; - - resized_column = in_resize_rect (widget, (int)event->x, (int)event->y); - clicked_column = in_column_rect (widget, (int)event->x, (int)event->y); - - if (resized_column != -1) { - GdkCursor *cursor; - - /* during the drag, use the resize cursor */ - cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - - /* grab the pointer events so that we get them even when - * the mouse tracks out of the widget window - */ - grab_result = gdk_pointer_grab (widget->window, FALSE, - GDK_POINTER_MOTION_HINT_MASK - | GDK_BUTTON1_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - NULL, cursor, event->time); - gdk_cursor_destroy (cursor); - - if (grab_result != 0) { - /* failed to grab the pointer, give up - * - * The grab results are not very well documented - * looks like they may be Success, GrabSuccess, AlreadyGrabbed - * or anything else the low level X calls in gdk_pointer_grab - * decide to return. - */ - return FALSE; - } - - /* set up new state */ - column_title->details->tracking_column_resize = resized_column; - column_title->details->tracking_column_prelight = -1; - - /* FIXME bugzilla.eazel.com 617: - * use a "resized" state here ? - */ - gtk_widget_set_state (widget, GTK_STATE_NORMAL); - - /* start column resize tracking */ - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track_start, - (parent_list, resized_column)); - - return FALSE; - } - - if (clicked_column != -1) { - /* clicked a column, draw the pressed column title */ - column_title->details->tracking_column_prelight = -1; - column_title->details->tracking_column_press = clicked_column; - gtk_widget_set_state (widget, GTK_STATE_ACTIVE); - - /* grab the pointer events so that we get release events even when - * the mouse tracks out of the widget window - */ - grab_result = gdk_pointer_grab (widget->window, FALSE, - GDK_BUTTON_RELEASE_MASK, - NULL, NULL, event->time); - - if (grab_result != 0) { - /* failed to grab the pointer, give up */ - return FALSE; - } - - nautilus_list_column_title_queue_buffered_draw (widget); - } - - } - - return FALSE; -} - -static gboolean -nautilus_list_column_title_button_release (GtkWidget *widget, GdkEventButton *event) -{ - NautilusListColumnTitle *column_title; - GtkWidget *parent_list; - - g_assert (event != NULL); - g_assert (NAUTILUS_IS_LIST_COLUMN_TITLE (widget)); - g_assert (NAUTILUS_IS_LIST (widget->parent)); - - - column_title = NAUTILUS_LIST_COLUMN_TITLE(widget); - parent_list = GTK_WIDGET (widget->parent); - - /* let go of all the pointer events */ - if ((column_title->details->tracking_column_resize != -1 - || column_title->details->tracking_column_press != -1) - && gdk_pointer_is_grabbed ()) - gdk_pointer_ungrab (event->time); - - if (column_title->details->tracking_column_resize != -1) { - - /* end column resize tracking */ - EEL_INVOKE_METHOD - (NAUTILUS_LIST_CLASS, parent_list, - column_resize_track_end, - (parent_list, column_title->details->tracking_column_resize)); - column_title->details->tracking_column_resize = -1; - - } else if (column_title->details->tracking_column_press != -1) { - - /* column title press -- change the sort order */ - gtk_signal_emit_by_name (GTK_OBJECT (parent_list), "click_column", - column_title->details->tracking_column_press); - /* end press tracking */ - column_title->details->tracking_column_press = -1; - } - - track_prelight (widget, (int)event->x, (int)event->y); - gtk_widget_set_state (widget, - column_title->details->tracking_column_prelight != -1 ? - GTK_STATE_PRELIGHT : GTK_STATE_NORMAL); - - nautilus_list_column_title_queue_buffered_draw (widget); - - return FALSE; -} diff --git a/libnautilus-private/nautilus-list-column-title.h b/libnautilus-private/nautilus-list-column-title.h deleted file mode 100644 index 5c069800b..000000000 --- a/libnautilus-private/nautilus-list-column-title.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- - - nautilus-list-column-title.h: List column title widget for interacting with list columns - - Copyright (C) 2000 Eazel, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Pavel Cisler <pavel@eazel.com> - -*/ - -#ifndef __NAUTILUS_LIST_COLUMN_TITLE__ -#define __NAUTILUS_LIST_COLUMN_TITLE__ - -#include <gdk/gdktypes.h> -#include <gtk/gtkwidget.h> -#include <gtk/gtkbin.h> -#include <gtk/gtkenums.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define NAUTILUS_TYPE_LIST_COLUMN_TITLE \ - (nautilus_list_column_title_get_type ()) -#define NAUTILUS_LIST_COLUMN_TITLE(obj) \ - (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_LIST_COLUMN_TITLE, NautilusListColumnTitle)) -#define NAUTILUS_LIST_COLUMN_TITLE_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_LIST_COLUMN_TITLE, NautilusListColumnTitleClass)) -#define NAUTILUS_IS_LIST_COLUMN_TITLE(obj) \ - (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_LIST_COLUMN_TITLE)) -#define NAUTILUS_IS_LIST_COLUMN_TITLE_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_LIST_COLUMN_TITLE)) - -typedef struct NautilusListColumnTitle NautilusListColumnTitle; -typedef struct NautilusListColumnTitleClass NautilusListColumnTitleClass; -typedef struct NautilusListColumnTitleDetails NautilusListColumnTitleDetails; - - -struct NautilusListColumnTitle -{ - GtkBin bin; - NautilusListColumnTitleDetails *details; -}; - -struct NautilusListColumnTitleClass -{ - GtkBinClass parent_class; -}; - -GtkType nautilus_list_column_title_get_type (void); -NautilusListColumnTitle *nautilus_list_column_title_new (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __NAUTILUS_LIST_COLUMN_TITLE__ */ diff --git a/libnautilus-private/nautilus-list.c b/libnautilus-private/nautilus-list.c deleted file mode 100644 index abb14a5ee..000000000 --- a/libnautilus-private/nautilus-list.c +++ /dev/null @@ -1,3732 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-list.c: Enhanced version of GtkCList for Nautilus. - - Copyright (C) 1999, 2000 Free Software Foundation - Copyright (C) 2000, 2001 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Federico Mena <federico@nuclecu.unam.mx>, - Ettore Perazzoli <ettore@gnu.org>, - John Sullivan <sullivan@eazel.com>, - Pavel Cisler <pavel@eazel.com> - */ - -#include <config.h> -#include "nautilus-list.h" - -#include <ctype.h> -#include <string.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdk.h> -#include <gtk/gtkbindings.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkenums.h> -#include <gtk/gtkmain.h> -#include <glib.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-background.h> -#include <eel/eel-graphic-effects.h> -#include <libnautilus-extensions/nautilus-drag.h> -#include <eel/eel-gdk-extensions.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-glib-extensions.h> -#include <eel/eel-gtk-extensions.h> -#include <eel/eel-gtk-macros.h> -#include <libnautilus-extensions/nautilus-list-column-title.h> - -/* Timeout for making the row currently selected for keyboard operation visible. - * Unlike in nautilus-icon-container, there appear to be no adverse effects from - * making this 0. - */ -#define KEYBOARD_ROW_REVEAL_TIMEOUT 0 - -/* FIXME bugzilla.eazel.com 2573: This constant and much of the code surrounding its use was copied from - * nautilus-icon-container; they should share code instead. - */ -#define CONTEXT_MENU_TIMEOUT_INTERVAL 500 - -#define NO_BUTTON 0 -#define ACTION_BUTTON 1 -#define CONTEXTUAL_MENU_BUTTON 3 - -#define CLIST_UNFROZEN(clist) nautilus_clist_check_unfrozen (clist) - -struct NautilusListDetails -{ - /* Single click mode ? */ - gboolean single_click_mode; - - /* Anti-aliased mode ? */ - gboolean anti_aliased_mode; - - /* The anchor row for range selections */ - int anchor_row; - - /* Mouse information saved on button press */ - int dnd_press_button; - int dnd_press_x, dnd_press_y; - int button_down_row; - guint32 button_down_time; - - /* Timeout used to make a selected row fully visible after a short - * period of time. (The timeout is needed to make sure - * double-clicking still works, and to optimize holding down arrow key.) - */ - guint keyboard_row_reveal_timer_id; - int keyboard_row_to_reveal; - - /* Typeahead state */ - char *type_select_pattern; - gint64 last_typeselect_time; - - /* Signal IDs that we sometimes want to block. */ - guint select_row_signal_id; - guint unselect_row_signal_id; - - /* Drag state */ - NautilusDragInfo *drag_info; - gboolean drag_started; - gboolean rejects_dropped_icons; - - guint context_menu_timeout_id; - - /* Delayed selection information */ - gboolean dnd_select_pending; - guint dnd_select_pending_state; - - /* Targets for drag data */ - GtkTargetList *target_list; - - NautilusCListRow *drag_prelight_row; - - GtkWidget *title; - - /* Rendering state */ - GdkGC *cell_lighter_background; - GdkGC *cell_darker_background; - GdkGC *cell_selected_lighter_background; - GdkGC *cell_selected_darker_background; - GdkGC *cell_divider_color; - GdkGC *selection_light_color; - GdkGC *selection_medium_color; - GdkGC *selection_main_color; - GdkGC *text_color; - GdkGC *selected_text_color; - GdkGC *link_text_color; - - /* Need RGB background values when compositing images */ - guint32 cell_lighter_background_rgb; - guint32 cell_darker_background_rgb; - guint32 cell_selected_lighter_background_rgb; - guint32 cell_selected_darker_background_rgb; - guint32 selection_light_color_rgb; - guint32 selection_medium_color_rgb; - guint32 selection_main_color_rgb; - - gboolean alternate_row_colors; - gulong background_color_offset, selection_color_offset; -}; - -/* maximum amount of milliseconds the mouse button is allowed to stay down and still be considered a click */ -#define MAX_CLICK_TIME 1500 - -/* horizontal space between images in a pixbuf list cell */ -#define PIXBUF_LIST_SPACING 2 - -/* Some #defines stolen from gtkclist.c that we need for other stolen code. */ - -/* minimum allowed width of a column */ -#define COLUMN_MIN_WIDTH 5 - -/* this defines the base grid spacing */ -#define CELL_SPACING 1 - -/* added the horizontal space at the beginning and end of a row */ -#define COLUMN_INSET 3 - -/* the width of the column resize windows */ -#define DRAG_WIDTH 6 - -/* gives the left pixel of the given column in context of - * the clist's hoffset */ -#define COLUMN_LEFT_XPIXEL(clist, colnum) ((clist)->column[(colnum)].area.x + \ - (clist)->hoffset) - -/* gives the top pixel of the given row in context of - * the clist's voffset */ -#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ - (((row) + 1) * CELL_SPACING) + \ - (clist)->voffset) - -/* returns the row index from a y pixel location in the - * context of the clist's voffset */ -#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ - ((clist)->row_height + CELL_SPACING)) - -/* returns the GList item for the nth row */ -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -/* returns the total height of the list */ -#define LIST_HEIGHT(clist) (((clist)->row_height * ((clist)->rows)) + \ - (CELL_SPACING * ((clist)->rows + 1))) - -enum { - CONTEXT_CLICK_SELECTION, - CONTEXT_CLICK_BACKGROUND, - ACTIVATE, - SELECTION_CHANGED, - SELECT_MATCHING_NAME, - SELECT_PREVIOUS_NAME, - SELECT_NEXT_NAME, - HANDLE_DROPPED_ITEMS, - HANDLE_DRAGGED_ITEMS, - GET_DEFAULT_ACTION, - GET_DRAG_PIXBUF, - GET_SORT_COLUMN_INDEX, - LAST_SIGNAL -}; - -static GtkTargetEntry nautilus_list_dnd_target_table[] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL }, - { NAUTILUS_ICON_DND_COLOR_TYPE, 0, NAUTILUS_ICON_DND_COLOR }, - { NAUTILUS_ICON_DND_BGIMAGE_TYPE, 0, NAUTILUS_ICON_DND_BGIMAGE }, - { NAUTILUS_ICON_DND_KEYWORD_TYPE, 0, NAUTILUS_ICON_DND_KEYWORD } -}; - -static GtkTargetList *nautilus_list_dnd_target_list = NULL; - -static void activate_row (NautilusList *list, - int row); -static int get_cell_horizontal_start_position (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - int content_width); -static void nautilus_list_initialize_class (NautilusListClass *class); -static void nautilus_list_initialize (NautilusList *list); -static void nautilus_list_destroy (GtkObject *object); -static int nautilus_list_button_press (GtkWidget *widget, - GdkEventButton *event); -static int nautilus_list_button_release (GtkWidget *widget, - GdkEventButton *event); -static int nautilus_list_motion (GtkWidget *widget, - GdkEventMotion *event); -static void nautilus_list_drag_end (GtkWidget *widget, - GdkDragContext *context); -static void nautilus_list_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time); -static gboolean nautilus_list_drag_motion (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time); -static gboolean nautilus_list_drag_drop (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time); -static void nautilus_list_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - GtkSelectionData *data, - guint info, - guint time); -static void nautilus_list_clear_keyboard_focus (NautilusList *list); -static void nautilus_list_draw_focus (GtkWidget *widget); -static int nautilus_list_key_press (GtkWidget *widget, - GdkEventKey *event); -static void nautilus_list_unselect_all (NautilusCList *clist); -static void nautilus_list_select_all (NautilusCList *clist); -static void schedule_keyboard_row_reveal (NautilusList *list, - int row); -static void unschedule_keyboard_row_reveal (NautilusList *list); -static void emit_selection_changed (NautilusList *clist); -static void nautilus_list_clear (NautilusCList *clist); -static void nautilus_list_draw (GtkWidget *widget, - GdkRectangle *area); -static int nautilus_list_expose (GtkWidget *widget, - GdkEventExpose *event); -static void draw_rows (NautilusCList *clist, - GdkRectangle *area); -static void draw_row (NautilusCList *list, - GdkRectangle *area, - int row_index, - NautilusCListRow *row); -static void draw_all (NautilusCList *clist); -static void nautilus_list_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void nautilus_list_realize (GtkWidget *widget); -static void nautilus_list_unrealize (GtkWidget *widget); -static gboolean nautilus_list_set_cell_contents (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf); -static void nautilus_list_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void nautilus_list_resize_column (NautilusCList *widget, - int column_index, - int width); -static void nautilus_list_column_resize_track_start (GtkWidget *widget, - int column_index); -static void nautilus_list_column_resize_track (GtkWidget *widget, - int column_index); -static void nautilus_list_column_resize_track_end (GtkWidget *widget, - int column_index); -static gboolean row_set_selected (NautilusList *list, - int row_index, - NautilusCListRow *row, - gboolean select); -static gboolean select_row_unselect_others (NautilusList *list, - int row_to_select); -static void nautilus_list_flush_typeselect_state (NautilusList *container); -static int insert_row (NautilusCList *list, - int row, - char *text[]); -static void nautilus_list_ensure_drag_data (NautilusList *list, - GdkDragContext *context, - guint32 time); -static void nautilus_list_start_auto_scroll (NautilusList *list); -static void nautilus_list_stop_auto_scroll (NautilusList *list); - -static void unref_gcs (NautilusList *list); - - -EEL_DEFINE_CLASS_BOILERPLATE (NautilusList, nautilus_list, NAUTILUS_TYPE_CLIST) - -static guint list_signals[LAST_SIGNAL]; - -static GtkTargetEntry drag_types [] = { - { NAUTILUS_ICON_DND_GNOME_ICON_LIST_TYPE, 0, NAUTILUS_ICON_DND_GNOME_ICON_LIST }, - { NAUTILUS_ICON_DND_URI_LIST_TYPE, 0, NAUTILUS_ICON_DND_URI_LIST }, - { NAUTILUS_ICON_DND_URL_TYPE, 0, NAUTILUS_ICON_DND_URL } -}; - - -/* Standard class initialization function */ -static void -nautilus_list_initialize_class (NautilusListClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - NautilusCListClass *clist_class; - NautilusListClass *list_class; - - GtkBindingSet *clist_binding_set; - - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - clist_class = (NautilusCListClass *) klass; - list_class = (NautilusListClass *) klass; - - list_signals[CONTEXT_CLICK_SELECTION] = - gtk_signal_new ("context_click_selection", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, context_click_selection), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[CONTEXT_CLICK_BACKGROUND] = - gtk_signal_new ("context_click_background", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, context_click_background), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[ACTIVATE] = - gtk_signal_new ("activate", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, activate), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - list_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[SELECT_MATCHING_NAME] = - gtk_signal_new ("select_matching_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_matching_name), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING, 0); - list_signals[SELECT_PREVIOUS_NAME] = - gtk_signal_new ("select_previous_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_previous_name), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[SELECT_NEXT_NAME] = - gtk_signal_new ("select_next_name", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, select_next_name), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - list_signals[HANDLE_DRAGGED_ITEMS] = - gtk_signal_new ("handle_dragged_items", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, handle_dragged_items), - eel_gtk_marshal_BOOL__INT_POINTER_INT_INT_UINT, - GTK_TYPE_BOOL, - 5, - GTK_TYPE_INT, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[HANDLE_DROPPED_ITEMS] = - gtk_signal_new ("handle_dropped_items", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, handle_dropped_items), - eel_gtk_marshal_NONE__INT_POINTER_INT_INT_UINT, - GTK_TYPE_NONE, 5, - GTK_TYPE_INT, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[GET_DEFAULT_ACTION] = - gtk_signal_new ("get_default_action", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_default_action), - eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_INT_INT_UINT, - GTK_TYPE_NONE, 7, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_POINTER, - GTK_TYPE_INT, - GTK_TYPE_INT, - GTK_TYPE_UINT); - list_signals[GET_DRAG_PIXBUF] = - gtk_signal_new ("get_drag_pixbuf", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_drag_pixbuf), - eel_gtk_marshal_POINTER__INT, - GTK_TYPE_POINTER, 1, - GTK_TYPE_INT); - list_signals[GET_SORT_COLUMN_INDEX] = - gtk_signal_new ("get_sort_column_index", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusListClass, get_sort_column_index), - eel_gtk_marshal_INT__NONE, - GTK_TYPE_INT, 0); - - gtk_object_class_add_signals (object_class, list_signals, LAST_SIGNAL); - - /* Turn off the GtkCList key bindings that we want unbound. - * We only need to do this for the keys that we don't handle - * in nautilus_list_key_press. These extra ones are turned off - * to avoid inappropriate GtkCList code and to standardize the - * keyboard behavior in Nautilus. - */ - clist_binding_set = gtk_binding_set_by_class (clist_class); - - /* Use Control-A for Select All, not Control-/ */ - gtk_binding_entry_clear (clist_binding_set, - '/', - GDK_CONTROL_MASK); - /* Don't use Control-\ for Unselect All (maybe invent Nautilus - * standard for this?) */ - gtk_binding_entry_clear (clist_binding_set, - '\\', - GDK_CONTROL_MASK); - /* Hide GtkCList's weird extend-selection-from-keyboard stuff. - * Users can use control-navigation and control-space to create - * extended selections. - */ - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_L, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | GDK_CONTROL_MASK); - gtk_binding_entry_clear (clist_binding_set, - GDK_Shift_R, - GDK_RELEASE_MASK | GDK_SHIFT_MASK | GDK_CONTROL_MASK); - - list_class->column_resize_track_start = nautilus_list_column_resize_track_start; - list_class->column_resize_track = nautilus_list_column_resize_track; - list_class->column_resize_track_end = nautilus_list_column_resize_track_end; - - clist_class->clear = nautilus_list_clear; - clist_class->draw_row = draw_row; - clist_class->draw_rows = draw_rows; - clist_class->draw_all = draw_all; - clist_class->insert_row = insert_row; - clist_class->resize_column = nautilus_list_resize_column; - clist_class->set_cell_contents = nautilus_list_set_cell_contents; - clist_class->select_all = nautilus_list_select_all; - clist_class->unselect_all = nautilus_list_unselect_all; - - widget_class->button_press_event = nautilus_list_button_press; - widget_class->button_release_event = nautilus_list_button_release; - widget_class->motion_notify_event = nautilus_list_motion; - - widget_class->draw = nautilus_list_draw; - widget_class->expose_event = nautilus_list_expose; - widget_class->draw_focus = nautilus_list_draw_focus; - widget_class->key_press_event = nautilus_list_key_press; - widget_class->style_set = nautilus_list_style_set; - widget_class->realize = nautilus_list_realize; - widget_class->unrealize = nautilus_list_unrealize; - widget_class->size_request = nautilus_list_size_request; - - object_class->destroy = nautilus_list_destroy; -} - -static gboolean -event_state_modifies_selection (guint event_state) -{ - return (event_state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0; -} - -void -nautilus_list_set_single_click_mode (NautilusList *list, - gboolean single_click_mode) -{ - list->details->single_click_mode = single_click_mode; - gtk_widget_queue_draw (GTK_WIDGET (list)); -} - -void -nautilus_list_set_anti_aliased_mode (NautilusList *list, - gboolean anti_aliased_mode) -{ - list->details->anti_aliased_mode = anti_aliased_mode; - gtk_widget_queue_draw (GTK_WIDGET (list)); -} - -gboolean -nautilus_list_is_anti_aliased (NautilusList *list) -{ - return list->details->anti_aliased_mode; -} - - -void -nautilus_list_initialize_dnd (NautilusList *list) -{ - g_assert (list->details->drag_info == NULL); - g_assert (!GTK_WIDGET_REALIZED (list)); - - list->details->drag_info = g_new0 (NautilusDragInfo, 1); - - nautilus_drag_init (list->details->drag_info, drag_types, - EEL_N_ELEMENTS (drag_types), NULL); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_end", - GTK_SIGNAL_FUNC (nautilus_list_drag_end), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_leave", - GTK_SIGNAL_FUNC (nautilus_list_drag_leave), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_motion", - GTK_SIGNAL_FUNC (nautilus_list_drag_motion), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_drop", - GTK_SIGNAL_FUNC (nautilus_list_drag_drop), - list); - - gtk_signal_connect (GTK_OBJECT (list), - "drag_data_received", - GTK_SIGNAL_FUNC (nautilus_list_drag_data_received), - list); - - - /* Get ready to accept some dragged stuff. */ - gtk_drag_dest_set (GTK_WIDGET (list), - 0, - nautilus_list_dnd_target_table, - EEL_N_ELEMENTS (nautilus_list_dnd_target_table), - GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK - | GDK_ACTION_ASK); - -} - -/* Standard object initialization function */ -static void -nautilus_list_initialize (NautilusList *list) -{ - list->details = g_new0 (NautilusListDetails, 1); - list->details->anchor_row = -1; - - list->details->drag_prelight_row = NULL; - - list->details->alternate_row_colors = TRUE; - list->details->background_color_offset = G_STRUCT_OFFSET (GtkStyle, bg[GTK_STATE_NORMAL]); - list->details->selection_color_offset = G_STRUCT_OFFSET (GtkStyle, bg[GTK_STATE_SELECTED]); - - /* GtkCList does not specify pointer motion by default */ - gtk_widget_add_events (GTK_WIDGET (list), GDK_POINTER_MOTION_MASK); - - /* Emit "selection changed" signal when parent class changes selection */ - list->details->select_row_signal_id = gtk_signal_connect (GTK_OBJECT (list), - "select_row", - emit_selection_changed, - list); - list->details->unselect_row_signal_id = gtk_signal_connect (GTK_OBJECT (list), - "unselect_row", - emit_selection_changed, - list); - - gtk_widget_push_composite_child (); - list->details->title = GTK_WIDGET (nautilus_list_column_title_new()); - gtk_widget_pop_composite_child (); - - list->details->type_select_pattern = NULL; - list->details->last_typeselect_time = G_GINT64_CONSTANT(0); -} - -static void -nautilus_list_destroy (GtkObject *object) -{ - NautilusList *list; - - list = NAUTILUS_LIST (object); - - if (list->details->drag_info != NULL) { - nautilus_drag_finalize (list->details->drag_info); - } - - unschedule_keyboard_row_reveal (list); - - EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); - - unref_gcs (list); - - g_free (list->details->type_select_pattern); - - /* Must do this after calling the parent, because GtkCList calls - * the clear method, which must have a valid details pointer. - */ - g_free (list->details); -} - -static void -emit_selection_changed (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECTION_CHANGED]); -} - -static void -activate_row_data_list (NautilusList *list, GList *activate_list) -{ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[ACTIVATE], - activate_list); -} - -static void -activate_selected_rows (NautilusList *list) -{ - GList *selection; - - selection = nautilus_list_get_selection (list); - activate_row_data_list (list, selection); - g_list_free (selection); -} - -static void -activate_row (NautilusList *list, int row) -{ - GList *singleton_list; - - singleton_list = NULL; - singleton_list = g_list_append (NULL, nautilus_clist_get_row_data (NAUTILUS_CLIST (list), row)); - activate_row_data_list (list, singleton_list); - g_list_free (singleton_list); -} - -gboolean -nautilus_list_is_row_selected (NautilusList *list, int row) -{ - NautilusCListRow *elem; - - g_return_val_if_fail (row >= 0, FALSE); - g_return_val_if_fail (row < NAUTILUS_CLIST (list)->rows, FALSE); - - elem = g_list_nth (NAUTILUS_CLIST (list)->row_list, row)->data; - - return elem->state == GTK_STATE_SELECTED; -} - -/* Selects the rows between the anchor to the specified row, inclusive. - * Returns TRUE if selection changed. */ -static gboolean -select_range (NautilusList *list, int row) -{ - int min, max; - int i; - gboolean selection_changed; - - selection_changed = FALSE; - - if (list->details->anchor_row == -1) { - list->details->anchor_row = row; - } - - if (row < list->details->anchor_row) { - min = row; - max = list->details->anchor_row; - } else { - min = list->details->anchor_row; - max = row; - } - - for (i = min; i <= max; i++) { - selection_changed |= row_set_selected (list, i, NULL, TRUE); - } - - return selection_changed; -} - -/* Handles row selection according to the specified modifier state */ -static void -select_row_from_mouse (NautilusList *list, int row, guint state) -{ - int range, additive; - gboolean should_select_row; - gboolean selection_changed; - - selection_changed = FALSE; - - range = (state & GDK_SHIFT_MASK) != 0; - additive = (state & GDK_CONTROL_MASK) != 0; - - nautilus_list_clear_keyboard_focus (list); - - if (!additive) { - selection_changed |= select_row_unselect_others (list, -1); - } - - if (range) { - selection_changed |= select_range (list, row); - } else { - should_select_row = !additive || !nautilus_list_is_row_selected (list, row); - selection_changed |= row_set_selected (list, row, NULL, should_select_row); - list->details->anchor_row = row; - } - - if (selection_changed) { - emit_selection_changed (list); - } -} - -/* - * row_set_selected: - * - * Select or unselect a row. Return TRUE if selection has changed. - * Does not emit the SELECTION_CHANGED signal; it's up to the caller - * to handle that. - * - * @list: The NautilusList in question. - * @row: index of row number to select or unselect. - * @row: NautilusCListRow pointer for given list. Passing this avoids - * expensive lookup. If it's NULL, it will be looked up in this function. - * @select: TRUE if row should be selected, FALSE otherwise. - * - * Return Value: TRUE if selection has changed, FALSE otherwise. - */ -static gboolean -row_set_selected (NautilusList *list, int row_index, NautilusCListRow *row, gboolean select) -{ - g_assert (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows); - - if (row == NULL) { - row = ROW_ELEMENT (NAUTILUS_CLIST (list), row_index)->data; - } - - if (select == (row->state == GTK_STATE_SELECTED)) { - return FALSE; - } - - /* Block signal handlers so we can make sure the selection-changed - * signal gets sent only once. - */ - gtk_signal_handler_block (GTK_OBJECT(list), - list->details->select_row_signal_id); - gtk_signal_handler_block (GTK_OBJECT(list), - list->details->unselect_row_signal_id); - - if (select) { - nautilus_clist_select_row (NAUTILUS_CLIST (list), row_index, -1); - } else { - nautilus_clist_unselect_row (NAUTILUS_CLIST (list), row_index, -1); - } - - gtk_signal_handler_unblock (GTK_OBJECT(list), - list->details->select_row_signal_id); - gtk_signal_handler_unblock (GTK_OBJECT(list), - list->details->unselect_row_signal_id); - - return TRUE; -} - -/** - * select_row_unselect_others: - * - * Change the selected rows as necessary such that only - * the given row remains selected. - * - * @list: The NautilusList in question. - * @row_to_select: The row number to leave selected. Use -1 to leave - * no row selected. - * - * Return value: TRUE if the selection changed; FALSE otherwise. - */ -static gboolean -select_row_unselect_others (NautilusList *list, int row_to_select) -{ - GList *p; - int row_index; - gboolean selection_changed; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), FALSE); - - selection_changed = FALSE; - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; p != NULL; p = p->next, ++row_index) { - selection_changed |= row_set_selected (list, row_index, p->data, row_index == row_to_select); - } - - return selection_changed; -} - -static void -nautilus_list_unselect_all (NautilusCList *clist) -{ - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - if (select_row_unselect_others (NAUTILUS_LIST (clist), -1)) { - emit_selection_changed (NAUTILUS_LIST (clist)); - } -} - -static void -nautilus_list_select_all (NautilusCList *clist) -{ - GList *p; - int row_index; - gboolean selection_changed; - - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - selection_changed = FALSE; - for (p = clist->row_list, row_index = 0; p != NULL; p = p->next, ++row_index) { - selection_changed |= row_set_selected (NAUTILUS_LIST (clist), row_index, p->data, TRUE); - } - - if (selection_changed) { - emit_selection_changed (NAUTILUS_LIST (clist)); - } -} - -typedef struct { - NautilusList *list; - GdkEventButton *event; -} ContextMenuParameters; - -static ContextMenuParameters * -context_menu_parameters_new (NautilusList *list, - GdkEventButton *event) -{ - ContextMenuParameters *parameters; - - parameters = g_new (ContextMenuParameters, 1); - parameters->list = list; - parameters->event = (GdkEventButton *)(gdk_event_copy ((GdkEvent *)event)); - - return parameters; -} - -static void -context_menu_parameters_free (ContextMenuParameters *parameters) -{ - gdk_event_free ((GdkEvent *)parameters->event); - g_free (parameters); -} - -static gboolean -show_context_menu_callback (void *cast_to_parameters) -{ - ContextMenuParameters *parameters; - - parameters = (ContextMenuParameters *)cast_to_parameters; - - g_assert (NAUTILUS_IS_LIST (parameters->list)); - - /* FIXME bugzilla.eazel.com 2574: - * Need to handle case where button has already been released, - * a la NautilusIconContainer code? - */ - - gtk_timeout_remove (parameters->list->details->context_menu_timeout_id); - - /* Context menu applies to all selected items. The only - * odd case is if this click deselected the item under - * the mouse, but at least the behavior is consistent. - */ - gtk_signal_emit (GTK_OBJECT (parameters->list), - list_signals[CONTEXT_CLICK_SELECTION], - parameters->event); - - context_menu_parameters_free (parameters); - - return TRUE; -} - -/* Our handler for button_press events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_button_press (GtkWidget *widget, GdkEventButton *event) -{ - NautilusList *list; - NautilusCList *clist; - int on_row; - int row_index, column_index; - int retval; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - retval = FALSE; - - if (!GTK_WIDGET_HAS_FOCUS (widget)) { - gtk_widget_grab_focus (widget); - } - - - /* Forget the typeahead state. */ - nautilus_list_flush_typeselect_state (list); - - if (event->window != clist->clist_window) - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, button_press_event, (widget, event)); - - on_row = nautilus_clist_get_selection_info (clist, event->x, event->y, &row_index, &column_index); - list->details->button_down_time = event->time; - list->details->drag_started = FALSE; - - list->details->button_down_row = -1; - - switch (event->type) { - case GDK_BUTTON_PRESS: - - if (event->button == CONTEXTUAL_MENU_BUTTON && !on_row) { - gtk_signal_emit (GTK_OBJECT (list), - list_signals[CONTEXT_CLICK_BACKGROUND], - event); - - retval = TRUE; - } else if (event->button == ACTION_BUTTON || event->button == CONTEXTUAL_MENU_BUTTON) { - if (on_row) { - - if (event->button == CONTEXTUAL_MENU_BUTTON) { - /* after a timeout we will decide if this is a - * context menu click or a drag start - */ - list->details->context_menu_timeout_id = gtk_timeout_add ( - CONTEXT_MENU_TIMEOUT_INTERVAL, - show_context_menu_callback, - context_menu_parameters_new (list, event)); - } - - /* Save the clicked row_index for DnD and single-click activate */ - - list->details->button_down_row = row_index; - - /* Save the mouse info for DnD */ - - list->details->dnd_press_button = event->button; - list->details->dnd_press_x = event->x; - list->details->dnd_press_y = event->y; - - /* Handle selection */ - - if ((nautilus_list_is_row_selected (list, row_index) - && !event_state_modifies_selection (event->state)) - || ((event->state & GDK_CONTROL_MASK) - && !(event->state & GDK_SHIFT_MASK))) { - /* don't change selection just yet, wait for - * possible drag - */ - list->details->dnd_select_pending = TRUE; - list->details->dnd_select_pending_state = event->state; - } - - if (!list->details->dnd_select_pending) { - select_row_from_mouse (list, row_index, event->state); - } - } else { - nautilus_clist_unselect_all (clist); - } - - retval = TRUE; - } - - break; - - case GDK_2BUTTON_PRESS: - if (event->button == ACTION_BUTTON) { - list->details->dnd_select_pending = FALSE; - list->details->dnd_select_pending_state = 0; - - if (on_row && !list->details->single_click_mode) { - /* We'll just eat the 2nd click if in single-click mode. */ - activate_selected_rows (list); - } - - retval = TRUE; - break; - } - - default: - break; - } - - return retval; -} - -/* Our handler for button_release events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_button_release (GtkWidget *widget, GdkEventButton *event) -{ - NautilusList *list; - NautilusCList *clist; - NautilusCListRow *row; - int on_row; - int row_index, column_index; - GtkStyle *style; - int text_x, text_width; - int retval; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - retval = FALSE; - - if (event->window != clist->clist_window) - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, button_release_event, (widget, event)); - - on_row = nautilus_clist_get_selection_info (clist, event->x, event->y, &row_index, &column_index); - - if (event->button != ACTION_BUTTON && event->button != CONTEXTUAL_MENU_BUTTON) - return FALSE; - - if (on_row) { - /* Clean up after abortive drag-and-drop attempt (since user can't - * reorder list view items, releasing mouse in list view cancels - * drag-and-drop possibility). - */ - if (list->details->dnd_select_pending) { - /* If clicked on a selected item, don't change selection - * (unless perhaps if modifiers were used) - */ - if (!nautilus_list_is_row_selected (list, row_index) - || event_state_modifies_selection (list->details->dnd_select_pending_state)) { - select_row_from_mouse (list, - list->details->button_down_row, - list->details->dnd_select_pending_state); - } - - list->details->dnd_select_pending = FALSE; - list->details->dnd_select_pending_state = 0; - } - - if (event->button == CONTEXTUAL_MENU_BUTTON && !list->details->drag_started) { - /* Right click, drag never happened, immediately show context menu */ - gtk_timeout_remove (list->details->context_menu_timeout_id); - gtk_signal_emit (GTK_OBJECT (list), - list_signals[CONTEXT_CLICK_SELECTION], - event); - } - - /* - * Activate on single click if not extending selection, mouse hasn't moved to - * a different row, not too much time has passed, and this is a link-type cell. - */ - if (event->button == ACTION_BUTTON && - list->details->single_click_mode && - !event_state_modifies_selection (event->state)) { - int elapsed_time = event->time - list->details->button_down_time; - - if (elapsed_time < MAX_CLICK_TIME && list->details->button_down_row == row_index) { - row = ROW_ELEMENT (clist, row_index)->data; - if (row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT) { - /* One final test. Check whether the click was in the - * horizontal bounds of the displayed text. - */ - nautilus_list_get_cell_style (list, row, GTK_STATE_NORMAL, row_index, column_index, &style, NULL, NULL, NULL); - text_width = gdk_string_width (style->font, NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - text_x = get_cell_horizontal_start_position (clist, row, column_index, text_width); - if (event->x >= text_x && event->x <= text_x + text_width) { - /* Note that we activate only the clicked-on item, - * not all selected items. This is because the UI - * feedback makes it clear that you're clicking on - * a link to activate that link, rather than activating - * the whole selection. - */ - activate_row (list, row_index); - } - } - } - } - - retval = TRUE; - } - - list->details->dnd_press_button = NO_BUTTON; - list->details->dnd_press_x = 0; - list->details->dnd_press_y = 0; - list->details->drag_started = FALSE; - - return retval; -} - -static void -nautilus_list_clear_keyboard_focus (NautilusList *list) -{ - if (NAUTILUS_CLIST (list)->focus_row >= 0) { - gtk_widget_draw_focus (GTK_WIDGET (list)); - } - - NAUTILUS_CLIST (list)->focus_row = -1; -} - -static void -nautilus_list_set_keyboard_focus (NautilusList *list, int row_index) -{ - g_assert (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows); - - if (row_index == NAUTILUS_CLIST (list)->focus_row) { - return; - } - - nautilus_list_clear_keyboard_focus (list); - - NAUTILUS_CLIST (list)->focus_row = row_index; - - gtk_widget_draw_focus (GTK_WIDGET (list)); -} - -static void -nautilus_list_keyboard_move_to (NautilusList *list, int row_index, GdkEventKey *event) -{ - NautilusCList *clist; - - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (row_index >= 0 || row_index < NAUTILUS_CLIST (list)->rows); - - clist = NAUTILUS_CLIST (list); - - if (event != NULL && (event->state & GDK_MOD1_MASK) != 0) { - /* Move the keyboard focus. */ - nautilus_list_set_keyboard_focus (list, row_index); - } else { - /* Select row_index and get rid of special keyboard focus. */ - nautilus_list_clear_keyboard_focus (list); - if (select_row_unselect_others (list, row_index)) { - emit_selection_changed (list); - } - } - - schedule_keyboard_row_reveal (list, row_index); -} - -void -nautilus_list_select_row (NautilusList *list, int row_index) -{ - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (row_index >= 0); - - if (row_index >= NAUTILUS_CLIST (list)->rows) - row_index = NAUTILUS_CLIST (list)->rows - 1; - - nautilus_list_keyboard_move_to (list, row_index, NULL); -} - -static gboolean -keyboard_row_reveal_timeout_callback (gpointer data) -{ - NautilusList *list; - int row_index; - - GDK_THREADS_ENTER (); - - list = NAUTILUS_LIST (data); - row_index = list->details->keyboard_row_to_reveal; - - if (row_index >= 0 && row_index < NAUTILUS_CLIST (list)->rows) { - /* Only reveal the icon if it's still the keyboard - * focus or if it's still selected. Someone originally - * thought we should cancel this reveal if the user - * manages to sneak a direct scroll in before the - * timeout fires, but we later realized this wouldn't - * actually be an improvement (see bugzilla.eazel.com - * 612). - */ - if (row_index == NAUTILUS_CLIST (list)->focus_row - || nautilus_list_is_row_selected (list, row_index)) { - nautilus_list_reveal_row (list, row_index); - } - list->details->keyboard_row_reveal_timer_id = 0; - } - - GDK_THREADS_LEAVE (); - - return FALSE; -} - -static void -unschedule_keyboard_row_reveal (NautilusList *list) -{ - if (list->details->keyboard_row_reveal_timer_id != 0) { - gtk_timeout_remove (list->details->keyboard_row_reveal_timer_id); - } -} - -static void -schedule_keyboard_row_reveal (NautilusList *list, int row_index) -{ - unschedule_keyboard_row_reveal (list); - - list->details->keyboard_row_to_reveal = row_index; - list->details->keyboard_row_reveal_timer_id - = gtk_timeout_add (KEYBOARD_ROW_REVEAL_TIMEOUT, - keyboard_row_reveal_timeout_callback, - list); -} - -void -nautilus_list_reveal_row (NautilusList *list, int row_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - g_return_if_fail (row_index >= 0 && row_index < NAUTILUS_CLIST (list) ->rows); - - clist = NAUTILUS_CLIST (list); - - if (ROW_TOP_YPIXEL (clist, row_index) + clist->row_height > - clist->clist_window_height) { - nautilus_clist_moveto (clist, row_index, -1, 1, 0); - } else if (ROW_TOP_YPIXEL (clist, row_index) < 0) { - nautilus_clist_moveto (clist, row_index, -1, 0, 0); - } -} - -static void -nautilus_list_keyboard_navigation_key_press (NautilusList *list, GdkEventKey *event, - GtkScrollType scroll_type, gboolean jump_to_end) -{ - NautilusCList *clist; - int start_row; - int destination_row; - int rows_per_page; - - g_assert (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - if (scroll_type == GTK_SCROLL_JUMP) { - destination_row = (jump_to_end ? - clist->rows - 1 : - 0); - } else { - /* Choose the row to start with. - * If we have a keyboard focus, start with it. - * If there's a selection, use the selected row farthest toward the end. - */ - - if (clist->focus_row >= 0) { - start_row = clist->focus_row; - } else { - start_row = (scroll_type == GTK_SCROLL_STEP_FORWARD - || scroll_type == GTK_SCROLL_PAGE_FORWARD ? - nautilus_list_get_last_selected_row (list) : - nautilus_list_get_first_selected_row (list)); - } - - /* If there's no row to start with, select the row farthest toward the end. - * If there is a row to start with, select the next row in the arrow direction. - */ - if (start_row < 0) { - destination_row = (scroll_type == GTK_SCROLL_STEP_FORWARD - || scroll_type == GTK_SCROLL_PAGE_FORWARD - ? 0 : clist->rows - 1); - } else if (scroll_type == GTK_SCROLL_STEP_FORWARD) { - destination_row = MIN (clist->rows - 1, start_row + 1); - } else if (scroll_type == GTK_SCROLL_STEP_BACKWARD) { - destination_row = MAX (0, start_row - 1); - } else { - g_assert (scroll_type == GTK_SCROLL_PAGE_FORWARD || GTK_SCROLL_PAGE_BACKWARD); - rows_per_page = (2 * clist->clist_window_height - - clist->row_height - CELL_SPACING) / - (2 * (clist->row_height + CELL_SPACING)); - - if (scroll_type == GTK_SCROLL_PAGE_FORWARD) { - destination_row = MIN (clist->rows - 1, - start_row + rows_per_page); - } else { - destination_row = MAX (0, - start_row - rows_per_page); - } - } - } - - nautilus_list_keyboard_move_to (list, destination_row, event); -} - -static void -nautilus_list_keyboard_home (NautilusList *list, GdkEventKey *event) -{ - /* Home selects the first row. - * Control-Home sets the keyboard focus to the first row. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_JUMP, FALSE); -} - -static void -nautilus_list_keyboard_end (NautilusList *list, GdkEventKey *event) -{ - /* End selects the last row. - * Control-End sets the keyboard focus to the last row. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_JUMP, TRUE); -} - -static void -nautilus_list_keyboard_up (NautilusList *list, GdkEventKey *event) -{ - /* Up selects the next higher row. - * Control-Up sets the keyboard focus to the next higher icon. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_STEP_BACKWARD, FALSE); -} - -static void -nautilus_list_keyboard_down (NautilusList *list, GdkEventKey *event) -{ - /* Down selects the next lower row. - * Control-Down sets the keyboard focus to the next lower icon. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_STEP_FORWARD, FALSE); -} - -static void -nautilus_list_keyboard_page_up (NautilusList *list, GdkEventKey *event) -{ - /* Page Up selects a row one screenful higher. - * Control-Page Up sets the keyboard focus to the row one screenful higher. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_PAGE_BACKWARD, FALSE); -} - -static void -nautilus_list_keyboard_page_down (NautilusList *list, GdkEventKey *event) -{ - /* Page Down selects a row one screenful lower. - * Control-Page Down sets the keyboard focus to the row one screenful lower. - */ - nautilus_list_keyboard_navigation_key_press (list, event, GTK_SCROLL_PAGE_FORWARD, FALSE); -} - -static void -nautilus_list_keyboard_space (NautilusList *list, GdkEventKey *event) -{ - if (event->state & GDK_MOD1_MASK) { - gtk_signal_emit_by_name (GTK_OBJECT (list), "toggle_focus_row"); - } -} - -static void -nautilus_list_activate_selected_items (NautilusList *list) -{ - int row_index; - - for (row_index = 0; row_index < NAUTILUS_CLIST (list)->rows; ++row_index) { - if (nautilus_list_is_row_selected (list, row_index)) { - activate_row (list, row_index); - } - } -} - -static void -nautilus_list_flush_typeselect_state (NautilusList *list) -{ - g_free (list->details->type_select_pattern); - list->details->type_select_pattern = NULL; - list->details->last_typeselect_time = G_GINT64_CONSTANT(0); -} - -enum { - NAUTILUS_TYPESELECT_FLUSH_DELAY = 1000000 - /* After this time the current typeselect buffer will be - * thrown away and the new pressed character will be made - * the the start of a new pattern. - */ -}; - -static gboolean -nautilus_list_handle_typeahead (NautilusList *list, const char *key_string) -{ - char *new_pattern; - gint64 now; - gint64 time_delta; - int key_string_length; - int index; - - g_assert (key_string != NULL); - g_assert (strlen (key_string) < 5); - - key_string_length = strlen (key_string); - - if (key_string_length == 0) { - /* can be an empty string if the modifier was held down, etc. */ - return FALSE; - } - - /* only handle if printable keys typed */ - for (index = 0; index < key_string_length; index++) { - if (!isprint (key_string[index])) { - return FALSE; - } - } - - /* find out how long since last character was typed */ - now = eel_get_system_time(); - time_delta = now - list->details->last_typeselect_time; - if (time_delta < 0 || time_delta > NAUTILUS_TYPESELECT_FLUSH_DELAY) { - /* the typeselect state is too old, start with a fresh one */ - g_free (list->details->type_select_pattern); - list->details->type_select_pattern = NULL; - } - - if (list->details->type_select_pattern != NULL) { - new_pattern = g_strconcat - (list->details->type_select_pattern, - key_string, NULL); - g_free (list->details->type_select_pattern); - } else { - new_pattern = g_strdup (key_string); - } - - list->details->type_select_pattern = new_pattern; - list->details->last_typeselect_time = now; - - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_MATCHING_NAME], new_pattern); - - return TRUE; -} - -static int -nautilus_list_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - NautilusList *list; - - list = NAUTILUS_LIST (widget); - - switch (event->keyval) { - case GDK_Home: - nautilus_list_keyboard_home (list, event); - break; - case GDK_End: - nautilus_list_keyboard_end (list, event); - break; - case GDK_Page_Up: - nautilus_list_keyboard_page_up (list, event); - break; - case GDK_Page_Down: - nautilus_list_keyboard_page_down (list, event); - break; - case GDK_Up: - nautilus_list_keyboard_up (list, event); - break; - case GDK_Down: - nautilus_list_keyboard_down (list, event); - break; - case GDK_space: - nautilus_list_keyboard_space (list, event); - break; - case GDK_Return: - nautilus_list_activate_selected_items (list); - break; - case GDK_Tab: - case GDK_ISO_Left_Tab: - if ((event->state & GDK_SHIFT_MASK) == 0) { - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_PREVIOUS_NAME]); - } else { - gtk_signal_emit (GTK_OBJECT (list), list_signals[SELECT_NEXT_NAME]); - } - break; - default: - /* Don't use Control or Alt keys for type-selecting, because they - * might be used for menus. - */ - if ((event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) == 0 && - nautilus_list_handle_typeahead (list, event->string)) { - return TRUE; - } - - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, key_press_event, (widget, event)); - } - - return TRUE; -} - -static guint32 -eel_gdk_set_shifted_foreground_gc_color (GdkGC *gc, guint32 color, float shift_by) -{ - guint32 shifted_color; - - shifted_color = eel_rgb_shift_color (color, shift_by); - gdk_rgb_gc_set_foreground (gc, shifted_color); - - return shifted_color; -} - -static GdkGC * -eel_gdk_gc_copy (GdkGC *source, GdkWindow *window) -{ - GdkGC *result; - - result = gdk_gc_new (window); - gdk_gc_copy (result, source); - - /* reset some properties to be on the safe side */ - gdk_gc_set_function (result, GDK_COPY); - gdk_gc_set_fill (result, GDK_SOLID); - gdk_gc_set_clip_origin (result, 0, 0); - gdk_gc_set_clip_mask (result, NULL); - - return result; -} - -static void -nautilus_list_setup_style_colors (NautilusList *list) -{ - guint32 style_background_color; - guint32 selection_background_color; - GdkColor text_color; - - gdk_rgb_init(); - - style_background_color = eel_gdk_color_to_rgb - (G_STRUCT_MEMBER_P (GTK_WIDGET (list)->style, - list->details->background_color_offset)); - selection_background_color = eel_gdk_color_to_rgb - (G_STRUCT_MEMBER_P (GTK_WIDGET (list)->style, - list->details->selection_color_offset)); - - list->details->cell_lighter_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_lighter_background, - style_background_color, 1); - - list->details->cell_darker_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_darker_background, - style_background_color, 1.03); - - list->details->cell_selected_lighter_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_selected_lighter_background, - style_background_color, 1.04); - - list->details->cell_selected_darker_background_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->cell_selected_darker_background, - style_background_color, 1.06); - - eel_gdk_set_shifted_foreground_gc_color (list->details->cell_divider_color, - style_background_color, 0.8); - - list->details->selection_main_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_main_color, - selection_background_color, 1); - - list->details->selection_medium_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_medium_color, - selection_background_color, 0.7); - - list->details->selection_light_color_rgb - = eel_gdk_set_shifted_foreground_gc_color (list->details->selection_light_color, - selection_background_color, 0.5); - - text_color = GTK_WIDGET (list)->style->fg[GTK_STATE_NORMAL]; - eel_gdk_gc_choose_foreground_color (list->details->text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_NORMAL]); - - text_color = GTK_WIDGET (list)->style->fg[GTK_STATE_SELECTED]; - eel_gdk_gc_choose_foreground_color (list->details->selected_text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_SELECTED]); - - text_color.red = 0; - text_color.green = 0; - text_color.blue = 65535; - eel_gdk_gc_choose_foreground_color (list->details->link_text_color, &text_color, - >K_WIDGET (list)->style->bg[GTK_STATE_NORMAL]); -} - -static void -unref_a_gc (GdkGC **gc) -{ - if (*gc != NULL) { - gdk_gc_unref (*gc); - *gc = NULL; - } -} - -static void -unref_gcs (NautilusList *list) -{ - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - unref_a_gc (&list->details->cell_lighter_background); - unref_a_gc (&list->details->cell_darker_background); - unref_a_gc (&list->details->cell_selected_lighter_background); - unref_a_gc (&list->details->cell_selected_darker_background); - unref_a_gc (&list->details->cell_divider_color); - unref_a_gc (&list->details->selection_light_color); - unref_a_gc (&list->details->selection_medium_color); - unref_a_gc (&list->details->selection_main_color); - unref_a_gc (&list->details->text_color); - unref_a_gc (&list->details->selected_text_color); - unref_a_gc (&list->details->link_text_color); -} - -static void -make_gcs_and_colors (NautilusList *list) -{ - GtkWidget *widget; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - g_return_if_fail (GTK_IS_WIDGET (list)); - - widget = GTK_WIDGET (list); - - /* First unref old gcs */ - unref_gcs (list); - - /* now setup new ones */ - list->details->cell_lighter_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_darker_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_selected_lighter_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_selected_darker_background = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->cell_divider_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_NORMAL], widget->window); - list->details->selection_light_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - list->details->selection_medium_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - list->details->selection_main_color = eel_gdk_gc_copy ( - widget->style->bg_gc[GTK_STATE_SELECTED], widget->window); - - list->details->text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_NORMAL], widget->window); - list->details->selected_text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_SELECTED], widget->window); - list->details->link_text_color = eel_gdk_gc_copy ( - widget->style->fg_gc[GTK_STATE_NORMAL], widget->window); - - nautilus_list_setup_style_colors (list); -} - -static void -nautilus_list_style_set (GtkWidget *widget, GtkStyle *previous_style) -{ - NautilusList *list; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - list = NAUTILUS_LIST (widget); - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, style_set, (widget, previous_style)); - - if (GTK_WIDGET_REALIZED (widget)) { - make_gcs_and_colors (list); - } -} - -static void -nautilus_list_realize (GtkWidget *widget) -{ - NautilusList *list; - NautilusCList *clist; - GtkWindow *window; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - - clist->column[0].button = list->details->title; - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget)); - - make_gcs_and_colors (list); - - if (list->details->title) { - gtk_widget_set_parent_window (list->details->title, clist->title_window); - gtk_widget_set_parent (list->details->title, GTK_WIDGET (clist)); - gtk_widget_show (list->details->title); - } - - /* make us the focused widget */ - g_assert (GTK_IS_WINDOW (gtk_widget_get_toplevel (widget))); - window = GTK_WINDOW (gtk_widget_get_toplevel (widget)); - gtk_window_set_focus (window, widget); -} - -static void -nautilus_list_unrealize (GtkWidget *widget) -{ - GtkWindow *window; - window = GTK_WINDOW (gtk_widget_get_toplevel (widget)); - gtk_window_set_focus (window, NULL); - - /* unref all the gcs we've created */ - unref_gcs (NAUTILUS_LIST (widget)); - - EEL_CALL_PARENT (GTK_WIDGET_CLASS, unrealize, (widget)); -} - -/* this is here just temporarily */ -static int -list_requisition_width (NautilusCList *clist) -{ - int width = CELL_SPACING; - int i; - - for (i = clist->columns - 1; i >= 0; i--) { - if (!clist->column[i].visible) - continue; - - if (clist->column[i].width_set) - width += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET); - else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) - width += clist->column[i].button->requisition.width; - } - - return width; -} - - -static void -nautilus_list_size_request (GtkWidget *widget, GtkRequisition *requisition) -{ - /* stolen from gtk_clist - * make sure the proper title ammount is allocated for the column - * title view -- this would not otherwise be done because - * NautilusList depends the buttons being there when doing a size calculation - */ - NautilusList *list; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - g_return_if_fail (requisition != NULL); - - clist = NAUTILUS_CLIST (widget); - list = NAUTILUS_LIST (widget); - - requisition->width = 0; - requisition->height = 0; - - /* compute the size of the column title (title) area */ - clist->column_title_area.height = 0; - if (NAUTILUS_CLIST_SHOW_TITLES(clist) && list->details->title) { - GtkRequisition child_requisition; - - gtk_widget_size_request (list->details->title, - &child_requisition); - - child_requisition.height = 20; - /* for now */ - - clist->column_title_area.height = - MAX (clist->column_title_area.height, - child_requisition.height); - } - - requisition->width += (widget->style->klass->xthickness + - GTK_CONTAINER (widget)->border_width) * 2; - requisition->height += (clist->column_title_area.height + - (widget->style->klass->ythickness + - GTK_CONTAINER (widget)->border_width) * 2); - - - requisition->width += list_requisition_width (clist); - requisition->height += LIST_HEIGHT (clist); -} - -static int -new_column_width (NautilusCList *clist, int column_index, int *x) -{ - int xthickness = GTK_WIDGET (clist)->style->klass->xthickness; - int width; - int cx; - int dx; - int last_column; - - /* first translate the x position from widget->window - * to clist->clist_window */ - cx = *x - xthickness; - - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--); - - /* calculate new column width making sure it doesn't end up - * less than the minimum width */ - dx = (COLUMN_LEFT_XPIXEL (clist, column_index) + COLUMN_INSET + - (column_index < last_column) * CELL_SPACING); - width = cx - dx; - - if (width < MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width)) { - width = MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width); - cx = dx + width; - *x = cx + xthickness; - } else if (clist->column[column_index].max_width >= COLUMN_MIN_WIDTH && - width > clist->column[column_index].max_width) { - width = clist->column[column_index].max_width; - cx = dx + clist->column[column_index].max_width; - *x = cx + xthickness; - } - - if (cx < 0 || cx > clist->clist_window_width) - *x = -1; - - return width; -} - -static void -size_allocate_columns (NautilusCList *clist, gboolean block_resize) -{ - int xoffset = CELL_SPACING + COLUMN_INSET; - int last_column; - int i; - - /* find last visible column and calculate correct column width */ - for (last_column = clist->columns - 1; - last_column >= 0 && !clist->column[last_column].visible; last_column--) - ; - - if (last_column < 0) - return; - - for (i = 0; i <= last_column; i++) { - if (!clist->column[i].visible) - continue; - - clist->column[i].area.x = xoffset; - if (clist->column[i].width_set) { - if (!block_resize && NAUTILUS_CLIST_SHOW_TITLES(clist) && - clist->column[i].auto_resize && clist->column[i].button) { - int width; - - width = (clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET))); - - if (width > clist->column[i].width) - nautilus_clist_set_column_width (clist, i, width); - } - - clist->column[i].area.width = clist->column[i].width; - xoffset += clist->column[i].width + CELL_SPACING + (2 * COLUMN_INSET); - } else if (NAUTILUS_CLIST_SHOW_TITLES(clist) && clist->column[i].button) { - clist->column[i].area.width = - clist->column[i].button->requisition.width - - (CELL_SPACING + (2 * COLUMN_INSET)); - xoffset += clist->column[i].button->requisition.width; - } - } - - clist->column[last_column].area.width - += MAX (0, clist->clist_window_width + COLUMN_INSET - xoffset); -} - -static void -size_allocate_title_buttons (NautilusCList *clist) -{ - GtkAllocation button_allocation; - int last_column; - int last_button = 0; - int i; - - button_allocation.x = clist->hoffset; - button_allocation.y = 0; - button_allocation.width = 0; - button_allocation.height = clist->column_title_area.height; - - /* find last visible column */ - for (last_column = clist->columns - 1; last_column >= 0; last_column--) - if (clist->column[last_column].visible) - break; - - for (i = 0; i < last_column; i++) { - if (!clist->column[i].visible) { - last_button = i + 1; - gdk_window_hide (clist->column[i].window); - continue; - } - - button_allocation.width += (clist->column[i].area.width + - CELL_SPACING + 2 * COLUMN_INSET); - - if (!clist->column[i + 1].button) { - gdk_window_hide (clist->column[i].window); - continue; - } - - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - button_allocation.x += button_allocation.width; - button_allocation.width = 0; - - last_button = i + 1; - } - - button_allocation.width += (clist->column[last_column].area.width + - 2 * (CELL_SPACING + COLUMN_INSET)); - gtk_widget_size_allocate (clist->column[last_button].button, - &button_allocation); - -} - -static void -nautilus_list_draw_focus (GtkWidget *widget) -{ - GdkGCValues saved_values; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - if (!GTK_WIDGET_DRAWABLE (widget) || !GTK_WIDGET_CAN_FOCUS (widget)) { - return; - } - - clist = NAUTILUS_CLIST (widget); - if (clist->focus_row < 0) { - return; - } - - gdk_gc_get_values (clist->xor_gc, &saved_values); - - gdk_gc_set_stipple (clist->xor_gc, eel_stipple_bitmap ()); - gdk_gc_set_fill (clist->xor_gc, GDK_STIPPLED); - - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - 0, ROW_TOP_YPIXEL(clist, clist->focus_row), - clist->clist_window_width - 1, - clist->row_height - 1); - /* Resetting the stipple to the saved value causes death - * deep in Bonobo X handling, believe it or not. Fortunately - * we don't need to. - */ - gdk_gc_set_fill (clist->xor_gc, saved_values.fill); -} - -static int -selected_column_index (NautilusList *list) -{ - int column; - - column = 2; - gtk_signal_emit_by_name (GTK_OBJECT (list), "get_sort_column_index", &column); - return column; -} - -static void -get_column_background (NautilusList *list, GdkGC **selected, GdkGC **plain) -{ - *plain = list->details->cell_lighter_background; - *selected = list->details->cell_selected_lighter_background; -} - -void -nautilus_list_get_cell_style (NautilusList *list, NautilusCListRow *row, - int state, int row_index, int column_index, GtkStyle **style, - GdkGC **fg_gc, GdkGC **bg_gc, guint32 *bg_rgb) -{ - gboolean lighter_row; - - lighter_row = (list->details->alternate_row_colors - ? (row_index % 2) != 0 : TRUE); - - if (style) { - *style = GTK_WIDGET (list)->style; - } - - if (state == GTK_STATE_SELECTED) { - if (fg_gc != NULL) { - *fg_gc = GTK_WIDGET (list)->style->fg_gc[state]; - } - if (bg_gc != NULL) { - if (column_index == selected_column_index (list)) { - *bg_gc = list->details->selection_medium_color; - } else { - *bg_gc = list->details->selection_light_color; - } - } - if (bg_rgb != NULL) { - if (column_index == selected_column_index (list)) { - *bg_rgb = list->details->selection_medium_color_rgb; - } else { - *bg_rgb = list->details->selection_light_color_rgb; - } - } - - - return; - } - - if (fg_gc != NULL) { - *fg_gc = GTK_WIDGET (list)->style->fg_gc[state]; - } - - if (bg_gc != NULL) { - if (column_index == selected_column_index (list)) { - if (lighter_row) { - *bg_gc = list->details->cell_selected_lighter_background; - } else { - *bg_gc = list->details->cell_selected_darker_background; - } - } else { - if (lighter_row) { - *bg_gc = list->details->cell_lighter_background; - } else { - *bg_gc = list->details->cell_darker_background; - } - } - } - if (bg_rgb != NULL) { - if (column_index == selected_column_index (list)) { - if (lighter_row) { - *bg_rgb = list->details->cell_selected_lighter_background_rgb; - } else { - *bg_rgb = list->details->cell_selected_darker_background_rgb; - } - } else { - if (lighter_row) { - *bg_rgb = list->details->cell_lighter_background_rgb; - } else { - *bg_rgb = list->details->cell_darker_background_rgb; - } - } - } -} - -void -nautilus_list_set_alternate_row_colors (NautilusList *list, - gboolean state) -{ - list->details->alternate_row_colors = state; -} - -void -nautilus_list_set_background_color_offsets (NautilusList *list, - long background_offset, - long selection_offset) -{ - g_return_if_fail (background_offset < 0 - || (gulong) background_offset < sizeof (GtkStyle)); - g_return_if_fail (selection_offset < 0 - || (gulong) selection_offset < sizeof (GtkStyle)); - - if (background_offset >= 0) { - list->details->background_color_offset = background_offset; - } - if (selection_offset >= 0) { - list->details->selection_color_offset = selection_offset; - } -} - -int -nautilus_list_draw_cell_pixbuf (NautilusList *list, GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, guint32 bg_rgb, - GdkPixbuf *pixbuf, int x, int y) -{ - GdkRectangle image_rectangle; - GdkRectangle intersect_rectangle; - GdkPixbuf *composited; - - image_rectangle.width = gdk_pixbuf_get_width (pixbuf); - image_rectangle.height = gdk_pixbuf_get_height (pixbuf); - image_rectangle.x = x; - image_rectangle.y = y; - - if (!gdk_rectangle_intersect (clip_rectangle, &image_rectangle, &intersect_rectangle)) { - return x; - } - - if (list && nautilus_list_is_anti_aliased (list)) { - /* Composite a version of the pixbuf with the background color */ - composited = gdk_pixbuf_composite_color_simple (pixbuf, - image_rectangle.width, - image_rectangle.height, - GDK_INTERP_BILINEAR, - 255, 64, - bg_rgb, bg_rgb); - if (composited == NULL) { - return x; - } - - gdk_pixbuf_render_to_drawable (composited, window, fg_gc, - intersect_rectangle.x - x, - intersect_rectangle.y - y, - image_rectangle.x, image_rectangle.y, - intersect_rectangle.width, - intersect_rectangle.height, - GDK_RGB_DITHER_MAX, 0, 0); - - gdk_pixbuf_unref (composited); - - } else { - - gdk_pixbuf_render_to_drawable_alpha (pixbuf, window, - intersect_rectangle.x - x, - intersect_rectangle.y - y, - image_rectangle.x, image_rectangle.y, - intersect_rectangle.width, - intersect_rectangle.height, - GDK_PIXBUF_ALPHA_BILEVEL, - EEL_STANDARD_ALPHA_THRESHHOLD, - GDK_RGB_DITHER_MAX, 0, 0); - } - - return x + intersect_rectangle.width; -} - -/** - * get_cell_horizontal_start_position: - * - * Get the leftmost x value at which the contents of this cell are painted. - * - * @clist: The list in question. - * @row: The row data structure for the target cell. - * @column_index: The column of the target cell. - * @content_width: The already-computed width of the cell contents. - * - * Return value: x value at which the contents of this cell are painted. - */ -static int -get_cell_horizontal_start_position (NautilusCList *clist, NautilusCListRow *row, int column_index, int content_width) -{ - int initial_offset; - - initial_offset = clist->column[column_index].area.x + - clist->hoffset + - row->cell[column_index].horizontal; - - switch (clist->column[column_index].justification) { - case GTK_JUSTIFY_LEFT: - return initial_offset; - case GTK_JUSTIFY_RIGHT: - return initial_offset + clist->column[column_index].area.width - content_width; - case GTK_JUSTIFY_CENTER: - case GTK_JUSTIFY_FILL: - default: - return initial_offset + (clist->column[column_index].area.width - content_width)/2; - } -} - -static int -last_column_index (NautilusCList *clist) -{ - int result; - for (result = clist->columns - 1; - result >= 0 && !clist->column[result].visible; - result--) { - } - - return result; -} - -void -nautilus_list_get_cell_rectangle (NautilusList *list, int row_index, int column_index, GdkRectangle *result) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - result->x = clist->column[column_index].area.x + clist->hoffset; - result->y = ROW_TOP_YPIXEL (clist, row_index); - result->width = clist->column[column_index].area.width; - result->height = clist->row_height; -} - -static void -get_cell_greater_rectangle (GdkRectangle *cell_rect, GdkRectangle *result, - gboolean last_column) -{ - *result = *cell_rect; - result->x -= COLUMN_INSET + CELL_SPACING; - result->width += 2 * COLUMN_INSET + CELL_SPACING; - if (last_column) { - result->width += CELL_SPACING; - } -} - -static void -draw_cell (NautilusCList *clist, GdkRectangle *area, int row_index, int column_index, - NautilusCListRow *row) -{ - GtkStyle *style; - GdkGC *fg_gc; - GdkGC *bg_gc; - GdkGC *text_gc; - guint32 bg_rgb; - - GList *p; - - int width; - int height; - int pixbuf_width; - int offset = 0; - int baseline; - int row_center_offset; - - GdkRectangle cell_rectangle; - GdkRectangle erase_rectangle; - GdkRectangle intersect_rectangle; - - if (!clist->column[column_index].visible) { - return; - } - - nautilus_list_get_cell_style (NAUTILUS_LIST(clist), row, row->state, row_index, - column_index, &style, &fg_gc, &bg_gc, &bg_rgb); - nautilus_list_get_cell_rectangle (NAUTILUS_LIST (clist), row_index, column_index, &cell_rectangle); - get_cell_greater_rectangle (&cell_rectangle, &erase_rectangle, - column_index == last_column_index (clist)); - - /* do we have anything do draw? */ - if (area && !gdk_rectangle_intersect (area, &erase_rectangle, &intersect_rectangle)) { - return; - } - - gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE, - erase_rectangle.x, erase_rectangle.y, - erase_rectangle.width, erase_rectangle.height); - - /* calculate real width for column justification */ - width = 0; - height = 0; - - switch ((NautilusCellType)row->cell[column_index].type) { - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - width = gdk_string_width (style->font, - NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - break; - case NAUTILUS_CELL_PIXBUF: - width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf); - break; - case NAUTILUS_CELL_PIXTEXT: - pixbuf_width = gdk_pixbuf_get_width (NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf); - height = gdk_pixbuf_get_height (NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf); - width = (pixbuf_width + - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->spacing + - gdk_string_width (style->font, NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->text)); - break; - case NAUTILUS_CELL_PIXBUF_LIST: - for (p = NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs; - p != NULL; p = p->next) { - if (width != 0) { - width += PIXBUF_LIST_SPACING; - } - width += gdk_pixbuf_get_width (p->data); - } - break; - case NAUTILUS_CELL_EMPTY: - case NAUTILUS_CELL_WIDGET: - return; - } - - offset = get_cell_horizontal_start_position (clist, row, column_index, width); - - /* Draw Text and/or Pixbuf */ - switch ((NautilusCellType) row->cell[column_index].type) { - case NAUTILUS_CELL_PIXBUF: { - NautilusList *list = NAUTILUS_LIST (clist); - GdkPixbuf *src_pixbuf, *dark_pixbuf; - - if (list->details->drag_prelight_row == row) { - - src_pixbuf = NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf; - - if (src_pixbuf != NULL) { - /* Create darkened pixbuf */ - dark_pixbuf = eel_create_darkened_pixbuf (src_pixbuf, - 0.8 * 255, - 0.8 * 255); - if (dark_pixbuf != NULL) { - nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - dark_pixbuf, offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - - gdk_pixbuf_unref (dark_pixbuf); - } - } - } else { - nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf, - offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - } - break; - } - - case NAUTILUS_CELL_PIXTEXT: - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, &cell_rectangle, fg_gc, bg_rgb, - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->pixbuf, - offset, - cell_rectangle.y + row->cell[column_index].vertical+ - (cell_rectangle.height - height) / 2); - offset += NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->spacing; - /* fall through */ - case NAUTILUS_CELL_TEXT: - case NAUTILUS_CELL_LINK_TEXT: - if (style != GTK_WIDGET (clist)->style) { - row_center_offset = (((clist->row_height - style->font->ascent - - style->font->descent - 1) / 2) + 1.5 + - style->font->ascent); - } else { - row_center_offset = clist->row_center_offset; - } - baseline = cell_rectangle.y + row_center_offset + row->cell[column_index].vertical; - - if (row->state != GTK_STATE_NORMAL) { - text_gc = NAUTILUS_LIST (clist)->details->selected_text_color; - } else if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT - && NAUTILUS_LIST (clist)->details->single_click_mode) { - /* For link text cells, draw with blue link-like color and use underline. */ - text_gc = NAUTILUS_LIST (clist)->details->link_text_color; - } else { - text_gc = NAUTILUS_LIST (clist)->details->text_color; - } - - gdk_gc_set_clip_rectangle (text_gc, &cell_rectangle); - - gdk_draw_string (clist->clist_window, style->font, text_gc, - offset, - baseline, - ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_PIXTEXT) ? - NAUTILUS_CELL_PIXTEXT (row->cell[column_index])->text : - NAUTILUS_CELL_TEXT (row->cell[column_index])->text); - - if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_LINK_TEXT - && NAUTILUS_LIST (clist)->details->single_click_mode) { - gdk_draw_line (clist->clist_window, text_gc, - offset, baseline + 1, - offset + width, baseline + 1); - } - - gdk_gc_set_clip_rectangle (text_gc, NULL); - break; - - case NAUTILUS_CELL_PIXBUF_LIST: { - guint pixbuf_width; - guint ellipsis_width; - - ellipsis_width = gdk_string_width (style->font, "..."); - - for (p = NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs; p != NULL; p = p->next) { - pixbuf_width = gdk_pixbuf_get_width (p->data); - - if ((p->next != NULL && (int) (pixbuf_width + ellipsis_width) >= - cell_rectangle.x + cell_rectangle.width - offset) - || ((int) pixbuf_width >= cell_rectangle.x + cell_rectangle.width - offset)) { - /* Not enough room for this icon & ellipsis, just draw ellipsis. */ - - gdk_draw_string (clist->clist_window, style->font, fg_gc, - offset, - cell_rectangle.y + cell_rectangle.height/2, - "..."); - - break; - } - - height = gdk_pixbuf_get_height (p->data); - - offset = nautilus_list_draw_cell_pixbuf (NAUTILUS_LIST (clist), clist->clist_window, - &cell_rectangle, - fg_gc, bg_rgb, p->data, - offset, - cell_rectangle.y + row->cell[column_index].vertical + - (cell_rectangle.height - height) / 2); - - offset += PIXBUF_LIST_SPACING; - } - break; - } - case NAUTILUS_CELL_EMPTY: - case NAUTILUS_CELL_WIDGET: - break; - } -} - -static void -draw_row (NautilusCList *clist, GdkRectangle *area, int row_index, NautilusCListRow *row) -{ - GtkWidget *widget; - GdkRectangle row_rectangle; - GdkRectangle extended_row_rectangle; - GdkRectangle intersect_rectangle; - int colum_index; - - g_return_if_fail (clist != NULL); - - /* bail now if we arn't drawable yet */ - if (!GTK_WIDGET_DRAWABLE (clist) || row_index < 0 || row_index >= clist->rows) { - return; - } - - widget = GTK_WIDGET (clist); - - /* if the function is passed the pointer to the row instead of null, - * it avoids this expensive lookup - */ - if (!row) { - row = ROW_ELEMENT (clist, row_index)->data; - } - - /* rectangle of the entire row */ - row_rectangle.x = 0; - row_rectangle.y = ROW_TOP_YPIXEL (clist, row_index); - row_rectangle.width = clist->clist_window_width; - row_rectangle.height = clist->row_height; - - /* rectangle of the entire row including spacing above and below the row */ - extended_row_rectangle.x = 0; - extended_row_rectangle.y = row_rectangle.y - CELL_SPACING; - extended_row_rectangle.width = row_rectangle.width; - extended_row_rectangle.height = row_rectangle.height + CELL_SPACING; - - if (row->state == GTK_STATE_NORMAL) { - if (row->fg_set) { - gdk_gc_set_foreground (clist->fg_gc, &row->foreground); - } - if (row->bg_set) { - gdk_gc_set_foreground (clist->bg_gc, &row->background); - } - } - - intersect_rectangle = extended_row_rectangle; - /* check if we have something to draw */ - if (area && !gdk_rectangle_intersect (area, &extended_row_rectangle, &intersect_rectangle)) { - return; - } - - - /* iterate and draw all the columns (row cells) and draw their contents */ - for (colum_index = 0; colum_index < clist->columns; colum_index++) { - draw_cell (clist, area, row_index, colum_index, row); - } - - /* draw the row spacer */ - gdk_draw_rectangle (clist->clist_window, - NAUTILUS_LIST (clist)->details->cell_divider_color, - TRUE, - intersect_rectangle.x, - extended_row_rectangle.y, - intersect_rectangle.width, - CELL_SPACING); - gdk_draw_rectangle (clist->clist_window, - NAUTILUS_LIST (clist)->details->cell_divider_color, - TRUE, - intersect_rectangle.x, - row_rectangle.y + row_rectangle.height, - intersect_rectangle.width, - CELL_SPACING); - - /* draw focus rectangle */ - if (clist->focus_row == row_index - && GTK_WIDGET_CAN_FOCUS (widget) && GTK_WIDGET_HAS_FOCUS (widget)) { - if (!area) { - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, row_rectangle.height - 1); - } else if (gdk_rectangle_intersect (area, &row_rectangle, &intersect_rectangle)) { - gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle); - gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, - row_rectangle.x, row_rectangle.y, - row_rectangle.width - 1, - row_rectangle.height - 1); - gdk_gc_set_clip_rectangle (clist->xor_gc, NULL); - } - } -} - -static void -rectangle_intersect (const GdkRectangle *source1, const GdkRectangle *source2, GdkRectangle *result) -{ - /* convenience call that returns result with defined values even if sources are disjucnt */ - if (!gdk_rectangle_intersect ((GdkRectangle *)source1, (GdkRectangle *)source2, result)) { - result->width = 0; - result->height = 0; - } -} - -static void -nautilus_list_clear_from_row (NautilusList *list, int row_index, - GdkRectangle *area) -{ - NautilusCList *clist; - GdkRectangle clip_area, tmp; - GdkRectangle first_column_plain_rectangle, selected_column_rectangle, - second_column_plain_rectangle; - GdkGC *selected_column_gc; - GdkGC *plain_column_gc; - - g_assert (NAUTILUS_IS_LIST (list)); - g_assert (area); - - clist = NAUTILUS_CLIST (list); - - /* calculate the area we need to erase */ - clip_area = *area; - clip_area.y = ROW_TOP_YPIXEL (clist, row_index); - if (clip_area.y < 0) { - clip_area.y = 0; - } - if (clip_area.y - area->y < area->height) { - clip_area.height = area->height - (clip_area.y - area->y); - } else { - clip_area.height = 0; - } - - if (clip_area.height <= 0) { - /* nothing visible to erase */ - return; - } - - /* calculate the rectangle for the selected column */ - nautilus_list_get_cell_rectangle (list, 0, selected_column_index (list), &tmp); - get_cell_greater_rectangle (&tmp, &tmp, - selected_column_index (list) == last_column_index (clist)); - tmp.y = clip_area.y; - tmp.height = clip_area.height; - - rectangle_intersect (&clip_area, &tmp, &selected_column_rectangle); - - /* calculate the first rectangle */ - tmp = clip_area; - if (selected_column_rectangle.x > tmp.x) { - tmp.width = selected_column_rectangle.x - tmp.x; - } else { - tmp.width = selected_column_rectangle.x - tmp.x; - } - rectangle_intersect (&clip_area, &tmp, &first_column_plain_rectangle); - - - /* calculate the last rectangle */ - tmp = clip_area; - tmp.x = selected_column_rectangle.x + selected_column_rectangle.width; - rectangle_intersect (&clip_area, &tmp, &second_column_plain_rectangle); - - /* get the colors for drawing */ - get_column_background (list, &selected_column_gc, &plain_column_gc); - - /* draw the first column if non-empty */ - if (first_column_plain_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, plain_column_gc, TRUE, - first_column_plain_rectangle.x, first_column_plain_rectangle.y, - first_column_plain_rectangle.width, first_column_plain_rectangle.height); - } - /* draw the selected column if non-empty */ - if (selected_column_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, selected_column_gc, TRUE, - selected_column_rectangle.x, selected_column_rectangle.y, - selected_column_rectangle.width, selected_column_rectangle.height); - } - /* draw the last column if non-empty */ - if (second_column_plain_rectangle.width > 0) { - gdk_draw_rectangle (clist->clist_window, plain_column_gc, TRUE, - second_column_plain_rectangle.x, second_column_plain_rectangle.y, - second_column_plain_rectangle.width, second_column_plain_rectangle.height); - } -} - -static void -draw_rows (NautilusCList *clist, GdkRectangle *area) -{ - GList *list; - int row_index; - int first_row; - int last_row; - - g_assert (area != NULL); - - if (clist->row_height == 0 || !GTK_WIDGET_DRAWABLE (clist)) { - return; - } - - first_row = ROW_FROM_YPIXEL (clist, area->y); - last_row = ROW_FROM_YPIXEL (clist, area->y + area->height); - - /* this is a small special case which exposes the bottom cell line - * on the last row -- it might go away if I change the wall the cell - * spacings are drawn - */ - if (clist->rows == first_row) { - first_row--; - } - - list = ROW_ELEMENT (clist, first_row); - for (row_index = first_row; row_index <= last_row ; row_index++) { - if (list == NULL) { - break; - } - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, - draw_row, (clist, area, row_index, list->data)); - list = list->next; - } - - nautilus_list_clear_from_row (NAUTILUS_LIST (clist), - row_index, area); -} - -static void -draw_all (NautilusCList *clist) -{ - GdkRectangle area; - area.x = 0; - area.y = 0; - area.width = clist->clist_window_width; - area.height = clist->clist_window_height; - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, &area)); -} - -static void -nautilus_list_draw (GtkWidget *widget, GdkRectangle *area) -{ - NautilusCList *clist; - NautilusList *list; - - g_assert (NAUTILUS_IS_LIST (widget)); - g_assert (area != NULL); - - clist = NAUTILUS_CLIST (widget); - list = NAUTILUS_LIST (widget); - - nautilus_list_setup_style_colors (NAUTILUS_LIST (widget)); - - if (GTK_WIDGET_DRAWABLE (widget)) { - int border_width; - border_width = GTK_CONTAINER (widget)->border_width; - gdk_window_clear_area (widget->window, - area->x - border_width, - area->y - border_width, - area->width, area->height); - - gtk_draw_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, clist->shadow_type, - 0, 0, - clist->clist_window_width + - (2 * widget->style->klass->xthickness), - clist->clist_window_height + - (2 * widget->style->klass->ythickness) + - clist->column_title_area.height); - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, area)); - - /* Draw the title if it exists */ - if (list->details->title) { - GdkRectangle draw_area; - - if (gtk_widget_intersect (list->details->title, - area, &draw_area)) { - gtk_widget_draw (list->details->title, &draw_area); - } - } - } -} - -static int -nautilus_list_expose (GtkWidget *widget, GdkEventExpose *event) -{ - NautilusCList *clist; - - g_assert (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - nautilus_list_setup_style_colors (NAUTILUS_LIST (widget)); - - if (GTK_WIDGET_DRAWABLE (widget)) { - - gtk_draw_shadow (widget->style, widget->window, - GTK_STATE_NORMAL, clist->shadow_type, - 0, 0, - clist->clist_window_width + - (2 * widget->style->klass->xthickness), - clist->clist_window_height + - (2 * widget->style->klass->ythickness) + - clist->column_title_area.height); - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, - (clist, &event->area)); - } - - return FALSE; -} - -static void -nautilus_list_resize_column (NautilusCList *clist, int column_index, int width) -{ - /* override resize column to invalidate the title */ - NautilusList *list; - - list = NAUTILUS_LIST (clist); - - gtk_widget_queue_draw (list->details->title); - - EEL_CALL_PARENT (NAUTILUS_CLIST_CLASS, resize_column, (clist, column_index, width)); -} - - -/** - * nautilus_list_mark_cell_as_link: - * - * Mark a text cell as a link cell. Link cells are drawn differently, - * and activate rather than select on single-click. The cell must - * be a text cell (not a pixbuf cell or one of the other types). - * - * @list: The NautilusList in question. - * @column_index: The column of the desired cell. - * @row: The row of the desired cell. - */ -void -nautilus_list_mark_cell_as_link (NautilusList *list, - int row_index, - int column_index) -{ - NautilusCListRow *row; - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - g_return_if_fail (row_index >= 0 && row_index < clist->rows); - g_return_if_fail (column_index >= 0 && column_index < clist->columns); - - row = ROW_ELEMENT (clist, row_index)->data; - - /* - * We only support changing text cells to links. Maybe someday - * we'll support pixbuf or pixtext link cells too. - */ - g_return_if_fail ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_TEXT); - - row->cell[column_index].type = NAUTILUS_CELL_LINK_TEXT; -} - - -static gboolean -nautilus_list_set_cell_contents (NautilusCList *clist, - NautilusCListRow *row, - int column_index, - NautilusCellType type, - const gchar *text, - guint8 spacing, - GdkPixbuf *pixbuf) -{ - gboolean result; - - /* - * Note that we don't do the auto_resize bracketing here that's done - * in the parent class. It would require copying over huge additional - * chunks of code. We might decide we need that someday, but the - * chances seem larger that we'll switch away from CList first. - */ - - /* Clean up old data, which parent class doesn't know about. */ - if ((NautilusCellType)row->cell[column_index].type == NAUTILUS_CELL_PIXBUF_LIST) { - eel_gdk_pixbuf_list_free (NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs); - } - - result = EEL_CALL_PARENT_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, set_cell_contents, - (clist, row, column_index, type, text, spacing, pixbuf)); - - if ((NautilusCellType)type == NAUTILUS_CELL_PIXBUF_LIST) { - row->cell[column_index].type = NAUTILUS_CELL_PIXBUF_LIST; - /* Hideously, we concealed our list of pixbufs in the pixbuf parameter. */ - NAUTILUS_CELL_PIXBUF_LIST (row->cell[column_index])->pixbufs = (GList *)pixbuf; - } - - return result; -} - -static void -set_list_cell (NautilusList *list, - int row_index, int column_index, - NautilusCellType type, - gpointer data) -{ - NautilusCList *clist; - NautilusCListRow *row; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - clist = NAUTILUS_CLIST (list); - - if (row_index < 0 || row_index >= clist->rows) { - return; - } - - if (column_index < 0 || column_index >= clist->columns) { - return; - } - - row = ROW_ELEMENT (clist, row_index)->data; - - /* - * We have to go through the set_cell_contents bottleneck, which only - * allows expected parameter types. Since our pixbuf is not an - * expected parameter type, we have to sneak it in by casting it into - * one of the expected parameters. - */ - if (EEL_CALL_METHOD_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, clist, set_cell_contents, - (clist, row, column_index, type, NULL, 0, data))) { - /* redraw the list if it's not frozen */ - if (CLIST_UNFROZEN (clist) - && nautilus_clist_row_is_visible (clist, row_index) != GTK_VISIBILITY_NONE) { - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_row, - (clist, NULL, row_index, row)); - } - } -} - -static gpointer -get_list_cell (NautilusList *list, - int row_index, int column_index, - NautilusCellType type) -{ - NautilusCList *clist; - NautilusCListRow *row; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), NULL); - - clist = NAUTILUS_CLIST (list); - - if (row_index < 0 || row_index >= clist->rows) { - return NULL; - } - - if (column_index < 0 || column_index >= clist->columns) { - return NULL; - } - - row = ROW_ELEMENT (clist, row_index)->data; - - if (row->cell[column_index].type == type) { - return NAUTILUS_CELL_PIXBUF (row->cell[column_index])->pixbuf; - } - - return NULL; -} - -/** - * nautilus_list_set_pixbuf_list: - * - * Set the contents of a cell to a list of similarly-sized GdkPixbufs. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - * @pixbufs: A GList of GdkPixbufs. - */ -void -nautilus_list_set_pixbuf_list (NautilusList *list, - int row_index, - int column_index, - GList *pixbufs) -{ - set_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF_LIST, pixbufs); -} - -/** - * nautilus_list_set_pixbuf: - * - * Similar to nautilus_list_set_pixbuf_list, but with a single pixbuf. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - * @pixbuf: A GdkPixbuf. - */ -void -nautilus_list_set_pixbuf (NautilusList *list, - int row_index, - int column_index, - GdkPixbuf *pixbuf) -{ - set_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF, pixbuf); -} - -/** - * nautilus_list_get_pixbuf: - * - * Return the pixbuf stored in the specified position, or a null pointer - * if the cell isn't a pixbuf. - * - * @list: The NautilusList in question. - * @row: The row of the target cell. - * @column_index: The column of the target cell. - */ -GdkPixbuf * -nautilus_list_get_pixbuf (NautilusList *list, - int row_index, - int column_index) -{ - return get_list_cell (list, row_index, column_index, - NAUTILUS_CELL_PIXBUF); -} - -static void -nautilus_list_track_new_column_width (NautilusCList *clist, int column_index, int new_width) -{ - NautilusList *list; - GdkRectangle area; - - list = NAUTILUS_LIST (clist); - - /* pin new_width to min and max values */ - if (new_width < MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width)) - new_width = MAX (COLUMN_MIN_WIDTH, clist->column[column_index].min_width); - if (clist->column[column_index].max_width >= 0 && - new_width > clist->column[column_index].max_width) - new_width = clist->column[column_index].max_width; - - /* check to see if the pinned value is still different */ - if (clist->column[column_index].width == new_width) - return; - - /* set the new width */ - clist->column[column_index].width = new_width; - clist->column[column_index].width_set = TRUE; - - size_allocate_columns (clist, TRUE); - size_allocate_title_buttons (clist); - - /* redraw the invalid columns */ - if (CLIST_UNFROZEN (clist)) { - area = clist->column_title_area; - area.x = clist->column[column_index].area.x; - area.height += clist->clist_window_height; - - EEL_CALL_METHOD (NAUTILUS_CLIST_CLASS, clist, draw_rows, (clist, &area)); - } -} - -static void -nautilus_list_drag_start (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusList *list; - GdkDragContext *context; - GdkPixbuf *pixbuf; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - list = NAUTILUS_LIST (widget); - - if (list->details->drag_info == NULL) { - return; - } - - list->details->drag_started = TRUE; - list->details->dnd_select_pending = FALSE; - /* reinit from last dnd if there was one */ - list->details->drag_info->got_drop_data_type = FALSE; - nautilus_drag_destroy_selection_list (list->details->drag_info->selection_list); - list->details->drag_info->selection_list = NULL; - - context = gtk_drag_begin (widget, list->details->drag_info->target_list, - list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON - ? GDK_ACTION_ASK - : GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK, - list->details->dnd_press_button, - (GdkEvent *) event); - - pixbuf = NULL; - gtk_signal_emit (GTK_OBJECT (list), list_signals[GET_DRAG_PIXBUF], - list->details->button_down_row, &pixbuf); - - if (pixbuf != NULL) { - /* FIXME: We can do better than 10,10. */ - eel_drag_set_icon_pixbuf (context, pixbuf, 10, 10); - - gdk_pixbuf_unref (pixbuf); - } -} - -/* Our handler for motion_notify events. We override all of GtkCList's broken - * behavior. - */ -static int -nautilus_list_motion (GtkWidget *widget, GdkEventMotion *event) -{ - NautilusList *list; - NautilusCList *clist; - - g_return_val_if_fail (NAUTILUS_IS_LIST (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - list = NAUTILUS_LIST (widget); - clist = NAUTILUS_CLIST (widget); - - if (event->window != clist->clist_window) { - return EEL_CALL_PARENT_WITH_RETURN_VALUE - (GTK_WIDGET_CLASS, motion_notify_event, (widget, event)); - } - - if (!((list->details->dnd_press_button == ACTION_BUTTON && (event->state & GDK_BUTTON1_MASK)) - || (list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON && (event->state & GDK_BUTTON3_MASK)))) - return FALSE; - - /* This is the same threshold value that is used in gtkdnd.c */ - - if (MAX (abs (list->details->dnd_press_x - event->x), - abs (list->details->dnd_press_y - event->y)) <= 3) { - return FALSE; - } - - - if (list->details->button_down_row < 0) { - /* We didn't hit a row, just blank space */ - return FALSE; - } - - g_assert (list->details->button_down_row < clist->rows); - if (!list->details->drag_started) { - if (list->details->dnd_press_button == CONTEXTUAL_MENU_BUTTON) { - gtk_timeout_remove (list->details->context_menu_timeout_id); - } - nautilus_list_drag_start (widget, event); - } - - return TRUE; -} - -void -nautilus_list_column_resize_track_start (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - clist->drag_pos = column_index; -} - -void -nautilus_list_column_resize_track (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - int x; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - - gtk_widget_get_pointer (widget, &x, NULL); - nautilus_list_track_new_column_width (clist, column_index, - new_column_width (clist, column_index, &x)); -} - -void -nautilus_list_column_resize_track_end (GtkWidget *widget, int column_index) -{ - NautilusCList *clist; - - g_return_if_fail (NAUTILUS_IS_LIST (widget)); - - clist = NAUTILUS_CLIST (widget); - clist->drag_pos = -1; -} - -/* FIXME bugzilla.eazel.com 7445: Needs to become a shared function */ -static void -get_data_on_first_target_we_support (GtkWidget *widget, GdkDragContext *context, guint32 time) -{ - GList *target; - - if (nautilus_list_dnd_target_list == NULL) - nautilus_list_dnd_target_list = gtk_target_list_new (nautilus_list_dnd_target_table, - EEL_N_ELEMENTS (nautilus_list_dnd_target_table)); - - for (target = context->targets; target != NULL; target = target->next) { - guint dummy_info; - GdkAtom target_atom = GPOINTER_TO_UINT (target->data); - - if (gtk_target_list_find (nautilus_list_dnd_target_list, - target_atom, - &dummy_info)) { - gtk_drag_get_data (GTK_WIDGET (widget), context, - target_atom, - time); - break; - } - } -} - - -static void -nautilus_list_ensure_drag_data (NautilusList *list, - GdkDragContext *context, - guint32 time) -{ - if (!list->details->drag_info->got_drop_data_type) { - get_data_on_first_target_we_support (GTK_WIDGET (list), context, time); - } -} - -static void -nautilus_list_drag_end (GtkWidget *widget, GdkDragContext *context) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - drag_info->got_drop_data_type = FALSE; - nautilus_drag_destroy_selection_list (list->details->drag_info->selection_list); - list->details->drag_info->selection_list = NULL; - -} - -static void -nautilus_list_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - nautilus_list_stop_auto_scroll (NAUTILUS_LIST (list)); - - nautilus_list_set_drag_prelight_row (list, -1); -} - -gboolean -nautilus_list_rejects_dropped_icons (NautilusList *list) -{ - return list->details->rejects_dropped_icons; -} - -void -nautilus_list_set_rejects_dropped_icons (NautilusList *list, gboolean new_value) -{ - list->details->rejects_dropped_icons = new_value; -} - -static void -nautilus_list_get_drop_action (NautilusList *list, - GdkDragContext *context, - int x, int y, - int *default_action, - int *non_default_action) -{ - NautilusDragInfo *drag_info; - - drag_info = NAUTILUS_LIST (list)->details->drag_info; - - /* FIXME bugzilla.eazel.com 2569: Too much code copied from nautilus-icon-dnd.c. - * Need to share more. - */ - - if (!drag_info->got_drop_data_type) { - /* drag_data_received didn't get called yet */ - return; - } - - /* get those actions from a subclass of this object */ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[GET_DEFAULT_ACTION], - default_action, - non_default_action, - context, - drag_info->selection_list, - x, y, - drag_info->data_type); - -} - - -static void -nautilus_list_real_scroll (NautilusList *list, float delta_x, float delta_y) -{ - GtkAdjustment *hadj, *vadj; - - hadj = nautilus_clist_get_hadjustment (NAUTILUS_CLIST (list)); - vadj = nautilus_clist_get_vadjustment (NAUTILUS_CLIST (list)); - - eel_gtk_adjustment_set_value (hadj, hadj->value + (int)delta_x); - eel_gtk_adjustment_set_value (vadj, vadj->value + (int)delta_y); - -} - -static int -auto_scroll_timeout_callback (gpointer data) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - GtkWidget *widget; - float x_scroll_delta, y_scroll_delta; - - g_assert (NAUTILUS_IS_LIST (data)); - widget = GTK_WIDGET (data); - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - if (drag_info->waiting_to_autoscroll - && drag_info->start_auto_scroll_in > eel_get_system_time()) { - /* not yet */ - return TRUE; - } - - drag_info->waiting_to_autoscroll = FALSE; - - nautilus_drag_autoscroll_calculate_delta (widget, &x_scroll_delta, &y_scroll_delta); - - nautilus_list_real_scroll (list, x_scroll_delta, y_scroll_delta); - - return TRUE; -} - -static void -nautilus_list_start_auto_scroll (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - - nautilus_drag_autoscroll_start (list->details->drag_info, - GTK_WIDGET (list), - auto_scroll_timeout_callback, - list); -} - -static void -nautilus_list_stop_auto_scroll (NautilusList *list) -{ - g_assert (NAUTILUS_IS_LIST (list)); - - nautilus_drag_autoscroll_stop (list->details->drag_info); -} - -static void -nautilus_list_prelight_if_necessary (NautilusList *list, GdkDragContext *context, - int x, int y, guint time) -{ - gboolean is_prelight_necessary; - - /* should we prelight the current row ? */ - gtk_signal_emit (GTK_OBJECT (list), - list_signals[HANDLE_DRAGGED_ITEMS], - context->action, - list->details->drag_info->selection_list, - x, y, - list->details->drag_info->data_type, - &is_prelight_necessary); - - if (is_prelight_necessary) { - nautilus_list_set_drag_prelight_row (list, y); - } else { - nautilus_list_set_drag_prelight_row (list, -1); - } -} - - -static gboolean -nautilus_list_drag_motion (GtkWidget *widget, GdkDragContext *context, - int x, int y, guint time) -{ - NautilusList *list; - int default_action, non_default_action, resulting_action; - - list = NAUTILUS_LIST (widget); - - nautilus_list_ensure_drag_data (list, context, time); - - nautilus_list_start_auto_scroll (NAUTILUS_LIST (widget)); - - default_action = 0; - non_default_action = 0; - - nautilus_list_get_drop_action (list, context, x, y, &default_action, &non_default_action); - resulting_action = nautilus_drag_modifier_based_action (default_action, non_default_action); - - gdk_drag_status (context, resulting_action, time); - - nautilus_list_prelight_if_necessary (list, context, x, y, time); - - return TRUE; -} - -static gboolean -nautilus_list_drag_drop (GtkWidget *widget, GdkDragContext *context, - int x, int y, guint time) -{ - NautilusList *list; - - list = NAUTILUS_LIST (widget); - - /* make sure that drag_data_received is going to be called - after this event and will do the actual actions */ - list->details->drag_info->drop_occured = TRUE; - get_data_on_first_target_we_support (widget, context, time); - - return FALSE; -} - -static void -nautilus_list_receive_dropped_icons (NautilusList *list, - int action, - GtkSelectionData *data, - int x, int y, guint info) -{ - NautilusDragInfo *drag_info; - GList *selected_items; - - g_assert (NAUTILUS_IS_LIST (list)); - drag_info = list->details->drag_info; - - /* Put selection list in local variable and NULL the global one - * so it doesn't get munged in a modal popup-menu event loop - * in the handle_dropped_item handler. - */ - selected_items = drag_info->selection_list; - drag_info->selection_list = NULL; - gtk_signal_emit (GTK_OBJECT (list), list_signals[HANDLE_DROPPED_ITEMS], - action, selected_items, x, y, info); - nautilus_drag_destroy_selection_list (selected_items); -} - -static void -nautilus_list_receive_dropped_keyword (NautilusList *list, - int action, - GtkSelectionData *data, - int x, int y, - guint info) -{ - GList *emblems; - - emblems = g_list_prepend (NULL, (char *)data->data); - - gtk_signal_emit (GTK_OBJECT (list), - list_signals[HANDLE_DROPPED_ITEMS], - action, emblems, x, y, info); - - g_list_free (emblems); -} - - - -static void -nautilus_list_drag_data_received (GtkWidget *widget, GdkDragContext *context, - int x, int y, GtkSelectionData *data, - guint info, guint time) -{ - NautilusList *list; - NautilusDragInfo *drag_info; - - list = NAUTILUS_LIST (widget); - drag_info = list->details->drag_info; - - - if (!drag_info->got_drop_data_type) { - - drag_info->data_type = info; - drag_info->got_drop_data_type = TRUE; - drag_info->selection_data = data; - - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); - break; - case NAUTILUS_ICON_DND_URI_LIST: - drag_info->selection_list = nautilus_drag_build_selection_list (data); - break; - case NAUTILUS_ICON_DND_COLOR: - break; - case NAUTILUS_ICON_DND_BGIMAGE: - break; - case NAUTILUS_ICON_DND_KEYWORD: - break; - default: - break; - } - } - - if (drag_info->drop_occured) { - - switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - nautilus_list_receive_dropped_icons - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_URI_LIST: - nautilus_list_receive_dropped_icons - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_COLOR: - eel_background_receive_dropped_color - (eel_get_widget_background (widget), - widget, x, y, data); - nautilus_list_setup_style_colors (NAUTILUS_LIST (list)); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_BGIMAGE: - eel_background_receive_dropped_background_image - (eel_get_widget_background (widget), - (char *)data->data); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - case NAUTILUS_ICON_DND_KEYWORD: - nautilus_list_receive_dropped_keyword - (NAUTILUS_LIST (list), - context->action, data, x, y, info); - gtk_drag_finish (context, TRUE, FALSE, time); - break; - default: - gtk_drag_finish (context, FALSE, FALSE, time); - break; - } - - - drag_info->drop_occured = FALSE; - drag_info->got_drop_data_type = FALSE; - } -} - - - -/* Our handler for the clear signal of the clist. We have to reset the anchor - * to null. - */ -static void -nautilus_list_clear (NautilusCList *clist) -{ - NautilusList *list; - - g_return_if_fail (NAUTILUS_IS_LIST (clist)); - - list = NAUTILUS_LIST (clist); - list->details->anchor_row = -1; - - EEL_CALL_PARENT (NAUTILUS_CLIST_CLASS, clear, (clist)); -} - - -/** - * nautilus_list_new_with_titles: - * @columns: The number of columns in the list - * @titles: The titles for the columns - * - * Return value: The newly-created file list. - **/ -GtkWidget * -nautilus_list_new_with_titles (int columns, const char * const *titles) -{ - NautilusList *list; - - list = NAUTILUS_LIST (gtk_type_new (nautilus_list_get_type ())); - nautilus_clist_construct (NAUTILUS_CLIST (list), columns, NULL); - if (titles) { - NautilusCList *clist; - int index; - - clist = NAUTILUS_CLIST(list); - - for (index = 0; index < columns; index++) { - clist->column[index].title = g_strdup (titles[index]); - } - } - - nautilus_clist_set_selection_mode (NAUTILUS_CLIST (list), - GTK_SELECTION_MULTIPLE); - - return GTK_WIDGET (list); -} - -NautilusCListRow * -nautilus_list_row_at (NautilusList *list, int y) -{ - NautilusCList *clist; - int row_index, column_index; - - clist = NAUTILUS_CLIST (list); - y -= (GTK_CONTAINER (list)->border_width + - GTK_WIDGET (list)->style->klass->ythickness + - clist->column_title_area.height); - - if (!nautilus_clist_get_selection_info (clist, 10, y, &row_index, &column_index)) { - return NULL; - } - - return g_list_nth (clist->row_list, row_index)->data; -} - -GList * -nautilus_list_get_selection (NautilusList *list) -{ - GList *retval; - GList *p; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), NULL); - - retval = NULL; - for (p = NAUTILUS_CLIST (list)->row_list; p != NULL; p = p->next) { - NautilusCListRow *row; - - row = p->data; - if (row->state == GTK_STATE_SELECTED) - retval = g_list_prepend (retval, row->data); - } - - return retval; -} - -void -nautilus_list_set_selection (NautilusList *list, GList *selection) -{ - gboolean selection_changed; - GHashTable *hash; - GList *p; - int i; - NautilusCListRow *row; - - g_return_if_fail (NAUTILUS_IS_LIST (list)); - - selection_changed = FALSE; - - hash = g_hash_table_new (NULL, NULL); - for (p = selection; p != NULL; p = p->next) { - g_hash_table_insert (hash, p->data, p->data); - } - - for (p = NAUTILUS_CLIST (list)->row_list, i = 0; p != NULL; p = p->next, i++) { - row = p->data; - selection_changed |= row_set_selected (list, i, row, g_hash_table_lookup (hash, row->data) != NULL); - } - - g_hash_table_destroy (hash); - - if (selection_changed) { - emit_selection_changed (list); - } -} - -void -nautilus_list_each_selected_row (NautilusList *list, NautilusEachRowFunction function, - gpointer data) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_assert (NAUTILUS_IS_LIST (list)); - - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; p != NULL; p = p->next, row_index++) { - row = p->data; - if (row->state != GTK_STATE_SELECTED) - continue; - - if (!function(row, row_index, data)) - return; - } -} - -/** - * nautilus_list_get_first_selected_row: - * - * Get the index of the first selected row, or -1 if no rows are selected. - * @list: Any NautilusList - **/ -int -nautilus_list_get_first_selected_row (NautilusList *list) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), -1); - - for (p = NAUTILUS_CLIST (list)->row_list, row_index = 0; - p != NULL; - p = p->next, ++row_index) { - row = p->data; - if (row->state == GTK_STATE_SELECTED) - return row_index; - } - - return -1; -} - -/** - * nautilus_list_get_last_selected_row: - * - * Get the index of the last selected row, or -1 if no rows are selected. - * @list: Any GtkCList - **/ -int -nautilus_list_get_last_selected_row (NautilusList *list) -{ - NautilusCListRow *row; - GList *p; - int row_index; - - g_return_val_if_fail (NAUTILUS_IS_LIST (list), -1); - - for (p = NAUTILUS_CLIST (list)->row_list_end, row_index = NAUTILUS_CLIST (list)->rows - 1; p != NULL; p = p->prev, --row_index) { - row = p->data; - if (row->state == GTK_STATE_SELECTED) { - return row_index; - } - } - - return -1; -} - -/* Workaround for a bug in GtkCList's insert_row. - * It sets the focus row to 0 if there is exactly one row, - * even if there was no focus on entry. - * Although this works for focus, there may still be a problem - * with selection. - */ -static int -insert_row (NautilusCList *list, int row_index, char *text[]) -{ - gboolean had_focus; - int result; - - had_focus = list->focus_row != -1; - - result = EEL_CALL_PARENT_WITH_RETURN_VALUE - (NAUTILUS_CLIST_CLASS, insert_row, (list, row_index, text)); - - if (!had_focus) { - list->focus_row = -1; - } - - return result; -} - - -void -nautilus_list_set_drag_prelight_row (NautilusList *list, int y) -{ - NautilusCList *clist; - NautilusCListRow *row, *last_row; - GdkRectangle rect; - int row_index; - - clist = NAUTILUS_CLIST (list); - - row = NULL; - - if (y >= 0) { - row = nautilus_list_row_at (list, y); - } - - if (row != list->details->drag_prelight_row) { - last_row = list->details->drag_prelight_row; - list->details->drag_prelight_row = row; - - /* Redraw old cell */ - if (last_row != NULL) { - row_index = g_list_index (clist->row_list, last_row); - nautilus_list_get_cell_rectangle (list, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (list), &rect); - } - - /* Draw new cell */ - if (list->details->drag_prelight_row != NULL) { - row_index = g_list_index (clist->row_list, list->details->drag_prelight_row); - nautilus_list_get_cell_rectangle (list, row_index, 0, &rect); - gtk_widget_draw (GTK_WIDGET (list), &rect); - } - } -} - -void -nautilus_list_get_initial_drag_offset (NautilusList *list, int *x, int *y) -{ - *x = list->details->dnd_press_x;// + NAUTILUS_CLIST (list)->hoffset; - *y = list->details->dnd_press_y;// + NAUTILUS_CLIST (list)->voffset; -} - diff --git a/libnautilus-private/nautilus-list.h b/libnautilus-private/nautilus-list.h deleted file mode 100644 index b9d43d588..000000000 --- a/libnautilus-private/nautilus-list.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* nautilus-list.h: Enhanced version of GtkCList for Nautilus. - - Copyright (C) 1999, 2000 Free Software Foundation - Copyright (C) 2000, 2001 Eazel, Inc. - - The Gnome Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: Federico Mena <federico@nuclecu.unam.mx>, - Ettore Perazzoli <ettore@gnu.org>, - John Sullivan <sullivan@eazel.com>, - Pavel Cisler <pavel@eazel.com> - */ - -#ifndef NAUTILUS_LIST_H -#define NAUTILUS_LIST_H - -#include <libgnome/gnome-defs.h> -#include <cut-n-paste-code/widgets/nautilusclist/nautilusclist.h> - -/* This class was originally derived from the GtkFList class in gmc. - */ - -/* It is sad that we have to do this. GtkCList's behavior is so broken that we - * have to override all the event handlers and implement our own selection - * behavior. Sigh. -Federico - */ - -/* pointer casting for cells */ -#define NAUTILUS_CELL_PIXBUF_LIST(cell) ((NautilusCellPixbufList *) &(cell)) -/* no #define for NAUTILUS_CELL_LINK_TEXT, use GTK_CELL_TEXT instead */ - -/* returns the GList item for the nth row */ -#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \ - (clist)->row_list_end : \ - g_list_nth ((clist)->row_list, (row))) - -typedef struct NautilusCellPixbufList NautilusCellPixbufList; -/* no struct for NautilusCellLinkText, use GtkCellText instead */ - -/* Since the info in each cell must fit in the GtkCell struct that CList defines, - * we disguise ours in the GtkCellWidget format, with our pixbufs list where - * the widget would be. - */ -struct NautilusCellPixbufList -{ - NautilusCellType type; - - gint16 vertical; - gint16 horizontal; - - GtkStyle *style; - - GList *pixbufs; /* list of GdkPixbuf * */ -}; - -#define NAUTILUS_TYPE_LIST (nautilus_list_get_type ()) -#define NAUTILUS_LIST(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_LIST, NautilusList)) -#define NAUTILUS_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_LIST, NautilusListClass)) -#define NAUTILUS_IS_LIST(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_LIST)) -#define NAUTILUS_IS_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_LIST)) - -typedef struct NautilusList NautilusList; -typedef struct NautilusListClass NautilusListClass; -typedef struct NautilusListDetails NautilusListDetails; - -struct NautilusList { - NautilusCList clist; - NautilusListDetails *details; -}; - -struct NautilusListClass { - NautilusCListClass parent_class; - - /* Signal: invoke the popup menu for selected items */ - void (* context_click_selection) (NautilusList *list, - GdkEventButton *event); - - /* Signal: invoke the popup menu for empty areas */ - void (* context_click_background) (NautilusList *list, - GdkEventButton *event); - - /* Signal: announce that one or more items have been activated. */ - void (* activate) (NautilusList *list, GList *row_data_list); - - /* Signal: selection has changed */ - void (* selection_changed) (NautilusList *list); - - /* column resize tracking calls */ - void (* column_resize_track_start) (GtkWidget *widget, int column); - void (* column_resize_track) (GtkWidget *widget, int column); - void (* column_resize_track_end) (GtkWidget *widget, int column); - void (* select_matching_name) (GtkWidget *widget, const char *); - void (* select_previous_name) (GtkWidget *widget); - void (* select_next_name) (GtkWidget *widget); - GdkPixbuf (* get_drag_pixbuf) (NautilusList *list, int row_index); - int (* get_sort_column_index) (NautilusList *list); - - /* dnd handling. defer the semantics of dnd to the application side, not nautilus-list */ - gboolean (* handle_dragged_items) (GtkWidget *widget, - int action, - GList *drop_data, - int x, - int y, - guint info); - void (* handle_dropped_items) (GtkWidget *widget, - int action, - GList *drop_data, - int x, - int y, - guint info); - void (* get_default_action) (GtkWidget *widget, - int *default_action, - int *non_default_action, - GdkDragContext *context, - GList *drop_data, - int x, - int y, - guint info); - -}; - -typedef gboolean (* NautilusEachRowFunction) (NautilusCListRow *, int, gpointer); - -GtkType nautilus_list_get_type (void); -GtkWidget * nautilus_list_new_with_titles (int columns, - const char * const *titles); -void nautilus_list_initialize_dnd (NautilusList *list); -GList * nautilus_list_get_selection (NautilusList *list); -void nautilus_list_set_selection (NautilusList *list, - GList *selection); -void nautilus_list_reveal_row (NautilusList *list, - int row); -gboolean nautilus_list_is_row_selected (NautilusList *list, - int row); -void nautilus_list_get_cell_rectangle (NautilusList *clist, - int row_index, - int column_index, - GdkRectangle *result); -void nautilus_list_set_pixbuf_list (NautilusList *list, - gint row, - gint column, - GList *pixbufs); -void nautilus_list_set_pixbuf (NautilusList *list, - int row_index, - int column_index, - GdkPixbuf *pixbuf); -GdkPixbuf *nautilus_list_get_pixbuf (NautilusList *list, - int row_index, - int column_index); -void nautilus_list_mark_cell_as_link (NautilusList *list, - gint row, - gint column); -void nautilus_list_set_single_click_mode (NautilusList *list, - gboolean single_click_mode); -void nautilus_list_select_row (NautilusList *list, - int row); -NautilusCListRow *nautilus_list_row_at (NautilusList *list, - int y); -int nautilus_list_get_first_selected_row (NautilusList *list); -int nautilus_list_get_last_selected_row (NautilusList *list); -void nautilus_list_each_selected_row (NautilusList *list, - NautilusEachRowFunction function, - gpointer data); -gboolean nautilus_list_rejects_dropped_icons (NautilusList *list); -void nautilus_list_set_rejects_dropped_icons (NautilusList *list, - gboolean new_value); -void nautilus_list_set_drag_prelight_row (NautilusList *list, - int y); -void nautilus_list_get_initial_drag_offset (NautilusList *list, - int *x, - int *y); - -void nautilus_list_set_anti_aliased_mode (NautilusList *list, - gboolean anti_aliased_mode); -gboolean nautilus_list_is_anti_aliased (NautilusList *list); - -int nautilus_list_draw_cell_pixbuf (NautilusList *list, - GdkWindow *window, - GdkRectangle *clip_rectangle, - GdkGC *fg_gc, - guint32 bg_rgb, - GdkPixbuf *pixbuf, - int x, - int y); -void nautilus_list_get_cell_style (NautilusList *list, - NautilusCListRow *row, - int state, - int row_index, - int column_index, - GtkStyle **style, - GdkGC **fg_gc, - GdkGC **bg_gc, - guint32 *bg_rgb); -void nautilus_list_set_alternate_row_colors (NautilusList *list, - gboolean state); -void nautilus_list_set_background_color_offsets (NautilusList *list, - long background_offset, - long selection_offset); - -#endif /* NAUTILUS_LIST_H */ - - - - - diff --git a/nautilus-installer/install-lib/Makefile.am b/nautilus-installer/install-lib/Makefile.am index 20f2c8521..315d8978a 100644 --- a/nautilus-installer/install-lib/Makefile.am +++ b/nautilus-installer/install-lib/Makefile.am @@ -48,7 +48,6 @@ TRILOBITE_HDRS = \ trilobite-core-messaging.h \ trilobite-core-network.h \ trilobite-core-utils.h \ - trilobite-file-utilities.h \ trilobite-i18n.h \ trilobite-md5-tools.h \ trilobite-redirect.h \ diff --git a/nautilus-installer/libtrilobite/Makefile.am b/nautilus-installer/libtrilobite/Makefile.am index 9e26e8d03..11c628481 100644 --- a/nautilus-installer/libtrilobite/Makefile.am +++ b/nautilus-installer/libtrilobite/Makefile.am @@ -36,7 +36,6 @@ TRILOBITE_HDRS = \ trilobite-core-messaging.h \ trilobite-core-network.h \ trilobite-core-utils.h \ - trilobite-file-utilities.h \ trilobite-i18n-utils.h \ trilobite-md5-tools.h \ trilobite-redirect.h \ diff --git a/po/ChangeLog b/po/ChangeLog index 1e777bb99..e98fee2dc 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,3 +1,8 @@ +2001-04-04 Ramiro Estrugo <ramiro@eazel.com> + + * POTFILES.in: + Remove a retired file. + 2001-04-04 Christian Rose <menthos@menthos.com> * sv.po: Updated Swedish translation. diff --git a/po/POTFILES.in b/po/POTFILES.in index fc167f3df..f81ff42f8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -92,7 +92,6 @@ icons/crux_eggplant/crux_eggplant.xml icons/default.xml icons/gnome/gnome.xml icons/villanova/villanova.xml -libnautilus-extensions/nautilus-drag.c libnautilus-extensions/nautilus-druid.c libnautilus-extensions/nautilus-druid-page-eazel.c libnautilus-extensions/nautilus-entry.c diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 1a3b1d8e0..21b751dea 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -60,8 +60,8 @@ #include <libnautilus-extensions/nautilus-bonobo-extensions.h> #include <libnautilus-extensions/nautilus-directory-background.h> #include <libnautilus-extensions/nautilus-directory.h> -#include <libnautilus-extensions/nautilus-drag.h> #include <libnautilus-extensions/nautilus-file-attributes.h> +#include <libnautilus-extensions/nautilus-file-dnd.h> #include <libnautilus-extensions/nautilus-file-operations.h> #include <libnautilus-extensions/nautilus-file-utilities.h> #include <libnautilus-extensions/nautilus-global-preferences.h> diff --git a/src/file-manager/fm-list-view.c b/src/file-manager/fm-list-view.c index 385756421..211bea6b2 100644 --- a/src/file-manager/fm-list-view.c +++ b/src/file-manager/fm-list-view.c @@ -27,25 +27,26 @@ #include "fm-list-view-private.h" #include "fm-properties-window.h" +#include <eel/eel-art-extensions.h> +#include <eel/eel-art-gtk-extensions.h> +#include <eel/eel-dnd.h> +#include <eel/eel-gdk-pixbuf-extensions.h> +#include <eel/eel-glib-extensions.h> +#include <eel/eel-gtk-extensions.h> +#include <eel/eel-gtk-macros.h> +#include <eel/eel-list.h> +#include <eel/eel-string.h> #include <gtk/gtkhbox.h> #include <gtk/gtkmenu.h> #include <gtk/gtkmenuitem.h> #include <libgnome/gnome-i18n.h> #include <libgnomeui/gnome-uidefs.h> -#include <eel/eel-art-gtk-extensions.h> -#include <eel/eel-art-extensions.h> #include <libnautilus-extensions/nautilus-directory-background.h> -#include <libnautilus-extensions/nautilus-drag.h> +#include <libnautilus-extensions/nautilus-file-dnd.h> #include <libnautilus-extensions/nautilus-font-factory.h> -#include <eel/eel-glib-extensions.h> #include <libnautilus-extensions/nautilus-global-preferences.h> -#include <eel/eel-gdk-pixbuf-extensions.h> -#include <eel/eel-gtk-extensions.h> -#include <eel/eel-gtk-macros.h> #include <libnautilus-extensions/nautilus-icon-factory.h> -#include <libnautilus-extensions/nautilus-list.h> #include <libnautilus-extensions/nautilus-metadata.h> -#include <eel/eel-string.h> struct FMListViewDetails { int sort_column; @@ -99,10 +100,10 @@ struct FMListViewDetails { #define DOWN_INDICATOR_VALUE 2 /* forward declarations */ -static void list_activate_callback (NautilusList *list, +static void list_activate_callback (EelList *list, GList *file_list, gpointer data); -static void list_selection_changed_callback (NautilusList *list, +static void list_selection_changed_callback (EelList *list, gpointer data); static void fm_list_view_add_file (FMDirectoryView *view, NautilusFile *file); @@ -158,7 +159,7 @@ static int get_column_from_attribute (FMListVie const char *attribute); static int get_sort_column_from_attribute (FMListView *list_view, const char *attribute); -static NautilusList * get_list (FMListView *list_view); +static EelList * get_list (FMListView *list_view); static void update_icons (FMListView *list_view); static int get_number_of_columns (FMListView *list_view); static int get_link_column (FMListView *list_view); @@ -277,7 +278,7 @@ fm_list_view_initialize (gpointer object, gpointer klass) list_view, GTK_OBJECT (list_view)); - /* It's important to not create the NautilusList (with a call + /* It's important to not create the EelList (with a call * to create_list) until later, when the function pointers * have been initialized by the subclass. */ @@ -298,14 +299,14 @@ fm_list_view_destroy (GtkObject *object) } static void -column_clicked_callback (NautilusCList *clist, int column, gpointer user_data) +column_clicked_callback (EelCList *clist, int column, gpointer user_data) { FMListView *list_view; gboolean reversed; - g_return_if_fail (NAUTILUS_IS_LIST (clist)); + g_return_if_fail (EEL_IS_LIST (clist)); g_return_if_fail (FM_IS_LIST_VIEW (user_data)); - g_return_if_fail (get_list (FM_LIST_VIEW (user_data)) == NAUTILUS_LIST (clist)); + g_return_if_fail (get_list (FM_LIST_VIEW (user_data)) == EEL_LIST (clist)); list_view = FM_LIST_VIEW (user_data); @@ -348,21 +349,21 @@ list_view_compare_files_for_sort (gconstpointer a, gconstpointer b, gpointer cal /* CList-style compare function */ static int -fm_list_view_compare_rows (NautilusCList *clist, +fm_list_view_compare_rows (EelCList *clist, gconstpointer ptr1, gconstpointer ptr2) { - NautilusCListRow *row1; - NautilusCListRow *row2; + EelCListRow *row1; + EelCListRow *row2; NautilusFile *file1; NautilusFile *file2; FMListView *list_view; - g_return_val_if_fail (NAUTILUS_IS_LIST (clist), 0); + g_return_val_if_fail (EEL_IS_LIST (clist), 0); g_return_val_if_fail (clist->sort_column != LIST_VIEW_COLUMN_NONE, 0); - row1 = (NautilusCListRow *) ptr1; - row2 = (NautilusCListRow *) ptr2; + row1 = (EelCListRow *) ptr1; + row2 = (EelCListRow *) ptr2; /* All of our rows have a NautilusFile in the row data. Therefore if * the row data is NULL it must be a row that's being added, and hasn't @@ -393,13 +394,13 @@ fm_list_view_compare_rows (NautilusCList *clist, static int compare_rows_by_name (gconstpointer a, gconstpointer b, void *callback_data) { - NautilusCListRow *row1; - NautilusCListRow *row2; + EelCListRow *row1; + EelCListRow *row2; g_assert (callback_data == NULL); - row1 = (NautilusCListRow *) a; - row2 = (NautilusCListRow *) b; + row1 = (EelCListRow *) a; + row2 = (EelCListRow *) b; return nautilus_file_compare_for_sort (NAUTILUS_FILE (row1->data), @@ -411,10 +412,10 @@ compare_rows_by_name (gconstpointer a, gconstpointer b, void *callback_data) static int match_row_name (gconstpointer a, void *callback_data) { - NautilusCListRow *row; + EelCListRow *row; const char *pattern; - row = (NautilusCListRow *) a; + row = (EelCListRow *) a; pattern = (const char *) callback_data; return nautilus_file_compare_name @@ -422,11 +423,11 @@ match_row_name (gconstpointer a, void *callback_data) } static void -context_click_selection_callback (NautilusCList *clist, +context_click_selection_callback (EelCList *clist, GdkEventButton *event, FMListView *list_view) { - g_assert (NAUTILUS_IS_CLIST (clist)); + g_assert (EEL_IS_CLIST (clist)); g_assert (FM_IS_LIST_VIEW (list_view)); fm_directory_view_pop_up_selection_context_menu @@ -434,7 +435,7 @@ context_click_selection_callback (NautilusCList *clist, } static void -context_click_background_callback (NautilusCList *clist, +context_click_background_callback (EelCList *clist, GdkEventButton *event, FMListView *list_view) { @@ -449,12 +450,12 @@ make_sorted_row_array (GtkWidget *widget) { GPtrArray *array; - if (NAUTILUS_CLIST (widget)->rows == 0) + if (EEL_CLIST (widget)->rows == 0) /* empty list, no work */ return NULL; /* build an array of rows */ - array = eel_g_ptr_array_new_from_list (NAUTILUS_CLIST (widget)->row_list); + array = eel_g_ptr_array_new_from_list (EEL_CLIST (widget)->row_list); /* sort the array by the names of the NautilusFile objects */ eel_g_ptr_array_sort (array, compare_rows_by_name, NULL); @@ -465,7 +466,7 @@ make_sorted_row_array (GtkWidget *widget) static void select_row_common (GtkWidget *widget, const GPtrArray *array, guint array_row_index) { - NautilusCListRow *row; + EelCListRow *row; int list_row_index; if (array_row_index >= array->len) { @@ -477,12 +478,12 @@ select_row_common (GtkWidget *widget, const GPtrArray *array, guint array_row_in g_assert (row != NULL); - list_row_index = g_list_index (NAUTILUS_CLIST (widget)->row_list, row); + list_row_index = g_list_index (EEL_CLIST (widget)->row_list, row); g_assert (list_row_index >= 0); - g_assert (list_row_index < NAUTILUS_CLIST (widget)->rows); + g_assert (list_row_index < EEL_CLIST (widget)->rows); /* select the matching row */ - nautilus_list_select_row (NAUTILUS_LIST (widget), list_row_index); + eel_list_select_row (EEL_LIST (widget), list_row_index); } static void @@ -491,7 +492,7 @@ select_matching_name_callback (GtkWidget *widget, const char *pattern, FMListVie GPtrArray *array; int array_row_index; - g_assert (NAUTILUS_IS_LIST (widget)); + g_assert (EEL_IS_LIST (widget)); g_assert (gtk_object_get_data (GTK_OBJECT (widget), PENDING_USER_DATA_KEY) == NULL); /* build an array of rows, sorted by name */ @@ -520,7 +521,7 @@ select_previous_next_common (GtkWidget *widget, FMListView *list_view, gboolean int first_selected_row; int last_selected_row; - g_assert (NAUTILUS_IS_LIST (widget)); + g_assert (EEL_IS_LIST (widget)); g_assert (gtk_object_get_data (GTK_OBJECT (widget), PENDING_USER_DATA_KEY) == NULL); /* build an array of rows */ @@ -535,7 +536,7 @@ select_previous_next_common (GtkWidget *widget, FMListView *list_view, gboolean first_selected_row = -1; last_selected_row = -1; for (index = 0; index < array->len; index++) { - if (((NautilusCListRow *) g_ptr_array_index (array, index))->state == GTK_STATE_SELECTED) { + if (((EelCListRow *) g_ptr_array_index (array, index))->state == GTK_STATE_SELECTED) { if (first_selected_row < 0) { first_selected_row = index; } @@ -592,11 +593,11 @@ select_next_name_callback (GtkWidget *widget, FMListView *list_view) } static NautilusFile * -fm_list_nautilus_file_at (NautilusList *list, int x, int y) +fm_list_nautilus_file_at (EelList *list, int x, int y) { - NautilusCListRow *row; + EelCListRow *row; - row = nautilus_list_row_at (list, y); + row = eel_list_row_at (list, y); if (row == NULL) { return NULL; } @@ -604,7 +605,7 @@ fm_list_nautilus_file_at (NautilusList *list, int x, int y) } static void -fm_list_receive_dropped_icons (NautilusList *list, +fm_list_receive_dropped_icons (EelList *list, int x, int y, int action, @@ -622,7 +623,7 @@ fm_list_receive_dropped_icons (NautilusList *list, directory_view = FM_DIRECTORY_VIEW (list_view); if (action == GDK_ACTION_ASK) { - action = nautilus_drag_drop_action_ask + action = eel_drag_drop_action_ask (GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK); } @@ -644,7 +645,7 @@ fm_list_receive_dropped_icons (NautilusList *list, if (target_item_uri != NULL && (action != GDK_ACTION_MOVE /* don't actually move the items if they are in the same directory */ - || !nautilus_drag_items_local (target_item_uri, drop_data))) { + || !eel_drag_items_local (target_item_uri, drop_data))) { /* build a list of URIs to copy */ for (p = drop_data; p != NULL; p = p->next) { /* do a shallow copy of all the uri strings of the copied files */ @@ -669,7 +670,7 @@ fm_list_receive_dropped_icons (NautilusList *list, } static void -fm_list_receive_dropped_keyword (NautilusList *list, char* keyword, int x, int y) +fm_list_receive_dropped_keyword (EelList *list, char* keyword, int x, int y) { NautilusFile *file; @@ -682,7 +683,7 @@ fm_list_receive_dropped_keyword (NautilusList *list, char* keyword, int x, int y static gboolean -fm_list_handle_dragged_items (NautilusList *list, +fm_list_handle_dragged_items (EelList *list, int action, GList *drop_data, int x, int y, guint info, @@ -692,8 +693,8 @@ fm_list_handle_dragged_items (NautilusList *list, NautilusFile *target_item; switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_URI_LIST: /* Find the item we dragged over and determine if it can accept dropped items */ target_item = fm_list_nautilus_file_at (list, x, y); if (target_item != NULL && nautilus_drag_can_accept_items (target_item, drop_data)) { @@ -703,11 +704,11 @@ fm_list_handle_dragged_items (NautilusList *list, } break; - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: ret_val = TRUE; break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: default: ret_val = FALSE; break; @@ -718,7 +719,7 @@ fm_list_handle_dragged_items (NautilusList *list, static char * -nautilus_list_find_icon_list_drop_target (NautilusList *list, +eel_list_find_icon_list_drop_target (EelList *list, int x, int y, GList *selection_list, FMListView *list_view) @@ -726,11 +727,11 @@ nautilus_list_find_icon_list_drop_target (NautilusList *list, NautilusFile *file; char *uri; - if (nautilus_list_rejects_dropped_icons (list)) { + if (eel_list_rejects_dropped_icons (list)) { return NULL; } - file = fm_list_nautilus_file_at (NAUTILUS_LIST (list), x, y); + file = fm_list_nautilus_file_at (EEL_LIST (list), x, y); if (file == NULL) { uri = fm_directory_view_get_uri (FM_DIRECTORY_VIEW (list_view)); return uri; @@ -750,7 +751,7 @@ nautilus_list_find_icon_list_drop_target (NautilusList *list, static void -fm_list_get_default_action (NautilusList *list, +fm_list_get_default_action (EelList *list, int *default_action, int *non_default_action, GdkDragContext *context, @@ -760,19 +761,19 @@ fm_list_get_default_action (NautilusList *list, { char *drop_target; - g_assert (NAUTILUS_IS_LIST (list)); + g_assert (EEL_IS_LIST (list)); /* FIXME bugzilla.eazel.com 2569: Too much code copied from nautilus-icon-dnd.c. Need to share more. */ switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: if (drop_data == NULL) { *default_action = 0; *non_default_action = 0; return; } - drop_target = nautilus_list_find_icon_list_drop_target (list, x, y, + drop_target = eel_list_find_icon_list_drop_target (list, x, y, drop_data, list_view); if (drop_target == NULL) { @@ -781,18 +782,18 @@ fm_list_get_default_action (NautilusList *list, return; } - nautilus_drag_default_drop_action_for_icons (context, drop_target, + eel_drag_default_drop_action_for_icons (context, drop_target, drop_data, default_action, non_default_action); break; - case NAUTILUS_ICON_DND_COLOR: - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_COLOR: + case EEL_ICON_DND_BGIMAGE: *default_action = context->suggested_action; *non_default_action = context->suggested_action; break; - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: *default_action = context->suggested_action; *non_default_action = context->suggested_action; break; @@ -801,7 +802,7 @@ fm_list_get_default_action (NautilusList *list, static void -fm_list_handle_dropped_items (NautilusList *list, +fm_list_handle_dropped_items (EelList *list, int action, GList *drop_data, int x, int y, guint info, @@ -812,18 +813,18 @@ fm_list_handle_dropped_items (NautilusList *list, */ switch (info) { - case NAUTILUS_ICON_DND_GNOME_ICON_LIST: - case NAUTILUS_ICON_DND_URI_LIST: + case EEL_ICON_DND_GNOME_ICON_LIST: + case EEL_ICON_DND_URI_LIST: fm_list_receive_dropped_icons (list, x, y, action, drop_data, list_view); break; - case NAUTILUS_ICON_DND_COLOR: + case EEL_ICON_DND_COLOR: break; - case NAUTILUS_ICON_DND_BGIMAGE: + case EEL_ICON_DND_BGIMAGE: break; - case NAUTILUS_ICON_DND_KEYWORD: + case EEL_ICON_DND_KEYWORD: fm_list_receive_dropped_keyword (list, (char *)drop_data->data, x, y); break; default: @@ -835,13 +836,13 @@ fm_list_handle_dropped_items (NautilusList *list, /* iteration glue struct */ typedef struct { - NautilusDragEachSelectedItemDataGet iteratee; - NautilusList *list; + EelDragEachSelectedItemDataGet iteratee; + EelList *list; gpointer iteratee_data; } RowGetDataBinderContext; static gboolean -row_get_data_binder (NautilusCListRow *row, int row_index, gpointer data) +row_get_data_binder (EelCListRow *row, int row_index, gpointer data) { RowGetDataBinderContext *context; char *uri; @@ -858,9 +859,9 @@ row_get_data_binder (NautilusCListRow *row, int row_index, gpointer data) return TRUE; } - nautilus_list_get_cell_rectangle (context->list, row_index, 0, &cell_rectangle); + eel_list_get_cell_rectangle (context->list, row_index, 0, &cell_rectangle); - nautilus_list_get_initial_drag_offset (context->list, &drag_offset_x, &drag_offset_y); + eel_list_get_initial_drag_offset (context->list, &drag_offset_x, &drag_offset_y); /* adjust the icons to be vertically relative to the initial mouse click position */ icon_rect = eel_art_irect_offset_by (eel_gdk_rectangle_to_art_irect (&cell_rectangle), @@ -893,17 +894,17 @@ row_get_data_binder (NautilusCListRow *row, int row_index, gpointer data) * values to the iteratee */ static void -each_icon_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee, +each_icon_get_data_binder (EelDragEachSelectedItemDataGet iteratee, gpointer iterator_context, gpointer data) { RowGetDataBinderContext context; - g_assert (NAUTILUS_IS_LIST (iterator_context)); + g_assert (EEL_IS_LIST (iterator_context)); context.iteratee = iteratee; - context.list = NAUTILUS_LIST (iterator_context); + context.list = EEL_LIST (iterator_context); context.iteratee_data = data; - nautilus_list_each_selected_row (NAUTILUS_LIST (iterator_context), + eel_list_each_selected_row (EEL_LIST (iterator_context), row_get_data_binder, &context); } @@ -913,14 +914,14 @@ fm_list_drag_data_get (GtkWidget *widget, GdkDragContext *context, FMListView *list_view) { g_assert (widget != NULL); - g_assert (NAUTILUS_IS_LIST (widget)); + g_assert (EEL_IS_LIST (widget)); g_return_if_fail (context != NULL); /* Call common function from nautilus-drag that set's up * the selection data in the right format. Pass it means to * iterate all the selected icons. */ - nautilus_drag_drag_data_get (widget, context, selection_data, + eel_drag_drag_data_get (widget, context, selection_data, info, time, widget, each_icon_get_data_binder); } @@ -929,7 +930,7 @@ fm_list_get_drag_pixbuf (GtkWidget *widget, int row_index, FMListView *list_view { g_assert (FM_IS_LIST_VIEW (list_view)); - return nautilus_list_get_pixbuf (NAUTILUS_LIST (widget), + return eel_list_get_pixbuf (EEL_LIST (widget), row_index, LIST_VIEW_COLUMN_ICON); } @@ -937,7 +938,7 @@ fm_list_get_drag_pixbuf (GtkWidget *widget, int row_index, FMListView *list_view static int fm_list_get_sort_column_index (GtkWidget *widget, FMListView *list_view) { - g_assert (NAUTILUS_IS_LIST (widget)); + g_assert (EEL_IS_LIST (widget)); return FM_LIST_VIEW (list_view)->details->sort_column; } @@ -945,7 +946,7 @@ fm_list_get_sort_column_index (GtkWidget *widget, FMListView *list_view) static void fm_list_view_update_smooth_graphics_mode (FMDirectoryView *directory_view) { - NautilusList *list; + EelList *list; gboolean smooth_graphics_mode, old_smooth_graphics_mode; g_assert (FM_IS_LIST_VIEW (directory_view)); @@ -953,11 +954,11 @@ fm_list_view_update_smooth_graphics_mode (FMDirectoryView *directory_view) list = get_list (FM_LIST_VIEW (directory_view)); g_assert (list != NULL); - old_smooth_graphics_mode = nautilus_list_is_anti_aliased (list); + old_smooth_graphics_mode = eel_list_is_anti_aliased (list); smooth_graphics_mode = nautilus_preferences_get_boolean (NAUTILUS_PREFERENCES_SMOOTH_GRAPHICS_MODE); if (old_smooth_graphics_mode != smooth_graphics_mode) { - nautilus_list_set_anti_aliased_mode (list, smooth_graphics_mode); + eel_list_set_anti_aliased_mode (list, smooth_graphics_mode); update_icons (FM_LIST_VIEW (directory_view)); } } @@ -965,7 +966,7 @@ fm_list_view_update_smooth_graphics_mode (FMDirectoryView *directory_view) static void real_sort_directories_first_changed (FMDirectoryView *directory_view) { - nautilus_clist_sort (NAUTILUS_CLIST (get_list (FM_LIST_VIEW (directory_view)))); + eel_clist_sort (EEL_CLIST (get_list (FM_LIST_VIEW (directory_view)))); } static void @@ -973,8 +974,8 @@ create_list (FMListView *list_view) { int number_of_columns; const char **titles; - NautilusList *list; - NautilusCList *clist; + EelList *list; + EelCList *clist; int i; FMListViewColumn column; @@ -987,43 +988,43 @@ create_list (FMListView *list_view) number_of_columns = get_number_of_columns (list_view); titles = get_column_titles (list_view); - list = NAUTILUS_LIST (nautilus_list_new_with_titles (get_number_of_columns (list_view), + list = EEL_LIST (eel_list_new_with_titles (get_number_of_columns (list_view), titles)); - nautilus_list_initialize_dnd (list); + eel_list_initialize_dnd (list); g_free (titles); - clist = NAUTILUS_CLIST (list); + clist = EEL_CLIST (list); - NAUTILUS_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES); + EEL_CLIST_SET_FLAG (clist, CLIST_SHOW_TITLES); for (i = 0; i < number_of_columns; ++i) { get_column_specification (list_view, i, &column); /* FIXME bugzilla.eazel.com 2532: Make a cover to do this trick. */ - nautilus_clist_set_column_max_width (clist, i, column.maximum_width); - nautilus_clist_set_column_min_width (clist, i, column.minimum_width); - /* work around broken NautilusCList that pins the max_width to be no less than + eel_clist_set_column_max_width (clist, i, column.maximum_width); + eel_clist_set_column_min_width (clist, i, column.minimum_width); + /* work around broken EelCList that pins the max_width to be no less than * the min_width instead of bumping min_width down too */ - nautilus_clist_set_column_max_width (clist, i, column.maximum_width); - nautilus_clist_set_column_width (clist, i, column.default_width); + eel_clist_set_column_max_width (clist, i, column.maximum_width); + eel_clist_set_column_width (clist, i, column.default_width); if (column.right_justified) { - /* Hack around a problem where nautilus_clist_set_column_justification + /* Hack around a problem where eel_clist_set_column_justification * crashes if there is a column title but no * column button (it should really be checking if it has a button instead) * this is an easy, dirty fix for now, will get straightened out - * with a replacement list view (alternatively, we'd fix this in NautilusCList) + * with a replacement list view (alternatively, we'd fix this in EelCList) */ char *saved_title = clist->column[i].title; clist->column[i].title = NULL; - nautilus_clist_set_column_justification (clist, i, GTK_JUSTIFY_RIGHT); + eel_clist_set_column_justification (clist, i, GTK_JUSTIFY_RIGHT); clist->column[i].title = saved_title; } } - nautilus_clist_set_auto_sort (clist, TRUE); - nautilus_clist_set_compare_func (clist, fm_list_view_compare_rows); + eel_clist_set_auto_sort (clist, TRUE); + eel_clist_set_compare_func (clist, fm_list_view_compare_rows); gtk_container_add (GTK_CONTAINER (list_view), GTK_WIDGET (list)); @@ -1070,7 +1071,7 @@ font_or_font_size_changed_callback (gpointer callback_data) void set_up_list (FMListView *list_view) { - NautilusList *list; + EelList *list; g_return_if_fail (FM_IS_LIST_VIEW (list_view)); @@ -1137,7 +1138,7 @@ set_up_list (FMListView *list_view) /* Make height tall enough for icons to look good. * This must be done after the list widget is realized, due to - * a bug/design flaw in nautilus_clist_set_row_height. Connecting to + * a bug/design flaw in eel_clist_set_row_height. Connecting to * the "realize" signal is slightly too early, so we connect to * "map". */ @@ -1154,7 +1155,7 @@ set_up_list (FMListView *list_view) * This is used only for views in which accepting file-drops is never * allowed, such as the search results view. */ - nautilus_list_set_rejects_dropped_icons + eel_list_set_rejects_dropped_icons (list, !fm_directory_view_accepts_dragged_files (FM_DIRECTORY_VIEW (list_view))); @@ -1163,11 +1164,11 @@ set_up_list (FMListView *list_view) } static void -list_activate_callback (NautilusList *list, +list_activate_callback (EelList *list, GList *file_list, gpointer data) { - g_return_if_fail (NAUTILUS_IS_LIST (list)); + g_return_if_fail (EEL_IS_LIST (list)); g_return_if_fail (FM_IS_LIST_VIEW (data)); g_return_if_fail (file_list != NULL); @@ -1175,7 +1176,7 @@ list_activate_callback (NautilusList *list, } static void -list_selection_changed_callback (NautilusList *list, +list_selection_changed_callback (EelList *list, gpointer data) { g_return_if_fail (FM_IS_LIST_VIEW (data)); @@ -1187,8 +1188,8 @@ list_selection_changed_callback (NautilusList *list, static int add_to_list (FMListView *list_view, NautilusFile *file) { - NautilusList *list; - NautilusCList *clist; + EelList *list; + EelCList *clist; char **text; int number_of_columns; int new_row; @@ -1212,20 +1213,20 @@ add_to_list (FMListView *list_view, NautilusFile *file) } list = get_list (list_view); - clist = NAUTILUS_CLIST (list); + clist = EEL_CLIST (list); /* Temporarily set user data value as hack for the problem * that compare_rows is called before the row data can be set. */ gtk_object_set_data (GTK_OBJECT (clist), PENDING_USER_DATA_KEY, file); /* Note that since list is auto-sorted new_row isn't necessarily last row. */ - new_row = nautilus_clist_append (clist, text); + new_row = eel_clist_append (clist, text); - nautilus_clist_set_row_data (clist, new_row, file); + eel_clist_set_row_data (clist, new_row, file); gtk_object_set_data (GTK_OBJECT (clist), PENDING_USER_DATA_KEY, NULL); /* Mark one column as a link. */ - nautilus_list_mark_cell_as_link (list, new_row, get_link_column (list_view)); + eel_list_mark_cell_as_link (list, new_row, get_link_column (list_view)); install_row_images (list_view, new_row); @@ -1238,7 +1239,7 @@ add_to_list (FMListView *list_view, NautilusFile *file) return new_row; } -static NautilusList * +static EelList * get_list_if_exists (FMListView *list_view) { GtkWidget *child; @@ -1250,10 +1251,10 @@ get_list_if_exists (FMListView *list_view) return NULL; } - return NAUTILUS_LIST (child); + return EEL_LIST (child); } -static NautilusList * +static EelList * get_list (FMListView *list_view) { GtkWidget *child; @@ -1266,7 +1267,7 @@ get_list (FMListView *list_view) child = GTK_BIN (list_view)->child; } - return NAUTILUS_LIST (child); + return EEL_LIST (child); } static void @@ -1346,8 +1347,8 @@ fm_list_view_get_background_widget (FMDirectoryView *view) static void fm_list_view_clear (FMDirectoryView *view) { - NautilusList *list; - NautilusCList *clist; + EelList *list; + EelCList *clist; int row; g_return_if_fail (FM_IS_LIST_VIEW (view)); @@ -1358,12 +1359,12 @@ fm_list_view_clear (FMDirectoryView *view) } /* Clear away the existing list items. */ - clist = NAUTILUS_CLIST (list); + clist = EEL_CLIST (list); for (row = 0; row < clist->rows; ++row) { fm_list_view_removing_file - (FM_LIST_VIEW (view), NAUTILUS_FILE (nautilus_clist_get_row_data (clist, row))); + (FM_LIST_VIEW (view), NAUTILUS_FILE (eel_clist_get_row_data (clist, row))); } - nautilus_clist_clear (clist); + eel_clist_clear (clist); } static void @@ -1371,7 +1372,7 @@ fm_list_view_begin_adding_files (FMDirectoryView *view) { g_return_if_fail (FM_IS_LIST_VIEW (view)); - nautilus_clist_freeze (NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view)))); + eel_clist_freeze (EEL_CLIST (get_list (FM_LIST_VIEW (view)))); } static void @@ -1417,7 +1418,7 @@ fm_list_view_add_file (FMDirectoryView *view, NautilusFile *file) g_return_if_fail (FM_IS_LIST_VIEW (view)); /* We are allowed to get the same icon twice, so don't re-add it. */ - if (nautilus_clist_find_row_from_data (NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view))), file) < 0) { + if (eel_clist_find_row_from_data (EEL_CLIST (get_list (FM_LIST_VIEW (view))), file) < 0) { add_to_list (FM_LIST_VIEW (view), file); } } @@ -1428,14 +1429,14 @@ remove_from_list (FMListView *list_view, gboolean *was_in_list, gboolean *was_selected) { - NautilusList *list; + EelList *list; int old_row; g_assert (was_in_list != NULL); g_assert (was_selected != NULL); list = get_list (list_view); - old_row = nautilus_clist_find_row_from_data (NAUTILUS_CLIST (list), file); + old_row = eel_clist_find_row_from_data (EEL_CLIST (list), file); /* Sometimes this might be called on files that are no longer in * the list. This happens when a NautilusFile has file_changed called @@ -1453,9 +1454,9 @@ remove_from_list (FMListView *list_view, } *was_in_list = TRUE; - *was_selected = nautilus_list_is_row_selected (list, old_row); + *was_selected = eel_list_is_row_selected (list, old_row); - nautilus_clist_remove (NAUTILUS_CLIST (list), old_row); + eel_clist_remove (EEL_CLIST (list), old_row); fm_list_view_removing_file (list_view, file); } @@ -1504,7 +1505,7 @@ static void fm_list_view_file_changed (FMDirectoryView *view, NautilusFile *file) { FMListView *list_view; - NautilusCList *clist; + EelCList *clist; int new_row; gboolean was_in_list; gboolean was_selected; @@ -1515,14 +1516,14 @@ fm_list_view_file_changed (FMDirectoryView *view, NautilusFile *file) * existing file going away. */ list_view = FM_LIST_VIEW (view); - clist = NAUTILUS_CLIST (get_list (list_view)); + clist = EEL_CLIST (get_list (list_view)); /* Ref it here so it doesn't go away entirely after we remove it * but before we reinsert it. */ nautilus_file_ref (file); - nautilus_clist_freeze (clist); + eel_clist_freeze (clist); remove_from_list (list_view, file, &was_in_list, &was_selected); @@ -1530,11 +1531,11 @@ fm_list_view_file_changed (FMDirectoryView *view, NautilusFile *file) new_row = add_to_list (list_view, file); if (was_selected) { - nautilus_clist_select_row (clist, new_row, -1); + eel_clist_select_row (clist, new_row, -1); } } - nautilus_clist_thaw (clist); + eel_clist_thaw (clist); /* Unref to match our keep-it-alive-for-this-function ref. */ nautilus_file_unref (file); @@ -1545,7 +1546,7 @@ fm_list_view_done_adding_files (FMDirectoryView *view) { g_return_if_fail (FM_IS_LIST_VIEW (view)); - nautilus_clist_thaw (NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view)))); + eel_clist_thaw (EEL_CLIST (get_list (FM_LIST_VIEW (view)))); } static guint @@ -1562,7 +1563,7 @@ real_is_empty (FMDirectoryView *view) { g_assert (FM_IS_LIST_VIEW (view)); - return NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view)))->rows == 0; + return EEL_CLIST (get_list (FM_LIST_VIEW (view)))->rows == 0; } static void @@ -1585,7 +1586,7 @@ fm_list_view_get_selection (FMDirectoryView *view) g_return_val_if_fail (FM_IS_LIST_VIEW (view), NULL); - list = nautilus_list_get_selection (get_list (FM_LIST_VIEW (view))); + list = eel_list_get_selection (get_list (FM_LIST_VIEW (view))); nautilus_file_list_ref (list); return list; } @@ -1604,7 +1605,7 @@ fm_list_view_set_zoom_level (FMListView *list_view, NautilusZoomLevel new_level, gboolean always_set_level) { - NautilusCList *clist; + EelCList *clist; int new_width; g_return_if_fail (FM_IS_LIST_VIEW (list_view)); @@ -1635,35 +1636,35 @@ fm_list_view_set_zoom_level (FMListView *list_view, fm_list_view_update_font (list_view); - clist = NAUTILUS_CLIST (get_list (list_view)); + clist = EEL_CLIST (get_list (list_view)); - nautilus_clist_freeze (clist); + eel_clist_freeze (clist); fm_list_view_reset_row_height (list_view); new_width = fm_list_view_get_icon_size (list_view); - /* This little dance is necessary due to bugs in NautilusCList. + /* This little dance is necessary due to bugs in EelCList. * Must set min, then max, then min, then actual width. */ /* FIXME bugzilla.eazel.com 2532: Make a cover to do this - * trick, or fix NautilusCList now that we have a copy of the + * trick, or fix EelCList now that we have a copy of the * code here in Nautilus. */ - nautilus_clist_set_column_min_width (clist, LIST_VIEW_COLUMN_ICON, new_width); - nautilus_clist_set_column_max_width (clist, LIST_VIEW_COLUMN_ICON, new_width); - nautilus_clist_set_column_min_width (clist, LIST_VIEW_COLUMN_ICON, new_width); - nautilus_clist_set_column_width (clist, LIST_VIEW_COLUMN_ICON, new_width); + eel_clist_set_column_min_width (clist, LIST_VIEW_COLUMN_ICON, new_width); + eel_clist_set_column_max_width (clist, LIST_VIEW_COLUMN_ICON, new_width); + eel_clist_set_column_min_width (clist, LIST_VIEW_COLUMN_ICON, new_width); + eel_clist_set_column_width (clist, LIST_VIEW_COLUMN_ICON, new_width); update_icons (list_view); - nautilus_clist_thaw (clist); + eel_clist_thaw (clist); } static void fm_list_view_reset_row_height (FMListView *list_view) { - nautilus_clist_set_row_height (NAUTILUS_CLIST (get_list (list_view)), + eel_clist_set_row_height (EEL_CLIST (get_list (list_view)), MAX (fm_list_view_get_icon_size (list_view), LIST_VIEW_MINIMUM_ROW_HEIGHT)); } @@ -1672,29 +1673,29 @@ fm_list_view_reset_row_height (FMListView *list_view) static void fm_list_view_select_all (FMDirectoryView *view) { - NautilusCList *clist; + EelCList *clist; g_return_if_fail (FM_IS_LIST_VIEW (view)); - clist = NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view))); - nautilus_clist_select_all (clist); + clist = EEL_CLIST (get_list (FM_LIST_VIEW (view))); + eel_clist_select_all (clist); } /* select items in the view */ static void fm_list_view_set_selection (FMDirectoryView *view, GList *selection) { - NautilusList *nlist; + EelList *nlist; g_return_if_fail (FM_IS_LIST_VIEW (view)); - nlist = NAUTILUS_LIST (get_list (FM_LIST_VIEW(view))); + nlist = EEL_LIST (get_list (FM_LIST_VIEW(view))); - nautilus_list_set_selection (nlist, selection); + eel_list_set_selection (nlist, selection); } static void fm_list_view_reveal_selection (FMDirectoryView *view) { - NautilusList *nlist; + EelList *nlist; GList *selection; g_return_if_fail (FM_IS_LIST_VIEW (view)); @@ -1702,9 +1703,9 @@ fm_list_view_reveal_selection (FMDirectoryView *view) selection = fm_directory_view_get_selection (view); /* Make sure at least one of the selected items is scrolled into view */ if (selection != NULL) { - nlist = NAUTILUS_LIST (get_list (FM_LIST_VIEW(view))); - nautilus_list_reveal_row - (nlist, nautilus_list_get_first_selected_row (nlist)); + nlist = EEL_LIST (get_list (FM_LIST_VIEW(view))); + eel_list_reveal_row + (nlist, eel_list_get_first_selected_row (nlist)); } nautilus_file_list_free (selection); @@ -1739,7 +1740,7 @@ fm_list_view_display_pending_files (FMDirectoryView *view, { GList *files_added, *files_changed, *node; NautilusFile *file; - NautilusCList *clist; + EelCList *clist; GList *selection; gboolean send_selection_change; NautilusFileSortType sort_criterion; @@ -1748,7 +1749,7 @@ fm_list_view_display_pending_files (FMDirectoryView *view, send_selection_change = FALSE; - clist = NAUTILUS_CLIST (get_list (FM_LIST_VIEW (view))); + clist = EEL_CLIST (get_list (FM_LIST_VIEW (view))); sort_criterion = get_column_sort_criterion (FM_LIST_VIEW (view), clist->sort_column); /* Sort the added items before displaying them, so that they'll be added in order, @@ -1823,13 +1824,13 @@ fm_list_view_sort_items (FMListView *list_view, int column, gboolean reversed) { - NautilusList *list; - NautilusCList *clist; + EelList *list; + EelCList *clist; NautilusFile *file; g_return_if_fail (FM_IS_LIST_VIEW (list_view)); g_return_if_fail (column >= 0); - g_return_if_fail (column < NAUTILUS_CLIST (get_list (list_view))->columns); + g_return_if_fail (column < EEL_CLIST (get_list (list_view))->columns); if (column == list_view->details->sort_column && reversed == list_view->details->sort_reversed) { @@ -1849,7 +1850,7 @@ fm_list_view_sort_items (FMListView *list_view, reversed); list = get_list (list_view); - clist = NAUTILUS_CLIST (list); + clist = EEL_CLIST (list); list_view->details->sort_column = column; @@ -1859,14 +1860,14 @@ fm_list_view_sort_items (FMListView *list_view, * games with the sort order in list_view_compare_files_for_sort * to make up for this. */ - nautilus_clist_set_sort_type (clist, reversed + eel_clist_set_sort_type (clist, reversed ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING); list_view->details->sort_reversed = reversed; } - nautilus_clist_set_sort_column (clist, column); - nautilus_clist_sort (clist); + eel_clist_set_sort_column (clist, column); + eel_clist_sort (clist); } /** @@ -1930,7 +1931,7 @@ fm_list_view_get_emblem_pixbufs_for_file (FMListView *list_view, EelStringList *emblems_to_ignore; gboolean anti_aliased; - anti_aliased = nautilus_list_is_anti_aliased (get_list (list_view)); + anti_aliased = eel_list_is_anti_aliased (get_list (list_view)); emblems_to_ignore = fm_directory_view_get_emblem_names_to_exclude (FM_DIRECTORY_VIEW (list_view)); @@ -1969,39 +1970,39 @@ fm_list_view_get_emblem_pixbufs_for_file (FMListView *list_view, void install_row_images (FMListView *list_view, guint row) { - NautilusList *list; - NautilusCList *clist; + EelList *list; + EelCList *clist; NautilusFile *file; GdkPixbuf *icon; g_return_if_fail (FM_IS_LIST_VIEW (list_view)); list = get_list (list_view); - clist = NAUTILUS_CLIST (list); - file = nautilus_clist_get_row_data (clist, row); + clist = EEL_CLIST (list); + file = eel_clist_get_row_data (clist, row); g_return_if_fail (file != NULL); /* Install the icon for this file. */ icon = (nautilus_icon_factory_get_pixbuf_for_file (file, NULL, fm_list_view_get_icon_size (list_view), - nautilus_list_is_anti_aliased (list))); - nautilus_list_set_pixbuf (list, row, LIST_VIEW_COLUMN_ICON, icon); + eel_list_is_anti_aliased (list))); + eel_list_set_pixbuf (list, row, LIST_VIEW_COLUMN_ICON, icon); /* Install any emblems for this file. */ - nautilus_list_set_pixbuf_list (list, row, LIST_VIEW_COLUMN_EMBLEMS, + eel_list_set_pixbuf_list (list, row, LIST_VIEW_COLUMN_EMBLEMS, fm_list_view_get_emblem_pixbufs_for_file (list_view, file)); } static void update_icons (FMListView *list_view) { - NautilusList *list; + EelList *list; int row; list = get_list (list_view); - for (row = 0; row < NAUTILUS_CLIST (list)->rows; ++row) { + for (row = 0; row < EEL_CLIST (list)->rows; ++row) { install_row_images (list_view, row); } } @@ -2016,7 +2017,7 @@ fm_list_view_update_click_mode (FMDirectoryView *view) click_mode = nautilus_preferences_get_integer (NAUTILUS_PREFERENCES_CLICK_POLICY); - nautilus_list_set_single_click_mode (get_list (FM_LIST_VIEW (view)), + eel_list_set_single_click_mode (get_list (FM_LIST_VIEW (view)), click_mode == NAUTILUS_CLICK_POLICY_SINGLE); } diff --git a/src/nautilus-information-panel.c b/src/nautilus-information-panel.c index ec6396754..e6b335857 100644 --- a/src/nautilus-information-panel.c +++ b/src/nautilus-information-panel.c @@ -54,7 +54,7 @@ #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libnautilus-extensions/nautilus-directory.h> -#include <libnautilus-extensions/nautilus-drag.h> +#include <libnautilus-extensions/nautilus-file-dnd.h> #include <libnautilus-extensions/nautilus-file-operations.h> #include <libnautilus-extensions/nautilus-file.h> #include <libnautilus-extensions/nautilus-global-preferences.h> diff --git a/src/nautilus-sidebar.c b/src/nautilus-sidebar.c index ec6396754..e6b335857 100644 --- a/src/nautilus-sidebar.c +++ b/src/nautilus-sidebar.c @@ -54,7 +54,7 @@ #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libnautilus-extensions/nautilus-directory.h> -#include <libnautilus-extensions/nautilus-drag.h> +#include <libnautilus-extensions/nautilus-file-dnd.h> #include <libnautilus-extensions/nautilus-file-operations.h> #include <libnautilus-extensions/nautilus-file.h> #include <libnautilus-extensions/nautilus-global-preferences.h> |