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