diff --git a/src/attributes.cpp b/src/attributes.cpp
index b2c676e8842ed58a26f3c8a2f4192b24235be579..e98f84700c08a8706b5d5481da15c375b509c2d0 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -137,6 +137,7 @@ static SPStyleProp const props[] = {
/* SPImage */
{SP_ATTR_X, "x"},
{SP_ATTR_Y, "y"},
+ {SP_ATTR_SVG_DPI, "inkscape:svg-dpi"},
/* SPPath */
{SP_ATTR_INKSCAPE_ORIGINAL_D, "inkscape:original-d"},
/* (Note: XML representation of connectors may change in future.) */
diff --git a/src/attributes.h b/src/attributes.h
index caad42f71dfbe2065fb5930c73e6e2d7d42471f1..c840161386ba7f1a7d0c4c1ae42d841a180971f6 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -145,6 +145,7 @@ enum SPAttributeEnum {
/* SPImage, SPRect, etc. */
SP_ATTR_X,
SP_ATTR_Y,
+ SP_ATTR_SVG_DPI,
/* SPPath */
// SP_ATTR_D, Promoted to property in SVG 2
SP_ATTR_INKSCAPE_ORIGINAL_D,
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp
index e34e4cd6b78d5e5f2016f96e99050fed529adc63..7279ac05233bf0b4f71c121174f413dd452087b3 100644
--- a/src/display/cairo-utils.cpp
+++ b/src/display/cairo-utils.cpp
@@ -207,7 +207,7 @@ Pixbuf::~Pixbuf()
}
}
-Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data)
+Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data, char const *svgdpi)
{
Pixbuf *pixbuf = nullptr;
@@ -310,7 +310,11 @@ Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data)
return nullptr;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- const double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0);
+ double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0);
+ if (svgdpi && atof(svgdpi) > 0) {
+ dpi = atof(svgdpi);
+ }
+ std::cout << dpi << "dpi" << std::endl;
// Get the size of the document
Inkscape::Util::Quantity svgWidth = svgDoc->getWidth();
Inkscape::Util::Quantity svgHeight = svgDoc->getHeight();
@@ -338,7 +342,7 @@ Pixbuf *Pixbuf::create_from_data_uri(gchar const *uri_data)
return pixbuf;
}
-Pixbuf *Pixbuf::create_from_file(std::string const &fn)
+Pixbuf *Pixbuf::create_from_file(std::string const &fn, char const *svgdpi)
{
Pixbuf *pb = nullptr;
// test correctness of filename
@@ -350,7 +354,6 @@ Pixbuf *Pixbuf::create_from_file(std::string const &fn)
if (val == 0 && stdir.st_mode & S_IFDIR){
return nullptr;
}
-
// we need to load the entire file into memory,
// since we'll store it as MIME data
gchar *data = nullptr;
@@ -383,7 +386,11 @@ Pixbuf *Pixbuf::create_from_file(std::string const &fn)
return nullptr;
}
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- const double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0);
+ double dpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", 96.0);
+ if (svgdpi && atof(svgdpi) > 0) {
+ dpi = atof(svgdpi);
+ }
+ std::cout << dpi << "dpi" << std::endl;
// Get the size of the document
Inkscape::Util::Quantity svgWidth = svgDoc->getWidth();
Inkscape::Util::Quantity svgHeight = svgDoc->getHeight();
diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h
index bada170ca1b51fa316cb058c6d046e93158f21fe..256bda94c3bb34de4e7df20e4dad50ec0a0ecd64 100644
--- a/src/display/cairo-utils.h
+++ b/src/display/cairo-utils.h
@@ -117,10 +117,10 @@ public:
PixelFormat pixelFormat() const { return _pixel_format; }
void ensurePixelFormat(PixelFormat fmt);
- static Pixbuf *create_from_data_uri(gchar const *uri);
- static Pixbuf *create_from_file(std::string const &fn);
+ static Pixbuf *create_from_data_uri(gchar const *uri, char const *svgdpi = NULL);
+ static Pixbuf *create_from_file(std::string const &fn, char const *svgddpi = NULL);
-private:
+ private:
void _ensurePixelsARGB32();
void _ensurePixelsPixbuf();
void _forceAlpha();
diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp
index 189ef3c58588edb21f88f3e1bd198404214b8d3d..d39f5a96039306a4eccadbc661d87694aa595e57 100644
--- a/src/extension/internal/svg.cpp
+++ b/src/extension/internal/svg.cpp
@@ -142,6 +142,7 @@ Svg::init()
"<_option value='embed' >" N_("Embed the SVG file in a image tag (not editable in this document)") "\n"
"<_option value='link' >" N_("Link the SVG file in a image tag (not editable in this document).") "\n"
"\n"
+ "96.00\n"
"\n"
"<_option value='auto' >" N_("None (auto)") "\n"
"<_option value='optimizeQuality' >" N_("Smooth (optimizeQuality)") "\n"
@@ -208,7 +209,8 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri)
Glib::ustring link_svg = prefs->getString("/dialogs/import/link_svg");
Glib::ustring scale = prefs->getString("/dialogs/import/scale");
bool is_import = false;
- if (strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") == 0) {
+ if (strcmp(prefs->getString("/options/openmethod/value").c_str(), "done") == 0 ||
+ strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") == 0) {
is_import = true;
}
if(INKSCAPE.use_gui() && is_import && ask) {
@@ -243,6 +245,8 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri)
// Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is
// what Inkscaper's expect.
image_node->setAttribute("preserveAspectRatio", "none");
+ Glib::ustring svgdpi = Glib::ustring::format(mod->get_param_float("svgdpi"));
+ image_node->setAttribute("inkscape:svg-dpi", svgdpi.c_str());
image_node->setAttribute("width", Glib::ustring::format(width));
image_node->setAttribute("height", Glib::ustring::format(height));
Glib::ustring scale = prefs->getString("/dialogs/import/scale");
@@ -254,11 +258,12 @@ Svg::open (Inkscape::Extension::Input *mod, const gchar *uri)
}
// convert filename to uri
if (embed) {
- std::unique_ptr pb(Inkscape::Pixbuf::create_from_file(uri));
+ std::unique_ptr pb(Inkscape::Pixbuf::create_from_file(uri, svgdpi.c_str()));
if(pb) {
sp_embed_svg(image_node, uri);
}
- } else {
+ }
+ else {
gchar* _uri = g_filename_to_uri(uri, nullptr, nullptr);
if(_uri) {
image_node->setAttribute("xlink:href", _uri);
diff --git a/src/extension/system.cpp b/src/extension/system.cpp
index 6802050b0c3f40ac82740b947ad8b13b57a359f4..2a74c6b0cc386de0b75846786f5f52c7cbedf67c 100644
--- a/src/extension/system.cpp
+++ b/src/extension/system.cpp
@@ -99,9 +99,10 @@ SPDocument *open(Extension *key, gchar const *filename)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool ask = prefs->getBool("/dialogs/import/ask");
Glib::ustring id = Glib::ustring(imod->get_id(), 22);
- if (id.compare( "org.inkscape.input.svg") == 0 &&
- (strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") != 0 || !ask))
- {
+ if (id.compare("org.inkscape.input.svg") == 0 &&
+ ((strcmp(prefs->getString("/options/openmethod/value").c_str(), "done") != 0 &&
+ strcmp(prefs->getString("/options/openmethod/value").c_str(), "import") != 0) ||
+ !ask)) {
show = false;
imod->set_gui(false);
} else if(strlen(imod->get_id()) > 27) {
diff --git a/src/object/sp-image.cpp b/src/object/sp-image.cpp
index a5bc115ce694b5cb81a6c06fa50f7e468abd964e..9c2fe9ac3e70b5e6b42de1e6cde245768374ac7a 100644
--- a/src/object/sp-image.cpp
+++ b/src/object/sp-image.cpp
@@ -72,7 +72,8 @@
static void sp_image_set_curve(SPImage *image);
-static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base );
+static Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base,
+ char const *svgdpi);
static void sp_image_update_arenaitem (SPImage *img, Inkscape::DrawingImage *ai);
static void sp_image_update_canvas_image (SPImage *image);
@@ -117,7 +118,9 @@ SPImage::SPImage() : SPItem(), SPViewBox() {
this->clipbox = Geom::Rect();
this->sx = this->sy = 1.0;
this->ox = this->oy = 0.0;
-
+ this->dpi = 96.00;
+ this->prev_width = 0.0;
+ this->prev_height = 0.0;
this->curve = nullptr;
this->href = nullptr;
@@ -137,6 +140,7 @@ void SPImage::build(SPDocument *document, Inkscape::XML::Node *repr) {
this->readAttr( "y" );
this->readAttr( "width" );
this->readAttr( "height" );
+ this->readAttr("inkscape:svg-dpi");
this->readAttr( "preserveAspectRatio" );
this->readAttr( "color-profile" );
@@ -216,6 +220,10 @@ void SPImage::set(unsigned int key, const gchar* value) {
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
break;
+ case SP_ATTR_SVG_DPI:
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG);
+ break;
+
case SP_ATTR_PRESERVEASPECTRATIO:
set_preserveAspectRatio( value );
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
@@ -330,11 +338,14 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) {
this->pixbuf = nullptr;
if (this->href) {
Inkscape::Pixbuf *pixbuf = nullptr;
- pixbuf = sp_image_repr_read_image (
- this->getRepr()->attribute("xlink:href"),
- this->getRepr()->attribute("sodipodi:absref"),
- doc->getBase());
-
+ const gchar *svgdpi = this->getRepr()->attribute("inkscape:svg-dpi");
+ if (!svgdpi) {
+ svgdpi = "96";
+ }
+ this->dpi = atof(svgdpi);
+ pixbuf = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"),
+ this->getRepr()->attribute("sodipodi:absref"), doc->getBase(), svgdpi);
+
if (pixbuf) {
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
if ( this->color_profile ) apply_profile( pixbuf );
@@ -348,7 +359,6 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) {
// Why continue without a pixbuf? So we can display "Missing Image" png.
// Eventually, we should properly support SVG image type (i.e. render it ourselves).
-
if (this->pixbuf) {
if (!this->x._set) {
this->x.unit = SVGLength::PX;
@@ -398,8 +408,32 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) {
this->sy = c2p[3];
}
+
+
// TODO: eliminate ox, oy, sx, sy
+
sp_image_update_canvas_image ((SPImage *) this);
+ double proportion_pixbuf = this->pixbuf->height() / (double)this->pixbuf->width();
+ double proportion_image = this->height.computed / (double)this->width.computed;
+ if (this->prev_width &&
+ (this->prev_width != this->pixbuf->width() || this->prev_height != this->pixbuf->height())) {
+ if (std::abs(this->prev_width - this->pixbuf->width()) > std::abs(this->prev_height - this->pixbuf->height())) {
+ proportion_pixbuf = this->pixbuf->width() / (double)this->pixbuf->height();
+ proportion_image = this->width.computed / (double)this->height.computed;
+ if (proportion_pixbuf != proportion_image) {
+ double new_height = this->height.computed * proportion_pixbuf;
+ sp_repr_set_svg_double(this->getRepr(), "width", new_height);
+ }
+ }
+ else {
+ if (proportion_pixbuf != proportion_image) {
+ double new_width = this->width.computed * proportion_pixbuf;
+ sp_repr_set_svg_double(this->getRepr(), "height", new_width);
+ }
+ }
+ }
+ this->prev_width = this->pixbuf->width();
+ this->prev_height = this->pixbuf->height();
}
void SPImage::modified(unsigned int flags) {
@@ -437,7 +471,7 @@ Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape::
if (this->height._set) {
sp_repr_set_svg_double(repr, "height", this->height.computed);
}
-
+ repr->setAttribute("inkscape:svg-dpi", this->getRepr()->attribute("inkscape:svg-dpi"));
//XML Tree being used directly here while it shouldn't be...
repr->setAttribute("preserveAspectRatio", this->getRepr()->attribute("preserveAspectRatio"));
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
@@ -511,10 +545,12 @@ gchar* SPImage::description() const {
this->document)
{
Inkscape::Pixbuf * pb = nullptr;
- pb = sp_image_repr_read_image (
- this->getRepr()->attribute("xlink:href"),
- this->getRepr()->attribute("sodipodi:absref"),
- this->document->getBase());
+ const gchar *svgdpi = this->getRepr()->attribute("inkscape:svg-dpi");
+ if (!svgdpi) {
+ svgdpi = "96";
+ }
+ pb = sp_image_repr_read_image(this->getRepr()->attribute("xlink:href"),
+ this->getRepr()->attribute("sodipodi:absref"), this->document->getBase(), svgdpi);
if (pb) {
ret = g_strdup_printf(_("%d × %d: %s"),
@@ -537,7 +573,7 @@ Inkscape::DrawingItem* SPImage::show(Inkscape::Drawing &drawing, unsigned int /*
return ai;
}
-Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base)
+Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absref, gchar const *base, char const *svgdpi)
{
Inkscape::Pixbuf *inkpb = nullptr;
@@ -547,7 +583,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
if (strncmp (filename,"file:",5) == 0) {
gchar *fullname = g_filename_from_uri(filename, nullptr, nullptr);
if (fullname) {
- inkpb = Inkscape::Pixbuf::create_from_file(fullname);
+ inkpb = Inkscape::Pixbuf::create_from_file(fullname, svgdpi);
g_free(fullname);
if (inkpb != nullptr) {
return inkpb;
@@ -556,7 +592,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
} else if (strncmp (filename,"data:",5) == 0) {
/* data URI - embedded image */
filename += 5;
- inkpb = Inkscape::Pixbuf::create_from_data_uri(filename);
+ inkpb = Inkscape::Pixbuf::create_from_data_uri(filename, svgdpi);
if (inkpb != nullptr) {
return inkpb;
}
@@ -574,7 +610,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
// different dir) or unset (when doc is not saved yet), so we check for base+href existence first,
// and if it fails, we also try to use bare href regardless of its g_path_is_absolute
if (g_file_test (fullname, G_FILE_TEST_EXISTS) && !g_file_test (fullname, G_FILE_TEST_IS_DIR)) {
- inkpb = Inkscape::Pixbuf::create_from_file(fullname);
+ inkpb = Inkscape::Pixbuf::create_from_file(fullname, svgdpi);
if (inkpb != nullptr) {
g_free (fullname);
return inkpb;
@@ -585,7 +621,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
/* try filename as absolute */
if (g_file_test (filename, G_FILE_TEST_EXISTS) && !g_file_test (filename, G_FILE_TEST_IS_DIR)) {
- inkpb = Inkscape::Pixbuf::create_from_file(filename);
+ inkpb = Inkscape::Pixbuf::create_from_file(filename, svgdpi);
if (inkpb != nullptr) {
return inkpb;
}
@@ -603,7 +639,7 @@ Inkscape::Pixbuf *sp_image_repr_read_image(gchar const *href, gchar const *absre
g_warning ("xlink:href did not resolve to a valid image file, now trying sodipodi:absref=\"%s\"", absref);
}
- inkpb = Inkscape::Pixbuf::create_from_file(filename);
+ inkpb = Inkscape::Pixbuf::create_from_file(filename, svgdpi);
if (inkpb != nullptr) {
return inkpb;
}
@@ -633,7 +669,6 @@ sp_image_update_arenaitem (SPImage *image, Inkscape::DrawingImage *ai)
static void sp_image_update_canvas_image(SPImage *image)
{
SPItem *item = SP_ITEM(image);
-
for (SPItemView *v = item->display; v != nullptr; v = v->next) {
sp_image_update_arenaitem(image, dynamic_cast(v->arenaitem));
}
diff --git a/src/object/sp-image.h b/src/object/sp-image.h
index 464d0f144bdbaddbef3a194654d31bfe326f6d8f..7d62e756a813263dc26c57e767c0762c4badd270 100644
--- a/src/object/sp-image.h
+++ b/src/object/sp-image.h
@@ -35,6 +35,8 @@ public:
Geom::Rect clipbox;
double sx, sy;
double ox, oy;
+ double dpi;
+ double prev_width, prev_height;
SPCurve *curve; // This curve is at the image's boundary for snapping
diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp
index ec3ce1b71645bdb9bac8174e1c6ac66eb2ee47ef..6801afa9c2e4aa98f30709abcabffd983e0acef2 100644
--- a/src/ui/dialog/object-attributes.cpp
+++ b/src/ui/dialog/object-attributes.cpp
@@ -67,7 +67,6 @@ static const SPAttrDesc image_desc[] = {
{ N_("Y:"), "y"},
{ N_("Width:"), "width"},
{ N_("Height:"), "height"},
- { N_("Image Rendering:"), "image-rendering"},
{ nullptr, nullptr}
};
diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp
index 8daa83e9c30dd0f4a48a77528d798584cc056afc..88d7daf074d10cc790e66457f13572f47f2f229e 100644
--- a/src/ui/dialog/object-properties.cpp
+++ b/src/ui/dialog/object-properties.cpp
@@ -48,14 +48,16 @@ namespace Dialog {
ObjectProperties::ObjectProperties()
: UI::Widget::Panel("/dialogs/object/", SP_VERB_DIALOG_ITEM)
- , _blocked (false)
+ , _blocked(false)
, _current_item(nullptr)
, _label_id(_("_ID:"), true)
, _label_label(_("_Label:"), true)
, _label_title(_("_Title:"), true)
+ , _label_dpi(_("_DPI SVG:"), true)
, _label_image_rendering(_("_Image Rendering:"), true)
, _cb_hide(_("_Hide"), true)
, _cb_lock(_("L_ock"), true)
+ , _cb_aspect_ratio(_("Pereserve Ratio"), true)
, _attr_table(Gtk::manage(new SPAttributeTable()))
, _desktop(nullptr)
{
@@ -185,12 +187,39 @@ void ObjectProperties::_init()
_ft_description.add(_tv_description);
_tv_description.add_mnemonic_label(*label_desc);
+ /* Create the text view box for the DPI svg */
+ _ft_description.set_border_width(4);
+ _ft_description.set_sensitive(FALSE);
+ frame_desc->add(_ft_description);
+ _ft_description.set_shadow_type(Gtk::SHADOW_IN);
+
+ _tv_description.set_wrap_mode(Gtk::WRAP_WORD);
+ _tv_description.get_buffer()->set_text("");
+ _ft_description.add(_tv_description);
+ _tv_description.add_mnemonic_label(*label_desc);
+
+ /* Create the label for the object title */
+ _label_dpi.set_label(_label_dpi.get_label() + " ");
+ _label_dpi.set_halign(Gtk::ALIGN_END);
+ _label_dpi.set_valign(Gtk::ALIGN_CENTER);
+ grid_top->attach(_label_dpi, 0, 3, 1, 1);
+
+ /* Create the entry box for the SVG DPI */
+ _spin_dpi.set_digits(2);
+ _spin_dpi.set_range(1, 1200);
+ grid_top->attach(_spin_dpi, 1, 3, 1, 1);
+
+ _label_dpi.set_mnemonic_widget(_spin_dpi);
+ // pressing enter in the label field is the same as clicking Set:
+ _spin_dpi.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged));
+
+
/* Image rendering */
/* Create the label for the object ImageRendering */
_label_image_rendering.set_label(_label_image_rendering.get_label() + " ");
_label_image_rendering.set_halign(Gtk::ALIGN_END);
_label_image_rendering.set_valign(Gtk::ALIGN_CENTER);
- grid_top->attach(_label_image_rendering, 0, 3, 1, 1);
+ grid_top->attach(_label_image_rendering, 0, 4, 1, 1);
/* Create the combo box text for the 'image-rendering' property */
_combo_image_rendering.append( "auto" );
@@ -199,7 +228,7 @@ void ObjectProperties::_init()
_combo_image_rendering.set_tooltip_text(_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation."));
_combo_image_rendering.set_valign(Gtk::ALIGN_CENTER);
- grid_top->attach(_combo_image_rendering, 1, 3, 1, 1);
+ grid_top->attach(_combo_image_rendering, 1, 4, 1, 1);
_label_image_rendering.set_mnemonic_widget(_combo_image_rendering);
@@ -207,6 +236,8 @@ void ObjectProperties::_init()
sigc::mem_fun(this, &ObjectProperties::_imageRenderingChanged)
);
+
+
/* Check boxes */
Gtk::HBox *hb_checkboxes = Gtk::manage(new Gtk::HBox());
contents->pack_start(*hb_checkboxes, FALSE, FALSE, 0);
@@ -235,12 +266,20 @@ void ObjectProperties::_init()
_cb_lock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_sensitivityToggled));
+ /* Preserve aspect ratio */
+ _cb_aspect_ratio.set_tooltip_text(_("Check to preserve aspect ratio on images"));
+ _cb_aspect_ratio.set_hexpand();
+ _cb_aspect_ratio.set_valign(Gtk::ALIGN_CENTER);
+ grid_cb->attach(_cb_aspect_ratio, 0, 1, 1, 1);
+
+ _cb_aspect_ratio.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_aspectRatioToggled));
+
/* Button for setting the object's id, label, title and description. */
Gtk::Button *btn_set = Gtk::manage(new Gtk::Button(_("_Set"), true));
btn_set->set_hexpand();
btn_set->set_valign(Gtk::ALIGN_CENTER);
- grid_cb->attach(*btn_set, 2, 0, 1, 1);
+ grid_cb->attach(*btn_set, 1, 1, 1, 1);
btn_set->signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged));
@@ -284,7 +323,7 @@ void ObjectProperties::update()
return;
}
_blocked = true;
-
+ _cb_aspect_ratio.set_active(item->getAttribute("preserveAspectRatio") == "true");
_cb_lock.set_active(item->isLocked()); /* Sensitive */
_cb_hide.set_active(item->isExplicitlyHidden()); /* Hidden */
@@ -409,6 +448,13 @@ void ObjectProperties::_labelChanged()
_("Set object title"));
}
+ /* Retrieve the DPI */
+ if (SP_IS_IMAGE(obj)) {
+ Glib::ustring dpi_value = Glib::ustring::format(_spin_dpi.get_value());
+ obj->setAttribute("inkscape:svg-dpi", dpi_value);
+ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set image DPI"));
+ }
+
/* Retrieve the description */
Gtk::TextBuffer::iterator start, end;
_tv_description.get_buffer()->get_bounds(start, end);
@@ -464,6 +510,34 @@ void ObjectProperties::_sensitivityToggled()
_blocked = false;
}
+void ObjectProperties::_aspectRatioToggled()
+{
+ if (_blocked) {
+ return;
+ }
+
+ SPItem *item = SP_ACTIVE_DESKTOP->getSelection()->singleItem();
+ g_return_if_fail(item != nullptr);
+
+ _blocked = true;
+
+ item->setLocked(_cb_aspect_ratio.get_active());
+ const char *active;
+ if (_cb_aspect_ratio.get_active()) {
+ active = "true";
+ }
+ else {
+ active = "none";
+ }
+ /* Retrieve the DPI */
+ if (SP_IS_IMAGE(item)) {
+ Glib::ustring dpi_value = Glib::ustring::format(_spin_dpi.get_value());
+ item->setAttribute("preserveAspectRatio", active);
+ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set preserve ratio"));
+ }
+ _blocked = false;
+}
+
void ObjectProperties::_hiddenToggled()
{
if (_blocked) {
diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h
index 4ce72ae1a1e27ad4460238cccd682d37dcc6ebb6..f603219c4eeaef661bd060f4f478870ef630ff87 100644
--- a/src/ui/dialog/object-properties.h
+++ b/src/ui/dialog/object-properties.h
@@ -40,6 +40,7 @@
#include
#include
#include
+#include
#include
#include
@@ -85,6 +86,7 @@ private:
Gtk::Entry _entry_label; //the entry for the object label
Gtk::Label _label_title; //the label for the object title
Gtk::Entry _entry_title; //the entry for the object title
+
Gtk::Label _label_image_rendering; // the label for 'image-rendering'
Gtk::ComboBoxText _combo_image_rendering; // the combo box text for 'image-rendering'
@@ -93,7 +95,10 @@ private:
Gtk::CheckButton _cb_hide; //the check button hide
Gtk::CheckButton _cb_lock; //the check button lock
+ Gtk::CheckButton _cb_aspect_ratio; //the preserve aspect ratio of images
+ Gtk::Label _label_dpi; //the entry for the dpi value
+ Gtk::SpinButton _spin_dpi; //the expander for interactivity
Gtk::Expander _exp_interactivity; //the expander for interactivity
SPAttributeTable *_attr_table; //the widget for showing the on... names at the bottom
@@ -118,6 +123,9 @@ private:
/// Callback for checkbox Hide.
void _hiddenToggled();
+ /// Callback for checkbox Preserve Aspect Ratio.
+ void _aspectRatioToggled();
+
/// Can be invoked for setting the desktop. Currently not used.
void _setDesktop(SPDesktop *desktop);
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 5f9a402f11f80498e527170fb8947658668e6b26..b19b102217732a795e7490aeed5924d541e0d6ca 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -750,6 +750,8 @@ static void
sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/)
{
// dealing with the bizarre filename convention in Inkscape for now
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setString("/options/openmethod/value", "open");
gchar *uri = gtk_recent_chooser_get_current_uri(GTK_RECENT_CHOOSER(recent_menu));
gchar *local_fn = g_filename_from_uri(uri, nullptr, nullptr);
gchar *utf8_fn = g_filename_to_utf8(local_fn, -1, nullptr, nullptr, nullptr);
@@ -757,6 +759,7 @@ sp_recent_open(GtkRecentChooser *recent_menu, gpointer /*user_data*/)
g_free(utf8_fn);
g_free(local_fn);
g_free(uri);
+ prefs->setString("/options/openmethod/value", "done");
}
static void
diff --git a/testfiles/src/attributes-test.cpp b/testfiles/src/attributes-test.cpp
index e6fbe8eceb32977e40c8a4beac02ddb9bba20d84..34963f22d247271229cdc15a0d5142616c60cc6a 100644
--- a/testfiles/src/attributes-test.cpp
+++ b/testfiles/src/attributes-test.cpp
@@ -463,6 +463,7 @@ std::vector getKnownAttrs()
AttributeInfo("inkscape:window-x", true),
AttributeInfo("inkscape:window-y", true),
AttributeInfo("inkscape:zoom", true),
+ AttributeInfo("inkscape:svg-dpi", true),
AttributeInfo("osb:paint", true),
AttributeInfo("sodipodi:arc-type", true),
AttributeInfo("sodipodi:arg1", true),