~ubuntu-branches/debian/squeeze/inkscape/squeeze

« back to all changes in this revision

Viewing changes to src/dialogs/export.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 * Authors:
9
9
 *   Lauris Kaplinski <lauris@kaplinski.com>
10
10
 *   bulia byak <buliabyak@users.sf.net>
 
11
 *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
11
12
 *
12
 
 * Copyright (C) 1999-2005 Authors
 
13
 * Copyright (C) 1999-2007 Authors
13
14
 * Copyright (C) 2001-2002 Ximian, Inc.
14
15
 *
15
16
 * Released under GNU GPL, read the file 'COPYING' for more information
29
30
#include <gtkmm/image.h>
30
31
#include <gtkmm/stockid.h>
31
32
#include <gtkmm/stock.h>
 
33
#ifdef WITH_GNOME_VFS
 
34
# include <libgnomevfs/gnome-vfs-init.h>  // gnome_vfs_initialized
 
35
#endif
32
36
 
33
37
#include <glibmm/i18n.h>
34
38
#include "helper/unit-menu.h"
43
47
#include "file.h"
44
48
#include "macros.h"
45
49
#include "sp-namedview.h"
 
50
#include "selection-chemistry.h"
46
51
 
47
52
#include "dialog-events.h"
48
53
#include "../prefs-utils.h"
54
59
 
55
60
#include "io/sys.h"
56
61
 
 
62
#include "helper/png-write.h"
 
63
#include <png.h>
 
64
 
57
65
 
58
66
#define SP_EXPORT_MIN_SIZE 1.0
59
67
 
61
69
 
62
70
#define EXPORT_COORD_PRECISION 3
63
71
 
 
72
#define MIN_ONSCREEN_DISTANCE 50
 
73
 
64
74
static void sp_export_area_toggled   ( GtkToggleButton *tb, GtkObject *base );
65
75
static void sp_export_export_clicked ( GtkButton *button, GtkObject *base );
66
76
static void sp_export_browse_clicked ( GtkButton *button, gpointer userdata );
67
77
 
68
 
static void sp_export_area_x_value_changed       ( GtkAdjustment *adj, 
69
 
                                                   GtkObject *base);
70
 
                                             
71
 
static void sp_export_area_y_value_changed       ( GtkAdjustment *adj, 
72
 
                                                   GtkObject *base);
73
 
                                             
74
 
static void sp_export_area_width_value_changed   ( GtkAdjustment *adj, 
75
 
                                                   GtkObject *base);
76
 
                                                 
77
 
static void sp_export_area_height_value_changed  ( GtkAdjustment *adj, 
78
 
                                                   GtkObject *base);
79
 
                                                  
80
 
static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj, 
81
 
                                                   GtkObject *base);
82
 
                                                   
83
 
static void sp_export_bitmap_height_value_changed ( GtkAdjustment *adj, 
84
 
                                                   GtkObject *base);
85
 
                                                   
86
 
static void sp_export_xdpi_value_changed         ( GtkAdjustment *adj, 
87
 
                                                   GtkObject *base);
88
 
                                           
89
 
static void sp_export_selection_changed ( Inkscape::Application *inkscape, 
90
 
                                          Inkscape::Selection *selection, 
 
78
static void sp_export_area_x_value_changed       ( GtkAdjustment *adj,
 
79
                                                   GtkObject *base);
 
80
 
 
81
static void sp_export_area_y_value_changed       ( GtkAdjustment *adj,
 
82
                                                   GtkObject *base);
 
83
 
 
84
static void sp_export_area_width_value_changed   ( GtkAdjustment *adj,
 
85
                                                   GtkObject *base);
 
86
 
 
87
static void sp_export_area_height_value_changed  ( GtkAdjustment *adj,
 
88
                                                   GtkObject *base);
 
89
 
 
90
static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj,
 
91
                                                   GtkObject *base);
 
92
 
 
93
static void sp_export_bitmap_height_value_changed ( GtkAdjustment *adj,
 
94
                                                   GtkObject *base);
 
95
 
 
96
static void sp_export_xdpi_value_changed         ( GtkAdjustment *adj,
 
97
                                                   GtkObject *base);
 
98
 
 
99
static void sp_export_selection_changed ( Inkscape::Application *inkscape,
 
100
                                          Inkscape::Selection *selection,
91
101
                                          GtkObject *base);
92
 
static void sp_export_selection_modified ( Inkscape::Application *inkscape, 
93
 
                                           Inkscape::Selection *selection, 
 
102
static void sp_export_selection_modified ( Inkscape::Application *inkscape,
 
103
                                           Inkscape::Selection *selection,
94
104
                                           guint flags,
95
105
                                           GtkObject *base );
96
106
 
133
143
    N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")};
134
144
 
135
145
static void
136
 
sp_export_dialog_destroy ( GtkObject *object, gpointer data )
 
146
sp_export_dialog_destroy ( GtkObject */*object*/, gpointer /*data*/ )
137
147
{
138
148
    sp_signal_disconnect_by_data (INKSCAPE, dlg);
139
149
 
151
161
 
152
162
/// Called when dialog is closed or inkscape is shut down.
153
163
static bool
154
 
sp_export_dialog_delete ( GtkObject *object, GdkEvent *event, gpointer data )
 
164
sp_export_dialog_delete ( GtkObject */*object*/, GdkEvent */*event*/, gpointer /*data*/ )
155
165
{
156
166
 
157
167
    gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
280
290
        b->set_data("key", GINT_TO_POINTER(i));
281
291
        gtk_object_set_data (GTK_OBJECT (dlg), selection_names[i], b->gobj());
282
292
        togglebox->pack_start(*b, false, true, 0);
283
 
        gtk_signal_connect ( GTK_OBJECT (b->gobj()), "clicked", 
 
293
        gtk_signal_connect ( GTK_OBJECT (b->gobj()), "clicked",
284
294
                             GTK_SIGNAL_FUNC (sp_export_area_toggled), dlg );
285
295
    }
286
296
 
287
 
    g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", 
 
297
    g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection",
288
298
                       G_CALLBACK (sp_export_selection_changed), dlg );
289
 
    g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", 
 
299
    g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection",
290
300
                       G_CALLBACK (sp_export_selection_modified), dlg );
291
 
    g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", 
 
301
    g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop",
292
302
                       G_CALLBACK (sp_export_selection_changed), dlg );
293
 
    
 
303
 
294
304
    Gtk::Table* t = new Gtk::Table(2, 6, FALSE);
295
305
    t->set_row_spacings (4);
296
306
    t->set_col_spacings (4);
297
307
 
298
 
    sp_export_spinbutton_new ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(), 
 
308
    sp_export_spinbutton_new ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
299
309
                               GTK_WIDGET(t->gobj()), 0, 0, _("_x0:"), NULL, EXPORT_COORD_PRECISION, 1,
300
 
                               G_CALLBACK ( sp_export_area_x_value_changed), 
 
310
                               G_CALLBACK ( sp_export_area_x_value_changed),
301
311
                               dlg );
302
312
 
303
 
    sp_export_spinbutton_new ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(), 
 
313
    sp_export_spinbutton_new ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
304
314
                               GTK_WIDGET(t->gobj()), 2, 0, _("x_1:"), NULL, EXPORT_COORD_PRECISION, 1,
305
 
                               G_CALLBACK (sp_export_area_x_value_changed), 
 
315
                               G_CALLBACK (sp_export_area_x_value_changed),
306
316
                               dlg );
307
317
 
308
 
    sp_export_spinbutton_new ( "width", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, 
 
318
    sp_export_spinbutton_new ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
309
319
                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 0, _("Width:"), NULL, EXPORT_COORD_PRECISION, 1,
310
 
                               G_CALLBACK 
311
 
                                   (sp_export_area_width_value_changed), 
 
320
                               G_CALLBACK
 
321
                                   (sp_export_area_width_value_changed),
312
322
                               dlg );
313
323
 
314
 
    sp_export_spinbutton_new ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(), 
 
324
    sp_export_spinbutton_new ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
315
325
                               GTK_WIDGET(t->gobj()), 0, 1, _("_y0:"), NULL, EXPORT_COORD_PRECISION, 1,
316
 
                               G_CALLBACK (sp_export_area_y_value_changed), 
 
326
                               G_CALLBACK (sp_export_area_y_value_changed),
317
327
                               dlg );
318
328
 
319
 
    sp_export_spinbutton_new ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(), 
 
329
    sp_export_spinbutton_new ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
320
330
                               GTK_WIDGET(t->gobj()), 2, 1, _("y_1:"), NULL, EXPORT_COORD_PRECISION, 1,
321
 
                               G_CALLBACK (sp_export_area_y_value_changed), 
 
331
                               G_CALLBACK (sp_export_area_y_value_changed),
322
332
                               dlg );
323
333
 
324
 
    sp_export_spinbutton_new ( "height", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, 
 
334
    sp_export_spinbutton_new ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
325
335
                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 1, _("Height:"), NULL, EXPORT_COORD_PRECISION, 1,
326
 
                               G_CALLBACK (sp_export_area_height_value_changed), 
 
336
                               G_CALLBACK (sp_export_area_height_value_changed),
327
337
                               dlg );
328
338
 
329
339
    vb->pack_start(*togglebox, false, false, 3);
334
344
} // end of sp_export_dialog_area_box
335
345
 
336
346
 
 
347
gchar* create_filepath_from_id (const gchar *id, const gchar *file_entry_text) {
 
348
 
 
349
    if (id == NULL) /* This should never happen */
 
350
        id = "bitmap";
 
351
 
 
352
    gchar * directory = NULL;
 
353
 
 
354
    if (directory == NULL && file_entry_text != NULL && file_entry_text[0] != '\0') {
 
355
        // std::cout << "Directory from dialog" << std::endl;
 
356
        directory = g_dirname(file_entry_text);
 
357
    }
 
358
 
 
359
    if (directory == NULL) {
 
360
        /* Grab document directory */
 
361
        if (SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)) {
 
362
            // std::cout << "Directory from document" << std::endl;
 
363
            directory = g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT));
 
364
        }
 
365
    }
 
366
 
 
367
    if (directory == NULL) {
 
368
        // std::cout << "Home Directory" << std::endl;
 
369
        directory = homedir_path(NULL);
 
370
    }
 
371
 
 
372
    gchar * id_ext = g_strconcat(id, ".png", NULL);
 
373
    gchar *filename = g_build_filename(directory, id_ext, NULL);
 
374
    g_free(directory);
 
375
    g_free(id_ext);
 
376
    return filename;
 
377
}
 
378
 
 
379
static void
 
380
batch_export_clicked (GtkWidget *widget, GtkObject *base)
 
381
{
 
382
    Gtk::Widget *vb_singleexport = (Gtk::Widget *)gtk_object_get_data(base, "vb_singleexport");
 
383
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) {
 
384
        vb_singleexport->set_sensitive(false);
 
385
    } else {
 
386
        vb_singleexport->set_sensitive(true);
 
387
    }
 
388
}
 
389
 
337
390
void
338
391
sp_export_dialog (void)
339
392
{
340
393
    if (!dlg) {
341
 
        Gtk::VBox* vb;
342
 
        Gtk::HBox* hb;
343
394
 
344
395
        gchar title[500];
345
396
        sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_FILE_EXPORT), title);
356
407
            h = prefs_get_int_attribute (prefs_path, "h", 0);
357
408
        }
358
409
 
359
 
        if (x<0) x=0;
360
 
        if (y<0) y=0;
 
410
//        if (x<0) x=0;
 
411
//        if (y<0) y=0;
361
412
 
362
 
        if (x != 0 || y != 0) {
 
413
        if (w && h) gtk_window_resize ((GtkWindow *) dlg, w, h);
 
414
        if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE)))
363
415
            gtk_window_move ((GtkWindow *) dlg, x, y);
364
 
        } else {
 
416
        else
365
417
            gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
366
 
        }
367
 
 
368
 
        if (w && h)
369
 
            gtk_window_resize ((GtkWindow *) dlg, w, h);
370
 
 
371
418
        sp_transientize (dlg);
372
419
        wd.win = dlg;
373
420
        wd.stop = 0;
395
442
 
396
443
        GtkTooltips *tt = gtk_tooltips_new();
397
444
 
398
 
        vb = new Gtk::VBox(false, 3);
 
445
        Gtk::VBox *vb = new Gtk::VBox(false, 3);
399
446
        vb->set_border_width(3);
400
447
        gtk_container_add (GTK_CONTAINER (dlg), GTK_WIDGET(vb->gobj()));
401
448
 
 
449
        Gtk::VBox *vb_singleexport = new Gtk::VBox(false, 0);
 
450
        vb_singleexport->set_border_width(0);
 
451
        vb->pack_start(*vb_singleexport);
 
452
        gtk_object_set_data(GTK_OBJECT(dlg), "vb_singleexport", vb_singleexport);
 
453
 
402
454
        /* Export area frame */
403
455
        {
404
456
            Gtk::VBox *area_box = sp_export_dialog_area_box(dlg);
405
457
            area_box->set_border_width(3);
406
 
            vb->pack_start(*area_box, false, false, 0);
 
458
            vb_singleexport->pack_start(*area_box, false, false, 0);
407
459
        }
408
460
 
409
461
        /* Bitmap size frame */
422
474
            t->set_col_spacings (4);
423
475
            size_box->pack_start(*t);
424
476
 
425
 
            sp_export_spinbutton_new ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, 
 
477
            sp_export_spinbutton_new ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0,
426
478
                                       NULL, GTK_WIDGET(t->gobj()), 0, 0,
427
479
                                       _("_Width:"), _("pixels at"), 0, 1,
428
 
                                       G_CALLBACK 
429
 
                                       (sp_export_bitmap_width_value_changed), 
 
480
                                       G_CALLBACK
 
481
                                       (sp_export_bitmap_width_value_changed),
430
482
                                       dlg );
431
483
 
432
 
            sp_export_spinbutton_new ( "xdpi", 
433
 
                                       prefs_get_double_attribute 
434
 
                                       ( "dialogs.export.defaultxdpi", 
435
 
                                         "value", DPI_BASE), 
 
484
            sp_export_spinbutton_new ( "xdpi",
 
485
                                       prefs_get_double_attribute
 
486
                                       ( "dialogs.export.defaultxdpi",
 
487
                                         "value", DPI_BASE),
436
488
                                       0.01, 100000.0, 0.1, 1.0, NULL, GTK_WIDGET(t->gobj()), 3, 0,
437
489
                                       NULL, _("dp_i"), 2, 1,
438
 
                                       G_CALLBACK (sp_export_xdpi_value_changed), 
 
490
                                       G_CALLBACK (sp_export_xdpi_value_changed),
439
491
                                       dlg );
440
492
 
441
 
            sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, 
442
 
                                       NULL, GTK_WIDGET(t->gobj()), 0, 1, 
443
 
                                       _("Height:"), _("pixels at"), 0, 1, 
 
493
            sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0,
 
494
                                       NULL, GTK_WIDGET(t->gobj()), 0, 1,
 
495
                                       _("Height:"), _("pixels at"), 0, 1,
444
496
                                       G_CALLBACK
445
 
                                       (sp_export_bitmap_height_value_changed), 
 
497
                                       (sp_export_bitmap_height_value_changed),
446
498
                                       dlg );
447
499
 
448
500
            /** \todo
449
 
             * Needs fixing: there's no way to set ydpi currently, so we use  
 
501
             * Needs fixing: there's no way to set ydpi currently, so we use
450
502
             *       the defaultxdpi value here, too...
451
503
             */
452
 
            sp_export_spinbutton_new ( "ydpi", prefs_get_double_attribute 
453
 
                                       ( "dialogs.export.defaultxdpi", 
454
 
                                         "value", DPI_BASE), 
 
504
            sp_export_spinbutton_new ( "ydpi", prefs_get_double_attribute
 
505
                                       ( "dialogs.export.defaultxdpi",
 
506
                                         "value", DPI_BASE),
455
507
                                       0.01, 100000.0, 0.1, 1.0, NULL, GTK_WIDGET(t->gobj()), 3, 1,
456
508
                                       NULL, _("dpi"), 2, 0, NULL, dlg );
457
509
 
458
 
            vb->pack_start(*size_box);
 
510
            vb_singleexport->pack_start(*size_box);
459
511
        }
460
512
 
461
513
        /* File entry */
523
575
            g_signal_connect ( G_OBJECT (fe->gobj()), "changed",
524
576
                               G_CALLBACK (sp_export_filename_modified), dlg);
525
577
 
526
 
            hb = new Gtk::HBox(FALSE, 5);
 
578
            Gtk::HBox *hb = new Gtk::HBox(FALSE, 5);
527
579
 
528
580
            {
529
581
                // true = has mnemonic
559
611
            // mnemonic in frame label moves focus to filename:
560
612
            flabel->set_mnemonic_widget(*fe);
561
613
 
562
 
            vb->pack_start(*file_box);
 
614
            vb_singleexport->pack_start(*file_box);
 
615
        }
 
616
 
 
617
        {
 
618
            Gtk::HBox* batch_box = new Gtk::HBox(FALSE, 5);
 
619
            GtkWidget *be = gtk_check_button_new_with_label(_("Batch export all selected objects"));
 
620
            gtk_widget_set_sensitive(GTK_WIDGET(be), TRUE);
 
621
            gtk_object_set_data(GTK_OBJECT(dlg), "batch_checkbox", be);
 
622
            batch_box->pack_start(*Glib::wrap(be), false, false);
 
623
            gtk_tooltips_set_tip(tt, be, _("Export each selected object into its own PNG file, using export hints if any (caution, overwrites without asking!)"), NULL);
 
624
            batch_box->show_all();
 
625
            g_signal_connect(G_OBJECT(be), "toggled", GTK_SIGNAL_FUNC(batch_export_clicked), dlg);
 
626
            vb->pack_start(*batch_box);
 
627
        }
 
628
 
 
629
        {
 
630
            Gtk::HBox* hide_box = new Gtk::HBox(FALSE, 5);
 
631
            GtkWidget *he = gtk_check_button_new_with_label(_("Hide all except selected"));
 
632
            gtk_widget_set_sensitive(GTK_WIDGET(he), TRUE);
 
633
            gtk_object_set_data(GTK_OBJECT(dlg), "hide_checkbox", he);
 
634
            hide_box->pack_start(*Glib::wrap(he), false, false);
 
635
            gtk_tooltips_set_tip(tt, he, _("In the exported image, hide all objects except those that are selected"), NULL);
 
636
            hide_box->show_all();
 
637
            vb->pack_start(*hide_box);
563
638
        }
564
639
 
565
640
        /* Buttons */
596
671
    return;
597
672
} // end of sp_export_dialog()
598
673
 
 
674
static void
 
675
sp_export_update_checkbuttons (GtkObject *base)
 
676
{
 
677
    gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList());
 
678
    GtkWidget *be = (GtkWidget *)gtk_object_get_data(base, "batch_checkbox");
 
679
    GtkWidget *he = (GtkWidget *)gtk_object_get_data(base, "hide_checkbox");
 
680
    if (num >= 2) {
 
681
        gtk_widget_set_sensitive (be, true);
 
682
        gtk_button_set_label (GTK_BUTTON(be), g_strdup_printf (ngettext("Batch export %d selected object","Batch export %d selected objects",num), num));
 
683
    } else {
 
684
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(be), FALSE);
 
685
        gtk_widget_set_sensitive (be, FALSE);
 
686
    }
 
687
    if (num > 0) {
 
688
        gtk_widget_set_sensitive (he, true);
 
689
    } else {
 
690
        gtk_widget_set_sensitive (he, false);
 
691
    }
 
692
}
 
693
 
599
694
static inline void
600
695
sp_export_find_default_selection(GtkWidget * dlg)
601
696
{
631
726
                                                       selection_names[key]);
632
727
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
633
728
 
634
 
    return;
 
729
    sp_export_update_checkbuttons (GTK_OBJECT(dlg));
635
730
}
636
731
 
637
732
 
638
733
/**
639
 
 * \brief  If selection changed or a different document activated, we must 
 
734
 * \brief  If selection changed or a different document activated, we must
640
735
 * recalculate any chosen areas
641
736
 *
642
737
 */
643
738
static void
644
 
sp_export_selection_changed ( Inkscape::Application *inkscape, 
645
 
                              Inkscape::Selection *selection, 
 
739
sp_export_selection_changed ( Inkscape::Application *inkscape,
 
740
                              Inkscape::Selection *selection,
646
741
                              GtkObject *base )
647
742
{
648
743
    selection_type current_key;
666
761
        GtkToggleButton * button;
667
762
        button = (GtkToggleButton *)gtk_object_get_data(base, selection_names[current_key]);
668
763
        sp_export_area_toggled(button, base);
669
 
    } // end of if()
 
764
    }
670
765
 
671
 
    return;
672
 
} // end of sp_export_selection_changed()
 
766
    sp_export_update_checkbuttons (base);
 
767
}
673
768
 
674
769
static void
675
 
sp_export_selection_modified ( Inkscape::Application *inkscape, 
676
 
                               Inkscape::Selection *selection, 
677
 
                               guint flags,
 
770
sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
 
771
                               Inkscape::Selection */*selection*/,
 
772
                               guint /*flags*/,
678
773
                               GtkObject *base )
679
774
{
680
775
    selection_type current_key;
685
780
            if ( SP_ACTIVE_DESKTOP ) {
686
781
                SPDocument *doc;
687
782
                doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
688
 
                NR::Rect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
689
 
 
690
 
                if (!(bbox.min()[NR::X] > bbox.max()[NR::X] &&
691
 
                      bbox.min()[NR::Y] > bbox.max()[NR::Y])) {
692
 
                    sp_export_set_area (base, bbox.min()[NR::X],
693
 
                                              bbox.min()[NR::Y],
694
 
                                              bbox.max()[NR::X],
695
 
                                              bbox.max()[NR::Y]);
 
783
                NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
 
784
                if (bbox) {
 
785
                    sp_export_set_area (base, bbox->min()[NR::X],
 
786
                                              bbox->min()[NR::Y],
 
787
                                              bbox->max()[NR::X],
 
788
                                              bbox->max()[NR::Y]);
696
789
                }
697
790
            }
698
791
            break;
746
839
    if ( SP_ACTIVE_DESKTOP )
747
840
    {
748
841
        SPDocument *doc;
749
 
        NR::Rect bbox;
 
842
        NR::Maybe<NR::Rect> bbox;
750
843
        doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
751
844
 
752
845
        /* Notice how the switch is used to 'fall through' here to get
765
858
                    break;
766
859
                }
767
860
            case SELECTION_DRAWING:
768
 
                /** \todo 
 
861
                /** \todo
769
862
                 * This returns wrong values if the document has a viewBox.
770
863
                 */
771
864
                bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
772
 
                
773
865
                /* If the drawing is valid, then we'll use it and break
774
866
                   otherwise we drop through to the page settings */
775
 
                if (!(bbox.min()[NR::X] > bbox.max()[NR::X] &&
776
 
                      bbox.min()[NR::Y] > bbox.max()[NR::Y])) { 
 
867
                if (bbox) {
777
868
                    // std::cout << "Using selection: DRAWING" << std::endl;
778
869
                    key = SELECTION_DRAWING;
779
870
                    break;
780
871
                }
781
872
            case SELECTION_PAGE:
782
 
                bbox = NR::Rect(NR::Point(0.0, 0.0), 
 
873
                bbox = NR::Rect(NR::Point(0.0, 0.0),
783
874
                                NR::Point(sp_document_width(doc), sp_document_height(doc))
784
875
                                );
785
876
 
790
881
            default:
791
882
                break;
792
883
        } // switch
793
 
        
 
884
 
794
885
        // remember area setting
795
 
        prefs_set_string_attribute ( "dialogs.export.exportarea", 
 
886
        prefs_set_string_attribute ( "dialogs.export.exportarea",
796
887
                                     "value", selection_names[key]);
797
888
 
798
 
        if (key != SELECTION_CUSTOM) {
799
 
            sp_export_set_area (base, bbox.min()[NR::X],
800
 
                                      bbox.min()[NR::Y],
801
 
                                      bbox.max()[NR::X],
802
 
                                      bbox.max()[NR::Y]);
 
889
        if ( key != SELECTION_CUSTOM && bbox ) {
 
890
            sp_export_set_area (base, bbox->min()[NR::X],
 
891
                                      bbox->min()[NR::Y],
 
892
                                      bbox->max()[NR::X],
 
893
                                      bbox->max()[NR::Y]);
803
894
        }
804
 
    
 
895
 
805
896
    } // end of if ( SP_ACTIVE_DESKTOP )
806
897
 
807
898
 
816
907
            case SELECTION_PAGE:
817
908
            case SELECTION_DRAWING: {
818
909
                SPDocument * doc = SP_ACTIVE_DOCUMENT;
819
 
                Inkscape::XML::Node * repr = sp_document_repr_root(doc);
820
 
                const gchar * dpi_string;
821
 
 
822
 
                filename = repr->attribute("inkscape:export-filename");
823
 
 
824
 
                dpi_string = NULL;
825
 
                dpi_string = repr->attribute("inkscape:export-xdpi");
826
 
                if (dpi_string != NULL) {
827
 
                    xdpi = atof(dpi_string);
828
 
                }
829
 
 
830
 
                dpi_string = NULL;
831
 
                dpi_string = repr->attribute("inkscape:export-ydpi");
832
 
                if (dpi_string != NULL) {
833
 
                    ydpi = atof(dpi_string);
834
 
                }
 
910
                sp_document_get_export_hints (doc, &filename, &xdpi, &ydpi);
835
911
 
836
912
                if (filename == NULL) {
837
913
                    if (doc_export_name != NULL) {
844
920
            }
845
921
            case SELECTION_SELECTION:
846
922
                if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
847
 
                    const GSList * reprlst;
848
 
                    bool filename_search = TRUE;
849
 
                    bool xdpi_search = TRUE;
850
 
                    bool ydpi_search = TRUE;
851
 
 
852
 
                    reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
853
 
                    for(; reprlst != NULL &&
854
 
                            filename_search &&
855
 
                            xdpi_search &&
856
 
                            ydpi_search;
857
 
                            reprlst = reprlst->next) {
858
 
                        const gchar * dpi_string;
859
 
                        Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
860
 
 
861
 
                        if (filename_search) {
862
 
                            filename = repr->attribute("inkscape:export-filename");
863
 
                            if (filename != NULL)
864
 
                                filename_search = FALSE;
865
 
                        }
866
 
 
867
 
                        if (xdpi_search) {
868
 
                            dpi_string = NULL;
869
 
                            dpi_string = repr->attribute("inkscape:export-xdpi");
870
 
                            if (dpi_string != NULL) {
871
 
                                xdpi = atof(dpi_string);
872
 
                                xdpi_search = FALSE;
873
 
                            }
874
 
                        }
875
 
 
876
 
                        if (ydpi_search) {
877
 
                            dpi_string = NULL;
878
 
                            dpi_string = repr->attribute("inkscape:export-ydpi");
879
 
                            if (dpi_string != NULL) {
880
 
                                ydpi = atof(dpi_string);
881
 
                                ydpi_search = FALSE;
882
 
                            }
883
 
                        }
884
 
                    }
 
923
 
 
924
                    sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), &filename, &xdpi, &ydpi);
885
925
 
886
926
                    /* If we still don't have a filename -- let's build
887
927
                       one that's nice */
888
928
                    if (filename == NULL) {
889
929
                        const gchar * id = NULL;
890
 
                        reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
 
930
                        const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
891
931
                        for(; reprlst != NULL; reprlst = reprlst->next) {
892
932
                            Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
893
933
                            if (repr->attribute("id")) {
895
935
                                break;
896
936
                            }
897
937
                        }
898
 
                        if (id == NULL) /* This should never happen */
899
 
                            id = "bitmap";
900
 
 
901
 
                        gchar * directory = NULL;
902
 
                        const gchar * file_entry_text;
903
 
 
904
 
                        file_entry_text = gtk_entry_get_text(GTK_ENTRY(file_entry));
905
 
                        if (directory == NULL && file_entry_text != NULL && file_entry_text[0] != '\0') {
906
 
                            // std::cout << "Directory from dialog" << std::endl;
907
 
                            directory = g_dirname(file_entry_text);
908
 
                        }
909
 
 
910
 
                        if (directory == NULL) {
911
 
                            /* Grab document directory */
912
 
                            if (SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)) {
913
 
                                // std::cout << "Directory from document" << std::endl;
914
 
                                directory = g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT));
915
 
                            }
916
 
                        }
917
 
 
918
 
                        if (directory == NULL) {
919
 
                            // std::cout << "Home Directory" << std::endl;
920
 
                            directory = homedir_path(NULL);
921
 
                        }
922
 
 
923
 
                        gchar * id_ext = g_strconcat(id, ".png", NULL);
924
 
                        filename = g_build_filename(directory, id_ext, NULL);
925
 
                        g_free(directory);
926
 
                        g_free(id_ext);
 
938
 
 
939
                        filename = create_filepath_from_id (id, gtk_entry_get_text(GTK_ENTRY(file_entry)));
927
940
                    }
928
941
                }
929
942
                break;
942
955
            sp_export_value_set(base, "xdpi", xdpi);
943
956
        }
944
957
 
945
 
        /* These can't be seperate, and setting x sets y, so for
 
958
        /* These can't be separate, and setting x sets y, so for
946
959
           now setting this is disabled.  Hopefully it won't be in
947
960
           the future */
948
961
        if (FALSE && ydpi != 0.0) {
955
968
 
956
969
/// Called when dialog is deleted
957
970
static gint
958
 
sp_export_progress_delete ( GtkWidget *widget, GdkEvent *event, GObject *base )
 
971
sp_export_progress_delete ( GtkWidget */*widget*/, GdkEvent */*event*/, GObject *base )
959
972
{
960
973
    g_object_set_data (base, "cancel", (gpointer) 1);
961
974
    return TRUE;
963
976
 
964
977
/// Called when progress is cancelled
965
978
static void
966
 
sp_export_progress_cancel ( GtkWidget *widget, GObject *base )
 
979
sp_export_progress_cancel ( GtkWidget */*widget*/, GObject *base )
967
980
{
968
981
    g_object_set_data (base, "cancel", (gpointer) 1);
969
982
} // end of sp_export_progress_cancel()
993
1006
 
994
1007
} // end of sp_export_progress_callback()
995
1008
 
 
1009
GtkWidget *
 
1010
create_progress_dialog (GtkObject *base, gchar *progress_text) {
 
1011
    GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */
 
1012
 
 
1013
    dlg = gtk_dialog_new ();
 
1014
    gtk_window_set_title (GTK_WINDOW (dlg), _("Export in progress"));
 
1015
    prg = gtk_progress_bar_new ();
 
1016
    sp_transientize (dlg);
 
1017
    gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
 
1018
    g_object_set_data ((GObject *) base, "progress", prg);
 
1019
 
 
1020
    gtk_progress_bar_set_text ((GtkProgressBar *) prg, progress_text);
 
1021
 
 
1022
    gtk_progress_bar_set_orientation ( (GtkProgressBar *) prg,
 
1023
                                       GTK_PROGRESS_LEFT_TO_RIGHT);
 
1024
    gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dlg)->vbox,
 
1025
                        prg, FALSE, FALSE, 4 );
 
1026
    btn = gtk_dialog_add_button ( GTK_DIALOG (dlg),
 
1027
                                  GTK_STOCK_CANCEL,
 
1028
                                  GTK_RESPONSE_CANCEL );
 
1029
 
 
1030
    g_signal_connect ( (GObject *) dlg, "delete_event",
 
1031
                       (GCallback) sp_export_progress_delete, base);
 
1032
    g_signal_connect ( (GObject *) btn, "clicked",
 
1033
                       (GCallback) sp_export_progress_cancel, base);
 
1034
    gtk_window_set_modal ((GtkWindow *) dlg, TRUE);
 
1035
    gtk_widget_show_all (dlg);
 
1036
 
 
1037
    return dlg;
 
1038
}
 
1039
 
 
1040
// FIXME: Some lib function should be available to do this ...
 
1041
static gchar *
 
1042
filename_add_extension (const gchar *filename, const gchar *extension)
 
1043
{
 
1044
  gchar *dot;
 
1045
 
 
1046
  dot = strrchr (filename, '.');
 
1047
  if ( !dot )
 
1048
    return g_strconcat (filename, ".", extension, NULL);
 
1049
  {
 
1050
    if (dot[1] == '\0')
 
1051
      return g_strconcat (filename, extension, NULL);
 
1052
    else
 
1053
    {
 
1054
      if (g_strcasecmp (dot + 1, extension) == 0)
 
1055
        return g_strdup (filename);
 
1056
      else
 
1057
      {
 
1058
        return g_strconcat (filename, ".", extension, NULL);
 
1059
      }
 
1060
    }
 
1061
  }
 
1062
}
 
1063
 
996
1064
/// Called when export button is clicked
997
1065
static void
998
 
sp_export_export_clicked (GtkButton *button, GtkObject *base)
 
1066
sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
999
1067
{
1000
1068
    if (!SP_ACTIVE_DESKTOP) return;
1001
1069
 
 
1070
    SPNamedView *nv = sp_desktop_namedview(SP_ACTIVE_DESKTOP);
 
1071
 
 
1072
    GtkWidget *be = (GtkWidget *)gtk_object_get_data(base, "batch_checkbox");
 
1073
    GtkWidget *he = (GtkWidget *)gtk_object_get_data(base, "hide_checkbox");
 
1074
    bool hide = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (he));
 
1075
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (be))) {
 
1076
        // Batch export of selected objects
 
1077
 
 
1078
        gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList());
 
1079
        gint n = 0;
 
1080
 
 
1081
        if (num < 1)
 
1082
            return;
 
1083
 
 
1084
        gchar *progress_text = g_strdup_printf (_("Exporting %d files"), num);
 
1085
        GtkWidget *prog_dlg = create_progress_dialog (base, progress_text);
 
1086
        g_free (progress_text);
 
1087
 
 
1088
        for (GSList *i = (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList();
 
1089
             i != NULL;
 
1090
             i = i->next) {
 
1091
            SPItem *item = (SPItem *) i->data;
 
1092
            // retrieve export filename hint
 
1093
            const gchar *fn = SP_OBJECT_REPR(item)->attribute("inkscape:export-filename");
 
1094
            if (!fn) {
 
1095
                fn = create_filepath_from_id (SP_OBJECT_ID(item), NULL);
 
1096
            }
 
1097
 
 
1098
            // retrieve export dpi hints
 
1099
            const gchar *dpi_hint = SP_OBJECT_REPR(item)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
 
1100
            gdouble dpi = 0.0;
 
1101
            if (dpi_hint) {
 
1102
                dpi = atof(dpi_hint);
 
1103
            }
 
1104
            if (dpi == 0.0) {
 
1105
                dpi = DPI_BASE;
 
1106
            }
 
1107
 
 
1108
            NRRect area;
 
1109
            sp_item_invoke_bbox(item, &area, sp_item_i2r_affine((SPItem *) item), TRUE);
 
1110
 
 
1111
            gint width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
 
1112
            gint height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
 
1113
 
 
1114
            if (width > 1 && height > 1) {
 
1115
                /* Do export */
 
1116
                if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), fn,
 
1117
                                         area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi,
 
1118
                                         nv->pagecolor,
 
1119
                                         NULL, NULL, TRUE,  // overwrite without asking
 
1120
                                         hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL
 
1121
                        )) {
 
1122
                    gchar * error;
 
1123
                    gchar * safeFile = Inkscape::IO::sanitizeString(fn);
 
1124
                    error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
 
1125
                    sp_ui_error_dialog(error);
 
1126
                    g_free(safeFile);
 
1127
                    g_free(error);
 
1128
                }
 
1129
            }
 
1130
            n++;
 
1131
            sp_export_progress_callback((float)n/num, base);
 
1132
        }
 
1133
 
 
1134
        gtk_widget_destroy (prog_dlg);
 
1135
        g_object_set_data (G_OBJECT (base), "cancel", (gpointer) 0);
 
1136
 
 
1137
    } else {
 
1138
 
1002
1139
    GtkWidget *fe = (GtkWidget *)gtk_object_get_data(base, "filename");
1003
1140
    gchar const *filename = gtk_entry_get_text(GTK_ENTRY(fe));
1004
1141
 
1008
1145
    float const y1 = sp_export_value_get_px(base, "y1");
1009
1146
    float const xdpi = sp_export_value_get(base, "xdpi");
1010
1147
    float const ydpi = sp_export_value_get(base, "ydpi");
1011
 
    int const width = int(sp_export_value_get(base, "bmwidth") + 0.5);
1012
 
    int const height = int(sp_export_value_get(base, "bmheight") + 0.5);
 
1148
    unsigned long int const width = int(sp_export_value_get(base, "bmwidth") + 0.5);
 
1149
    unsigned long int const height = int(sp_export_value_get(base, "bmheight") + 0.5);
1013
1150
 
1014
1151
    if (filename == NULL || *filename == '\0') {
1015
1152
        sp_ui_error_dialog(_("You have to enter a filename"));
1021
1158
        return;
1022
1159
    }
1023
1160
 
1024
 
    gchar *dirname = g_dirname(filename);
 
1161
    gchar *dirname = g_path_get_dirname(filename);
1025
1162
    if ( dirname == NULL
1026
1163
         || !Inkscape::IO::file_test(dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) )
1027
1164
    {
1036
1173
    }
1037
1174
    g_free(dirname);
1038
1175
 
1039
 
    SPNamedView *nv = sp_desktop_namedview(SP_ACTIVE_DESKTOP);
1040
 
    GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */
1041
 
    char *fn;
1042
 
    gchar *text;
1043
 
 
1044
 
    dlg = gtk_dialog_new ();
1045
 
    gtk_window_set_title (GTK_WINDOW (dlg), _("Export in progress"));
1046
 
    prg = gtk_progress_bar_new ();
1047
 
    sp_transientize (dlg);
1048
 
    gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
1049
 
    g_object_set_data ((GObject *) base, "progress", prg);
1050
 
    fn = g_path_get_basename (filename);
1051
 
    text = g_strdup_printf ( _("Exporting %s (%d x %d)"), 
1052
 
                             fn, width, height);
 
1176
    // make sure that .png is the extension of the file:
 
1177
    gchar * filename_ext = filename_add_extension(filename, "png");
 
1178
    gtk_entry_set_text(GTK_ENTRY(fe), filename_ext);
 
1179
 
 
1180
    gchar *fn = g_path_get_basename (filename_ext);
 
1181
 
 
1182
    gchar *progress_text = g_strdup_printf (_("Exporting %s (%lu x %lu)"), fn, width, height);
1053
1183
    g_free (fn);
1054
 
    gtk_progress_bar_set_text ((GtkProgressBar *) prg, text);
1055
 
    g_free (text);
1056
 
    gtk_progress_bar_set_orientation ( (GtkProgressBar *) prg, 
1057
 
                                       GTK_PROGRESS_LEFT_TO_RIGHT);
1058
 
    gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dlg)->vbox, 
1059
 
                        prg, FALSE, FALSE, 4 );
1060
 
    btn = gtk_dialog_add_button ( GTK_DIALOG (dlg), 
1061
 
                                  GTK_STOCK_CANCEL, 
1062
 
                                  GTK_RESPONSE_CANCEL );
1063
 
                                  
1064
 
    g_signal_connect ( (GObject *) dlg, "delete_event", 
1065
 
                       (GCallback) sp_export_progress_delete, base);
1066
 
    g_signal_connect ( (GObject *) btn, "clicked", 
1067
 
                       (GCallback) sp_export_progress_cancel, base);
1068
 
    gtk_window_set_modal ((GtkWindow *) dlg, TRUE);
1069
 
    gtk_widget_show_all (dlg);
1070
 
    
 
1184
    GtkWidget *prog_dlg = create_progress_dialog (base, progress_text);
 
1185
    g_free (progress_text);
 
1186
 
1071
1187
    /* Do export */
1072
 
    if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), filename, 
1073
 
                             x0, y0, x1, y1, width, height, xdpi, ydpi, 
1074
 
                             nv->pagecolor, 
1075
 
                             sp_export_progress_callback, base)) {
 
1188
    if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), filename_ext,
 
1189
                             x0, y0, x1, y1, width, height, xdpi, ydpi,
 
1190
                             nv->pagecolor,
 
1191
                             sp_export_progress_callback, base, FALSE,
 
1192
                             hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL
 
1193
            )) {
1076
1194
        gchar * error;
1077
1195
        gchar * safeFile = Inkscape::IO::sanitizeString(filename);
1078
1196
        error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
1084
1202
    /* Reset the filename so that it can be changed again by changing
1085
1203
       selections and all that */
1086
1204
    g_free(original_name);
1087
 
    original_name = g_strdup(filename);
 
1205
    original_name = g_strdup(filename_ext);
1088
1206
    gtk_object_set_data (GTK_OBJECT (base), "filename-modified", (gpointer)FALSE);
1089
1207
 
1090
 
    gtk_widget_destroy (dlg);
 
1208
    gtk_widget_destroy (prog_dlg);
1091
1209
    g_object_set_data (G_OBJECT (base), "cancel", (gpointer) 0);
1092
1210
 
1093
1211
    /* Setup the values in the document */
1096
1214
        case SELECTION_DRAWING: {
1097
1215
            SPDocument * doc = SP_ACTIVE_DOCUMENT;
1098
1216
            Inkscape::XML::Node * repr = sp_document_repr_root(doc);
1099
 
            bool modified = FALSE;
 
1217
            bool modified = false;
1100
1218
            const gchar * temp_string;
1101
1219
 
1102
1220
            bool saved = sp_document_get_undo_sensitive(doc);
1103
 
            sp_document_set_undo_sensitive(doc, FALSE);
 
1221
            sp_document_set_undo_sensitive(doc, false);
1104
1222
 
1105
1223
            temp_string = repr->attribute("inkscape:export-filename");
1106
 
            if (temp_string == NULL || strcmp(temp_string, filename)) {
1107
 
                repr->setAttribute("inkscape:export-filename", filename);
1108
 
                modified = TRUE;
 
1224
            if (temp_string == NULL || strcmp(temp_string, filename_ext)) {
 
1225
                repr->setAttribute("inkscape:export-filename", filename_ext);
 
1226
                modified = true;
1109
1227
            }
1110
1228
            temp_string = repr->attribute("inkscape:export-xdpi");
1111
1229
            if (temp_string == NULL || xdpi != atof(temp_string)) {
1112
1230
                sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
1113
 
                modified = TRUE;
 
1231
                modified = true;
1114
1232
            }
1115
1233
            temp_string = repr->attribute("inkscape:export-ydpi");
1116
1234
            if (temp_string == NULL || xdpi != atof(temp_string)) {
1117
1235
                sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
1118
 
                modified = TRUE;
 
1236
                modified = true;
1119
1237
            }
 
1238
            sp_document_set_undo_sensitive(doc, saved);
1120
1239
 
1121
 
            if (modified)
1122
 
                repr->setAttribute("sodipodi:modified", "TRUE");
1123
 
            sp_document_set_undo_sensitive(doc, saved);
 
1240
            if (modified) {
 
1241
                doc->setModifiedSinceSave();
 
1242
            }
1124
1243
            break;
1125
1244
        }
1126
1245
        case SELECTION_SELECTION: {
1127
1246
            const GSList * reprlst;
1128
1247
            SPDocument * doc = SP_ACTIVE_DOCUMENT;
1129
 
            bool modified = FALSE;
 
1248
            bool modified = false;
1130
1249
 
1131
1250
            bool saved = sp_document_get_undo_sensitive(doc);
1132
 
            sp_document_set_undo_sensitive(doc, FALSE);
 
1251
            sp_document_set_undo_sensitive(doc, false);
1133
1252
            reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
1134
1253
 
1135
1254
            for(; reprlst != NULL; reprlst = reprlst->next) {
1137
1256
                const gchar * temp_string;
1138
1257
 
1139
1258
                if (repr->attribute("id") == NULL ||
1140
 
                        !(g_strrstr(filename, repr->attribute("id")) != NULL &&
 
1259
                        !(g_strrstr(filename_ext, repr->attribute("id")) != NULL &&
1141
1260
                          (!SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT) ||
1142
1261
                            strcmp(g_dirname(filename), g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT))) == 0))) {
1143
1262
                    temp_string = repr->attribute("inkscape:export-filename");
1144
 
                    if (temp_string == NULL || strcmp(temp_string, filename)) {
1145
 
                        repr->setAttribute("inkscape:export-filename", filename);
1146
 
                        modified = TRUE;
 
1263
                    if (temp_string == NULL || strcmp(temp_string, filename_ext)) {
 
1264
                        repr->setAttribute("inkscape:export-filename", filename_ext);
 
1265
                        modified = true;
1147
1266
                    }
1148
1267
                }
1149
1268
                temp_string = repr->attribute("inkscape:export-xdpi");
1150
1269
                if (temp_string == NULL || xdpi != atof(temp_string)) {
1151
1270
                    sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
1152
 
                    modified = TRUE;
 
1271
                    modified = true;
1153
1272
                }
1154
1273
                temp_string = repr->attribute("inkscape:export-ydpi");
1155
1274
                if (temp_string == NULL || xdpi != atof(temp_string)) {
1156
1275
                    sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
1157
 
                    modified = TRUE;
 
1276
                    modified = true;
1158
1277
                }
1159
1278
            }
 
1279
            sp_document_set_undo_sensitive(doc, saved);
1160
1280
 
1161
1281
            if (modified) {
1162
 
                Inkscape::XML::Node * repr = sp_document_repr_root(doc);
1163
 
                repr->setAttribute("sodipodi:modified", "TRUE");
 
1282
                doc->setModifiedSinceSave();
1164
1283
            }
1165
 
 
1166
 
            sp_document_set_undo_sensitive(doc, saved);
1167
1284
            break;
1168
1285
        }
1169
1286
        default:
1170
1287
            break;
1171
1288
    }
1172
1289
 
1173
 
 
1174
 
    return;
 
1290
    g_free (filename_ext);
 
1291
 
 
1292
    }
 
1293
 
1175
1294
} // end of sp_export_export_clicked()
1176
1295
 
1177
1296
/// Called when Browse button is clicked
1178
1297
static void
1179
 
sp_export_browse_clicked (GtkButton *button, gpointer userdata)
 
1298
sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
1180
1299
{
1181
1300
    GtkWidget *fs, *fe;
1182
1301
    const gchar *filename;
1183
1302
 
1184
1303
    fs = gtk_file_chooser_dialog_new (_("Select a filename for exporting"),
1185
 
                                      NULL,
 
1304
                                      (GtkWindow*)dlg,
1186
1305
                                      GTK_FILE_CHOOSER_ACTION_SAVE,
1187
1306
                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1188
1307
                                      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
1189
1308
                                      NULL );
1190
1309
 
 
1310
#ifdef WITH_GNOME_VFS
 
1311
    if (gnome_vfs_initialized()) {
 
1312
        gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fs), false);
 
1313
    }
 
1314
#endif
 
1315
 
1191
1316
    fe = (GtkWidget *)g_object_get_data (G_OBJECT (dlg), "filename");
1192
1317
 
1193
1318
    sp_transientize (fs);
1207
1332
        gchar *file;
1208
1333
 
1209
1334
        file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fs));
 
1335
 
1210
1336
        gchar * utf8file = g_filename_to_utf8( file, -1, NULL, NULL, NULL );
1211
1337
        gtk_entry_set_text (GTK_ENTRY (fe), utf8file);
 
1338
 
 
1339
        g_object_set_data (G_OBJECT (dlg), "filename", fe);
 
1340
 
1212
1341
        g_free(utf8file);
1213
 
 
1214
 
        g_object_set_data (G_OBJECT (dlg), "filename", fe);
1215
1342
        g_free(file);
1216
1343
    }
1217
1344
 
1223
1350
// TODO: Move this to nr-rect-fns.h.
1224
1351
static bool
1225
1352
sp_export_bbox_equal(NR::Rect const &one, NR::Rect const &two)
1226
 
 
1353
{
1227
1354
    double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION);
1228
1355
    return (
1229
1356
        (fabs(one.min()[NR::X] - two.min()[NR::X]) < epsilon) &&
1283
1410
        switch (this_test[i]) {
1284
1411
            case SELECTION_SELECTION:
1285
1412
                if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
1286
 
                    NR::Rect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds();
 
1413
                    NR::Maybe<NR::Rect> bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds();
1287
1414
 
1288
1415
                    //std::cout << "Selection " << bbox;
1289
 
                    if (sp_export_bbox_equal(bbox,current_bbox)) {
 
1416
                    if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) {
1290
1417
                        key = SELECTION_SELECTION;
1291
1418
                    }
1292
1419
                }
1294
1421
            case SELECTION_DRAWING: {
1295
1422
                SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
1296
1423
 
1297
 
                NR::Rect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
 
1424
                NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
1298
1425
 
1299
1426
                // std::cout << "Drawing " << bbox2;
1300
 
                if (sp_export_bbox_equal(bbox,current_bbox)) {
 
1427
                if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) {
1301
1428
                    key = SELECTION_DRAWING;
1302
1429
                }
1303
1430
                break;
1435
1562
 
1436
1563
/// Called when x1-x0 or area width is changed
1437
1564
static void
1438
 
sp_export_area_width_value_changed (GtkAdjustment *adj, GtkObject *base)
 
1565
sp_export_area_width_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
1439
1566
{
1440
1567
    float x0, x1, xdpi, width, bmwidth;
1441
1568
 
1472
1599
 
1473
1600
/// Called when y1-y0 or area height is changed.
1474
1601
static void
1475
 
sp_export_area_height_value_changed (GtkAdjustment *adj, GtkObject *base)
 
1602
sp_export_area_height_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
1476
1603
{
1477
1604
 
1478
1605
    float y0, y1, ydpi, height, bmheight;
1555
1682
 
1556
1683
/// Called when pixel width is changed
1557
1684
static void
1558
 
sp_export_bitmap_width_value_changed (GtkAdjustment *adj, GtkObject *base)
 
1685
sp_export_bitmap_width_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
1559
1686
{
1560
1687
    float x0, x1, bmwidth, xdpi;
1561
1688
 
1590
1717
 
1591
1718
/// Called when pixel height is changed
1592
1719
static void
1593
 
sp_export_bitmap_height_value_changed (GtkAdjustment *adj, GtkObject *base)
 
1720
sp_export_bitmap_height_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
1594
1721
{
1595
1722
    float y0, y1, bmheight, xdpi;
1596
1723
 
1652
1779
    currently be independent.  This is likely to change in the future.
1653
1780
*/
1654
1781
void
1655
 
sp_export_xdpi_value_changed (GtkAdjustment *adj, GtkObject *base)
 
1782
sp_export_xdpi_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
1656
1783
{
1657
1784
    float x0, x1, xdpi, bmwidth;
1658
1785