27
26
# include "config.h"
30
30
#include <glib/gmem.h>
31
#include <glibmm/i18n.h>
31
32
#include <libnr/nr-pixops.h>
34
#include "application/application.h"
35
#include "application/editor.h"
37
#include "desktop-handles.h"
38
#include "dialogs/export.h"
33
40
#include "document-private.h"
34
#include "selection-chemistry.h"
35
#include "ui/view/view-widget.h"
41
#include "extension/db.h"
42
#include "extension/input.h"
43
#include "extension/output.h"
44
#include "extension/system.h"
37
46
#include "helper/png-write.h"
38
#include "dialogs/export.h"
39
#include <glibmm/i18n.h>
42
#include "selection.h"
43
50
#include "interface.h"
47
52
#include "message.h"
48
53
#include "message-stack.h"
54
#include "path-prefix.h"
55
#include "preferences.h"
58
#include "selection-chemistry.h"
59
#include "selection.h"
60
#include "sp-namedview.h"
49
62
#include "ui/dialog/filedialog.h"
50
63
#include "ui/dialog/ocaldialogs.h"
51
#include "prefs-utils.h"
52
#include "path-prefix.h"
54
#include "sp-namedview.h"
55
#include "desktop-handles.h"
57
#include "extension/db.h"
58
#include "extension/input.h"
59
#include "extension/output.h"
60
/* #include "extension/menu.h" */
61
#include "extension/system.h"
64
#include "application/application.h"
65
#include "application/editor.h"
64
#include "ui/view/view-widget.h"
66
#include "xml/rebase-hrefs.h"
69
68
#ifdef WITH_GNOME_VFS
70
69
# include <libgnomevfs/gnome-vfs.h>
377
402
sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*data*/)
380
404
//# Get the current directory for finding files
381
Glib::ustring open_path;
382
char *attr = (char *)prefs_get_string_attribute("dialogs.open", "path");
405
static Glib::ustring open_path;
406
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
408
if(open_path.empty())
410
Glib::ustring attr = prefs->getString("/dialogs/open/path");
411
if (!attr.empty()) open_path = attr;
387
414
//# Test if the open_path directory exists
388
415
if (!Inkscape::IO::file_test(open_path.c_str(),
389
416
(GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
420
//# If no open path, default to our win32 documents folder
421
if (open_path.empty())
423
// The path to the My Documents folder is read from the
424
// value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal"
426
if(RegOpenKeyExA(HKEY_CURRENT_USER,
427
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
428
0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
430
WCHAR utf16path[_MAX_PATH];
432
DWORD data_size = sizeof(utf16path);
433
if(RegQueryValueExW(key, L"Personal", NULL, &value_type,
434
(BYTE*)utf16path, &data_size) == ERROR_SUCCESS)
436
g_assert(value_type == REG_SZ);
437
gchar *utf8path = g_utf16_to_utf8(
438
(const gunichar2*)utf16path, -1, NULL, NULL, NULL);
441
open_path = Glib::ustring(utf8path);
392
449
//# If no open path, default to our home directory
393
if (open_path.size() < 1)
450
if (open_path.empty())
395
452
open_path = g_get_home_dir();
396
453
open_path.append(G_DIR_SEPARATOR_S);
399
//# Create a dialog if we don't already have one
400
if (!openDialogInstance) {
457
Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance =
402
458
Inkscape::UI::Dialog::FileOpenDialog::create(
459
parentWindow, open_path,
405
460
Inkscape::UI::Dialog::SVG_TYPES,
406
(char const *)_("Select file to open"));
461
_("Select file to open"));
410
463
//# Show the dialog
411
464
bool const success = openDialogInstance->show();
466
//# Save the folder the user selected for later
467
open_path = openDialogInstance->getCurrentDirectory();
471
delete openDialogInstance;
415
475
//# User selected something. Get name and type
416
476
Glib::ustring fileName = openDialogInstance->getFilename();
417
478
Inkscape::Extension::Extension *selection =
418
479
openDialogInstance->getSelectionType();
420
//# Code to check & open iff multiple files.
421
std::vector<Glib::ustring> flist=openDialogInstance->getFilenames();
481
//# Code to check & open if multiple files.
482
std::vector<Glib::ustring> flist = openDialogInstance->getFilenames();
484
//# We no longer need the file dialog object - delete it
485
delete openDialogInstance;
486
openDialogInstance = NULL;
423
488
//# Iterate through filenames if more than 1
424
489
if (flist.size() > 1)
491
for (unsigned int i = 0; i < flist.size(); i++)
426
for (unsigned int i=1 ; i<flist.size() ; i++)
428
Glib::ustring fName = flist[i];
430
if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) {
431
Glib::ustring newFileName = Glib::filename_to_utf8(fName);
495
Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
432
496
if ( newFileName.size() > 0 )
497
fileName = newFileName;
435
499
g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
437
501
#ifdef INK_DUMP_FILENAME_CONV
438
g_message("Opening File %s\n",fileName);
502
g_message("Opening File %s\n", fileName.c_str());
440
504
sp_file_open(fileName, selection);
447
if (fileName.size() > 0) {
511
if (!fileName.empty())
449
513
Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
451
515
if ( newFileName.size() > 0)
708
777
dialog_title = (char const *) _("Select file to save to");
779
gchar* doc_title = doc->root->title();
710
780
Inkscape::UI::Dialog::FileSaveDialog *saveDialog =
711
781
Inkscape::UI::Dialog::FileSaveDialog::create(
714
784
Inkscape::UI::Dialog::SVG_TYPES,
715
(char const *) _("Select file to save to"),
787
doc_title ? doc_title : ""
719
saveDialog->change_title(dialog_title);
720
790
saveDialog->setSelectionType(extension);
722
// allow easy access to the user's own templates folder
723
gchar *templates = profile_path ("templates");
724
if (Inkscape::IO::file_test(templates, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
725
dynamic_cast<Gtk::FileChooser *>(saveDialog)->add_shortcut_folder(templates);
729
792
bool success = saveDialog->show();
731
794
delete saveDialog;
798
// set new title here (call RDF to ensure metadata and title element are updated)
799
rdf_set_work_entity(doc, rdf_find_entity("title"), saveDialog->getDocTitle().c_str());
800
// free up old string
801
if(doc_title) g_free(doc_title);
735
803
Glib::ustring fileName = saveDialog->getFilename();
736
804
Inkscape::Extension::Extension *selectionType = saveDialog->getSelectionType();
861
931
if (doc != NULL) {
862
// move imported defs to our document's defs
932
Inkscape::XML::rebase_hrefs(doc, in_doc->base, true);
933
Inkscape::XML::Document *xml_in_doc = sp_document_repr_doc(in_doc);
935
prevent_id_clashes(doc, in_doc);
863
937
SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
864
SPObject *defs = SP_DOCUMENT_DEFS(doc);
866
Inkscape::IO::fixupHrefs(doc, in_doc->base, true);
867
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
869
938
Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();
870
for (SPObject *child = sp_object_first_child(defs);
940
SPCSSAttr *style = sp_css_attr_from_object(SP_DOCUMENT_ROOT(doc));
942
// Count the number of top-level items in the imported document.
943
guint items_count = 0;
944
for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
871
945
child != NULL; child = SP_OBJECT_NEXT(child))
873
// FIXME: in case of id conflict, newly added thing will be re-ided and thus likely break a reference to it from imported stuff
874
SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(child)->duplicate(xml_doc), last_def);
877
guint items_count = 0;
878
for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
879
child != NULL; child = SP_OBJECT_NEXT(child)) {
880
if (SP_IS_ITEM(child))
883
SPCSSAttr *style = sp_css_attr_from_object (SP_DOCUMENT_ROOT (doc));
947
if (SP_IS_ITEM(child)) items_count++;
950
// Create a new group if necessary.
951
Inkscape::XML::Node *newgroup = NULL;
952
if ((style && style->firstChild()) || items_count > 1) {
953
newgroup = xml_in_doc->createElement("svg:g");
954
sp_repr_css_set(newgroup, style, "style");
957
// Determine the place to insert the new object.
958
// This will be the current layer, if possible.
959
// FIXME: If there's no desktop (command line run?) we need
960
// a document:: method to return the current layer.
961
// For now, we just use the root in this case.
962
SPObject *place_to_insert;
964
place_to_insert = desktop->currentLayer();
966
place_to_insert = SP_DOCUMENT_ROOT(in_doc);
969
// Construct a new object representing the imported image,
970
// and insert it into the current document.
885
971
SPObject *new_obj = NULL;
887
if ((style && style->firstChild()) || items_count > 1) {
889
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(in_doc);
890
Inkscape::XML::Node *newgroup = xml_doc->createElement("svg:g");
891
sp_repr_css_set (newgroup, style, "style");
893
for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) {
894
if (SP_IS_ITEM(child)) {
895
Inkscape::XML::Node *newchild = SP_OBJECT_REPR(child)->duplicate(xml_doc);
897
// convert layers to groups; FIXME: add "preserve layers" mode where each layer
898
// from impot is copied to the same-named layer in host
899
newchild->setAttribute("inkscape:groupmode", NULL);
901
newgroup->appendChild(newchild);
906
// Add it to the current layer
907
new_obj = desktop->currentLayer()->appendChildRepr(newgroup);
909
// There's no desktop (command line run?)
910
// FIXME: For such cases we need a document:: method to return the current layer
911
new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newgroup);
914
Inkscape::GC::release(newgroup);
917
for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) {
918
if (SP_IS_ITEM(child)) {
919
Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(xml_doc);
920
newitem->setAttribute("inkscape:groupmode", NULL);
923
// Add it to the current layer
924
new_obj = desktop->currentLayer()->appendChildRepr(newitem);
926
// There's no desktop (command line run?)
927
// FIXME: For such cases we need a document:: method to return the current layer
928
new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newitem);
972
for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
973
child != NULL; child = SP_OBJECT_NEXT(child) )
975
if (SP_IS_ITEM(child)) {
976
Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(xml_in_doc);
978
// convert layers to groups, and make sure they are unlocked
979
// FIXME: add "preserve layers" mode where each layer from
980
// import is copied to the same-named layer in host
981
newitem->setAttribute("inkscape:groupmode", NULL);
982
newitem->setAttribute("sodipodi:insensitive", NULL);
984
if (newgroup) newgroup->appendChild(newitem);
985
else new_obj = place_to_insert->appendChildRepr(newitem);
988
// don't lose top-level defs or style elements
989
else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
990
const gchar *tag = SP_OBJECT_REPR(child)->name();
991
if (!strcmp(tag, "svg:defs")) {
992
for (SPObject *x = sp_object_first_child(child);
993
x != NULL; x = SP_OBJECT_NEXT(x))
995
SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(x)->duplicate(xml_in_doc), last_def);
998
else if (!strcmp(tag, "svg:style")) {
999
SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(SP_OBJECT_REPR(child)->duplicate(xml_in_doc));
1003
if (newgroup) new_obj = place_to_insert->appendChildRepr(newgroup);
935
if (style) sp_repr_css_attr_unref (style);
1005
// release some stuff
1006
if (newgroup) Inkscape::GC::release(newgroup);
1007
if (style) sp_repr_css_attr_unref(style);
937
1009
// select and move the imported item
938
1010
if (new_obj && SP_IS_ITEM(new_obj)) {
939
1011
Inkscape::Selection *selection = sp_desktop_selection(desktop);
940
1012
selection->set(SP_ITEM(new_obj));
942
// To move the imported object, we must temporarily set the "transform pattern with
1014
// preserve parent and viewBox transformations
1015
// c2p is identity matrix at this point unless sp_document_ensure_up_to_date is called
1016
sp_document_ensure_up_to_date(doc);
1017
Geom::Matrix affine = SP_ROOT(SP_DOCUMENT_ROOT(doc))->c2p * sp_item_i2doc_affine(SP_ITEM(place_to_insert)).inverse();
1018
sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false);
1020
// move to mouse pointer
945
int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1);
946
prefs_set_int_attribute("options.transform", "pattern", 1);
947
1022
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
948
NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
1023
Geom::OptRect sel_bbox = selection->bounds();
950
NR::Point m( desktop->point() - sel_bbox->midpoint() );
951
sp_selection_move_relative(selection, m);
1025
Geom::Point m( desktop->point() - sel_bbox->midpoint() );
1026
sp_selection_move_relative(selection, m, false);
953
prefs_set_int_attribute("options.transform", "pattern", saved_pref);
1251
1334
// Start now the submition
1253
1336
// Create the uri
1337
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1254
1338
Glib::ustring uri = "dav://";
1255
char *username = (char *)prefs_get_string_attribute("options.ocalusername", "str");
1256
char *password = (char *)prefs_get_string_attribute("options.ocalpassword", "str");
1257
if ((username == NULL) || (!strcmp(username, "")) || (password == NULL) || (!strcmp(password, "")))
1339
Glib::ustring username = prefs->getString("/options/ocalusername/str");
1340
Glib::ustring password = prefs->getString("/options/ocalpassword/str");
1341
if (username.empty() || password.empty())
1343
Inkscape::UI::Dialog::FileExportToOCALPasswordDialog *exportPasswordDialogInstance = NULL;
1259
1344
if(!gotSuccess)
1261
if (!exportPasswordDialogInstance)
1262
exportPasswordDialogInstance = new Inkscape::UI::Dialog::FileExportToOCALPasswordDialog(
1346
exportPasswordDialogInstance = new Inkscape::UI::Dialog::FileExportToOCALPasswordDialog(
1264
1348
(char const *) _("Open Clip Art Login"));
1265
1349
success = exportPasswordDialogInstance->show();
1351
delete exportPasswordDialogInstance;
1267
1352
return success;
1269
username = (char *)exportPasswordDialogInstance->getUsername().c_str();
1270
password = (char *)exportPasswordDialogInstance->getPassword().c_str();
1355
username = exportPasswordDialogInstance->getUsername();
1356
password = exportPasswordDialogInstance->getPassword();
1358
delete exportPasswordDialogInstance;
1359
exportPasswordDialogInstance = NULL;
1272
1361
uri.append(username);
1273
1362
uri.append(":");
1274
1363
uri.append(password);
1275
1364
uri.append("@");
1276
uri.append(prefs_get_string_attribute("options.ocalurl", "str"));
1365
uri.append(prefs->getString("/options/ocalurl/str"));
1277
1366
uri.append("/dav.php/");
1278
1367
uri.append(Glib::path_get_basename(fileName));
1395
void Inkscape::IO::fixupHrefs( SPDocument *doc, const gchar *base, gboolean spns )
1397
//g_message("Inkscape::IO::fixupHrefs( , [%s], )", base );
1400
gchar const* things[] = {
1402
"http://www.google.com/image.png",
1403
"ftp://ssd.com/doo",
1406
"file:/foo/dee/bar.svg",
1407
"file:///foo/dee/bar.svg",
1409
"/foo/bar\xe1\x84\x92.svg",
1410
"file:///foo/bar\xe1\x84\x92.svg",
1411
"file:///foo/bar%e1%84%92.svg",
1412
"/foo/bar%e1%84%92.svg",
1413
"bar\xe1\x84\x92.svg",
1417
g_message("+------");
1418
for ( int i = 0; things[i]; i++ )
1423
gboolean isAbs = g_path_is_absolute( things[i] );
1424
gchar *str = uri.toString();
1425
g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs,
1426
(int)uri.isRelative(),
1434
catch ( MalformedURIException err )
1436
dump_str( things[i], "MalformedURIException" );
1437
xmlChar *redo = xmlURIEscape((xmlChar const *)things[i]);
1438
g_message(" gone from [%s] to [%s]", things[i], redo );
1441
URI again = URI::fromUtf8( things[i] );
1442
gboolean isAbs = g_path_is_absolute( things[i] );
1443
gchar *str = again.toString();
1444
g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs,
1445
(int)again.isRelative(),
1456
g_message("+------");
1459
GSList const *images = sp_document_get_resource_list(doc, "image");
1460
for (GSList const *l = images; l != NULL; l = l->next) {
1461
Inkscape::XML::Node *ir = SP_OBJECT_REPR(l->data);
1463
const gchar *href = ir->attribute("xlink:href");
1465
// First try to figure out an absolute path to the asset
1466
//g_message("image href [%s]", href );
1467
if (spns && !g_path_is_absolute(href)) {
1468
const gchar *absref = ir->attribute("sodipodi:absref");
1469
const gchar *base_href = g_build_filename(base, href, NULL);
1470
//g_message(" absr [%s]", absref );
1472
if ( absref && Inkscape::IO::file_test(absref, G_FILE_TEST_EXISTS) && !Inkscape::IO::file_test(base_href, G_FILE_TEST_EXISTS))
1474
// only switch over if the absref is valid while href is not
1476
//g_message(" copied absref to href");
1480
// Once we have an absolute path, convert it relative to the new location
1481
if (href && g_path_is_absolute(href)) {
1482
const gchar *relname = sp_relative_path_from_path(href, base);
1483
//g_message(" setting to [%s]", relname );
1484
ir->setAttribute("xlink:href", relname);
1486
// TODO next refinement is to make the first choice keeping the relative path as-is if
1487
// based on the new location it gives us a valid file.
1493
1490
Local Variables: