~elementary-apps/pantheon-files/trunk

106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
1
/* nautilus-file-conflict-dialog: dialog that handles file conflicts
2
 * during transfer operations.
3
 *
4
 * Copyright (C) 2008-2010 Cosimo Cecchi
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License as
2484.2.1 by Jeremy Wootten
Fix licensecheck warnings
8
 * published by the Free Software Foundation, Inc.,; either version 2 of the
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
9
 * License, or (at your option) any later version.
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
10
 *
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
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 GNU
14
 * General Public License for more details.
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
15
 *
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
16
 * You should have received a copy of the GNU General Public
17
 * License along with this program; if not, write to the
2484.2.1 by Jeremy Wootten
Fix licensecheck warnings
18
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
19
 * Boston, MA 02110-1335 USA.
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
20
 *
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
21
 * Authors: Cosimo Cecchi <cosimoc@gnome.org>
22
 */
23
24
#include "marlin-file-conflict-dialog.h"
25
26
#include <string.h>
27
#include <glib-object.h>
28
#include <gio/gio.h>
29
#include <glib/gi18n.h>
30
#include <pango/pango.h>
31
#include "eel-vfs-extensions.h"
32
33
#include "gof-file.h"
641 by am.monkeyd at gmail
cleanup, some renames
34
#include "marlin-icon-info.h"
1564 by xapantu
Rename both filescore and fileswidgets to files-core and files-widgets
35
#include "pantheon-files-core.h"
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
36
1811.1.1 by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments
37
#define FILE_ICON_SIZE_LARGE        64
641 by am.monkeyd at gmail
cleanup, some renames
38
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
39
typedef void GOFFileListHandle;
40
41
struct _MarlinFileConflictDialogDetails
42
{
43
    /* conflicting objects */
44
    GOFFile *source;
45
    GOFFile *destination;
46
    GOFFile *dest_dir;
47
48
    gchar *conflict_name;
49
    GOFFileListHandle *handle;
50
    gulong src_handler_id;
51
    gulong dest_handler_id;
52
53
    /* UI objects */
54
    GtkWidget *titles_vbox;
55
    GtkWidget *first_hbox;
56
    GtkWidget *second_hbox;
57
    GtkWidget *expander;
58
59
    GtkWidget *entry;
60
    GtkWidget *checkbox;
61
62
    GtkWidget *rename_button;
63
    GtkWidget *replace_button;
64
    GtkWidget *dest_image;
65
    GtkWidget *src_image;
66
};
67
68
G_DEFINE_TYPE (MarlinFileConflictDialog,
69
               marlin_file_conflict_dialog,
70
               GTK_TYPE_DIALOG);
71
1811.1.1 by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments
72
#define MARLIN_FILE_CONFLICT_DIALOG_GET_PRIVATE(object)                         \
73
    (G_TYPE_INSTANCE_GET_PRIVATE ((object), MARLIN_TYPE_FILE_CONFLICT_DIALOG,   \
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
74
                                  MarlinFileConflictDialogDetails))
75
76
static void
77
file_icons_changed (GOFFile *file,
78
                    MarlinFileConflictDialog *fcd)
79
{
80
    GdkPixbuf *pixbuf;
81
641 by am.monkeyd at gmail
cleanup, some renames
82
    pixbuf = gof_file_get_icon_pixbuf (fcd->details->destination, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
83
                                       TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
84
85
    gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->details->dest_image), pixbuf);
86
    g_object_unref (pixbuf);
87
641 by am.monkeyd at gmail
cleanup, some renames
88
    pixbuf = gof_file_get_icon_pixbuf (fcd->details->source, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
89
                                       TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
90
91
    gtk_image_set_from_pixbuf (GTK_IMAGE (fcd->details->src_image), pixbuf);
92
    g_object_unref (pixbuf);
93
}
94
95
#if 0
96
static void
97
file_list_ready_cb (GList *files,
98
                    gpointer user_data)
99
{
100
    MarlinFileConflictDialog *fcd = user_data;
101
    GOFFile *src, *dest, *dest_dir;
102
    time_t src_mtime, dest_mtime;
103
    GtkDialog *dialog;
1811.1.1 by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments
104
    gboolean source_is_dir, dest_is_dir, should_show_type;
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
105
    MarlinFileConflictDialogDetails *details;
106
    char *primary_text, *message, *secondary_text;
107
    const gchar *message_extra;
108
    char *src_name, *dest_name, *dest_dir_name, *edit_name;
109
    char *label_text;
110
    char *size, *date, *type = NULL;
111
    GdkPixbuf *pixbuf;
112
    GtkWidget *label;
113
    GString *str;
114
    PangoFontDescription *desc;
115
116
    dialog = GTK_DIALOG (fcd);
117
    details = fcd->details;
118
119
    details->handle = NULL;
120
121
    dest_dir = g_list_nth_data (files, 0);
122
    dest = g_list_nth_data (files, 1);
123
    src = g_list_nth_data (files, 2);
124
125
    src_mtime = marlin_file_get_mtime (src);
126
    dest_mtime = marlin_file_get_mtime (dest);
127
128
    src_name = marlin_file_get_display_name (src);
129
    dest_name = marlin_file_get_display_name (dest);
130
    dest_dir_name = marlin_file_get_display_name (dest_dir);
131
132
    source_is_dir = marlin_file_is_directory (src);
133
    dest_is_dir = marlin_file_is_directory (dest);
134
135
    type = marlin_file_get_mime_type (dest);
136
    should_show_type = !marlin_file_is_mime_type (src, type);
137
138
    g_free (type);
139
    type = NULL;
140
141
    /* Set up the right labels */
142
    if (dest_is_dir) {
143
        if (source_is_dir) {
144
            primary_text = g_strdup_printf
145
                (_("Merge folder \"%s\"?"),
146
                 dest_name);
147
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
148
            message_extra =
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
149
                _("Merging will ask for confirmation before replacing any files in "
150
                  "the folder that conflict with the files being copied.");
151
152
            if (src_mtime > dest_mtime) {
153
                message = g_strdup_printf (
154
                                           _("An older folder with the same name already exists in \"%s\"."),
155
                                           dest_dir_name);
156
            } else if (src_mtime < dest_mtime) {
157
                message = g_strdup_printf (
158
                                           _("A newer folder with the same name already exists in \"%s\"."),
159
                                           dest_dir_name);
160
            } else {
161
                message = g_strdup_printf (
162
                                           _("Another folder with the same name already exists in \"%s\"."),
163
                                           dest_dir_name);
164
            }
165
        } else {
166
            message_extra =
167
                _("Replacing it will remove all files in the folder.");
168
            primary_text = g_strdup_printf
169
                (_("Replace folder \"%s\"?"), dest_name);
170
            message = g_strdup_printf
171
                (_("A folder with the same name already exists in \"%s\"."),
172
                 dest_dir_name);
173
        }
174
    } else {
175
        primary_text = g_strdup_printf
176
            (_("Replace file \"%s\"?"), dest_name);
177
178
        message_extra = _("Replacing it will overwrite its content.");
179
180
        if (src_mtime > dest_mtime) {
181
            message = g_strdup_printf (
182
                                       _("An older file with the same name already exists in \"%s\"."),
183
                                       dest_dir_name);
184
        } else if (src_mtime < dest_mtime) {
185
            message = g_strdup_printf (
186
                                       _("A newer file with the same name already exists in \"%s\"."),
187
                                       dest_dir_name);
188
        } else {
189
            message = g_strdup_printf (
190
                                       _("Another file with the same name already exists in \"%s\"."),
191
                                       dest_dir_name);
192
        }
193
    }
194
195
    secondary_text = g_strdup_printf ("%s\n%s", message, message_extra);
196
    g_free (message);
197
198
    label = gtk_label_new (primary_text);
199
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
200
    gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
201
    gtk_widget_set_size_request (label, 350, -1);
202
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
203
    gtk_box_pack_start (GTK_BOX (details->titles_vbox),
204
                        label, FALSE, FALSE, 0);
205
    gtk_widget_modify_font (label, NULL);
206
    desc = pango_font_description_new ();
207
    pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
208
    pango_font_description_set_size (desc,
209
                                     pango_font_description_get_size (gtk_widget_get_style (label)->font_desc) * PANGO_SCALE_LARGE);
210
    gtk_widget_modify_font (label, desc);
211
    pango_font_description_free (desc);
212
    gtk_widget_show (label);
213
214
    label = gtk_label_new (secondary_text);
215
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
216
    gtk_widget_set_size_request (label, 350, -1);
217
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
218
    gtk_box_pack_start (GTK_BOX (details->titles_vbox),
219
                        label, FALSE, FALSE, 0);
220
    gtk_widget_show (label);
221
    g_free (primary_text);
222
    g_free (secondary_text);
223
224
    /* Set up file icons */
641 by am.monkeyd at gmail
cleanup, some renames
225
    pixbuf = gof_file_get_icon_pixbuf (dest, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
226
                                       TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
227
    details->dest_image = gtk_image_new_from_pixbuf (pixbuf);
228
    gtk_box_pack_start (GTK_BOX (details->first_hbox),
229
                        details->dest_image, FALSE, FALSE, 0);
230
    gtk_widget_show (details->dest_image);
231
    g_object_unref (pixbuf);
232
641 by am.monkeyd at gmail
cleanup, some renames
233
    pixbuf = marlin_file_get_icon_pixbuf (src, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
234
                                          TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
235
    details->src_image = gtk_image_new_from_pixbuf (pixbuf);
236
    gtk_box_pack_start (GTK_BOX (details->second_hbox),
237
                        details->src_image, FALSE, FALSE, 0);
238
    gtk_widget_show (details->src_image);
239
    g_object_unref (pixbuf);
240
241
    /* Set up labels */
242
    label = gtk_label_new (NULL);
243
    date = marlin_file_get_string_attribute (dest,
244
                                             "date_modified");
245
    size = marlin_file_get_string_attribute (dest, "size");
246
247
    if (should_show_type) {
248
        type = marlin_file_get_string_attribute (dest, "type");
249
    }
250
251
    str = g_string_new (NULL);
252
    g_string_append_printf (str, "<b>%s</b>\n", _("Original file"));
253
    g_string_append_printf (str, "<i>%s</i> %s\n", _("Size:"), size);
254
255
    if (should_show_type) {
256
        g_string_append_printf (str, "<i>%s</i> %s\n", _("Type:"), type);
257
    }
258
259
    g_string_append_printf (str, "<i>%s</i> %s", _("Last modified:"), date);
260
261
    label_text = str->str;
262
    gtk_label_set_markup (GTK_LABEL (label),
263
                          label_text);
264
    gtk_box_pack_start (GTK_BOX (details->first_hbox),
265
                        label, FALSE, FALSE, 0);
266
    gtk_widget_show (label);
267
268
    g_free (size);
269
    g_free (type);
270
    g_free (date);
271
    g_string_erase (str, 0, -1);
272
273
    /* Second label */
274
    label = gtk_label_new (NULL);
275
    date = marlin_file_get_string_attribute (src,
276
                                             "date_modified");
277
    size = marlin_file_get_string_attribute (src, "size");
278
279
    if (should_show_type) {
280
        type = marlin_file_get_string_attribute (src, "type");
281
    }
282
283
    g_string_append_printf (str, "<b>%s</b>\n", _("Replace with"));
284
    g_string_append_printf (str, "<i>%s</i> %s\n", _("Size:"), size);
285
286
    if (should_show_type) {
287
        g_string_append_printf (str, "<i>%s</i> %s\n", _("Type:"), type);
288
    }
289
290
    g_string_append_printf (str, "<i>%s</i> %s", _("Last modified:"), date);
291
    label_text = g_string_free (str, FALSE);
292
293
    gtk_label_set_markup (GTK_LABEL (label),
294
                          label_text);
295
    gtk_box_pack_start (GTK_BOX (details->second_hbox),
296
                        label, FALSE, FALSE, 0);
297
    gtk_widget_show (label);
298
299
    g_free (size);
300
    g_free (date);
301
    g_free (type);
302
    g_free (label_text);
303
304
    /* Populate the entry */
305
    edit_name = marlin_file_get_edit_name (dest);
306
    details->conflict_name = edit_name;
307
308
    gtk_entry_set_text (GTK_ENTRY (details->entry), edit_name);
309
310
    if (source_is_dir && dest_is_dir) {
311
        gtk_button_set_label (GTK_BUTTON (details->replace_button),
312
                              _("Merge"));
313
    }
314
315
    //TODO
316
    //marlin_file_monitor_add (src, fcd, MARLIN_FILE_ATTRIBUTES_FOR_ICON);
317
    //marlin_file_monitor_add (dest, fcd, MARLIN_FILE_ATTRIBUTES_FOR_ICON);
318
319
    details->src_handler_id = g_signal_connect (src, "changed",
320
                                                G_CALLBACK (file_icons_changed), fcd);
321
    details->dest_handler_id = g_signal_connect (dest, "changed",
322
                                                 G_CALLBACK (file_icons_changed), fcd);
323
}
324
#endif
325
326
static void
604.1.20 by am.monkeyd at gmail
gof-callwhenready.vala
327
file_list_ready_cb (GList *files, gpointer user_data)
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
328
{
604.1.20 by am.monkeyd at gmail
gof-callwhenready.vala
329
    MarlinFileConflictDialog *fcd = MARLIN_FILE_CONFLICT_DIALOG (user_data);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
330
    GOFFile *src, *dest, *dest_dir;
331
    gboolean should_show_type;
332
    MarlinFileConflictDialogDetails *details;
333
    char *primary_text, *message, *secondary_text;
334
    const gchar *message_extra;
335
    char *label_text;
336
    GdkPixbuf *pixbuf;
337
    GtkWidget *label;
338
    GString *str;
339
    PangoFontDescription *desc;
340
1740.1.40 by Fabio Zaramella
This revision adds 'Move to Trash'
341
    gtk_window_set_deletable (GTK_WINDOW (fcd), FALSE);
342
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
343
    details = fcd->details;
344
345
    details->handle = NULL;
346
347
    dest_dir = g_list_nth_data (files, 0);
348
    dest = g_list_nth_data (files, 1);
349
    src = g_list_nth_data (files, 2);
350
757 by am.monkeyd at gmail
goffile more clean up
351
    const gchar *src_ftype = gof_file_get_ftype (src);
352
    const gchar *dest_ftype = gof_file_get_ftype (dest);
353
1465.1.1 by Niclas Lockner
Handle unknown file types gracefully when showing the conflict dialog
354
    if (src_ftype == NULL) {
355
        g_warning ("Could not determine file type of source file: %s\n",
1465.1.2 by Niclas Lockner
Code-style fix
356
                   gof_file_get_uri (src));
1465.1.1 by Niclas Lockner
Handle unknown file types gracefully when showing the conflict dialog
357
    }
358
359
    if (dest_ftype == NULL) {
360
        g_warning ("Could not determine file type of destination file: %s\n",
1465.1.2 by Niclas Lockner
Code-style fix
361
                   gof_file_get_uri (dest));
1465.1.1 by Niclas Lockner
Handle unknown file types gracefully when showing the conflict dialog
362
    }
363
1811.1.1 by Jeremy Wootten
Code clean: tabs, trailing space, headers, comments
364
    should_show_type = g_strcmp0 (src_ftype, dest_ftype);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
365
756 by am.monkeyd at gmail
goffile clean up
366
    const gchar *dest_display_name = gof_file_get_display_name (dest);
367
    const gchar *dest_dir_display_name = gof_file_get_display_name (dest_dir);
368
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
369
    /* Set up the right labels */
370
    if (dest->is_directory) {
371
        if (src->is_directory) {
756 by am.monkeyd at gmail
goffile clean up
372
            primary_text = g_strdup_printf (_("Merge folder \"%s\"?"), dest_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
373
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
374
            message_extra =
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
375
                _("Merging will ask for confirmation before replacing any files in "
376
                  "the folder that conflict with the files being copied.");
377
378
            if (src->modified > dest->modified) {
379
                message = g_strdup_printf (
380
                                           _("An older folder with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
381
                                           dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
382
            } else if (src->modified < dest->modified) {
383
                message = g_strdup_printf (
384
                                           _("A newer folder with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
385
                                           dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
386
            } else {
387
                message = g_strdup_printf (
388
                                           _("Another folder with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
389
                                           dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
390
            }
391
        } else {
392
            message_extra =
393
                _("Replacing it will remove all files in the folder.");
394
            primary_text = g_strdup_printf
756 by am.monkeyd at gmail
goffile clean up
395
                (_("Replace folder \"%s\"?"), dest_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
396
            message = g_strdup_printf
397
                (_("A folder with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
398
                 dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
399
        }
400
    } else {
401
        primary_text = g_strdup_printf
756 by am.monkeyd at gmail
goffile clean up
402
            (_("Replace file \"%s\"?"), dest_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
403
404
        message_extra = _("Replacing it will overwrite its content.");
405
406
        if (src->modified > dest->modified) {
407
            message = g_strdup_printf (
408
                                       _("An older file with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
409
                                       dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
410
        } else if (src->modified < dest->modified) {
411
            message = g_strdup_printf (
412
                                       _("A newer file with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
413
                                       dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
414
        } else {
415
            message = g_strdup_printf (
416
                                       _("Another file with the same name already exists in \"%s\"."),
756 by am.monkeyd at gmail
goffile clean up
417
                                       dest_dir_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
418
        }
419
    }
420
421
    secondary_text = g_strdup_printf ("%s\n%s", message, message_extra);
422
    g_free (message);
423
424
    label = gtk_label_new (primary_text);
425
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
426
    gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
427
    gtk_widget_set_size_request (label, 350, -1);
428
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
429
    gtk_box_pack_start (GTK_BOX (details->titles_vbox),
430
                        label, FALSE, FALSE, 0);
431
    gtk_widget_modify_font (label, NULL);
432
    desc = pango_font_description_new ();
433
    pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
434
    pango_font_description_set_size (desc,
435
                                     pango_font_description_get_size (gtk_widget_get_style (label)->font_desc) * PANGO_SCALE_LARGE);
436
    gtk_widget_modify_font (label, desc);
437
    pango_font_description_free (desc);
438
    gtk_widget_show (label);
439
440
    label = gtk_label_new (secondary_text);
441
    gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
442
    gtk_widget_set_size_request (label, 350, -1);
443
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
444
    gtk_box_pack_start (GTK_BOX (details->titles_vbox),
445
                        label, FALSE, FALSE, 0);
446
    gtk_widget_show (label);
447
    g_free (primary_text);
448
    g_free (secondary_text);
449
450
    /* Set up file icons */
641 by am.monkeyd at gmail
cleanup, some renames
451
    pixbuf = gof_file_get_icon_pixbuf (dest, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
452
                                       TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
453
    details->dest_image = gtk_image_new_from_pixbuf (pixbuf);
454
    gtk_box_pack_start (GTK_BOX (details->first_hbox),
455
                        details->dest_image, FALSE, FALSE, 0);
456
    gtk_widget_show (details->dest_image);
457
    g_object_unref (pixbuf);
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
458
641 by am.monkeyd at gmail
cleanup, some renames
459
    pixbuf = gof_file_get_icon_pixbuf (src, FILE_ICON_SIZE_LARGE,
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
460
                                       TRUE, GOF_FILE_ICON_FLAGS_USE_THUMBNAILS);
461
    details->src_image = gtk_image_new_from_pixbuf (pixbuf);
462
    gtk_box_pack_start (GTK_BOX (details->second_hbox),
463
                        details->src_image, FALSE, FALSE, 0);
464
    gtk_widget_show (details->src_image);
465
    g_object_unref (pixbuf);
466
467
    /* Set up labels */
468
    label = gtk_label_new (NULL);
469
470
    str = g_string_new (NULL);
471
    g_string_append_printf (str, "<b>%s</b>\n", _("Original file"));
472
    g_string_append_printf (str, "<i>%s</i> %s\n", _("Size:"), dest->format_size);
473
1465.1.1 by Niclas Lockner
Handle unknown file types gracefully when showing the conflict dialog
474
    if (should_show_type && dest_ftype != NULL) {
757 by am.monkeyd at gmail
goffile more clean up
475
        g_string_append_printf (str, "<i>%s</i> %s\n", _("Type:"), dest_ftype);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
476
    }
477
478
    g_string_append_printf (str, "<i>%s</i> %s", _("Last modified:"), dest->formated_modified);
479
480
    label_text = str->str;
481
    gtk_label_set_markup (GTK_LABEL (label),
482
                          label_text);
483
    gtk_box_pack_start (GTK_BOX (details->first_hbox),
484
                        label, FALSE, FALSE, 0);
485
    gtk_widget_show (label);
486
487
    g_string_erase (str, 0, -1);
488
489
    /* Second label */
490
    label = gtk_label_new (NULL);
491
492
    g_string_append_printf (str, "<b>%s</b>\n", _("Replace with"));
493
    g_string_append_printf (str, "<i>%s</i> %s\n", _("Size:"), src->format_size);
494
1465.1.1 by Niclas Lockner
Handle unknown file types gracefully when showing the conflict dialog
495
    if (should_show_type && src_ftype != NULL) {
757 by am.monkeyd at gmail
goffile more clean up
496
        g_string_append_printf (str, "<i>%s</i> %s\n", _("Type:"), src_ftype);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
497
    }
498
499
    g_string_append_printf (str, "<i>%s</i> %s", _("Last modified:"), src->formated_modified);
500
    label_text = g_string_free (str, FALSE);
501
502
    gtk_label_set_markup (GTK_LABEL (label),
503
                          label_text);
504
    gtk_box_pack_start (GTK_BOX (details->second_hbox),
505
                        label, FALSE, FALSE, 0);
506
    gtk_widget_show (label);
507
508
    g_free (label_text);
509
510
    /* Populate the entry */
756 by am.monkeyd at gmail
goffile clean up
511
    details->conflict_name = g_strdup (dest_display_name);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
512
513
    gtk_entry_set_text (GTK_ENTRY (details->entry), details->conflict_name);
514
515
    if (src->is_directory && dest->is_directory) {
516
        gtk_button_set_label (GTK_BUTTON (details->replace_button),
517
                              _("Merge"));
518
    }
519
520
    //TODO
521
    //marlin_file_monitor_add (src, fcd, MARLIN_FILE_ATTRIBUTES_FOR_ICON);
522
    //marlin_file_monitor_add (dest, fcd, MARLIN_FILE_ATTRIBUTES_FOR_ICON);
523
524
    details->src_handler_id = g_signal_connect (src, "changed",
525
                                                G_CALLBACK (file_icons_changed), fcd);
526
    details->dest_handler_id = g_signal_connect (dest, "changed",
527
                                                 G_CALLBACK (file_icons_changed), fcd);
528
}
529
530
static void
531
build_dialog_appearance (MarlinFileConflictDialog *fcd)
532
{
533
    GList *files = NULL;
534
    MarlinFileConflictDialogDetails *details = fcd->details;
535
536
    files = g_list_prepend (files, details->source);
537
    files = g_list_prepend (files, details->destination);
538
    files = g_list_prepend (files, details->dest_dir);
539
604.1.24 by am.monkeyd at gmail
caches checked. places ensure file_info. update tests
540
    GOFCallWhenReady *cwr = gof_call_when_ready_new (files, file_list_ready_cb, G_OBJECT (fcd));
541
    g_object_unref (cwr);
604.1.20 by am.monkeyd at gmail
gof-callwhenready.vala
542
604.1.21 by am.monkeyd at gmail
clean up
543
    g_list_free (files);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
544
}
545
546
static void
547
set_source_and_destination (GtkWidget *w,
548
                            GFile *source,
549
                            GFile *destination,
550
                            GFile *dest_dir)
551
{
552
    MarlinFileConflictDialog *dialog;
553
    MarlinFileConflictDialogDetails *details;
554
555
    dialog = MARLIN_FILE_CONFLICT_DIALOG (w);
556
    details = dialog->details;
557
558
    details->source = gof_file_get (source);
559
    details->destination = gof_file_get (destination);
560
    details->dest_dir = gof_file_get (dest_dir);
561
562
    build_dialog_appearance (dialog);
563
}
564
565
static void
566
entry_text_changed_cb (GtkEditable *entry,
567
                       MarlinFileConflictDialog *dialog)
568
{
569
    MarlinFileConflictDialogDetails *details;
570
571
    details = dialog->details;
572
573
    /* The rename button is visible only if there's text
574
     * in the entry.
575
     */
576
    if  (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (entry)), "") != 0 &&
577
         g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (entry)), details->conflict_name) != 0) {
578
        gtk_widget_hide (details->replace_button);
579
        gtk_widget_show (details->rename_button);
580
581
        gtk_widget_set_sensitive (details->checkbox, FALSE);
582
583
        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
584
                                         CONFLICT_RESPONSE_RENAME);
585
    } else {
586
        gtk_widget_hide (details->rename_button);
587
        gtk_widget_show (details->replace_button);
588
589
        gtk_widget_set_sensitive (details->checkbox, TRUE);
590
591
        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
592
                                         CONFLICT_RESPONSE_REPLACE);
593
    }
594
}
595
596
static void
597
expander_activated_cb (GtkExpander *w,
598
                       MarlinFileConflictDialog *dialog)
599
{
600
    MarlinFileConflictDialogDetails *details;
601
    int start_pos, end_pos;
602
603
    details = dialog->details;
604
605
    if (!gtk_expander_get_expanded (w)) {
606
        if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (details->entry)),
607
                       details->conflict_name) == 0) {
608
            gtk_widget_grab_focus (details->entry);
609
610
            eel_filename_get_rename_region (details->conflict_name,
611
                                            &start_pos, &end_pos);
612
            gtk_editable_select_region (GTK_EDITABLE (details->entry),
613
                                        start_pos, end_pos);
614
        }
615
    }
616
}
617
618
static void
619
checkbox_toggled_cb (GtkToggleButton *t,
620
                     MarlinFileConflictDialog *dialog)
621
{
622
    MarlinFileConflictDialogDetails *details;
623
624
    details = dialog->details;
625
626
    gtk_widget_set_sensitive (details->expander,
627
                              !gtk_toggle_button_get_active (t));
628
    gtk_widget_set_sensitive (details->rename_button,
629
                              !gtk_toggle_button_get_active (t));
630
631
    if  (!gtk_toggle_button_get_active (t) &&
632
         g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (details->entry)),
633
                    "") != 0 &&
634
         g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (details->entry)),
635
                    details->conflict_name) != 0) {
636
        gtk_widget_hide (details->replace_button);
637
        gtk_widget_show (details->rename_button);
638
    } else {
639
        gtk_widget_hide (details->rename_button);
640
        gtk_widget_show (details->replace_button);
641
    }
642
}
643
644
static void
645
reset_button_clicked_cb (GtkButton *w,
646
                         MarlinFileConflictDialog *dialog)
647
{
648
    MarlinFileConflictDialogDetails *details;
649
    int start_pos, end_pos;
650
651
    details = dialog->details;
652
653
    gtk_entry_set_text (GTK_ENTRY (details->entry),
654
                        details->conflict_name);
655
    gtk_widget_grab_focus (details->entry);
656
    eel_filename_get_rename_region (details->conflict_name,
657
                                    &start_pos, &end_pos);
658
    gtk_editable_select_region (GTK_EDITABLE (details->entry),
659
                                start_pos, end_pos);
660
661
}
662
663
static void
664
marlin_file_conflict_dialog_init (MarlinFileConflictDialog *fcd)
665
{
666
    GtkWidget *hbox, *vbox, *vbox2, *alignment;
667
    GtkWidget *widget, *dialog_area;
668
    MarlinFileConflictDialogDetails *details;
669
    GtkDialog *dialog;
670
671
    details = fcd->details = MARLIN_FILE_CONFLICT_DIALOG_GET_PRIVATE (fcd);
672
    dialog = GTK_DIALOG (fcd);
673
674
    /* Setup the main hbox */
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
675
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
676
    dialog_area = gtk_dialog_get_content_area (dialog);
677
    gtk_box_pack_start (GTK_BOX (dialog_area), hbox, FALSE, FALSE, 0);
678
    gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
679
680
    /* Setup the dialog image */
681
    widget = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
682
                                       GTK_ICON_SIZE_DIALOG);
683
    gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
684
    gtk_misc_set_alignment (GTK_MISC (widget), 0.5, 0.0);
685
686
    /* Setup the vbox containing the dialog body */
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
687
    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
688
    gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
689
690
    /* Setup the vbox for the dialog labels */
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
691
    widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
692
    gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
693
    details->titles_vbox = widget;
694
695
    /* Setup the hboxes to pack file infos into */
696
    alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
697
    g_object_set (alignment, "left-padding", 12, NULL);
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
698
    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
699
    gtk_container_add (GTK_CONTAINER (alignment), vbox2);
700
    gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
701
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
702
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
703
    gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
704
    details->first_hbox = hbox;
705
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
706
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
707
    gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
708
    details->second_hbox = hbox;
709
710
    /* Setup the expander for the rename action */
711
    details->expander = gtk_expander_new_with_mnemonic (_("_Select a new name for the destination"));
712
    gtk_box_pack_start (GTK_BOX (vbox2), details->expander, FALSE, FALSE, 0);
713
    g_signal_connect (details->expander, "activate",
714
                      G_CALLBACK (expander_activated_cb), dialog);
715
798.2.2 by am.monkeyd at gmail
replace deprecated fcts from gtk & glib
716
    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
717
    gtk_container_add (GTK_CONTAINER (details->expander), hbox);
718
719
    widget = gtk_entry_new ();
720
    gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6);
721
    details->entry = widget;
722
    g_signal_connect (widget, "changed",
723
                      G_CALLBACK (entry_text_changed_cb), dialog);
724
725
    widget = gtk_button_new_with_label (_("Reset"));
726
    gtk_button_set_image (GTK_BUTTON (widget),
727
                          gtk_image_new_from_stock (GTK_STOCK_UNDO,
728
                                                    GTK_ICON_SIZE_MENU));
729
    gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 6);
730
    g_signal_connect (widget, "clicked",
731
                      G_CALLBACK (reset_button_clicked_cb), dialog);
732
733
    gtk_widget_show_all (alignment);
734
735
736
    /* Setup the checkbox to apply the action to all files */
737
    widget = gtk_check_button_new_with_mnemonic (_("Apply this action to all files"));
738
    gtk_box_pack_start (GTK_BOX (vbox),
739
                        widget, FALSE, FALSE, 0);
740
    details->checkbox = widget;
741
    g_signal_connect (widget, "toggled",
742
                      G_CALLBACK (checkbox_toggled_cb), dialog);
743
744
    /* Add buttons */
745
    gtk_dialog_add_buttons (dialog,
746
                            GTK_STOCK_CANCEL,
747
                            GTK_RESPONSE_CANCEL,
748
                            _("_Skip"),
749
                            CONFLICT_RESPONSE_SKIP,
750
                            NULL);
751
    details->rename_button =
752
        gtk_dialog_add_button (dialog,
753
                               _("Re_name"),
754
                               CONFLICT_RESPONSE_RENAME);
755
    gtk_widget_hide (details->rename_button);
756
757
    details->replace_button =
758
        gtk_dialog_add_button (dialog,
759
                               _("Replace"),
760
                               CONFLICT_RESPONSE_REPLACE);
761
    gtk_widget_grab_focus (details->replace_button);
762
763
    /* Setup HIG properties */
764
    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
765
    gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (dialog)), 14);
766
    gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
767
768
    gtk_widget_show_all (dialog_area);
769
}
770
771
static void
772
do_finalize (GObject *self)
773
{
774
    MarlinFileConflictDialogDetails *details =
775
        MARLIN_FILE_CONFLICT_DIALOG (self)->details;
776
777
    g_free (details->conflict_name);
778
779
    //TODO
780
    /*if (details->handle != NULL) {
781
      marlin_file_list_cancel_call_when_ready (details->handle);
782
      }*/
783
784
    if (details->src_handler_id) {
785
        g_signal_handler_disconnect (details->source, details->src_handler_id);
786
        //marlin_file_monitor_remove (details->source, self);
787
    }
788
789
    if (details->dest_handler_id) {
790
        g_signal_handler_disconnect (details->destination, details->dest_handler_id);
791
        //marlin_file_monitor_remove (details->destination, self);
792
    }
793
794
    gof_file_unref (details->source);
795
    gof_file_unref (details->destination);
796
    gof_file_unref (details->dest_dir);
797
798
    G_OBJECT_CLASS (marlin_file_conflict_dialog_parent_class)->finalize (self);
799
}
800
801
static void
802
marlin_file_conflict_dialog_class_init (MarlinFileConflictDialogClass *klass)
803
{
804
    G_OBJECT_CLASS (klass)->finalize = do_finalize;
805
806
    g_type_class_add_private (klass, sizeof (MarlinFileConflictDialogDetails));
807
}
808
809
char *
810
marlin_file_conflict_dialog_get_new_name (MarlinFileConflictDialog *dialog)
811
{
812
    return g_strdup (gtk_entry_get_text
813
                     (GTK_ENTRY (dialog->details->entry)));
814
}
815
816
gboolean
817
marlin_file_conflict_dialog_get_apply_to_all (MarlinFileConflictDialog *dialog)
818
{
1266.3.5 by David Gomes
Stripped more trailing white space and fixed a typo on Animations.vala.
819
    return gtk_toggle_button_get_active
106.1.2 by am.monkeyd at gmail
file_operations mount/unmount copy/move
820
        (GTK_TOGGLE_BUTTON (dialog->details->checkbox));
821
}
822
823
GtkWidget *
824
marlin_file_conflict_dialog_new (GtkWindow *parent,
825
                                 GFile *source,
826
                                 GFile *destination,
827
                                 GFile *dest_dir)
828
{
829
    GtkWidget *dialog;
830
831
    dialog = GTK_WIDGET (g_object_new (MARLIN_TYPE_FILE_CONFLICT_DIALOG,
832
                                       "title", _("File conflict"),
833
                                       NULL));
834
    set_source_and_destination (dialog, source, destination, dest_dir);
835
    gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
836
    return dialog;
837
}