1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /* caja-file-drag.c - Drag & drop handling code that operated on
4 CajaFile objects.
5
6 Copyright (C) 2000 Eazel, Inc.
7
8 The Mate Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 The Mate Library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with the Mate Library; see the file COPYING.LIB. If not,
20 write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22
23 Authors: Pavel Cisler <pavel@eazel.com>,
24 */
25
26 #include <config.h>
27 #include "caja-file-dnd.h"
28 #include "caja-desktop-icon-file.h"
29
30 #include "caja-dnd.h"
31 #include "caja-directory.h"
32 #include "caja-file-utilities.h"
33 #include <string.h>
34
35 static gboolean
caja_drag_can_accept_files(CajaFile * drop_target_item)36 caja_drag_can_accept_files (CajaFile *drop_target_item)
37 {
38 if (caja_file_is_directory (drop_target_item))
39 {
40 CajaDirectory *directory;
41 gboolean res;
42
43 /* target is a directory, accept if editable */
44 directory = caja_directory_get_for_file (drop_target_item);
45 res = caja_directory_is_editable (directory);
46 caja_directory_unref (directory);
47 return res;
48 }
49
50 if (CAJA_IS_DESKTOP_ICON_FILE (drop_target_item))
51 {
52 return TRUE;
53 }
54
55 /* All Caja links are assumed to be links to directories.
56 * Therefore, they all can accept drags, like all other
57 * directories to. As with other directories, there can be
58 * errors when the actual copy is attempted due to
59 * permissions.
60 */
61 if (caja_file_is_caja_link (drop_target_item))
62 {
63 return TRUE;
64 }
65
66 if (caja_is_engrampa_installed () &&
67 caja_file_is_archive (drop_target_item))
68 {
69 return TRUE;
70 }
71
72 return FALSE;
73 }
74
75 gboolean
caja_drag_can_accept_item(CajaFile * drop_target_item,const char * item_uri)76 caja_drag_can_accept_item (CajaFile *drop_target_item,
77 const char *item_uri)
78 {
79 if (caja_file_matches_uri (drop_target_item, item_uri))
80 {
81 /* can't accept itself */
82 return FALSE;
83 }
84
85 return caja_drag_can_accept_files (drop_target_item);
86 }
87
88 gboolean
caja_drag_can_accept_items(CajaFile * drop_target_item,const GList * items)89 caja_drag_can_accept_items (CajaFile *drop_target_item,
90 const GList *items)
91 {
92 int max;
93
94 if (drop_target_item == NULL)
95 return FALSE;
96
97 g_assert (CAJA_IS_FILE (drop_target_item));
98
99 /* Iterate through selection checking if item will get accepted by the
100 * drop target. If more than 100 items selected, return an over-optimisic
101 * result
102 */
103 for (max = 100; items != NULL && max >= 0; items = items->next, max--)
104 {
105 if (!caja_drag_can_accept_item (drop_target_item,
106 ((CajaDragSelectionItem *)items->data)->uri))
107 {
108 return FALSE;
109 }
110 }
111
112 return TRUE;
113 }
114
115 gboolean
caja_drag_can_accept_info(CajaFile * drop_target_item,CajaIconDndTargetType drag_type,const GList * items)116 caja_drag_can_accept_info (CajaFile *drop_target_item,
117 CajaIconDndTargetType drag_type,
118 const GList *items)
119 {
120 switch (drag_type)
121 {
122 case CAJA_ICON_DND_MATE_ICON_LIST:
123 return caja_drag_can_accept_items (drop_target_item, items);
124
125 case CAJA_ICON_DND_URI_LIST:
126 case CAJA_ICON_DND_NETSCAPE_URL:
127 case CAJA_ICON_DND_TEXT:
128 return caja_drag_can_accept_files (drop_target_item);
129
130 case CAJA_ICON_DND_XDNDDIRECTSAVE:
131 case CAJA_ICON_DND_RAW:
132 return caja_drag_can_accept_files (drop_target_item); /* Check if we can accept files at this location */
133
134 case CAJA_ICON_DND_KEYWORD:
135 return TRUE;
136
137 case CAJA_ICON_DND_ROOTWINDOW_DROP:
138 return FALSE;
139
140 /* TODO return TRUE for folders as soon as drop handling is implemented */
141 case CAJA_ICON_DND_COLOR:
142 case CAJA_ICON_DND_BGIMAGE:
143 case CAJA_ICON_DND_RESET_BACKGROUND:
144 return FALSE;
145
146 default:
147 g_assert_not_reached ();
148 return FALSE;
149 }
150 }
151
152 void
caja_drag_file_receive_dropped_keyword(CajaFile * file,const char * keyword)153 caja_drag_file_receive_dropped_keyword (CajaFile *file,
154 const char *keyword)
155 {
156 GList *keywords;
157
158 g_return_if_fail (CAJA_IS_FILE (file));
159 g_return_if_fail (keyword != NULL);
160
161 /* special case the erase emblem */
162 if (strcmp (keyword, CAJA_FILE_DND_ERASE_KEYWORD) == 0)
163 {
164 keywords = NULL;
165 }
166 else
167 {
168 GList *word;
169
170 keywords = caja_file_get_keywords (file);
171 word = g_list_find_custom (keywords, keyword, (GCompareFunc) strcmp);
172 if (word == NULL)
173 {
174 keywords = g_list_prepend (keywords, g_strdup (keyword));
175 }
176 else
177 {
178 keywords = g_list_remove_link (keywords, word);
179 g_free (word->data);
180 g_list_free_1 (word);
181 }
182 }
183
184 caja_file_set_keywords (file, keywords);
185 g_list_free_full (keywords, g_free);
186 }
187