Mercurial > geeqie
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 |