ui/gtk/dnd.c

changeset 90
f501f0efc9a8
parent 32
e5f4d8af567e
equal deleted inserted replaced
89:2fbb3cac05a5 90:f501f0efc9a8
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 32
33 #include "dnd.h" 33 #include "dnd.h"
34 #include <cx/buffer.h> 34 #include <cx/buffer.h>
35 #include <cx/array_list.h>
35 36
36 #ifdef UI_GTK2LEGACY 37 #ifdef UI_GTK2LEGACY
37 static gboolean selection_data_set_uris(GtkSelectionData *selection_data, char **uris) { 38 static gboolean selection_data_set_uris(GtkSelectionData *selection_data, char **uris) {
38 CxBuffer *buf = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND); 39 CxBuffer *buf = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
39 char *uri; 40 char *uri;
100 } 101 }
101 return NULL; 102 return NULL;
102 } 103 }
103 */ 104 */
104 105
106 #if GTK_MAJOR_VERSION >= 4
107
105 void ui_selection_settext(UiDnD *sel, char *str, int len) { 108 void ui_selection_settext(UiDnD *sel, char *str, int len) {
106 109 if(!sel->providers) {
110 return;
111 }
112
113 if(len == -1) {
114 len = strlen(str);
115 }
116 GBytes *bytes = g_bytes_new(str, len);
117 GdkContentProvider *provider = gdk_content_provider_new_for_bytes("text/plain;charset=utf-8", bytes);
118 g_bytes_unref(bytes);
119
120 cxListAdd(sel->providers, &provider);
107 } 121 }
108 122
109 void ui_selection_seturis(UiDnD *sel, char **uris, int nelm) { 123 void ui_selection_seturis(UiDnD *sel, char **uris, int nelm) {
110 124 if(!sel->providers) {
125 return;
126 }
127
128 GFile **files = calloc(nelm, sizeof(GFile*));
129 for(int i=0;i<nelm;i++) {
130 GFile *file = uris[i][0] == '/' ? g_file_new_for_path(uris[i]) : g_file_new_for_uri(uris[i]);
131 files[i] = file;
132 }
133 GdkFileList *list = gdk_file_list_new_from_array(files, nelm);
134
135 GdkContentProvider *provider = gdk_content_provider_new_typed(GDK_TYPE_FILE_LIST, list);
136 cxListAdd(sel->providers, &provider);
137
138 g_slist_free_full ((GSList*)list, g_object_unref);
139 free(files);
111 } 140 }
112 141
113 char* ui_selection_gettext(UiDnD *sel) { 142 char* ui_selection_gettext(UiDnD *sel) {
143 if(!sel->value) {
144 return NULL;
145 }
146
147 if(G_VALUE_HOLDS(sel->value, G_TYPE_STRING)) {
148 const char *str = g_value_get_string(sel->value);
149 return str ? strdup(str) : NULL;
150 }
151
114 return NULL; 152 return NULL;
115 } 153 }
116 154
117 UiFileList ui_selection_geturis(UiDnD *sel) { 155 UiFileList ui_selection_geturis(UiDnD *sel) {
156 if(!sel->value) {
157 return (UiFileList){NULL,0};
158 }
159
160 if(G_VALUE_HOLDS(sel->value, GDK_TYPE_FILE_LIST)) {
161 GSList *list = g_value_get_boxed(sel->value);
162 if(!list) {
163 return (UiFileList){NULL,0};
164 }
165 guint size = g_slist_length(list);
166
167 UiFileList flist;
168 flist.nfiles = size;
169 flist.files = calloc(size, sizeof(char*));
170 int i=0;
171 while(list) {
172 GFile *file = list->data;
173 char *uri = g_file_get_uri(file);
174 flist.files[i++] = strdup(uri);
175 g_free(uri);
176 list = list->next;
177 }
178 return flist;
179 }
118 return (UiFileList){NULL,0}; 180 return (UiFileList){NULL,0};
119 } 181 }
182
183
184 UiDnD* ui_create_dnd(void) {
185 UiDnD *dnd = malloc(sizeof(UiDnD));
186 memset(dnd, 0, sizeof(UiDnD));
187 dnd->providers = cxArrayListCreateSimple(sizeof(void*), 16);
188 dnd->selected_action = 0;
189 dnd->delete = FALSE;
190 return dnd;
191 }
192
193 void ui_dnd_free(UiDnD *dnd) {
194 cxListDestroy(dnd->providers);
195 free(dnd);
196 }
197
198 UiDnDAction ui_dnd_result(UiDnD *dnd) {
199 switch(dnd->selected_action) {
200 case 0: return UI_DND_ACTION_NONE;
201 case GDK_ACTION_COPY: return UI_DND_ACTION_COPY;
202 case GDK_ACTION_MOVE: return UI_DND_ACTION_MOVE;
203 case GDK_ACTION_LINK: return UI_DND_ACTION_LINK;
204 default: break;
205 }
206 return UI_DND_ACTION_CUSTOM;
207 }
208
209 #else
210
211 void ui_selection_settext(UiDnD *sel, char *str, int len) {
212 gtk_selection_data_set_text(sel->data, str, len);
213 }
214
215 void ui_selection_seturis(UiDnD *sel, char **uris, int nelm) {
216 char **uriarray = calloc(nelm+1, sizeof(char*));
217 for(int i=0;i<nelm;i++) {
218 uriarray[i] = uris[i];
219 }
220 uriarray[nelm] = NULL;
221 gtk_selection_data_set_uris(sel->data, uriarray);
222 free(uriarray);
223 }
224
225 char* ui_selection_gettext(UiDnD *sel) {
226 if(!sel->data) {
227 return NULL;
228 }
229
230 guchar *text = gtk_selection_data_get_text(sel->data);
231 if(text) {
232 char *textcp = strdup((char*)text);
233 g_free(text);
234 return textcp;
235 }
236 return NULL;
237 }
238
239 UiFileList ui_selection_geturis(UiDnD *sel) {
240 if(!sel->data) {
241 return (UiFileList){NULL,0};
242 }
243
244 gchar **uris = gtk_selection_data_get_uris(sel->data);
245 if(uris) {
246 size_t al = 32;
247 char **array = malloc(al * sizeof(char*));
248 size_t i = 0;
249 while(uris[i] != NULL) {
250 if(i >= al) {
251 al *= 2;
252 array = realloc(array, al * sizeof(char*));
253 }
254 array[i] = strdup((char*)uris[i]);
255 i++;
256 }
257 g_strfreev(uris);
258 return (UiFileList){array,i};
259 }
260
261 return (UiFileList){NULL,0};
262 }
263
264 UiDnDAction ui_dnd_result(UiDnD *dnd) {
265 switch(dnd->selected_action) {
266 case 0: return UI_DND_ACTION_NONE;
267 case GDK_ACTION_COPY: return UI_DND_ACTION_COPY;
268 case GDK_ACTION_MOVE: return UI_DND_ACTION_MOVE;
269 case GDK_ACTION_LINK: return UI_DND_ACTION_LINK;
270 default: break;
271 }
272 return UI_DND_ACTION_CUSTOM;
273 }
274
275
276 UiDnD* ui_create_dnd(void) {
277 UiDnD *dnd = malloc(sizeof(UiDnD));
278 memset(dnd, 0, sizeof(UiDnD));
279 return dnd;
280 }
281
282 void ui_dnd_free(UiDnD *dnd) {
283 free(dnd);
284 }
285
286 #endif
287
288 UiBool ui_dnd_need_delete(UiDnD *dnd) {
289 return dnd->delete;
290 }
291
292 void ui_dnd_accept(UiDnD *dnd, UiBool accept) {
293 dnd->accept = accept;
294 }
295

mercurial