No issues found
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /* nautilus-error-reporting.h - implementation of file manager functions that report
4 errors to the user.
5
6 Copyright (C) 2000 Eazel, Inc.
7
8 The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
20 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22
23 Authors: John Sullivan <sullivan@eazel.com>
24 */
25
26 #include <config.h>
27
28 #include "nautilus-error-reporting.h"
29
30 #include <string.h>
31 #include <glib/gi18n.h>
32 #include <libnautilus-private/nautilus-file.h>
33 #include <eel/eel-string.h>
34 #include <eel/eel-stock-dialogs.h>
35
36 #define DEBUG_FLAG NAUTILUS_DEBUG_DIRECTORY_VIEW
37 #include <libnautilus-private/nautilus-debug.h>
38
39 #define NEW_NAME_TAG "Nautilus: new name"
40 #define MAXIMUM_DISPLAYED_FILE_NAME_LENGTH 50
41
42 static void finish_rename (NautilusFile *file, gboolean stop_timer, GError *error);
43
44 void
45 nautilus_report_error_loading_directory (NautilusFile *file,
46 GError *error,
47 GtkWindow *parent_window)
48 {
49 char *file_name;
50 char *message;
51
52 if (error == NULL ||
53 error->message == NULL) {
54 return;
55 }
56
57 if (error->domain == G_IO_ERROR &&
58 error->code == G_IO_ERROR_NOT_MOUNTED) {
59 /* This case is retried automatically */
60 return;
61 }
62
63 file_name = nautilus_file_get_display_name (file);
64
65 if (error->domain == G_IO_ERROR) {
66 switch (error->code) {
67 case G_IO_ERROR_PERMISSION_DENIED:
68 message = g_strdup_printf (_("You do not have the permissions necessary to view the contents of “%s”."),
69 file_name);
70 break;
71 case G_IO_ERROR_NOT_FOUND:
72 message = g_strdup_printf (_("“%s” could not be found. Perhaps it has recently been deleted."),
73 file_name);
74 break;
75 default:
76 message = g_strdup_printf (_("Sorry, could not display all the contents of “%s”: %s"), file_name,
77 error->message);
78 }
79 } else {
80 message = g_strdup (error->message);
81 }
82
83 eel_show_error_dialog (_("This location could not be displayed."), message, parent_window);
84
85 g_free (file_name);
86 g_free (message);
87 }
88
89 void
90 nautilus_report_error_setting_group (NautilusFile *file,
91 GError *error,
92 GtkWindow *parent_window)
93 {
94 char *file_name;
95 char *message;
96
97 if (error == NULL) {
98 return;
99 }
100
101 file_name = nautilus_file_get_display_name (file);
102
103 message = NULL;
104 if (error->domain == G_IO_ERROR) {
105 switch (error->code) {
106 case G_IO_ERROR_PERMISSION_DENIED:
107 message = g_strdup_printf (_("You do not have the permissions necessary to change the group of “%s”."),
108 file_name);
109 break;
110 default:
111 break;
112 }
113 }
114
115 if (message == NULL) {
116 /* We should invent decent error messages for every case we actually experience. */
117 g_warning ("Hit unhandled case %s:%d in nautilus_report_error_setting_group",
118 g_quark_to_string (error->domain), error->code);
119 /* fall through */
120 message = g_strdup_printf (_("Sorry, could not change the group of “%s”: %s"), file_name,
121 error->message);
122 }
123
124
125 eel_show_error_dialog (_("The group could not be changed."), message, parent_window);
126
127 g_free (file_name);
128 g_free (message);
129 }
130
131 void
132 nautilus_report_error_setting_owner (NautilusFile *file,
133 GError *error,
134 GtkWindow *parent_window)
135 {
136 char *file_name;
137 char *message;
138
139 if (error == NULL) {
140 return;
141 }
142
143 file_name = nautilus_file_get_display_name (file);
144
145 message = g_strdup_printf (_("Sorry, could not change the owner of “%s”: %s"), file_name, error->message);
146
147 eel_show_error_dialog (_("The owner could not be changed."), message, parent_window);
148
149 g_free (file_name);
150 g_free (message);
151 }
152
153 void
154 nautilus_report_error_setting_permissions (NautilusFile *file,
155 GError *error,
156 GtkWindow *parent_window)
157 {
158 char *file_name;
159 char *message;
160
161 if (error == NULL) {
162 return;
163 }
164
165 file_name = nautilus_file_get_display_name (file);
166
167 message = g_strdup_printf (_("Sorry, could not change the permissions of “%s”: %s"), file_name, error->message);
168
169 eel_show_error_dialog (_("The permissions could not be changed."), message, parent_window);
170
171 g_free (file_name);
172 g_free (message);
173 }
174
175 typedef struct _NautilusRenameData {
176 char *name;
177 NautilusFileOperationCallback callback;
178 gpointer callback_data;
179 } NautilusRenameData;
180
181 void
182 nautilus_report_error_renaming_file (NautilusFile *file,
183 const char *new_name,
184 GError *error,
185 GtkWindow *parent_window)
186 {
187 char *original_name, *original_name_truncated;
188 char *new_name_truncated;
189 char *message;
190
191 /* Truncate names for display since very long file names with no spaces
192 * in them won't get wrapped, and can create insanely wide dialog boxes.
193 */
194 original_name = nautilus_file_get_display_name (file);
195 original_name_truncated = eel_str_middle_truncate (original_name, MAXIMUM_DISPLAYED_FILE_NAME_LENGTH);
196 g_free (original_name);
197
198 new_name_truncated = eel_str_middle_truncate (new_name, MAXIMUM_DISPLAYED_FILE_NAME_LENGTH);
199
200 message = NULL;
201 if (error->domain == G_IO_ERROR) {
202 switch (error->code) {
203 case G_IO_ERROR_EXISTS:
204 message = g_strdup_printf (_("The name “%s” is already used in this location. "
205 "Please use a different name."),
206 new_name_truncated);
207 break;
208 case G_IO_ERROR_NOT_FOUND:
209 message = g_strdup_printf (_("There is no “%s” in this location. "
210 "Perhaps it was just moved or deleted?"),
211 original_name_truncated);
212 break;
213 case G_IO_ERROR_PERMISSION_DENIED:
214 message = g_strdup_printf (_("You do not have the permissions necessary to rename “%s”."),
215 original_name_truncated);
216 break;
217 case G_IO_ERROR_INVALID_FILENAME:
218 if (strchr (new_name, '/') != NULL) {
219 message = g_strdup_printf (_("The name “%s” is not valid because it contains the character “/”. "
220 "Please use a different name."),
221 new_name_truncated);
222 } else {
223 message = g_strdup_printf (_("The name “%s” is not valid. "
224 "Please use a different name."),
225 new_name_truncated);
226 }
227 break;
228 case G_IO_ERROR_FILENAME_TOO_LONG:
229 message = g_strdup_printf (_("The name “%s” is too long. "
230 "Please use a different name."),
231 new_name_truncated);
232 break;
233 default:
234 break;
235 }
236 }
237
238 if (message == NULL) {
239 /* We should invent decent error messages for every case we actually experience. */
240 g_warning ("Hit unhandled case %s:%d in nautilus_report_error_renaming_file",
241 g_quark_to_string (error->domain), error->code);
242 /* fall through */
243 message = g_strdup_printf (_("Sorry, could not rename “%s” to “%s”: %s"),
244 original_name_truncated, new_name_truncated,
245 error->message);
246 }
247
248 g_free (original_name_truncated);
249 g_free (new_name_truncated);
250
251 eel_show_error_dialog (_("The item could not be renamed."), message, parent_window);
252 g_free (message);
253 }
254
255 static void
256 nautilus_rename_data_free (NautilusRenameData *data)
257 {
258 g_free (data->name);
259 g_free (data);
260 }
261
262 static void
263 rename_callback (NautilusFile *file, GFile *result_location,
264 GError *error, gpointer callback_data)
265 {
266 NautilusRenameData *data;
267 gboolean cancelled = FALSE;
268
269 g_assert (NAUTILUS_IS_FILE (file));
270 g_assert (callback_data == NULL);
271
272 data = g_object_get_data (G_OBJECT (file), NEW_NAME_TAG);
273 g_assert (data != NULL);
274
275 if (error) {
276 if (!(error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED)) {
277 /* If rename failed, notify the user. */
278 nautilus_report_error_renaming_file (file, data->name, error, NULL);
279 } else {
280 cancelled = TRUE;
281 }
282 }
283
284 finish_rename (file, ! cancelled, error);
285 }
286
287 static void
288 cancel_rename_callback (gpointer callback_data)
289 {
290 nautilus_file_cancel (NAUTILUS_FILE (callback_data), rename_callback, NULL);
291 }
292
293 static void
294 finish_rename (NautilusFile *file, gboolean stop_timer, GError *error)
295 {
296 NautilusRenameData *data;
297
298 data = g_object_get_data (G_OBJECT (file), NEW_NAME_TAG);
299 if (data == NULL) {
300 return;
301 }
302
303 /* Cancel both the rename and the timed wait. */
304 nautilus_file_cancel (file, rename_callback, NULL);
305 if (stop_timer) {
306 eel_timed_wait_stop (cancel_rename_callback, file);
307 }
308
309 if (data->callback != NULL) {
310 data->callback (file, NULL, error, data->callback_data);
311 }
312
313 /* Let go of file name. */
314 g_object_set_data (G_OBJECT (file), NEW_NAME_TAG, NULL);
315 }
316
317 void
318 nautilus_rename_file (NautilusFile *file,
319 const char *new_name,
320 NautilusFileOperationCallback callback,
321 gpointer callback_data)
322 {
323 char *old_name, *wait_message;
324 NautilusRenameData *data;
325 char *uri;
326 GError *error;
327
328 g_return_if_fail (NAUTILUS_IS_FILE (file));
329 g_return_if_fail (new_name != NULL);
330
331 /* Stop any earlier rename that's already in progress. */
332 error = g_error_new (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
333 finish_rename (file, TRUE, error);
334 g_error_free (error);
335
336 data = g_new0 (NautilusRenameData, 1);
337 data->name = g_strdup (new_name);
338 data->callback = callback;
339 data->callback_data = callback_data;
340
341 /* Attach the new name to the file. */
342 g_object_set_data_full (G_OBJECT (file),
343 NEW_NAME_TAG,
344 data, (GDestroyNotify)nautilus_rename_data_free);
345
346 /* Start the timed wait to cancel the rename. */
347 old_name = nautilus_file_get_display_name (file);
348 wait_message = g_strdup_printf (_("Renaming “%s” to “%s”."),
349 old_name,
350 new_name);
351 g_free (old_name);
352 eel_timed_wait_start (cancel_rename_callback, file, wait_message,
353 NULL); /* FIXME bugzilla.gnome.org 42395: Parent this? */
354 g_free (wait_message);
355
356 uri = nautilus_file_get_uri (file);
357 DEBUG ("Renaming file %s to %s", uri, new_name);
358 g_free (uri);
359
360 /* Start the rename. */
361 nautilus_file_rename (file, new_name,
362 rename_callback, NULL);
363 }