comparison src/view_dir.c @ 394:4a5e1377f3d7

Merge dirlist/dirview dnd code.
author zas_
date Thu, 17 Apr 2008 14:51:32 +0000
parents 5a73f2e1bf79
children c359fc2c5a1f
comparison
equal deleted inserted replaced
393:8d422d424d51 394:4a5e1377f3d7
10 */ 10 */
11 11
12 #include "main.h" 12 #include "main.h"
13 #include "view_dir.h" 13 #include "view_dir.h"
14 14
15 #include "dnd.h"
15 #include "dupe.h" 16 #include "dupe.h"
16 #include "filelist.h" 17 #include "filelist.h"
17 #include "layout_image.h" 18 #include "layout_image.h"
18 #include "layout_util.h" 19 #include "layout_util.h"
20 #include "ui_bookmark.h"
19 #include "ui_fileops.h" 21 #include "ui_fileops.h"
20 #include "ui_tree_edit.h" 22 #include "ui_tree_edit.h"
21 #include "ui_menu.h" 23 #include "ui_menu.h"
22 #include "utilops.h" 24 #include "utilops.h"
23 #include "view_dir_list.h" 25 #include "view_dir_list.h"
574 G_CALLBACK(vd_pop_menu_refresh_cb), vd); 576 G_CALLBACK(vd_pop_menu_refresh_cb), vd);
575 577
576 return menu; 578 return menu;
577 } 579 }
578 580
581 /*
582 *-----------------------------------------------------------------------------
583 * dnd
584 *-----------------------------------------------------------------------------
585 */
586
587 static GtkTargetEntry vd_dnd_drop_types[] = {
588 { "text/uri-list", 0, TARGET_URI_LIST }
589 };
590 static gint vd_dnd_drop_types_count = 1;
591
592 static void vd_dest_set(ViewDir *vd, gint enable)
593 {
594 if (enable)
595 {
596 gtk_drag_dest_set(vd->view,
597 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
598 vd_dnd_drop_types, vd_dnd_drop_types_count,
599 GDK_ACTION_MOVE | GDK_ACTION_COPY);
600 }
601 else
602 {
603 gtk_drag_dest_unset(vd->view);
604 }
605 }
606
607 static void vd_dnd_get(GtkWidget *widget, GdkDragContext *context,
608 GtkSelectionData *selection_data, guint info,
609 guint time, gpointer data)
610 {
611 ViewDir *vd = data;
612 GList *list;
613 gchar *uritext = NULL;
614 gint length = 0;
615
616 if (!vd->click_fd) return;
617
618 switch (info)
619 {
620 case TARGET_URI_LIST:
621 case TARGET_TEXT_PLAIN:
622 list = g_list_prepend(NULL, vd->click_fd);
623 uritext = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN));
624 g_list_free(list);
625 break;
626 }
627 if (uritext)
628 {
629 gtk_selection_data_set (selection_data, selection_data->target,
630 8, (guchar *)uritext, length);
631 g_free(uritext);
632 }
633 }
634
635 static void vd_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
636 {
637 ViewDir *vd = data;
638
639 vd_color_set(vd, vd->click_fd, TRUE);
640 vd_dest_set(vd, FALSE);
641 }
642
643 static void vd_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
644 {
645 ViewDir *vd = data;
646
647 vd_color_set(vd, vd->click_fd, FALSE);
648
649 if (vd->type == DIRVIEW_LIST && context->action == GDK_ACTION_MOVE)
650 {
651 vd_refresh(vd);
652 }
653 vd_dest_set(vd, TRUE);
654 }
655
656 static void vd_dnd_drop_receive(GtkWidget *widget,
657 GdkDragContext *context, gint x, gint y,
658 GtkSelectionData *selection_data, guint info,
659 guint time, gpointer data)
660 {
661 ViewDir *vd = data;
662 GtkTreePath *tpath;
663 GtkTreeIter iter;
664 FileData *fd = NULL;
665
666 vd->click_fd = NULL;
667
668 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), x, y,
669 &tpath, NULL, NULL, NULL))
670 {
671 GtkTreeModel *store;
672
673 store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
674 gtk_tree_model_get_iter(store, &iter, tpath);
675 switch (vd->type)
676 {
677 case DIRVIEW_LIST:
678 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1);
679 break;
680 case DIRVIEW_TREE:
681 {
682 NodeData *nd;
683 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);
684 fd = (nd) ? nd->fd : NULL;
685 };
686 break;
687 }
688 gtk_tree_path_free(tpath);
689 }
690
691 if (!fd) return;
692
693 if (info == TARGET_URI_LIST)
694 {
695 GList *list;
696 gint active;
697
698 list = uri_filelist_from_text((gchar *)selection_data->data, TRUE);
699 if (!list) return;
700
701 active = access_file(fd->path, W_OK | X_OK);
702
703 vd_color_set(vd, fd, TRUE);
704 vd->popup = vd_drop_menu(vd, active);
705 gtk_menu_popup(GTK_MENU(vd->popup), NULL, NULL, NULL, NULL, 0, time);
706
707 vd->drop_fd = fd;
708 vd->drop_list = list;
709 }
710 }
711
712 static void vd_drop_update(ViewDir *vd, gint x, gint y)
713 {
714 GtkTreePath *tpath;
715 GtkTreeIter iter;
716 FileData *fd = NULL;
717
718 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vd->view), x, y,
719 &tpath, NULL, NULL, NULL))
720 {
721 GtkTreeModel *store;
722
723 store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view));
724 gtk_tree_model_get_iter(store, &iter, tpath);
725 switch (vd->type)
726 {
727 case DIRVIEW_LIST:
728 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &fd, -1);
729 break;
730 case DIRVIEW_TREE:
731 {
732 NodeData *nd;
733 gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);
734 fd = (nd) ? nd->fd : NULL;
735 };
736 break;
737 }
738 gtk_tree_path_free(tpath);
739 }
740
741 if (fd != vd->drop_fd)
742 {
743 vd_color_set(vd, vd->drop_fd, FALSE);
744 vd_color_set(vd, fd, TRUE);
745 if (vd->type == DIRVIEW_TREE && fd) vdtree_dnd_drop_expand(vd);
746 }
747
748 vd->drop_fd = fd;
749 }
750
751 void vd_dnd_drop_scroll_cancel(ViewDir *vd)
752 {
753 if (vd->drop_scroll_id != -1) g_source_remove(vd->drop_scroll_id);
754 vd->drop_scroll_id = -1;
755 }
756
757 static gint vd_auto_scroll_idle_cb(gpointer data)
758 {
759 ViewDir *vd = data;
760
761 if (vd->drop_fd)
762 {
763 GdkWindow *window;
764 gint x, y;
765 gint w, h;
766
767 window = vd->view->window;
768 gdk_window_get_pointer(window, &x, &y, NULL);
769 gdk_drawable_get_size(window, &w, &h);
770 if (x >= 0 && x < w && y >= 0 && y < h)
771 {
772 vd_drop_update(vd, x, y);
773 }
774 }
775
776 vd->drop_scroll_id = -1;
777 return FALSE;
778 }
779
780 static gint vd_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data)
781 {
782 ViewDir *vd = data;
783
784 if (!vd->drop_fd || vd->drop_list) return FALSE;
785
786 if (vd->drop_scroll_id == -1) vd->drop_scroll_id = g_idle_add(vd_auto_scroll_idle_cb, vd);
787
788 return TRUE;
789 }
790
791 static gint vd_dnd_drop_motion(GtkWidget *widget, GdkDragContext *context,
792 gint x, gint y, guint time, gpointer data)
793 {
794 ViewDir *vd = data;
795
796 vd->click_fd = NULL;
797
798 if (gtk_drag_get_source_widget(context) == vd->view)
799 {
800 /* from same window */
801 gdk_drag_status(context, 0, time);
802 return TRUE;
803 }
804 else
805 {
806 gdk_drag_status(context, context->suggested_action, time);
807 }
808
809 vd_drop_update(vd, x, y);
810
811 if (vd->drop_fd)
812 {
813 GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vd->view));
814 widget_auto_scroll_start(vd->view, adj, -1, -1, vd_auto_scroll_notify_cb, vd);
815 }
816
817 return FALSE;
818 }
819
820 static void vd_dnd_drop_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
821 {
822 ViewDir *vd = data;
823
824 if (vd->drop_fd != vd->click_fd) vd_color_set(vd, vd->drop_fd, FALSE);
825
826 vd->drop_fd = NULL;
827
828 if (vd->type == DIRVIEW_TREE) vdtree_dnd_drop_expand_cancel(vd);
829 }
830
831 void vd_dnd_init(ViewDir *vd)
832 {
833 gtk_drag_source_set(vd->view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
834 dnd_file_drag_types, dnd_file_drag_types_count,
835 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
836 g_signal_connect(G_OBJECT(vd->view), "drag_data_get",
837 G_CALLBACK(vd_dnd_get), vd);
838 g_signal_connect(G_OBJECT(vd->view), "drag_begin",
839 G_CALLBACK(vd_dnd_begin), vd);
840 g_signal_connect(G_OBJECT(vd->view), "drag_end",
841 G_CALLBACK(vd_dnd_end), vd);
842
843 vd_dest_set(vd, TRUE);
844 g_signal_connect(G_OBJECT(vd->view), "drag_data_received",
845 G_CALLBACK(vd_dnd_drop_receive), vd);
846 g_signal_connect(G_OBJECT(vd->view), "drag_motion",
847 G_CALLBACK(vd_dnd_drop_motion), vd);
848 g_signal_connect(G_OBJECT(vd->view), "drag_leave",
849 G_CALLBACK(vd_dnd_drop_leave), vd);
850 }
851