~noskcaj/ubuntu/utopic/libfm/merge

« back to all changes in this revision

Viewing changes to src/gtk/fm-dnd-src.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Lee (李健秋)
  • Date: 2010-04-29 03:52:06 UTC
  • Revision ID: james.westby@ubuntu.com-20100429035206-qlj1jwsfcgr5mdx3
Tags: upstream-0.1.11
Import upstream version 0.1.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      fm-dnd-src.c
 
3
 *      
 
4
 *      Copyright 2009 PCMan <pcman.tw@gmail.com>
 
5
 *      
 
6
 *      This program is free software; you can redistribute it and/or modify
 
7
 *      it under the terms of the GNU General Public License as published by
 
8
 *      the Free Software Foundation; either version 2 of the License, or
 
9
 *      (at your option) any later version.
 
10
 *      
 
11
 *      This program is distributed in the hope that it will be useful,
 
12
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *      GNU General Public License for more details.
 
15
 *      
 
16
 *      You should have received a copy of the GNU General Public License
 
17
 *      along with this program; if not, write to the Free Software
 
18
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
19
 *      MA 02110-1301, USA.
 
20
 */
 
21
 
 
22
#include "fm-dnd-src.h"
 
23
 
 
24
GtkTargetEntry fm_default_dnd_src_targets[] = 
 
25
{
 
26
        {"application/x-fmlist-ptr", GTK_TARGET_SAME_APP, FM_DND_SRC_TARGET_FM_LIST},
 
27
        {"text/uri-list", 0, FM_DND_SRC_TARGET_URI_LIST}
 
28
};
 
29
 
 
30
enum
 
31
{
 
32
        DATA_GET,
 
33
        N_SIGNALS
 
34
};
 
35
 
 
36
static void fm_dnd_src_finalize                         (GObject *object);
 
37
 
 
38
static void
 
39
on_drag_data_get ( GtkWidget *src_widget,
 
40
                                   GdkDragContext *drag_context,
 
41
                                   GtkSelectionData *sel_data,
 
42
                                   guint info,
 
43
                                   guint time,
 
44
                                   FmDndSrc* ds );
 
45
 
 
46
static void
 
47
on_drag_begin ( GtkWidget *src_widget,
 
48
                                GdkDragContext *drag_context,
 
49
                                FmDndSrc* ds );
 
50
 
 
51
static void
 
52
on_drag_end ( GtkWidget *src_widget,
 
53
                          GdkDragContext *drag_context,
 
54
                          FmDndSrc* ds );
 
55
 
 
56
static guint signals[N_SIGNALS];
 
57
 
 
58
 
 
59
G_DEFINE_TYPE(FmDndSrc, fm_dnd_src, G_TYPE_OBJECT);
 
60
 
 
61
 
 
62
static void fm_dnd_src_class_init(FmDndSrcClass *klass)
 
63
{
 
64
        GObjectClass *g_object_class;
 
65
        FmDndSrcClass *dnd_src_class;
 
66
 
 
67
        g_object_class = G_OBJECT_CLASS(klass);
 
68
        g_object_class->finalize = fm_dnd_src_finalize;
 
69
 
 
70
        dnd_src_class = FM_DND_SRC_CLASS(klass);
 
71
 
 
72
        /* emitted when information of source files is needed.
 
73
         * call fm_dnd_source_set_files() in its callback to 
 
74
         * provide info of dragged source files. */
 
75
    signals[ DATA_GET ] =
 
76
        g_signal_new ( "data-get",
 
77
                       G_TYPE_FROM_CLASS( klass ),
 
78
                       G_SIGNAL_RUN_FIRST,
 
79
                       G_STRUCT_OFFSET ( FmDndSrcClass, data_get ),
 
80
                       NULL, NULL,
 
81
                       g_cclosure_marshal_VOID__VOID,
 
82
                       G_TYPE_NONE, 0 );
 
83
}
 
84
 
 
85
 
 
86
static void fm_dnd_src_finalize(GObject *object)
 
87
{
 
88
        FmDndSrc *ds;
 
89
 
 
90
        g_return_if_fail(object != NULL);
 
91
        g_return_if_fail(FM_IS_DND_SRC(object));
 
92
 
 
93
        ds = FM_DND_SRC(object);
 
94
 
 
95
        if(ds->files)
 
96
                fm_list_unref(ds->files);
 
97
 
 
98
        fm_dnd_src_set_widget(ds, NULL);
 
99
 
 
100
        G_OBJECT_CLASS(fm_dnd_src_parent_class)->finalize(object);
 
101
}
 
102
 
 
103
 
 
104
static void fm_dnd_src_init(FmDndSrc *self)
 
105
{
 
106
        
 
107
}
 
108
 
 
109
 
 
110
FmDndSrc *fm_dnd_src_new(GtkWidget* w)
 
111
{
 
112
        FmDndSrc* ds = (FmDndSrc*)g_object_new(FM_TYPE_DND_SRC, NULL);
 
113
        fm_dnd_src_set_widget(ds, w);
 
114
        return ds;
 
115
}
 
116
 
 
117
void fm_dnd_src_set_widget(FmDndSrc* ds, GtkWidget* w)
 
118
{
 
119
        if(w == ds->widget)
 
120
                return;
 
121
        if(ds->widget) /* there is an old widget connected */
 
122
        {
 
123
                g_signal_handlers_disconnect_by_func(ds->widget, on_drag_data_get, ds);
 
124
                g_signal_handlers_disconnect_by_func(ds->widget, on_drag_begin, ds);
 
125
                g_signal_handlers_disconnect_by_func(ds->widget, on_drag_end, ds);
 
126
        }
 
127
        ds->widget = w;
 
128
        if( w )
 
129
        {
 
130
        g_object_add_weak_pointer(G_OBJECT(w), &ds->widget);
 
131
                g_signal_connect(w, "drag-data-get", G_CALLBACK(on_drag_data_get), ds);
 
132
                g_signal_connect_after(w, "drag-begin", G_CALLBACK(on_drag_begin), ds);
 
133
                g_signal_connect_after(w, "drag-end", G_CALLBACK(on_drag_end), ds);
 
134
        }
 
135
}
 
136
 
 
137
void fm_dnd_src_set_files(FmDndSrc* ds, FmFileInfoList* files)
 
138
{
 
139
        ds->files = fm_list_ref(files);
 
140
}
 
141
 
 
142
void fm_dnd_src_set_file(FmDndSrc* ds, FmFileInfo* file)
 
143
{
 
144
        FmFileInfoList* files = fm_file_info_list_new();
 
145
        fm_list_push_tail(files, file);
 
146
        ds->files = files;
 
147
}
 
148
 
 
149
static void
 
150
on_drag_data_get ( GtkWidget *src_widget,
 
151
                                   GdkDragContext *drag_context,
 
152
                                   GtkSelectionData *sel_data,
 
153
                                   guint info,
 
154
                                   guint time,
 
155
                                   FmDndSrc* ds )
 
156
{
 
157
    GdkAtom type;
 
158
 
 
159
    /*  Don't call the default handler  */
 
160
    g_signal_stop_emission_by_name( src_widget, "drag-data-get" );
 
161
    drag_context->actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;
 
162
 
 
163
        type = gdk_atom_intern_static_string(fm_default_dnd_src_targets[info].target);
 
164
        switch( info )
 
165
        {
 
166
        case FM_DND_SRC_TARGET_FM_LIST:
 
167
                /* just store the pointer in GtkSelection since this is used 
 
168
                 * within the same app. */
 
169
                gtk_selection_data_set(sel_data, type, 8,
 
170
                                                                &ds->files, sizeof(gpointer));
 
171
                break;
 
172
        case FM_DND_SRC_TARGET_URI_LIST:
 
173
                {
 
174
                        gchar* uri;
 
175
                        GString* uri_list = g_string_sized_new( 8192 );
 
176
                        GList* l;
 
177
                        FmFileInfo* file;
 
178
                        char* full_path;
 
179
 
 
180
                        for( l = fm_list_peek_head_link(ds->files); l; l=l->next )
 
181
                        {
 
182
                                file = (FmFileInfo*)l->data;
 
183
                                uri = fm_path_to_uri(file->path);
 
184
                                g_string_append( uri_list, uri );
 
185
                                g_free( uri );
 
186
                                g_string_append( uri_list, "\r\n" );
 
187
                        }
 
188
                        gtk_selection_data_set ( sel_data, type, 8,
 
189
                                                                         ( guchar* ) uri_list->str, uri_list->len + 1 );
 
190
                        g_string_free( uri_list, TRUE );
 
191
                }
 
192
                break;
 
193
        }
 
194
}
 
195
 
 
196
static void
 
197
on_drag_begin ( GtkWidget *src_widget,
 
198
                                GdkDragContext *drag_context,
 
199
                                FmDndSrc* ds )
 
200
{
 
201
        /* block default handler */
 
202
 
 
203
    gtk_drag_set_icon_default( drag_context );
 
204
 
 
205
        /* FIXME: set the icon to file icon later */
 
206
        // gtk_drag_set_icon_pixbuf();
 
207
 
 
208
        /* ask drag source to provide list of source files. */
 
209
        g_signal_emit(ds, signals[DATA_GET], 0);
 
210
}
 
211
 
 
212
static void
 
213
on_drag_end ( GtkWidget *src_widget,
 
214
                          GdkDragContext *drag_context,
 
215
                          FmDndSrc* ds )
 
216
{
 
217
 
 
218
}
 
219