summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2014-08-26 08:44:06 +0000
committer~suv <suv-sf@users.sourceforge.net>2014-08-26 08:44:06 +0000
commit84632bca5511a1daae902bbd9faad00d67fd58bf (patch)
tree2dd483c8d5c7411b9cbac3b263f3f77f86d37c38 /src
parentlibrevenge: update to latest patch from bug #1323592 (support old and new ver... (diff)
parentUI. Fix for Bug #340723 "Interface inconsistency of tooltips". (diff)
downloadinkscape-84632bca5511a1daae902bbd9faad00d67fd58bf.tar.gz
inkscape-84632bca5511a1daae902bbd9faad00d67fd58bf.zip
update to trunk (r13532)
(bzr r13398.1.8)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/svg-path-parser.cpp37
-rw-r--r--src/display/canvas-axonomgrid.cpp3
-rw-r--r--src/document-undo.cpp1
-rw-r--r--src/extension/implementation/xslt.cpp40
-rw-r--r--src/extension/internal/bitmap/crop.cpp2
-rw-r--r--src/extension/internal/bitmap/opacity.cpp2
-rw-r--r--src/file.cpp16
-rw-r--r--src/ink-comboboxentry-action.cpp16
-rw-r--r--src/inkscape-x64.rc8
-rw-r--r--src/inkscape.rc8
-rw-r--r--src/inkview-x64.rc8
-rw-r--r--src/inkview.rc8
-rw-r--r--src/knot-holder-entity.cpp18
-rw-r--r--src/knot-holder-entity.h10
-rw-r--r--src/knotholder.cpp32
-rw-r--r--src/libavoid/connector.cpp5
-rw-r--r--src/live_effects/lpe-perspective_path.cpp102
-rw-r--r--src/live_effects/lpe-perspective_path.h3
-rw-r--r--src/live_effects/parameter/parameter.cpp8
-rw-r--r--src/live_effects/parameter/parameter.h2
-rw-r--r--src/live_effects/parameter/path.cpp2
-rw-r--r--src/object-edit.cpp4
-rw-r--r--src/selection-chemistry.cpp17
-rw-r--r--src/selection-chemistry.h2
-rw-r--r--src/seltrans.cpp13
-rw-r--r--src/snap.cpp85
-rw-r--r--src/sp-item-group.cpp8
-rw-r--r--src/sp-item.cpp35
-rw-r--r--src/sp-item.h10
-rw-r--r--src/sp-solid-color.cpp2
-rw-r--r--src/sp-star.cpp3
-rw-r--r--src/ui/dialog/document-properties.cpp7
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp8
-rw-r--r--src/ui/dialog/inkscape-preferences.h1
-rw-r--r--src/ui/dialog/print.cpp12
-rw-r--r--src/ui/dialog/xml-tree.cpp1
-rw-r--r--src/ui/widget/rendering-options.cpp18
-rw-r--r--src/util/units.cpp6
-rw-r--r--src/widgets/font-selector.cpp7
-rw-r--r--src/widgets/gradient-toolbar.cpp75
-rw-r--r--src/widgets/text-toolbar.cpp45
41 files changed, 445 insertions, 245 deletions
diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp
index ccc383920..932f95829 100644
--- a/src/2geom/svg-path-parser.cpp
+++ b/src/2geom/svg-path-parser.cpp
@@ -1,5 +1,3 @@
-
-#line 1 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
/**
* \file
* \brief parse SVG path specifications
@@ -130,6 +128,9 @@ private:
void _arcTo(double rx, double ry, double angle,
bool large_arc, bool sweep, Point p)
{
+ if (are_near(_current, p)) {
+ return;
+ }
_quad_tangent = _cubic_tangent = _current = p;
_sink.arcTo(rx, ry, angle, large_arc, sweep, p);
}
@@ -141,7 +142,6 @@ private:
};
-#line 145 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp"
static const char _svg_path_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 5, 1, 15, 1,
@@ -1147,9 +1147,6 @@ static const int svg_path_first_final = 270;
//static const int svg_path_en_main = 1;
-#line 144 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
-
-
void Parser::parse(char const *str)
throw(SVGPathParseError)
{
@@ -1159,13 +1156,11 @@ throw(SVGPathParseError)
_reset();
-
-#line 1164 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp"
{
cs = svg_path_start;
}
-#line 1169 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp"
+
{
int _klen;
unsigned int _trans;
@@ -1238,13 +1233,12 @@ _match:
switch ( *_acts++ )
{
case 0:
-#line 156 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
start = p;
}
break;
case 1:
-#line 160 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
+
{
char const *end=p;
std::string buf(start, end);
@@ -1253,55 +1247,49 @@ _match:
}
break;
case 2:
-#line 167 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
+
{
_push(1.0);
}
break;
case 3:
-#line 171 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
+
{
_push(0.0);
}
break;
case 4:
-#line 175 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
+
{
_absolute = true;
}
break;
case 5:
-#line 179 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_absolute = false;
}
break;
case 6:
-#line 183 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_moveTo(_pop_point());
}
break;
case 7:
-#line 187 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_lineTo(_pop_point());
}
break;
case 8:
-#line 191 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_hlineTo(Point(_pop_coord(X), _current[Y]));
}
break;
case 9:
-#line 195 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_vlineTo(Point(_current[X], _pop_coord(Y)));
}
break;
case 10:
-#line 199 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
Point p = _pop_point();
Point c1 = _pop_point();
@@ -1310,7 +1298,6 @@ _match:
}
break;
case 11:
-#line 206 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
Point p = _pop_point();
Point c1 = _pop_point();
@@ -1318,7 +1305,6 @@ _match:
}
break;
case 12:
-#line 212 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
Point p = _pop_point();
Point c = _pop_point();
@@ -1326,14 +1312,12 @@ _match:
}
break;
case 13:
-#line 218 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
Point p = _pop_point();
_quadTo(_quad_tangent, p);
}
break;
case 14:
-#line 223 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
Point point = _pop_point();
bool sweep = _pop_flag();
@@ -1346,16 +1330,13 @@ _match:
}
break;
case 15:
-#line 234 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{
_closePath();
}
break;
case 16:
-#line 370 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
{{p++; goto _out; }}
break;
-#line 1359 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp"
}
}
@@ -1367,8 +1348,6 @@ _again:
_out: {}
}
-#line 380 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl"
-
if ( cs < svg_path_first_final ) {
throw SVGPathParseError();
diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp
index 312a8d655..592c962a6 100644
--- a/src/display/canvas-axonomgrid.cpp
+++ b/src/display/canvas-axonomgrid.cpp
@@ -387,6 +387,9 @@ _wr.setUpdating (false);
_rcp_gmcol->setRgba32 (empcolor);
_rsi->setValue (empspacing);
+ _rsu_ox->setProgrammatically = false;
+ _rsu_oy->setProgrammatically = false;
+
return table;
}
diff --git a/src/document-undo.cpp b/src/document-undo.cpp
index 39c8a04a0..53e701648 100644
--- a/src/document-undo.cpp
+++ b/src/document-undo.cpp
@@ -255,6 +255,7 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc)
Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data;
doc->priv->undo = g_slist_remove (doc->priv->undo, log);
sp_repr_undo_log (log->event);
+ doc->_updateDocument();
doc->priv->redo = g_slist_prepend (doc->priv->redo, log);
doc->setModifiedSinceSave();
diff --git a/src/extension/implementation/xslt.cpp b/src/extension/implementation/xslt.cpp
index bcea06cb5..85ae9efde 100644
--- a/src/extension/implementation/xslt.cpp
+++ b/src/extension/implementation/xslt.cpp
@@ -20,6 +20,7 @@
#include "xslt.h"
#include "../extension.h"
#include "../output.h"
+#include "extension/input.h"
#include "xml/repr.h"
#include "io/sys.h"
@@ -53,8 +54,7 @@ XSLT::XSLT(void) :
{
}
-Glib::ustring
-XSLT::solve_reldir(Inkscape::XML::Node *reprin) {
+Glib::ustring XSLT::solve_reldir(Inkscape::XML::Node *reprin) {
gchar const *s = reprin->attribute("reldir");
@@ -90,8 +90,7 @@ XSLT::solve_reldir(Inkscape::XML::Node *reprin) {
return "";
}
-bool
-XSLT::check(Inkscape::Extension::Extension *module)
+bool XSLT::check(Inkscape::Extension::Extension *module)
{
if (load(module)) {
unload(module);
@@ -101,8 +100,7 @@ XSLT::check(Inkscape::Extension::Extension *module)
}
}
-bool
-XSLT::load(Inkscape::Extension::Extension *module)
+bool XSLT::load(Inkscape::Extension::Extension *module)
{
if (module->loaded()) { return true; }
@@ -130,8 +128,7 @@ XSLT::load(Inkscape::Extension::Extension *module)
return true;
}
-void
-XSLT::unload(Inkscape::Extension::Extension *module)
+void XSLT::unload(Inkscape::Extension::Extension *module)
{
if (!module->loaded()) { return; }
xsltFreeStylesheet(_stylesheet);
@@ -139,8 +136,8 @@ XSLT::unload(Inkscape::Extension::Extension *module)
return;
}
-SPDocument *
-XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename)
+SPDocument * XSLT::open(Inkscape::Extension::Input */*module*/,
+ gchar const *filename)
{
xmlDocPtr filein = xmlParseFile(filename);
if (filein == NULL) { return NULL; }
@@ -184,8 +181,7 @@ XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename)
return doc;
}
-void
-XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const *filename)
+void XSLT::save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename)
{
/* TODO: Should we assume filename to be in utf8 or to be a raw filename?
* See JavaFXOutput::save for discussion. */
@@ -214,10 +210,24 @@ XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const
return;
}
- const char * params[1];
- params[0] = NULL;
+ std::list<std::string> params;
+ module->paramListString(params);
+ const int max_parameters = params.size() * 2;
+ const char * xslt_params[max_parameters+1] ;
+
+ int count = 0;
+ for(std::list<std::string>::iterator t=params.begin(); t != params.end(); ++t) {
+ std::size_t pos = t->find("=");
+ std::ostringstream parameter;
+ std::ostringstream value;
+ parameter << t->substr(2,pos-2);
+ value << t->substr(pos+1);
+ xslt_params[count++] = g_strdup_printf("%s", parameter.str().c_str());
+ xslt_params[count++] = g_strdup_printf("'%s'", value.str().c_str());
+ }
+ xslt_params[count] = NULL;
- xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, params);
+ xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, xslt_params);
//xmlSaveFile(filename, newdoc);
int success = xsltSaveResultToFilename(filename, newdoc, _stylesheet, 0);
diff --git a/src/extension/internal/bitmap/crop.cpp b/src/extension/internal/bitmap/crop.cpp
index 0e633afd6..02d92668b 100644
--- a/src/extension/internal/bitmap/crop.cpp
+++ b/src/extension/internal/bitmap/crop.cpp
@@ -74,7 +74,7 @@ Crop::init(void)
"<effects-menu>\n"
"<submenu name=\"" N_("Raster") "\" />\n"
"</effects-menu>\n"
- "<menu-tip>" N_("Crop selected bitmap(s).") "</menu-tip>\n"
+ "<menu-tip>" N_("Crop selected bitmap(s)") "</menu-tip>\n"
"</effect>\n"
"</inkscape-extension>\n", new Crop());
}
diff --git a/src/extension/internal/bitmap/opacity.cpp b/src/extension/internal/bitmap/opacity.cpp
index 742cb7019..f9b4bbc27 100644
--- a/src/extension/internal/bitmap/opacity.cpp
+++ b/src/extension/internal/bitmap/opacity.cpp
@@ -43,7 +43,7 @@ Opacity::init(void)
"<effects-menu>\n"
"<submenu name=\"" N_("Raster") "\" />\n"
"</effects-menu>\n"
- "<menu-tip>" N_("Modify opacity channel(s) of selected bitmap(s).") "</menu-tip>\n"
+ "<menu-tip>" N_("Modify opacity channel(s) of selected bitmap(s)") "</menu-tip>\n"
"</effect>\n"
"</inkscape-extension>\n", new Opacity());
}
diff --git a/src/file.cpp b/src/file.cpp
index 51e629c7d..200077de5 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -148,14 +148,14 @@ SPDesktop *sp_file_new(const std::string &templ)
DocumentUndo::setUndoSensitive(doc, true);
}
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if (desktop)
- desktop->setWaitingCursor();
+ SPDesktop *olddesktop = SP_ACTIVE_DESKTOP;
+ if (olddesktop)
+ olddesktop->setWaitingCursor();
SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc.
g_return_val_if_fail(dtw != NULL, NULL);
sp_create_window(dtw, TRUE);
- desktop = static_cast<SPDesktop *>(dtw->view);
+ SPDesktop* desktop = static_cast<SPDesktop *>(dtw->view);
doc->doUnref();
@@ -166,6 +166,8 @@ SPDesktop *sp_file_new(const std::string &templ)
Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop);
#endif
+ if (olddesktop)
+ olddesktop->clearWaitingCursor();
if (desktop)
desktop->clearWaitingCursor();
@@ -1087,9 +1089,9 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
Inkscape::Selection *selection = sp_desktop_selection(desktop);
selection->setReprList(pasted_objects);
- // invers apply parent transform
+ // Apply inverse of parent transform
Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false);
+ sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
// Update (among other things) all curves in paths, for bounds() to work
target_document->ensureUpToDate();
@@ -1226,7 +1228,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// c2p is identity matrix at this point unless ensureUpToDate is called
doc->ensureUpToDate();
Geom::Affine affine = doc->getRoot()->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse();
- sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false);
+ sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false);
// move to mouse pointer
{
diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp
index ebd238edc..6579c8ff8 100644
--- a/src/ink-comboboxentry-action.cpp
+++ b/src/ink-comboboxentry-action.cpp
@@ -383,6 +383,15 @@ GtkWidget* create_tool_item( GtkAction* action )
g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action );
+ // Optionally add separator function...
+ if( ink_comboboxentry_action->separator_func != NULL ) {
+ gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
+ GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
+ NULL, NULL );
+ }
+
+ gtk_widget_show_all (comboBoxEntry);
+
// Optionally add formatting...
if( ink_comboboxentry_action->cell_data_func != NULL ) {
GtkCellRenderer *cell = gtk_cell_renderer_text_new();
@@ -393,13 +402,6 @@ GtkWidget* create_tool_item( GtkAction* action )
NULL, NULL );
}
- // Optionally add separator function...
- if( ink_comboboxentry_action->separator_func != NULL ) {
- gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox,
- GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func),
- NULL, NULL );
- }
-
// Optionally widen the combobox width... which widens the drop-down list in list mode.
if( ink_comboboxentry_action->extra_width > 0 ) {
GtkRequisition req;
diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc
index ce286c2ca..65a2b08b9 100644
--- a/src/inkscape-x64.rc
+++ b/src/inkscape-x64.rc
@@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico"
1 24 DISCARDABLE "./inkscape-manifest-x64.xml"
1 VERSIONINFO
- FILEVERSION 0,48,0,9
- PRODUCTVERSION 0,48,0,9
+ FILEVERSION 0,91,0,0
+ PRODUCTVERSION 0,91,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
@@ -13,11 +13,11 @@ BEGIN
VALUE "Comments", "Published under the GNU GPL"
VALUE "CompanyName", "inkscape.org"
VALUE "FileDescription", "Inkscape"
- VALUE "FileVersion", "0.48+devel"
+ VALUE "FileVersion", "0.91pre2"
VALUE "InternalName", "Inkscape"
VALUE "LegalCopyright", "© 2014 Inkscape"
VALUE "ProductName", "Inkscape"
- VALUE "ProductVersion", "0.48+devel"
+ VALUE "ProductVersion", "0.91pre2"
END
END
BLOCK "VarFileInfo"
diff --git a/src/inkscape.rc b/src/inkscape.rc
index 395ef39e1..689653f74 100644
--- a/src/inkscape.rc
+++ b/src/inkscape.rc
@@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico"
1 24 DISCARDABLE "./inkscape-manifest.xml"
1 VERSIONINFO
- FILEVERSION 0,48,0,9
- PRODUCTVERSION 0,48,0,9
+ FILEVERSION 0,91,0,0
+ PRODUCTVERSION 0,91,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
@@ -13,11 +13,11 @@ BEGIN
VALUE "Comments", "Published under the GNU GPL"
VALUE "CompanyName", "inkscape.org"
VALUE "FileDescription", "Inkscape"
- VALUE "FileVersion", "0.48+devel"
+ VALUE "FileVersion", "0.91pre2"
VALUE "InternalName", "Inkscape"
VALUE "LegalCopyright", "© 2014 Inkscape"
VALUE "ProductName", "Inkscape"
- VALUE "ProductVersion", "0.48+devel"
+ VALUE "ProductVersion", "0.91pre2"
END
END
BLOCK "VarFileInfo"
diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc
index 2de16060b..f23fe84c9 100644
--- a/src/inkview-x64.rc
+++ b/src/inkview-x64.rc
@@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico"
1 24 DISCARDABLE "./inkview-manifest-x64.xml"
1 VERSIONINFO
- FILEVERSION 0,48,0,9
- PRODUCTVERSION 0,48,0,9
+ FILEVERSION 0,91,0,0
+ PRODUCTVERSION 0,91,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
@@ -13,11 +13,11 @@ BEGIN
VALUE "Comments", "Published under the GNU GPL"
VALUE "CompanyName", "inkscape.org"
VALUE "FileDescription", "Inkview"
- VALUE "FileVersion", "0.48+devel"
+ VALUE "FileVersion", "0.91pre2"
VALUE "InternalName", "Inkview"
VALUE "LegalCopyright", "© 2014 Inkscape"
VALUE "ProductName", "Inkview"
- VALUE "ProductVersion", "0.48+devel"
+ VALUE "ProductVersion", "0.91pre2"
END
END
BLOCK "VarFileInfo"
diff --git a/src/inkview.rc b/src/inkview.rc
index fd7eb50a1..43a63c725 100644
--- a/src/inkview.rc
+++ b/src/inkview.rc
@@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico"
1 24 DISCARDABLE "./inkview-manifest.xml"
1 VERSIONINFO
- FILEVERSION 0,48,0,9
- PRODUCTVERSION 0,48,0,9
+ FILEVERSION 0,91,0,0
+ PRODUCTVERSION 0,91,0,0
BEGIN
BLOCK "StringFileInfo"
BEGIN
@@ -13,11 +13,11 @@ BEGIN
VALUE "Comments", "Published under the GNU GPL"
VALUE "CompanyName", "inkscape.org"
VALUE "FileDescription", "Inkview"
- VALUE "FileVersion", "0.48+devel"
+ VALUE "FileVersion", "0.91pre2"
VALUE "InternalName", "Inkview"
VALUE "LegalCopyright", "© 2014 Inkscape"
VALUE "ProductName", "Inkview"
- VALUE "ProductVersion", "0.48+devel"
+ VALUE "ProductVersion", "0.91pre2"
END
END
BLOCK "VarFileInfo"
diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp
index 6af5c6a56..b66156b09 100644
--- a/src/knot-holder-entity.cpp
+++ b/src/knot-holder-entity.cpp
@@ -158,7 +158,7 @@ static Geom::Point sp_pattern_extract_trans(SPPattern const *pat)
void
PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
{
- SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
// FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used.
Geom::Point p_snapped = snap_knot_position(p, state);
@@ -173,7 +173,7 @@ PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &ori
if (state) {
Geom::Point const q = p_snapped - sp_pattern_extract_trans(pat);
- item->adjust_pattern(Geom::Affine(Geom::Translate(q)));
+ item->adjust_pattern(Geom::Translate(q), false, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE);
}
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
@@ -182,14 +182,14 @@ PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &ori
Geom::Point
PatternKnotHolderEntityXY::knot_get() const
{
- SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
return sp_pattern_extract_trans(pat);
}
Geom::Point
PatternKnotHolderEntityAngle::knot_get() const
{
- SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
gdouble x = pattern_width(pat);
gdouble y = 0;
@@ -207,7 +207,7 @@ PatternKnotHolderEntityAngle::knot_set(Geom::Point const &p, Geom::Point const &
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);
- SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
// get the angle from pattern 0,0 to the cursor pos
Geom::Point delta = p - sp_pattern_extract_trans(pat);
@@ -223,14 +223,14 @@ PatternKnotHolderEntityAngle::knot_set(Geom::Point const &p, Geom::Point const &
Geom::Point const t = sp_pattern_extract_trans(pat);
rot[4] = t[Geom::X];
rot[5] = t[Geom::Y];
- item->adjust_pattern(rot, true);
+ item->adjust_pattern(rot, true, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE);
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
void
PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state)
{
- SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
// FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used.
Geom::Point p_snapped = snap_knot_position(p, state);
@@ -257,7 +257,7 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &
Geom::Point const t = sp_pattern_extract_trans(pat);
rot[4] = t[Geom::X];
rot[5] = t[Geom::Y];
- item->adjust_pattern(rot, true);
+ item->adjust_pattern(rot, true, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE);
item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
@@ -265,7 +265,7 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &
Geom::Point
PatternKnotHolderEntityScale::knot_get() const
{
- SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style));
+ SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
gdouble x = pattern_width(pat);
gdouble y = pattern_height(pat);
diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h
index a9268d396..dde60f515 100644
--- a/src/knot-holder-entity.h
+++ b/src/knot-holder-entity.h
@@ -101,20 +101,30 @@ protected:
class PatternKnotHolderEntityXY : public KnotHolderEntity {
public:
+ PatternKnotHolderEntityXY(bool fill) : KnotHolderEntity(), _fill(fill) {}
virtual Geom::Point knot_get() const;
virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+private:
+ // true if the entity tracks fill, false for stroke
+ bool _fill;
};
class PatternKnotHolderEntityAngle : public KnotHolderEntity {
public:
+ PatternKnotHolderEntityAngle(bool fill) : KnotHolderEntity(), _fill(fill) {}
virtual Geom::Point knot_get() const;
virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+private:
+ bool _fill;
};
class PatternKnotHolderEntityScale : public KnotHolderEntity {
public:
+ PatternKnotHolderEntityScale(bool fill) : KnotHolderEntity(), _fill(fill) {}
virtual Geom::Point knot_get() const;
virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+private:
+ bool _fill;
};
#endif /* !SEEN_KNOT_HOLDER_ENTITY_H */
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index cf87423d4..f0e69716b 100644
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
@@ -247,12 +247,32 @@ void KnotHolder::add(KnotHolderEntity *e)
void KnotHolder::add_pattern_knotholder()
{
- if ((item->style->fill.isPaintserver())
- && SP_IS_PATTERN(item->style->getFillPaintServer()))
- {
- PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY();
- PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle();
- PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale();
+ if ((item->style->fill.isPaintserver()) && SP_IS_PATTERN(item->style->getFillPaintServer())) {
+ PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(true);
+ PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(true);
+ PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(true);
+ entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT,
+ // TRANSLATORS: This refers to the pattern that's inside the object
+ _("<b>Move</b> the pattern fill inside the object"),
+ SP_KNOT_SHAPE_CROSS);
+
+ entity_scale->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER,
+ _("<b>Scale</b> the pattern fill; uniformly if with <b>Ctrl</b>"),
+ SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR);
+
+ entity_angle->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE,
+ _("<b>Rotate</b> the pattern fill; with <b>Ctrl</b> to snap angle"),
+ SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR);
+
+ entity.push_back(entity_xy);
+ entity.push_back(entity_angle);
+ entity.push_back(entity_scale);
+ }
+
+ if ((item->style->stroke.isPaintserver()) && SP_IS_PATTERN(item->style->getStrokePaintServer())) {
+ PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(false);
+ PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(false);
+ PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(false);
entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT,
// TRANSLATORS: This refers to the pattern that's inside the object
_("<b>Move</b> the pattern fill inside the object"),
diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp
index b8c99a48c..40ded7498 100644
--- a/src/libavoid/connector.cpp
+++ b/src/libavoid/connector.cpp
@@ -845,7 +845,10 @@ bool ConnRef::generatePath(void)
break;
}
// Check we don't have an apparent infinite connector path.
- COLA_ASSERT(pathlen < 200);
+//#ifdef PATHDEBUG
+ db_printf("Path length: %i\n", pathlen);
+//#endif
+ COLA_ASSERT(pathlen < 10000);
}
std::vector<Point> path(pathlen);
diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp
index c255f8665..a2372131c 100644
--- a/src/live_effects/lpe-perspective_path.cpp
+++ b/src/live_effects/lpe-perspective_path.cpp
@@ -10,17 +10,18 @@
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
+#include <gtkmm.h>
#include <glibmm/i18n.h>
#include "persp3d.h"
//#include "transf_mat_3x4.h"
#include "document.h"
-
+#include "document-private.h"
#include "live_effects/lpe-perspective_path.h"
#include "sp-item-group.h"
#include "knot-holder-entity.h"
#include "knotholder.h"
+#include "desktop.h"
#include "inkscape.h"
@@ -41,6 +42,7 @@ public:
} // namespace PP
+static Glib::ustring perspectiveID = _("First perspective");
LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
// initialise your parameters here:
@@ -59,9 +61,18 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) :
concatenate_before_pwd2 = true; // don't split the path into its subpaths
_provides_knotholder_entities = true;
-
+ unapply = false;
Persp3D *persp = persp3d_document_first_persp(inkscape_active_document());
+ if(persp == 0 ){
+ char *msg = _("You need a BOX 3D object");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK, true);
+ dialog.run();
+ unapply = true;
+ return;
+ }
Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat;
+ pmat = pmat * inkscape_active_desktop()->doc2dt();
pmat.copy_tmat(tmat);
}
@@ -74,8 +85,50 @@ void
LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem)
{
original_bbox(lpeitem, true);
+ if(unapply){
+ SP_LPE_ITEM(lpeitem)->removeCurrentPathEffect(false);
+ return;
+ }
}
+void LPEPerspectivePath::refresh(Gtk::Entry* perspective) {
+ perspectiveID = perspective->get_text();
+ Persp3D *first = 0;
+ Persp3D *persp = 0;
+ for ( SPObject *child = inkscape_active_document()->getDefs()->firstChild(); child && !persp; child = child->getNext() ) {
+ if (SP_IS_PERSP3D(child) && first == 0) {
+ first = SP_PERSP3D(child);
+ }
+ if (SP_IS_PERSP3D(child) && strcmp(child->getId(), const_cast<const gchar *>(perspectiveID.c_str())) == 0) {
+ persp = SP_PERSP3D(child);
+ break;
+ }
+ }
+ if(first == 0 ){
+ char *msg = _("You need a BOX 3D object");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK, true);
+ dialog.run();
+ return;
+ }
+ if(persp == 0){
+ persp = first;
+ char *msg = _("First perspective selected");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK, true);
+ dialog.run();
+ perspectiveID = _("First perspective");
+ }else{
+ char *msg = _("Perspective changed");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK, true);
+ dialog.run();
+ }
+ Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat;
+ pmat = pmat * inkscape_active_desktop()->doc2dt();
+ pmat.copy_tmat(tmat);
+};
+
Geom::Piecewise<Geom::D2<Geom::SBasis> >
LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
{
@@ -139,6 +192,49 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > cons
return output;
}
+Gtk::Widget *
+LPEPerspectivePath::newWidget()
+{
+ // use manage here, because after deletion of Effect object, others might still be pointing to this widget.
+ Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) );
+
+ vbox->set_border_width(5);
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ Parameter * param = *it;
+ Gtk::Widget * widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
+ Glib::ustring * tip = param->param_getTooltip();
+ if (widg) {
+ vbox->pack_start(*widg, true, true, 2);
+ if (tip) {
+ widg->set_tooltip_text(*tip);
+ } else {
+ widg->set_tooltip_text("");
+ widg->set_has_tooltip(false);
+ }
+ }
+ }
+
+ ++it;
+ }
+ Gtk::HBox * perspectiveId = Gtk::manage(new Gtk::HBox(true,0));
+ Gtk::Label* labelPerspective = Gtk::manage(new Gtk::Label("Perspective ID:", 0., 0.));
+ Gtk::Entry* perspective = Gtk::manage(new Gtk::Entry());
+ perspective->set_text(perspectiveID);
+ perspective->set_tooltip_text("Set the perspective ID to apply");
+ perspectiveId->pack_start(*labelPerspective, true, true, 2);
+ perspectiveId->pack_start(*perspective, true, true, 2);
+ vbox->pack_start(*perspectiveId, true, true, 2);
+ Gtk::Button* apply3D = Gtk::manage(new Gtk::Button(Glib::ustring(_("Refresh perspective"))));
+ apply3D->set_alignment(0.0, 0.5);
+ apply3D->signal_clicked().connect(sigc::bind<Gtk::Entry*>(sigc::mem_fun(*this,&LPEPerspectivePath::refresh),perspective));
+ Gtk::Widget* apply3DWidget = dynamic_cast<Gtk::Widget *>(apply3D);
+ apply3DWidget->set_tooltip_text("Refresh perspective");
+ vbox->pack_start(*apply3DWidget, true, true,2);
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
void LPEPerspectivePath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
KnotHolderEntity *e = new PP::KnotHolderEntityOffset(this);
e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN,
diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h
index a9ee004f9..6ccac4a51 100644
--- a/src/live_effects/lpe-perspective_path.h
+++ b/src/live_effects/lpe-perspective_path.h
@@ -38,6 +38,8 @@ public:
virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
+ virtual void refresh(Gtk::Entry* perspective);
+ virtual Gtk::Widget * newWidget();
/* the knotholder entity classes must be declared friends */
friend class PP::KnotHolderEntityOffset;
void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
@@ -52,6 +54,7 @@ private:
BoolParam uses_plane_xy;
// there are all kinds of parameters. Check the /live_effects/parameter directory which types exist!
+ bool unapply;
Geom::Point orig;
LPEPerspectivePath(const LPEPerspectivePath&);
diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp
index a5de2169e..ad2960cd9 100644
--- a/src/live_effects/parameter/parameter.cpp
+++ b/src/live_effects/parameter/parameter.cpp
@@ -36,13 +36,19 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip,
{
}
-
void
Parameter::param_write_to_repr(const char * svgd)
{
param_effect->getRepr()->setAttribute(param_key.c_str(), svgd);
}
+void Parameter::write_to_SVG(void)
+{
+ gchar * str = param_getSVGValue();
+ param_write_to_repr(str);
+ g_free(str);
+}
+
/*###########################################
* REAL PARAM
*/
diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h
index 785ada92e..2e6cae49f 100644
--- a/src/live_effects/parameter/parameter.h
+++ b/src/live_effects/parameter/parameter.h
@@ -49,7 +49,7 @@ public:
virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted.
virtual gchar * param_getSVGValue() const = 0;
- void write_to_SVG() { param_write_to_repr(param_getSVGValue()); }
+ void write_to_SVG();
virtual void param_set_default() = 0;
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp
index 44d414942..8095056b7 100644
--- a/src/live_effects/parameter/path.cpp
+++ b/src/live_effects/parameter/path.cpp
@@ -197,7 +197,7 @@ PathParam::param_newWidget()
pButton->show();
pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click));
static_cast<Gtk::HBox*>(_widget)->pack_start(*pButton, true, true);
- pButton->set_tooltip_text(_("Link to path"));
+ pButton->set_tooltip_text(_("Link to path on clipboard"));
static_cast<Gtk::HBox*>(_widget)->show_all_children();
diff --git a/src/object-edit.cpp b/src/object-edit.cpp
index e9b183eca..fe22f6c1c 100644
--- a/src/object-edit.cpp
+++ b/src/object-edit.cpp
@@ -79,8 +79,8 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop)
knotholder = new OffsetKnotHolder(desktop, item, NULL);
} else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) {
knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL);
- } else if ((item->style->fill.isPaintserver())
- && SP_IS_PATTERN(item->style->getFillPaintServer())) {
+ } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) ||
+ (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) {
knotholder = new KnotHolder(desktop, item, NULL);
knotholder->add_pattern_knotholder();
}
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index f058189d3..01ce20509 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1466,7 +1466,7 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live
that case, items are already in the new position, but the repr is in the old, and this function
then simply updates the repr from item->transform.
*/
-void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate)
+void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center)
{
if (selection->isEmpty())
return;
@@ -1621,14 +1621,13 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate);
}
- // if we're transforming the actual object, not just updating the repr, we can transform the
- // center by the same matrix (only necessary for non-translations)
- if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) {
- // If there's a viewbox, we might have an affine with a translation component;
- // we will only apply the scaling/skewing components, not the translations
- // because otherwise the center will move relative to the item
- item->setCenter(old_center * affine.withoutTranslation());
- item->updateRepr();
+ if (adjust_transf_center) { // The transformation center should not be touched in case of pasting or importing, which is allowed by this if clause
+ // if we're moving the actual object, not just updating the repr, we can transform the
+ // center by the same matrix (only necessary for non-translations)
+ if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) {
+ item->setCenter(old_center * affine);
+ item->updateRepr();
+ }
}
}
}
diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h
index d76a67a9d..01c35d65a 100644
--- a/src/selection-chemistry.h
+++ b/src/selection-chemistry.h
@@ -104,7 +104,7 @@ void sp_selection_to_next_layer( SPDesktop *desktop, bool suppressDone = false )
void sp_selection_to_prev_layer( SPDesktop *desktop, bool suppressDone = false );
void sp_selection_to_layer( SPDesktop *desktop, SPObject *layer, bool suppressDone = false );
-void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true);
+void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true);
void sp_selection_remove_transform (SPDesktop *desktop);
void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1);
void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale);
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 6b8cd19bb..e15249f94 100644
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -9,7 +9,7 @@
* Abhishek Sharma
*
* Copyright (C) 1999-2002 Lauris Kaplinski
- * Copyright (C) 1999-2008 Authors
+ * Copyright (C) 1999-2014 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -1109,10 +1109,17 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::P
break;
}
+ // _point and _origin are noisy, ranging from 1 to 1e-9 or even smaller; this is due to the
+ // limited SVG output precision, which can be arbitrarily set in the preferences
Geom::Point const initial_delta = _point - _origin;
- if (fabs(initial_delta[dim_a]) < 1e-15) {
- return false;
+ // The handle and the origin shouldn't be too close to each other; let's check for that!
+ // Due to the limited resolution though (see above), we'd better use a relative error here
+ if (_bbox) {
+ Geom::Coord d = (*_bbox).dimensions()[dim_a];
+ if (fabs(initial_delta[dim_a]/d) < 1e-4) {
+ return false;
+ }
}
// Calculate the scale factors, which can be either visual or geometric
diff --git a/src/snap.cpp b/src/snap.cpp
index ea6322e37..5b795b22f 100644
--- a/src/snap.cpp
+++ b/src/snap.cpp
@@ -274,7 +274,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint
/* See the documentation for constrainedSnap() directly above for more details.
* The difference is that multipleConstrainedSnaps() will take a list of constraints instead of a single one,
- * and will try to snap the SnapCandidatePoint to all of the provided constraints and see which one fits best
+ * and will try to snap the SnapCandidatePoint to only the closest constraint
* \param p Source point to be snapped
* \param constraints List of directions or lines along which snapping must occur
* \param dont_snap If true then we will only apply the constraint, without snapping
@@ -293,16 +293,11 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi
return no_snap;
}
- IntermSnapResults isr;
- SnapperList const snappers = getSnappers();
- std::vector<Geom::Point> projections;
- bool snapping_is_futile = !someSnapperMightSnap() || dont_snap;
-
- Inkscape::SnappedPoint result = no_snap;
-
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false);
+ // We haven't tried to snap yet; we will first determine which constraint is closest to where we are now,
+ // i.e. lets find out which of the constraints yields the closest projection of point p
+ // Project the mouse pointer on each of the constraints
+ std::vector<Geom::Point> projections;
for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) {
// Project the mouse pointer onto the constraint; In case we don't snap then we will
// return the projection onto the constraint, such that the constraint is always enforced
@@ -310,55 +305,47 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi
projections.push_back(pp);
}
- if (snap_mouse && p.isSingleHandle() && !dont_snap) {
+ // Select the closest constraint
+ no_snap.setPoint(projections.front());
+ Inkscape::Snapper::SnapConstraint cc = constraints.front(); //closest constraint
+
+ std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin();
+ std::vector<Geom::Point>::iterator pp = projections.begin();
+ for (; pp != projections.end(); ++pp) {
+ if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) {
+ no_snap.setPoint(*pp); // Remember the projection onto the closest constraint
+ cc = *c; // Remember the closest constraint itself
+ }
+ ++c;
+ }
+
+ if (!someSnapperMightSnap() || dont_snap) {
+ return no_snap;
+ }
+
+ IntermSnapResults isr;
+ SnapperList const snappers = getSnappers();
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false);
+
+ Inkscape::SnappedPoint result = no_snap;
+ if (snap_mouse && p.isSingleHandle()) {
// Snapping the mouse pointer instead of the constrained position of the knot allows
// to snap to things which don't intersect with the constraint line; this is basically
// then just a freesnap with the constraint applied afterwards
// We'll only to this if we're dragging a single handle, and for example not when transforming an object in the selector tool
result = freeSnap(p, bbox_to_snap);
+ // Now apply the constraint afterwards
+ result.setPoint(cc.projection(result.getPoint()));
} else {
- // Iterate over the constraints
- for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) {
- // Try to snap to the constraint
- if (!snapping_is_futile) {
- for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) {
- (*i)->constrainedSnap(isr, p, bbox_to_snap, *c, &_items_to_ignore,_unselected_nodes);
- }
- }
+ // Try to snap along the closest constraint
+ for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) {
+ (*i)->constrainedSnap(isr, p, bbox_to_snap, cc, &_items_to_ignore,_unselected_nodes);
}
result = findBestSnap(p, isr, true);
}
- if (result.getSnapped()) {
- if (snap_mouse) {
- // If "snap_mouse" then we still have to apply the constraint, because so far we only tried a freeSnap
- Geom::Point result_closest;
- for (std::vector<Inkscape::Snapper::SnapConstraint>::const_iterator c = constraints.begin(); c != constraints.end(); ++c) {
- // Project the mouse pointer onto the constraint; In case we don't snap then we will
- // return the projection onto the constraint, such that the constraint is always enforced
- Geom::Point result_p = (*c).projection(result.getPoint());
- if (c == constraints.begin() || (Geom::L2(result_p - p.getPoint()) < Geom::L2(result_closest - p.getPoint()))) {
- result_closest = result_p;
- }
- }
- result.setPoint(result_closest);
- }
- return result;
- }
-
- // So we didn't snap, but we still need to return a point on one of the constraints
- // Find out which of the constraints yielded the closest projection of point p
- for (std::vector<Geom::Point>::iterator pp = projections.begin(); pp != projections.end(); ++pp) {
- if (pp != projections.begin()) {
- if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) {
- no_snap.setPoint(*pp);
- }
- } else {
- no_snap.setPoint(projections.front());
- }
- }
-
- return no_snap;
+ return result.getSnapped() ? result : no_snap;
}
Inkscape::SnappedPoint SnapManager::constrainedAngularSnap(Inkscape::SnapCandidatePoint const &p,
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 657aca692..bb52b0c55 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -660,12 +660,6 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
Geom::Translate const s(p);
Geom::Affine final = s.inverse() * sc * s;
- Geom::Point old_center(0,0);
- if (item->isCenterSet()) {
- item->scaleCenter(sc.inverse()); // Convert the old relative center position to the new coordinates already now
- old_center = item->getCenter(); // because getCenter() will use the bbox midpoint, which is also already in the new coordinates
- }
-
gchar const *conn_type = NULL;
if (SP_IS_TEXT_TEXTPATH(item)) {
SP_TEXT(item)->optimizeTextpathText();
@@ -710,7 +704,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p)
}
if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) {
- item->setCenter(old_center * final);
+ item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled
item->updateRepr();
}
}
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 6c2ada9d7..428f9555e 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -228,18 +228,25 @@ void SPItem::setExplicitlyHidden(bool val) {
}
/**
- * Sets the transform_center_x and transform_center_y properties to retain the rotation centre
- */
+ * Sets the transform_center_x and transform_center_y properties to retain the rotation center
+*/
void SPItem::setCenter(Geom::Point const &object_centre) {
document->ensureUpToDate();
+ // Copied from DocumentProperties::onDocUnitChange()
+ gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width();
+ gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
+
// FIXME this is seriously wrong
Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
- transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X];
+ // object centre is document coordinates (i.e. in pixels), so we need to consider the viewbox
+ // to translate to user units; transform_center_x/y is in user units
+ transform_center_x = (object_centre[Geom::X] - bbox->midpoint()[Geom::X])/viewscale;
if (Geom::are_near(transform_center_x, 0)) // rounding error
transform_center_x = 0;
- transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y];
+ transform_center_y = (object_centre[Geom::Y] - bbox->midpoint()[Geom::Y])/viewscale;
if (Geom::are_near(transform_center_y, 0)) // rounding error
transform_center_y = 0;
}
@@ -255,16 +262,25 @@ bool SPItem::isCenterSet() const {
return (transform_center_x != 0 || transform_center_y != 0);
}
+// Get the item's transformation center in document coordinates (i.e. in pixels)
Geom::Point SPItem::getCenter() const {
document->ensureUpToDate();
+ // Copied from DocumentProperties::onDocUnitChange()
+ gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width();
+ gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
+
// FIXME this is seriously wrong
Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
- return bbox->midpoint() + Geom::Point (transform_center_x, transform_center_y);
+ // transform_center_x/y are stored in user units, so we have to take the viewbox into account to translate to document coordinates
+ return bbox->midpoint() + Geom::Point (transform_center_x*viewscale, transform_center_y*viewscale);
+
} else {
return Geom::Point(0, 0); // something's wrong!
}
+
}
void
@@ -778,6 +794,7 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const
bbox = const_cast<SPItem*>(this)->bbox(transform, SPItem::VISUAL_BBOX);
}
if (clip_ref->getObject()) {
+ SP_ITEM(clip_ref->getOwner())->bbox_valid = FALSE; // LP Bug 1349018
bbox.intersectWith(SP_CLIPPATH(clip_ref->getObject())->geometricBounds(transform));
}
@@ -1109,9 +1126,10 @@ void SPItem::invoke_hide(unsigned key)
// Adjusters
-void SPItem::adjust_pattern (Geom::Affine const &postmul, bool set)
+void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransform pt)
{
- if (style && (style->fill.isPaintserver())) {
+ bool fill = (pt == TRANSFORM_FILL || pt == TRANSFORM_BOTH);
+ if (fill && style && (style->fill.isPaintserver())) {
SPObject *server = style->getFillPaintServer();
if ( SP_IS_PATTERN(server) ) {
SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "fill");
@@ -1119,7 +1137,8 @@ void SPItem::adjust_pattern (Geom::Affine const &postmul, bool set)
}
}
- if (style && (style->stroke.isPaintserver())) {
+ bool stroke = (pt == TRANSFORM_STROKE || pt == TRANSFORM_BOTH);
+ if (stroke && style && (style->stroke.isPaintserver())) {
SPObject *server = style->getStrokePaintServer();
if ( SP_IS_PATTERN(server) ) {
SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "stroke");
diff --git a/src/sp-item.h b/src/sp-item.h
index ce93b1d40..15784d041 100644
--- a/src/sp-item.h
+++ b/src/sp-item.h
@@ -51,6 +51,14 @@ enum {
SP_EVENT_MOUSEOUT
};
+// TODO make a completely new function that transforms either the fill or
+// stroke of any SPItem without adding an extra parameter to adjust_pattern.
+enum PatternTransform {
+ TRANSFORM_BOTH,
+ TRANSFORM_FILL,
+ TRANSFORM_STROKE
+};
+
/**
* Event structure.
*
@@ -199,7 +207,7 @@ public:
Inkscape::DrawingItem *invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
void invoke_hide(unsigned int key);
void getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs=0) const;
- void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false);
+ void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false, PatternTransform = TRANSFORM_BOTH);
void adjust_gradient(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false);
void adjust_stroke(gdouble ex);
void adjust_stroke_width_recursive(gdouble ex);
diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp
index 1f606d176..9f6692f98 100644
--- a/src/sp-solid-color.cpp
+++ b/src/sp-solid-color.cpp
@@ -72,7 +72,7 @@ Inkscape::XML::Node* SPSolidColor::write(Inkscape::XML::Document* xml_doc, Inksc
return repr;
}
-cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const &bbox, double opacity) {
+cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const & /*bbox*/, double opacity) {
SPIColor *c = &(this->style->solid_color);
cairo_pattern_t *cp = cairo_pattern_create_rgba ( c->value.color.v.c[0], c->value.color.v.c[1], c->value.color.v.c[2], SP_SCALE24_TO_FLOAT(this->style->solid_opacity.value) * opacity );
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index eac33ed7b..97a690520 100644
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
@@ -515,6 +515,7 @@ void SPStar::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::
Geom::Affine SPStar::set_transform(Geom::Affine const &xform)
{
+ bool opt_trans = (randomized == 0);
// Only set transform with proportional scaling
if (!xform.withoutTranslation().isUniformScale()) {
return xform;
@@ -530,7 +531,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &xform)
/* This function takes care of translation and scaling, we return whatever parts we can't
handle. */
- Geom::Affine ret(Geom::Affine(xform).withoutTranslation());
+ Geom::Affine ret(opt_trans ? xform.withoutTranslation() : xform);
gdouble const s = hypot(ret[0], ret[1]);
if (s > 1e-9) {
ret[0] /= s;
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 9141b2268..4e4616724 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -45,6 +45,7 @@
#include "widgets/icon.h"
#include "xml/node-event-vector.h"
#include "xml/repr.h"
+#include <algorithm> // std::min
#include "rdf.h"
#include "ui/widget/entity-entry.h"
@@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange()
prefs->setBool("/options/transform/gradient", true);
{
ShapeEditor::blockSetItem(true);
- gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width();
- if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale)
- viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height();
+ gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width();
+ gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height();
+ gdouble viewscale = std::min(viewscale_h, viewscale_w);
gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit);
doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] +
(doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2,
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index f1a29e971..5d065dc60 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -76,7 +76,8 @@ InkscapePreferences::InkscapePreferences()
: UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY),
_max_dialog_width(0),
_max_dialog_height(0),
- _current_page(0)
+ _current_page(0),
+ _init(true)
{
//get the width of a spinbutton
Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton;
@@ -2000,6 +2001,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter)
Gtk::TreeModel::Row row = *iter;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int desired_page = prefs->getInt("/dialogs/preferences/page", 0);
+ _init = false;
if (desired_page == row[_page_list_columns._col_id])
{
if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR)
@@ -2049,7 +2051,9 @@ void InkscapePreferences::on_pagelist_selection_changed()
Gtk::TreeModel::Row row = *iter;
_current_page = row[_page_list_columns._col_page];
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]);
+ if (!_init) {
+ prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]);
+ }
_page_title.set_markup("<span size='large'><b>" + row[_page_list_columns._col_name] + "</b></span>");
_page_frame.add(*_current_page);
_current_page->show();
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 1c2151605..9f37626ed 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -532,6 +532,7 @@ private:
InkscapePreferences();
InkscapePreferences(InkscapePreferences const &d);
InkscapePreferences operator=(InkscapePreferences const &d);
+ bool _init;
};
} // namespace Dialog
diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp
index 03ac9dc64..a015d28f9 100644
--- a/src/ui/dialog/print.cpp
+++ b/src/ui/dialog/print.cpp
@@ -13,13 +13,16 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+
+#include <gtkmm.h>
+
#ifdef WIN32
#include <io.h>
#include <windows.h>
#endif
+#include "preferences.h"
#include "print.h"
-#include <gtkmm/stock.h>
#include "extension/internal/cairo-render-context.h"
#include "extension/internal/cairo-renderer.h"
@@ -44,14 +47,18 @@ static void draw_page(
gint /*page_nr*/,
gpointer user_data)
{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data;
//printf("%s %d\n",__FUNCTION__, page_nr);
if (junk->_tab->as_bitmap()) {
// Render as exported PNG
+ prefs->setBool("/dialogs/printing/asbitmap", true);
gdouble width = (junk->_doc)->getWidth().value("px");
gdouble height = (junk->_doc)->getHeight().value("px");
gdouble dpi = junk->_tab->bitmap_dpi();
+ prefs->setDouble("/dialogs/printing/dpi", dpi);
+
std::string tmp_png;
std::string tmp_base = "inkscape-print-png-XXXXXX";
@@ -92,7 +99,7 @@ static void draw_page(
cairo_get_matrix(cr, &m);
cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi);
// FIXME: why is the origin offset??
- cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0);
+ cairo_set_source_surface(cr, png->cobj(), 0, 0);
cairo_paint(cr);
cairo_set_matrix(cr, &m);
}
@@ -106,6 +113,7 @@ static void draw_page(
}
else {
// Render as vectors
+ prefs->setBool("/dialogs/printing/asbitmap", false);
Inkscape::Extension::Internal::CairoRenderer renderer;
Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext();
diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp
index 55d0aff09..c87e42633 100644
--- a/src/ui/dialog/xml-tree.cpp
+++ b/src/ui/dialog/xml-tree.cpp
@@ -1033,6 +1033,7 @@ void XmlTree::cmd_set_attr()
updated->updateRepr();
}
+ reinterpret_cast<SPObject *>(current_desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
DocumentUndo::done(current_document, SP_VERB_DIALOG_XML_EDITOR,
_("Change attribute"));
diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp
index d6248df69..837387f7b 100644
--- a/src/ui/widget/rendering-options.cpp
+++ b/src/ui/widget/rendering-options.cpp
@@ -12,6 +12,9 @@
# include <config.h>
#endif
+#include <gtkmm.h>
+
+#include "preferences.h"
#include "rendering-options.h"
#include "util/units.h"
#include <glibmm/i18n.h>
@@ -38,6 +41,7 @@ RenderingOptions::RenderingOptions () :
Glib::ustring(""), Glib::ustring(""),
false)
{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// set up tooltips
_radio_vector.set_tooltip_text(
_("Render using Cairo vector operations. "
@@ -52,15 +56,21 @@ RenderingOptions::RenderingOptions () :
set_border_width(2);
- // default to vector operations
- _radio_vector.set_active (true);
Gtk::RadioButtonGroup group = _radio_vector.get_group ();
_radio_bitmap.set_group (group);
_radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled));
-
+
+ // default to vector operations
+ if (prefs->getBool("/dialogs/printing/asbitmap", false)) {
+ _radio_bitmap.set_active();
+ } else {
+ _radio_vector.set_active();
+ }
+
// configure default DPI
_dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0);
- _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt"));
+ _dpi.setValue(prefs->getDouble("/dialogs/printing/dpi",
+ Inkscape::Util::Quantity::convert(1, "in", "pt")));
_dpi.setIncrements(1.0,10.0);
_dpi.setDigits(0);
_dpi.update();
diff --git a/src/util/units.cpp b/src/util/units.cpp
index d2053f60b..eb4a313e0 100644
--- a/src/util/units.cpp
+++ b/src/util/units.cpp
@@ -291,11 +291,15 @@ Quantity UnitTable::parseQuantity(Glib::ustring const &q) const
std::istringstream tmp_v(match_info.fetch(0));
tmp_v >> value;
}
+ int start_pos, end_pos;
+ match_info.fetch_pos(0, end_pos, start_pos);
+ end_pos = q.size() - start_pos;
+ Glib::ustring u = q.substr(start_pos, end_pos);
// Extract unit abbreviation
Glib::ustring abbr;
Glib::RefPtr<Glib::Regex> unit_regex = Glib::Regex::create("[A-z%]+");
- if (unit_regex->match(q, match_info)) {
+ if (unit_regex->match(u, match_info)) {
abbr = match_info.fetch(0);
}
diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp
index ccaf93e55..f00f05768 100644
--- a/src/widgets/font-selector.cpp
+++ b/src/widgets/font-selector.cpp
@@ -157,6 +157,10 @@ static void sp_font_selector_init(SPFontSelector *fsel)
gtk_container_add(GTK_CONTAINER(f), sw);
fsel->family_treeview = gtk_tree_view_new ();
+ gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview),
+ GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func),
+ NULL, NULL );
+ gtk_widget_show_all(GTK_WIDGET (fsel->family_treeview));
GtkTreeViewColumn *column = gtk_tree_view_column_new ();
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, FALSE);
@@ -166,9 +170,6 @@ static void sp_font_selector_init(SPFontSelector *fsel)
NULL, NULL );
gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->family_treeview), column);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->family_treeview), FALSE);
- gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview),
- GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func),
- NULL, NULL );
/* Muck with style, see text-toolbar.cpp */
gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" );
diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp
index 4fda44c8d..f5a99f3e7 100644
--- a/src/widgets/gradient-toolbar.cpp
+++ b/src/widgets/gradient-toolbar.cpp
@@ -448,11 +448,6 @@ static void gr_defs_modified(SPObject * /*defs*/, guint /*flags*/, GtkWidget *wi
gr_tb_selection_changed(NULL, (gpointer) widget);
}
-static void gr_disconnect_sigc(GObject * /*obj*/, sigc::connection *connection) {
- connection->disconnect();
- delete connection;
-}
-
static SPStop *get_selected_stop( GtkWidget *vb)
{
SPStop *stop = NULL;
@@ -1018,6 +1013,9 @@ void check_renderer(GtkWidget *combo)
g_object_set_data(G_OBJECT(combo), "renderers", renderer);
}
}
+
+static void gradient_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
+
/**
* Gradient auxiliary toolbar construction and setup.
*
@@ -1229,34 +1227,51 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions,
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), !linkedmode );
}
- Inkscape::Selection *selection = sp_desktop_selection(desktop);
- SPDocument *document = sp_desktop_document(desktop);
-
g_object_set_data(holder, "desktop", desktop);
- // connect to selection modified and changed signals
- sigc::connection *conn1 = new sigc::connection(
- selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), (gpointer) holder)));
- sigc::connection *conn2 = new sigc::connection(
- selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), (gpointer) holder)));
- sigc::connection *conn3 = new sigc::connection(
- desktop->connectToolSubselectionChanged( sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), (gpointer) holder)));
-
- // when holder is destroyed, disconnect
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
-
- // connect to release and modified signals of the defs (i.e. when someone changes gradient)
- sigc::connection *release_connection = new sigc::connection();
- *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), GTK_WIDGET(holder)));
- sigc::connection *modified_connection = new sigc::connection();
- *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), GTK_WIDGET(holder)));
-
- // when holder is destroyed, disconnect
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
- g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(&gradient_toolbox_check_ec), holder));
+}
+
+// lp:1327267
+/**
+ * Checks the current tool and connects gradient aux toolbox signals if it happens to be the gradient tool.
+ * Called every time the current tool changes by signal emission.
+ */
+static void gradient_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder)
+{
+ static sigc::connection connChanged;
+ static sigc::connection connModified;
+ static sigc::connection connSubselectionChanged;
+ static sigc::connection connDefsRelease;
+ static sigc::connection connDefsModified;
+
+ if (SP_IS_GRADIENT_CONTEXT(ec)) {
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
+ SPDocument *document = sp_desktop_document(desktop);
+ // connect to selection modified and changed signals
+ connChanged = selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), holder));
+ connModified = selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), holder));
+ connSubselectionChanged = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), holder));
+
+ // Is this necessary? Couldn't hurt.
+ gr_tb_selection_changed(selection, holder);
+
+ // connect to release and modified signals of the defs (i.e. when someone changes gradient)
+ connDefsRelease = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), GTK_WIDGET(holder)));
+ connDefsModified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), GTK_WIDGET(holder)));
+ } else {
+ if (connChanged)
+ connChanged.disconnect();
+ if (connModified)
+ connModified.disconnect();
+ if (connSubselectionChanged)
+ connSubselectionChanged.disconnect();
+ if (connDefsRelease)
+ connDefsRelease.disconnect();
+ if (connDefsModified)
+ connDefsModified.disconnect();
+ }
}
/*
diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp
index 64a7cd5e7..36a151c52 100644
--- a/src/widgets/text-toolbar.cpp
+++ b/src/widgets/text-toolbar.cpp
@@ -31,7 +31,6 @@
#include "libnrtype/font-lister.h"
#include <glibmm/i18n.h>
#include "text-toolbar.h"
-#include "connection-pool.h"
#include "desktop-handles.h"
#include "desktop-style.h"
#include "desktop.h"
@@ -54,6 +53,7 @@
#include "toolbox.h"
#include "ui/icon-names.h"
#include "ui/tools/text-tool.h"
+#include "ui/tools/tool-base.h"
#include "verbs.h"
#include "xml/repr.h"
@@ -1200,6 +1200,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p
selection->setList(selectList);
}
+static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder);
// Define all the "widgets" in the toolbar.
void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
@@ -1622,31 +1623,35 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje
// Is this necessary to call? Shouldn't hurt.
sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder);
- // Watch selection
- Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISTextToolboxGTK");
-
- sigc::connection *c_selection_changed =
- new sigc::connection (sp_desktop_selection (desktop)->connectChanged
- (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), holder)));
- pool->add_connection ("selection-changed", c_selection_changed);
-
- sigc::connection *c_selection_modified =
- new sigc::connection (sp_desktop_selection (desktop)->connectModified
- (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), holder)));
- pool->add_connection ("selection-modified", c_selection_modified);
-
- sigc::connection *c_subselection_changed =
- new sigc::connection (desktop->connectToolSubselectionChanged
- (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), holder)));
- pool->add_connection ("tool-subselection-changed", c_subselection_changed);
-
- Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool);
+ desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder));
g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
}
+static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) {
+ using sigc::connection;
+ using sigc::bind;
+ using sigc::ptr_fun;
+ static connection c_selection_changed;
+ static connection c_selection_modified;
+ static connection c_subselection_changed;
+
+ if (SP_IS_TEXT_CONTEXT(ec)) {
+ // Watch selection
+ c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder));
+ c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder));
+ c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder));
+ } else {
+ if (c_selection_changed)
+ c_selection_changed.disconnect();
+ if (c_selection_modified)
+ c_selection_modified.disconnect();
+ if (c_subselection_changed)
+ c_subselection_changed.disconnect();
+ }
+}
/*
Local Variables:
mode:c++