summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2013-08-29 21:06:10 +0000
committer~suv <suv-sf@users.sourceforge.net>2013-08-29 21:06:10 +0000
commit4d331e73a76dce7d703716093923ca01b3cc5936 (patch)
treeb444657ba269b25f60684e66858a138b74fe240d /src/ui
parentFix compiler warnings (diff)
parentUpdating outdated test. Fixes bug #1202271. (diff)
downloadinkscape-4d331e73a76dce7d703716093923ca01b3cc5936.tar.gz
inkscape-4d331e73a76dce7d703716093923ca01b3cc5936.zip
merge from trunk (r12487)
(bzr r11668.1.75)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt4
-rw-r--r--src/ui/clipboard.cpp8
-rw-r--r--src/ui/dialog/Makefile_insert8
-rw-r--r--src/ui/dialog/align-and-distribute.cpp192
-rw-r--r--src/ui/dialog/align-and-distribute.h10
-rw-r--r--src/ui/dialog/clonetiler.cpp77
-rw-r--r--src/ui/dialog/clonetiler.h20
-rw-r--r--src/ui/dialog/dialog-manager.cpp3
-rw-r--r--src/ui/dialog/document-properties.cpp3
-rw-r--r--src/ui/dialog/export.cpp77
-rw-r--r--src/ui/dialog/export.h8
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp15
-rw-r--r--src/ui/dialog/filter-effects-dialog.h1
-rw-r--r--src/ui/dialog/guides.cpp2
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp16
-rw-r--r--src/ui/dialog/inkscape-preferences.h2
-rw-r--r--src/ui/dialog/layers.cpp11
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp8
-rw-r--r--src/ui/dialog/new-from-template.cpp59
-rw-r--r--src/ui/dialog/new-from-template.h39
-rw-r--r--src/ui/dialog/print.cpp12
-rw-r--r--src/ui/dialog/scriptdialog.cpp255
-rw-r--r--src/ui/dialog/scriptdialog.h64
-rw-r--r--src/ui/dialog/swatches.cpp3
-rw-r--r--src/ui/dialog/symbols.cpp6
-rw-r--r--src/ui/dialog/template-load-tab.cpp281
-rw-r--r--src/ui/dialog/template-load-tab.h102
-rw-r--r--src/ui/dialog/template-widget.cpp117
-rw-r--r--src/ui/dialog/template-widget.h48
-rw-r--r--src/ui/dialog/text-edit.cpp4
-rw-r--r--src/ui/dialog/transformation.cpp39
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp8
-rw-r--r--src/ui/tool/node.cpp18
-rw-r--r--src/ui/tool/transform-handle-set.cpp12
-rw-r--r--src/ui/widget/Makefile_insert4
-rw-r--r--src/ui/widget/dock.cpp20
-rw-r--r--src/ui/widget/dock.h10
-rw-r--r--src/ui/widget/page-sizer.cpp172
-rw-r--r--src/ui/widget/page-sizer.h8
-rw-r--r--src/ui/widget/registered-widget.cpp5
-rw-r--r--src/ui/widget/registered-widget.h4
-rw-r--r--src/ui/widget/rendering-options.cpp6
-rw-r--r--src/ui/widget/scalar-unit.cpp7
-rw-r--r--src/ui/widget/selected-style.cpp29
-rw-r--r--src/ui/widget/selected-style.h11
-rw-r--r--src/ui/widget/style-swatch.cpp9
-rw-r--r--src/ui/widget/style-swatch.h8
-rw-r--r--src/ui/widget/unit-menu.cpp16
-rw-r--r--src/ui/widget/unit-menu.h3
-rw-r--r--src/ui/widget/unit-tracker.cpp263
-rw-r--r--src/ui/widget/unit-tracker.h74
51 files changed, 1412 insertions, 769 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index f3c3b8473..b592d2527 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -59,7 +59,6 @@ set(ui_SRC
dialog/ocaldialogs.cpp
dialog/print-colors-preview-dialog.cpp
dialog/print.cpp
- dialog/scriptdialog.cpp
dialog/symbols.cpp
dialog/xml-tree.cpp
# dialog/session-player.cpp
@@ -113,6 +112,7 @@ set(ui_SRC
widget/text.cpp
widget/tolerance-slider.cpp
widget/unit-menu.cpp
+ widget/unit-tracker.cpp
view/view.cpp
view/view-widget.cpp
@@ -172,7 +172,6 @@ set(ui_SRC
dialog/panel-dialog.h
dialog/print-colors-preview-dialog.h
dialog/print.h
- dialog/scriptdialog.h
dialog/spellcheck.h
dialog/svg-fonts-dialog.h
dialog/swatches.h
@@ -242,6 +241,7 @@ set(ui_SRC
widget/text.h
widget/tolerance-slider.h
widget/unit-menu.h
+ widget/unit-tracker.h
view/edit-widget-interface.h
view/view-widget.h
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 72ddd90a9..629960613 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -79,7 +79,7 @@
#include "text-editing.h"
#include "tools-switch.h"
#include "path-chemistry.h"
-#include "unit-constants.h"
+#include "util/units.h"
#include "helper/png-write.h"
#include "svg/svg-color.h"
#include "sp-namedview.h"
@@ -1078,14 +1078,14 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/)
try {
if (out == outlist.end() && target == "image/png")
{
- gdouble dpi = PX_PER_IN;
+ gdouble dpi = Inkscape::Util::Quantity::convert(1, "in", "px");
guint32 bgcolor = 0x00000000;
Geom::Point origin (_clipboardSPDoc->getRoot()->x.computed, _clipboardSPDoc->getRoot()->y.computed);
Geom::Rect area = Geom::Rect(origin, origin + _clipboardSPDoc->getDimensions());
- unsigned long int width = (unsigned long int) (area.width() * dpi / PX_PER_IN + 0.5);
- unsigned long int height = (unsigned long int) (area.height() * dpi / PX_PER_IN + 0.5);
+ unsigned long int width = (unsigned long int) (area.width() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
+ unsigned long int height = (unsigned long int) (area.height() * dpi / Inkscape::Util::Quantity::convert(1, "in", "px") + 0.5);
// read from namedview
Inkscape::XML::Node *nv = sp_repr_lookup_name (_clipboardSPDoc->rroot, "sodipodi:namedview");
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert
index 580b47522..09a7ef573 100644
--- a/src/ui/dialog/Makefile_insert
+++ b/src/ui/dialog/Makefile_insert
@@ -70,6 +70,8 @@ ink_common_sources += \
ui/dialog/memory.h \
ui/dialog/messages.cpp \
ui/dialog/messages.h \
+ ui/dialog/new-from-template.cpp \
+ ui/dialog/new-from-template.h \
ui/dialog/ocaldialogs.cpp \
ui/dialog/ocaldialogs.h \
ui/dialog/object-attributes.cpp \
@@ -81,8 +83,6 @@ ink_common_sources += \
ui/dialog/print.h \
ui/dialog/print-colors-preview-dialog.cpp \
ui/dialog/print-colors-preview-dialog.h \
- ui/dialog/scriptdialog.cpp \
- ui/dialog/scriptdialog.h \
ui/dialog/spellcheck.cpp \
ui/dialog/spellcheck.h \
ui/dialog/svg-fonts-dialog.cpp \
@@ -91,6 +91,10 @@ ink_common_sources += \
ui/dialog/swatches.h \
ui/dialog/symbols.cpp \
ui/dialog/symbols.h \
+ ui/dialog/template-load-tab.cpp \
+ ui/dialog/template-load-tab.h \
+ ui/dialog/template-widget.cpp \
+ ui/dialog/template-widget.h \
ui/dialog/text-edit.cpp \
ui/dialog/text-edit.h \
ui/dialog/tile.cpp \
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index dbd06d9e8..8845b60e5 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -88,119 +88,73 @@ Action::Action(const Glib::ustring &id,
}
-void ActionAlign::do_action(SPDesktop *desktop, int index) {
-
+void ActionAlign::do_action(SPDesktop *desktop, int index)
+{
Inkscape::Selection *selection = sp_desktop_selection(desktop);
if (!selection) return;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool sel_as_group = prefs->getBool("/dialogs/align/sel-as-groups");
- int prefs_bbox = prefs->getBool("/tools/bounding_box");
using Inkscape::Util::GSListConstIterator;
std::list<SPItem *> selected;
selected.insert<GSListConstIterator<SPItem *> >(selected.end(), selection->itemList(), NULL);
if (selected.empty()) return;
- Geom::Point mp; //Anchor point
- AlignAndDistribute::AlignTarget target = AlignAndDistribute::getAlignTarget();
- const Coeffs &a= _allCoeffs[index];
- switch (target)
- {
- case AlignAndDistribute::LAST:
- case AlignAndDistribute::FIRST:
- case AlignAndDistribute::BIGGEST:
- case AlignAndDistribute::SMALLEST:
+ const Coeffs &a = _allCoeffs[index];
+ SPItem *focus = NULL;
+ Geom::OptRect b = Geom::OptRect();
+ Selection::CompareSize horiz = (a.mx0 != 0.0) || (a.mx1 != 0.0)
+ ? Selection::HORIZONTAL : Selection::VERTICAL;
+
+ switch (AlignTarget(prefs->getInt("/dialogs/align/align-to", 6)))
{
- //Check 2 or more selected objects
- std::list<SPItem *>::iterator second(selected.begin());
- ++second;
- if (second == selected.end())
- return;
- //Find the master (anchor on which the other objects are aligned)
- std::list<SPItem *>::iterator master(
- AlignAndDistribute::find_master (
- selected,
- (a.mx0 != 0.0) ||
- (a.mx1 != 0.0) )
- );
- //remove the master from the selection
- SPItem * thing = *master;
- // TODO: either uncomment or remove the following commented lines, depending on which
- // behaviour of moving objects makes most sense; also cf. discussion at
- // https://bugs.launchpad.net/inkscape/+bug/255933
- /*if (!sel_as_group) { */
- selected.erase(master);
- /*}*/
- //Compute the anchor point
- Geom::OptRect b = !prefs_bbox ? thing->desktopVisualBounds() : thing->desktopGeometricBounds();
- if (b) {
- mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
- a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
- } else {
- return;
- }
+ case LAST:
+ focus = SP_ITEM(*selected.begin());
break;
- }
-
- case AlignAndDistribute::PAGE:
- mp = Geom::Point(a.mx1 * sp_desktop_document(desktop)->getWidth(),
- a.my1 * sp_desktop_document(desktop)->getHeight());
+ case FIRST:
+ focus = SP_ITEM(*--(selected.end()));
break;
-
- case AlignAndDistribute::DRAWING:
- {
- Geom::OptRect b = !prefs_bbox ? sp_desktop_document(desktop)->getRoot()->desktopVisualBounds()
- : sp_desktop_document(desktop)->getRoot()->desktopGeometricBounds();
- if (b) {
- mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
- a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
- } else {
- return;
- }
+ case BIGGEST:
+ focus = selection->largestItem(horiz);
break;
- }
-
- case AlignAndDistribute::SELECTION:
- {
- Geom::OptRect b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds();
- if (b) {
- mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
- a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
- } else {
- return;
- }
+ case SMALLEST:
+ focus = selection->smallestItem(horiz);
+ break;
+ case PAGE:
+ b = sp_desktop_document(desktop)->preferredBounds();
+ break;
+ case DRAWING:
+ b = sp_desktop_document(desktop)->getRoot()->desktopPreferredBounds();
+ break;
+ case SELECTION:
+ b = selection->preferredBounds();
break;
- }
-
default:
g_assert_not_reached ();
break;
- }; // end of switch
+ };
+
+ if(focus)
+ b = focus->desktopPreferredBounds();
+ g_return_if_fail(b);
- // Top hack: temporarily set clone compensation to unmoved, so that we can align/distribute
- // clones with their original (and the move of the original does not disturb the
- // clones). The only problem with this is that if there are outside-of-selection clones of
- // a selected original, they will be unmoved too, possibly contrary to user's
- // expecation. However this is a minor point compared to making align/distribute always
- // work as expected, and "unmoved" is the default option anyway.
- int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
- prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+ // Generate the move point from the selected bounding box
+ Geom::Point mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
+ a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
bool changed = false;
- Geom::OptRect b;
if (sel_as_group)
- b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds();
+ b = selection->preferredBounds();
//Move each item in the selected list separately
for (std::list<SPItem *>::iterator it(selected.begin());
- it != selected.end();
- it++)
+ it != selected.end(); ++it)
{
sp_desktop_document (desktop)->ensureUpToDate();
if (!sel_as_group)
- b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds();
- if (b) {
+ b = (*it)->desktopPreferredBounds();
+ if (b && (!focus || (*it) != focus)) {
Geom::Point const sp(a.sx0 * b->min()[Geom::X] + a.sx1 * b->max()[Geom::X],
a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]);
Geom::Point const mp_rel( mp - sp );
@@ -211,15 +165,10 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) {
}
}
- // restore compensation setting
- prefs->setInt("/options/clonecompensation/value", saved_compensation);
-
if (changed) {
DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
_("Align"));
}
-
-
}
@@ -347,7 +296,7 @@ private :
float pos = sorted.front().bbox.min()[_orientation];
for ( std::vector<BBoxSort> ::iterator it (sorted.begin());
it < sorted.end();
- it ++ )
+ ++it )
{
if (!Geom::are_near(pos, it->bbox.min()[_orientation], 1e-6)) {
Geom::Point t(0.0, 0.0);
@@ -1265,69 +1214,6 @@ void AlignAndDistribute::addBaselineButton(const Glib::ustring &id, const Glib::
*this, table, orientation, distribute));
}
-
-
-
-std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem *> &list, bool horizontal){
- std::list<SPItem *>::iterator master = list.end();
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int prefs_bbox = prefs->getBool("/tools/bounding_box");
- switch (getAlignTarget()) {
- case LAST:
- return list.begin();
- break;
-
- case FIRST:
- return --(list.end());
- break;
-
- case BIGGEST:
- {
- gdouble max = -1e18;
- for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); ++it) {
- Geom::OptRect b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds();
- if (b) {
- gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
- if (dim > max) {
- max = dim;
- master = it;
- }
- }
- }
- return master;
- }
-
- case SMALLEST:
- {
- gdouble max = 1e18;
- for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); ++it) {
- Geom::OptRect b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds();
- if (b) {
- gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
- if (dim < max) {
- max = dim;
- master = it;
- }
- }
- }
- return master;
- }
-
- default:
- g_assert_not_reached ();
- break;
-
- } // end of switch statement
- return master;
-}
-
-AlignAndDistribute::AlignTarget AlignAndDistribute::getAlignTarget() {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- return AlignTarget(prefs->getInt("/dialogs/align/align-to", 6));
-}
-
-
-
} // namespace Dialog
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index c9165a83e..dfd84535b 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -47,12 +47,6 @@ public:
static AlignAndDistribute &getInstance() { return *new AlignAndDistribute(); }
- enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION };
-
-
-
- static AlignTarget getAlignTarget();
-
#if WITH_GTKMM_3_0
Gtk::Grid &align_table(){return _alignTable;}
Gtk::Grid &distribute_table(){return _distributeTable;}
@@ -67,7 +61,6 @@ public:
Gtk::Table &nodes_table(){return _nodesTable;}
#endif
- static std::list<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal);
void setMode(bool nodeEdit);
Geom::OptRect randomize_bbox;
@@ -189,6 +182,7 @@ public :
double sx0, sx1, sy0, sy1;
int verb_id;
};
+ enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION };
ActionAlign(const Glib::ustring &id,
const Glib::ustring &tiptext,
guint row, guint column,
@@ -204,6 +198,7 @@ public :
* Static function called to align from a keyboard shortcut
*/
static void do_verb_action(SPDesktop *desktop, int verb);
+ static int verb_to_coeff(int verb);
private :
@@ -217,7 +212,6 @@ private :
}
static void do_action(SPDesktop *desktop, int index);
- static int verb_to_coeff(int verb);
guint _index;
AlignAndDistribute &_dialog;
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index 753320ab9..b3675440b 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -34,8 +34,8 @@
#include "document.h"
#include "document-undo.h"
#include "filter-chemistry.h"
-#include "helper/unit-menu.h"
-#include "helper/units.h"
+#include "ui/widget/unit-menu.h"
+#include "util/units.h"
#include "helper/window.h"
#include "inkscape.h"
#include "interface.h"
@@ -58,6 +58,7 @@
#include "sp-root.h"
using Inkscape::DocumentUndo;
+using Inkscape::Util::unit_table;
namespace Inkscape {
namespace UI {
@@ -1092,35 +1093,36 @@ CloneTiler::CloneTiler (void) :
g_object_set_data (G_OBJECT(dlg), "widthheight", (gpointer) hb);
// unitmenu
- GtkWidget *u = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
- sp_unit_selector_set_unit (SP_UNIT_SELECTOR(u), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units);
+ unit_menu = new Inkscape::UI::Widget::UnitMenu();
+ unit_menu->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR);
+ unit_menu->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr);
+ unitChangedConn = unit_menu->signal_changed().connect(sigc::mem_fun(*this, &CloneTiler::clonetiler_unit_changed));
{
// Width spinbutton
#if WITH_GTKMM_3_0
- Glib::RefPtr<Gtk::Adjustment> a = Gtk::Adjustment::create(0.0, -1e6, 1e6, 1.0, 10.0, 0);
+ fill_width = Gtk::Adjustment::create(0.0, -1e6, 1e6, 1.0, 10.0, 0);
#else
- Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0);
+ fill_width = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0);
#endif
- sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj()));
double value = prefs->getDouble(prefs_path + "fillwidth", 50.0);
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u));
- gdouble const units = sp_pixels_get_units (value, unit);
- a->set_value (units);
+ Inkscape::Util::Unit const unit = unit_menu->getUnit();
+ gdouble const units = Inkscape::Util::Quantity::convert(value, "px", unit);
+ fill_width->set_value (units);
#if WITH_GTKMM_3_0
- Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton(a, 1.0, 2);
+ Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton(fill_width, 1.0, 2);
#else
- Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2);
+ Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*fill_width, 1.0, 2);
#endif
e->set_tooltip_text (_("Width of the rectangle to be filled"));
e->set_width_chars (7);
e->set_digits (4);
gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0);
// TODO: C++ification
- g_signal_connect(G_OBJECT(a->gobj()), "value_changed",
- G_CALLBACK(clonetiler_fill_width_changed), u);
+ g_signal_connect(G_OBJECT(fill_width->gobj()), "value_changed",
+ G_CALLBACK(clonetiler_fill_width_changed), unit_menu);
}
{
GtkWidget *l = gtk_label_new ("");
@@ -1132,32 +1134,31 @@ CloneTiler::CloneTiler (void) :
{
// Height spinbutton
#if WITH_GTKMM_3_0
- Glib::RefPtr<Gtk::Adjustment> a = Gtk::Adjustment::create(0.0, -1e6, 1e6, 1.0, 10.0, 0);
+ fill_height = Gtk::Adjustment::create(0.0, -1e6, 1e6, 1.0, 10.0, 0);
#else
- Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0);
+ fill_height = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0);
#endif
- sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj()));
double value = prefs->getDouble(prefs_path + "fillheight", 50.0);
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u));
- gdouble const units = sp_pixels_get_units (value, unit);
- a->set_value (units);
+ Inkscape::Util::Unit const unit = unit_menu->getUnit();
+ gdouble const units = Inkscape::Util::Quantity::convert(value, "px", unit);
+ fill_height->set_value (units);
#if WITH_GTKMM_3_0
- Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton(a, 1.0, 2);
+ Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton(fill_height, 1.0, 2);
#else
- Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2);
+ Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*fill_height, 1.0, 2);
#endif
e->set_tooltip_text (_("Height of the rectangle to be filled"));
e->set_width_chars (7);
e->set_digits (4);
gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0);
// TODO: C++ification
- g_signal_connect(G_OBJECT(a->gobj()), "value_changed",
- G_CALLBACK(clonetiler_fill_height_changed), u);
+ g_signal_connect(G_OBJECT(fill_height->gobj()), "value_changed",
+ G_CALLBACK(clonetiler_fill_height_changed), unit_menu);
}
- gtk_box_pack_start (GTK_BOX (hb), u, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hb), (GtkWidget*) unit_menu->gobj(), TRUE, TRUE, 0);
clonetiler_table_attach (table, hb, 0.0, 2, 2);
}
@@ -2944,26 +2945,39 @@ void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton * /*tb*/, GtkWidget *
-void CloneTiler::clonetiler_fill_width_changed(GtkAdjustment *adj, GtkWidget *u)
+void CloneTiler::clonetiler_fill_width_changed(GtkAdjustment *adj, Inkscape::UI::Widget::UnitMenu *u)
{
gdouble const raw_dist = gtk_adjustment_get_value (adj);
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u));
- gdouble const pixels = sp_units_get_pixels (raw_dist, unit);
+ Inkscape::Util::Unit const unit = u->getUnit();
+ gdouble const pixels = Inkscape::Util::Quantity::convert(raw_dist, unit, "px");
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble(prefs_path + "fillwidth", pixels);
}
-void CloneTiler::clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u)
+void CloneTiler::clonetiler_fill_height_changed(GtkAdjustment *adj, Inkscape::UI::Widget::UnitMenu *u)
{
gdouble const raw_dist = gtk_adjustment_get_value (adj);
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u));
- gdouble const pixels = sp_units_get_pixels (raw_dist, unit);
+ Inkscape::Util::Unit const unit = u->getUnit();
+ gdouble const pixels = Inkscape::Util::Quantity::convert(raw_dist, unit, "px");
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble(prefs_path + "fillheight", pixels);
}
+void CloneTiler::clonetiler_unit_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gdouble width_pixels = prefs->getDouble(prefs_path + "fillwidth");
+ gdouble height_pixels = prefs->getDouble(prefs_path + "fillheight");
+
+ Inkscape::Util::Unit unit = unit_menu->getUnit();
+
+ gdouble width_value = Inkscape::Util::Quantity::convert(width_pixels, "px", unit);
+ gdouble height_value = Inkscape::Util::Quantity::convert(height_pixels, "px", unit);
+ gtk_adjustment_set_value(fill_width->gobj(), width_value);
+ gtk_adjustment_set_value(fill_height->gobj(), height_value);
+}
void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg)
{
@@ -2977,7 +2991,6 @@ void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg)
}
}
-
}
}
}
diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h
index 7ec30cfaa..e2a0240ee 100644
--- a/src/ui/dialog/clonetiler.h
+++ b/src/ui/dialog/clonetiler.h
@@ -19,6 +19,11 @@
namespace Inkscape {
namespace UI {
+
+namespace Widget {
+ class UnitMenu;
+}
+
namespace Dialog {
class CloneTiler : public Widget::Panel {
@@ -45,8 +50,9 @@ protected:
static void clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg);
static void clonetiler_pick_to(GtkToggleButton *tb, gpointer data);
static void clonetiler_xy_changed(GtkAdjustment *adj, gpointer data);
- static void clonetiler_fill_width_changed(GtkAdjustment *adj, GtkWidget *u);
- static void clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u);
+ static void clonetiler_fill_width_changed(GtkAdjustment *adj, Inkscape::UI::Widget::UnitMenu *u);
+ static void clonetiler_fill_height_changed(GtkAdjustment *adj, Inkscape::UI::Widget::UnitMenu *u);
+ void clonetiler_unit_changed();
static void clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg);
static void clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg);
static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/);
@@ -112,12 +118,22 @@ private:
DesktopTracker deskTrack;
Inkscape::UI::Widget::ColorPicker *color_picker;
GtkSizeGroup* table_row_labels;
+ Inkscape::UI::Widget::UnitMenu *unit_menu;
+
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> fill_width;
+ Glib::RefPtr<Gtk::Adjustment> fill_height;
+#else
+ Gtk::Adjustment *fill_width;
+ Gtk::Adjustment *fill_height;
+#endif
sigc::connection desktopChangeConn;
sigc::connection selectChangedConn;
sigc::connection subselChangedConn;
sigc::connection selectModifiedConn;
sigc::connection color_changed_connection;
+ sigc::connection unitChangedConn;
/**
* Can be invoked for setting the desktop. Currently not used.
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index 993f48d8f..0ce74f54e 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -32,7 +32,6 @@
#include "ui/dialog/livepatheffect-editor.h"
#include "ui/dialog/memory.h"
#include "ui/dialog/messages.h"
-#include "ui/dialog/scriptdialog.h"
#include "ui/dialog/symbols.h"
#include "ui/dialog/tile.h"
#include "ui/dialog/tracedialog.h"
@@ -114,7 +113,6 @@ DialogManager::DialogManager() {
registerFactory("ObjectAttributes", &create<ObjectAttributes, FloatingBehavior>);
registerFactory("ObjectProperties", &create<ObjectProperties, FloatingBehavior>);
// registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>);
- registerFactory("Script", &create<ScriptDialog, FloatingBehavior>);
registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>);
registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>);
registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>);
@@ -148,7 +146,6 @@ DialogManager::DialogManager() {
registerFactory("ObjectAttributes", &create<ObjectAttributes, DockBehavior>);
registerFactory("ObjectProperties", &create<ObjectProperties, DockBehavior>);
// registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>);
- registerFactory("Script", &create<ScriptDialog, DockBehavior>);
registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>);
registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>);
registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>);
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index d335fb303..77fb182e5 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -28,7 +28,6 @@
#include "document.h"
#include "desktop-handles.h"
#include "desktop.h"
-#include "helper/units.h"
#include "inkscape.h"
#include "io/sys.h"
#include "preferences.h"
@@ -1432,7 +1431,7 @@ void DocumentProperties::update()
_rcb_shad.setActive (nv->showpageshadow);
if (nv->doc_units)
- _rum_deflt.setUnit (nv->doc_units);
+ _rum_deflt.setUnit (nv->doc_units->abbr);
double const doc_w_px = sp_desktop_document(dt)->getWidth();
double const doc_h_px = sp_desktop_document(dt)->getHeight();
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index a851503fe..2c92608d7 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -48,9 +48,8 @@
#include <glibmm/i18n.h>
#include <glibmm/miscutils.h>
-#include "helper/unit-menu.h"
-#include "helper/units.h"
-#include "unit-constants.h"
+#include "ui/widget/unit-menu.h"
+#include "util/units.h"
#include "helper/window.h"
#include "inkscape-private.h"
#include "document.h"
@@ -98,7 +97,7 @@
#define SP_EXPORT_MIN_SIZE 1.0
-#define DPI_BASE PX_PER_IN
+#define DPI_BASE Inkscape::Util::Quantity::convert(1, "in", "px")
#define EXPORT_COORD_PRECISION 3
@@ -108,6 +107,8 @@
#include "verbs.h"
#include "export.h"
+using Inkscape::Util::unit_table;
+
namespace {
class MessageCleaner
@@ -198,10 +199,13 @@ Export::Export (void) :
/* Units box */
/* gets added to the vbox later, but the unit selector is needed
earlier than that */
- unit_selector = Glib::wrap(sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE));
+ unit_selector = new Inkscape::UI::Widget::UnitMenu();
+ unit_selector->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR);
+ unitChangedConn = unit_selector->signal_changed().connect(sigc::mem_fun(*this, &Export::onUnitChanged));
+
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop)
- sp_unit_selector_set_unit (SP_UNIT_SELECTOR(unit_selector->gobj()), sp_desktop_namedview(desktop)->doc_units);
+ unit_selector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr);
unitbox.pack_end(*unit_selector, false, false, 0);
unitbox.pack_end(units_label, false, false, 3);
@@ -226,28 +230,28 @@ Export::Export (void) :
t->set_col_spacings (4);
#endif
- x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, unit_selector->gobj(),
+ x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, ((Gtk::Widget*) unit_selector)->gobj(),
t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaX0Change);
- x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, unit_selector->gobj(),
+ x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, ((Gtk::Widget*) unit_selector)->gobj(),
t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaX1Change);
width_adj = createSpinbutton ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
- unit_selector->gobj(), t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1,
+ ((Gtk::Widget*) unit_selector)->gobj(), t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaWidthChange);
- y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, unit_selector->gobj(),
+ y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, ((Gtk::Widget*) unit_selector)->gobj(),
t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaY0Change);
- y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, unit_selector->gobj(),
+ y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, ((Gtk::Widget*) unit_selector)->gobj(),
t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaY1Change);
height_adj = createSpinbutton ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
- unit_selector->gobj(), t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1,
+ ((Gtk::Widget*) unit_selector)->gobj(), t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1,
&Export::onAreaHeightChange);
area_box.pack_start(togglebox, false, false, 3);
@@ -496,9 +500,6 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
#else
Gtk::Adjustment *adj = new Gtk::Adjustment ( val, min, max, step, page, 0 );
#endif
- if (us) {
- sp_unit_selector_add_adjustment ( SP_UNIT_SELECTOR (us), GTK_ADJUSTMENT (adj->gobj()) );
- }
int pos = 0;
Gtk::Label *l = NULL;
@@ -979,6 +980,12 @@ Glib::ustring Export::absolutize_path_from_document_location (SPDocument *doc, c
return path;
}
+// Called when unit is changed
+void Export::onUnitChanged()
+{
+ onAreaToggled();
+}
+
void Export::onHideExceptSelected ()
{
prefs->setBool("/dialogs/export/hideexceptselected/value", hide_export.get_active());
@@ -1042,8 +1049,8 @@ void Export::onExport ()
Geom::OptRect area = item->desktopVisualBounds();
if (area) {
- gint width = (gint) (area->width() * dpi / PX_PER_IN + 0.5);
- gint height = (gint) (area->height() * dpi / PX_PER_IN + 0.5);
+ gint width = (gint) (area->width() * dpi / DPI_BASE + 0.5);
+ gint height = (gint) (area->height() * dpi / DPI_BASE + 0.5);
if (width > 1 && height > 1) {
// Do export
@@ -1507,10 +1514,6 @@ void Export::areaXChange (Gtk::Adjustment *adj)
return;
}
- if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
- return;
- }
-
update = true;
x0 = getValuePx(x0_adj);
@@ -1554,10 +1557,6 @@ void Export::areaYChange (Gtk::Adjustment *adj)
return;
}
- if (sp_unit_selector_update_test (SP_UNIT_SELECTOR(unit_selector->gobj()))) {
- return;
- }
-
update = true;
y0 = getValuePx(y0_adj);
@@ -1597,10 +1596,6 @@ void Export::onAreaWidthChange()
return;
}
- if (sp_unit_selector_update_test(reinterpret_cast<SPUnitSelector *>(unit_selector->gobj()))) {
- return;
- }
-
update = true;
float x0 = getValuePx(x0_adj);
@@ -1630,10 +1625,6 @@ void Export::onAreaHeightChange()
return;
}
- if (sp_unit_selector_update_test(reinterpret_cast<SPUnitSelector *>(unit_selector->gobj()))) {
- return;
- }
-
update = true;
float y0 = getValuePx(y0_adj);
@@ -1709,10 +1700,6 @@ void Export::onBitmapWidthChange ()
return;
}
- if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
- return;
- }
-
update = true;
x0 = getValuePx(x0_adj);
@@ -1743,10 +1730,6 @@ void Export::onBitmapHeightChange ()
return;
}
- if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
- return;
- }
-
update = true;
y0 = getValuePx(y0_adj);
@@ -1803,10 +1786,6 @@ void Export::onExportXdpiChange()
return;
}
- if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
- return;
- }
-
update = true;
x0 = getValuePx(x0_adj);
@@ -1905,9 +1884,9 @@ void Export::setValuePx(Glib::RefPtr<Gtk::Adjustment>& adj, double val)
void Export::setValuePx( Gtk::Adjustment *adj, double val)
#endif
{
- const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj()) );
+ const Unit unit = unit_selector->getUnit();
- setValue(adj, sp_pixels_get_units (val, *unit));
+ setValue(adj, Inkscape::Util::Quantity::convert(val, "px", unit));
return;
}
@@ -1955,9 +1934,9 @@ float Export::getValuePx( Gtk::Adjustment *adj )
#endif
{
float value = getValue( adj);
- const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj()));
+ const Unit unit = unit_selector->getUnit();
- return sp_units_get_pixels (value, *unit);
+ return Inkscape::Util::Quantity::convert(value, unit, "px");
} // end of sp_export_value_get_px()
/**
diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h
index b10c98fd2..f324f5dc5 100644
--- a/src/ui/dialog/export.h
+++ b/src/ui/dialog/export.h
@@ -172,6 +172,11 @@ private:
#endif
/**
+ * Unit changed callback
+ */
+ void onUnitChanged();
+
+ /**
* Hide except selected callback
*/
void onHideExceptSelected ();
@@ -330,7 +335,7 @@ private:
/* Unit selector widgets */
Gtk::HBox unitbox;
- Gtk::Widget* unit_selector;
+ Inkscape::UI::Widget::UnitMenu *unit_selector;
Gtk::Label units_label;
/* Filename widgets */
@@ -365,6 +370,7 @@ private:
sigc::connection selectChangedConn;
sigc::connection subselChangedConn;
sigc::connection selectModifiedConn;
+ sigc::connection unitChangedConn;
};
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 4c289d54e..4401d5658 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -1155,7 +1155,13 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d)
sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
_list.get_column(1)->set_resizable(true);
-
+ _list.set_reorderable(true);
+
+ // We can track the drag/drop reordering from the row_delete (occurs after
+ // row_inserted and may occur many times when adding a new item)
+ _model->signal_row_deleted().connect(
+ sigc::mem_fun(*this, &FilterModifier::on_filter_reorder));
+
sw->set_shadow_type(Gtk::SHADOW_IN);
show_all_children();
_add.signal_clicked().connect(sigc::mem_fun(*this, &FilterModifier::add_filter));
@@ -1301,6 +1307,13 @@ void FilterEffectsDialog::FilterModifier::on_name_edited(const Glib::ustring& pa
}
}
+void FilterEffectsDialog::FilterModifier::on_filter_reorder(const Gtk::TreeModel::Path& path) {
+ for(Gtk::TreeModel::iterator i = _model->children().begin(); i != _model->children().end(); ++i) {
+ SPObject* object = (*i)[_columns.filter];
+ object->getRepr()->setPosition(0);
+ }
+}
+
void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustring& path)
{
Gtk::TreeIter iter = _model->get_iter(path);
diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h
index 658aac790..a2a2a3c6e 100644
--- a/src/ui/dialog/filter-effects-dialog.h
+++ b/src/ui/dialog/filter-effects-dialog.h
@@ -86,6 +86,7 @@ private:
void on_filter_selection_changed();
void on_name_edited(const Glib::ustring&, const Glib::ustring&);
+ void on_filter_reorder(const Gtk::TreeModel::Path& path);
void on_selection_toggled(const Glib::ustring&);
void update_filters();
diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp
index 51bbc7d9a..2de387364 100644
--- a/src/ui/dialog/guides.cpp
+++ b/src/ui/dialog/guides.cpp
@@ -230,7 +230,7 @@ void GuidelinePropertiesDialog::_setup() {
_unit_menu.setUnitType(UNIT_TYPE_LINEAR);
_unit_menu.setUnit("px");
if (_desktop->namedview->doc_units) {
- _unit_menu.setUnit( sp_unit_get_abbreviation(_desktop->namedview->doc_units) );
+ _unit_menu.setUnit( _desktop->namedview->doc_units->abbr );
}
_spin_angle.setUnit(_angle_unit_status);
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index bc648002d..b06c1fd1f 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -28,7 +28,7 @@
#include "preferences.h"
#include "verbs.h"
#include "selcue.h"
-#include "unit-constants.h"
+#include "util/units.h"
#include <iostream>
#include "enums.h"
#include "desktop-handles.h"
@@ -879,8 +879,12 @@ void InkscapePreferences::initPageIO()
_page_svgoutput.add_group_header( _("Path data"));
- _svgoutput_allowrelativecoordinates.init( _("Allow relative coordinates"), "/options/svgoutput/allowrelativecoordinates", true);
- _page_svgoutput.add_line( true, "", _svgoutput_allowrelativecoordinates, "", _("If set, relative coordinates may be used in path data"), false);
+ int const numPathstringFormat = 3;
+ Glib::ustring pathstringFormatLabels[numPathstringFormat] = {_("Absolute"), _("Relative"), _("Optimized")};
+ int pathstringFormatValues[numPathstringFormat] = {0, 1, 2};
+
+ _svgoutput_pathformat.init("/options/svgoutput/pathstring_format", pathstringFormatLabels, pathstringFormatValues, numPathstringFormat, 2);
+ _page_svgoutput.add_line( true, _("Path string format"), _svgoutput_pathformat, "", _("Path data should be written: only with absolute coordinates, only with relative coordinates, or optimized for string length (mixed absolute and relative coordinates)"), false);
_svgoutput_forcerepeatcommands.init( _("Force repeat commands"), "/options/svgoutput/forcerepeatcommands", false);
_page_svgoutput.add_line( true, "", _svgoutput_forcerepeatcommands, "", _("Force repeating of the same path command (for example, 'L 1,2 L 3,4' instead of 'L 1,2 3,4')"), false);
@@ -1428,10 +1432,10 @@ void InkscapePreferences::initPageBitmaps()
_("Automatically reload linked images when file is changed on disk"));
_misc_bitmap_editor.init("/options/bitmapeditor/value", true);
_page_bitmaps.add_line( false, _("_Bitmap editor:"), _misc_bitmap_editor, "", "", true);
- _importexport_export_res.init("/dialogs/export/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false);
+ _importexport_export_res.init("/dialogs/export/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, Inkscape::Util::Quantity::convert(1, "in", "px"), true, false);
_page_bitmaps.add_line( false, _("Default export _resolution:"), _importexport_export_res, _("dpi"),
_("Default bitmap resolution (in dots per inch) in the Export dialog"), false);
- _bitmap_copy_res.init("/options/createbitmap/resolution", 1.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false);
+ _bitmap_copy_res.init("/options/createbitmap/resolution", 1.0, 6000.0, 1.0, 1.0, Inkscape::Util::Quantity::convert(1, "in", "px"), true, false);
_page_bitmaps.add_line( false, _("Resolution for Create Bitmap _Copy:"), _bitmap_copy_res, _("dpi"),
_("Resolution used by the Create Bitmap Copy command"), false);
{
@@ -1443,7 +1447,7 @@ void InkscapePreferences::initPageBitmaps()
_bitmap_import_quality.init("/dialogs/import/quality", 1, 100, 1, 1, 100, true, false);
_page_bitmaps.add_line( false, _("Bitmap import quality:"), _bitmap_import_quality, "%", "Bitmap import quality (jpeg only). 100 is best quality", false);
}
- _importexport_import_res.init("/dialogs/import/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false);
+ _importexport_import_res.init("/dialogs/import/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, Inkscape::Util::Quantity::convert(1, "in", "px"), true, false);
_page_bitmaps.add_line( false, _("Default _import resolution:"), _importexport_import_res, _("dpi"),
_("Default bitmap resolution (in dots per inch) for bitmap import"), false);
_importexport_import_res_override.init(_("Override file resolution"), "/dialogs/import/forcexdpi", false);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 37c05df05..56222fb22 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -426,7 +426,7 @@ protected:
UI::Widget::PrefSpinButton _svgoutput_minimumexponent;
UI::Widget::PrefCheckButton _svgoutput_inlineattrs;
UI::Widget::PrefSpinButton _svgoutput_indent;
- UI::Widget::PrefCheckButton _svgoutput_allowrelativecoordinates;
+ UI::Widget::PrefCombo _svgoutput_pathformat;
UI::Widget::PrefCheckButton _svgoutput_forcerepeatcommands;
// Attribute Checking controls for SVG Output page:
diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp
index 5cc9578f1..c41046123 100644
--- a/src/ui/dialog/layers.cpp
+++ b/src/ui/dialog/layers.cpp
@@ -27,6 +27,7 @@
#include "document.h"
#include "document-undo.h"
#include "helper/action.h"
+#include "helper/action-context.h"
#include "inkscape.h"
#include "layer-fns.h"
#include "layer-manager.h"
@@ -99,7 +100,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i
if ( desktop ) {
Verb *verb = Verb::get( code );
if ( verb ) {
- SPAction *action = verb->get_action(desktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext(desktop));
if ( !set && action && action->image ) {
GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image );
gtk_widget_show( child );
@@ -131,7 +132,7 @@ Gtk::MenuItem& LayersPanel::_addPopupItem( SPDesktop *desktop, unsigned int code
if ( desktop ) {
Verb *verb = Verb::get( code );
if ( verb ) {
- SPAction *action = verb->get_action(desktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext(desktop));
if ( !iconWidget && action && action->image ) {
iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image );
}
@@ -172,7 +173,7 @@ void LayersPanel::_fireAction( unsigned int code )
if ( _desktop ) {
Verb *verb = Verb::get( code );
if ( verb ) {
- SPAction *action = verb->get_action(_desktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext(_desktop));
if ( action ) {
sp_action_perform( action, NULL );
// } else {
@@ -404,13 +405,13 @@ void LayersPanel::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::R
SPObject *child = _desktop->layer_manager->nthChildOf(layer, i);
if ( child ) {
#if DUMP_LAYERS
- g_message(" %3d layer:%p {%s} [%s]", level, child, child->id, child->label() );
+ g_message(" %3d layer:%p {%s} [%s]", level, child, child->getId(), child->label() );
#endif // DUMP_LAYERS
Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend();
Gtk::TreeModel::Row row = *iter;
row[_model->_colObject] = child;
- row[_model->_colLabel] = child->label() ? child->label() : child->getId();
+ row[_model->_colLabel] = child->defaultLabel();
row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false;
row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false;
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index e6bb9b43d..6dc9c1ee3 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -416,7 +416,7 @@ LivePathEffectEditor::onAdd()
// If item is a SPRect, convert it to path first:
if ( SP_IS_RECT(item) ) {
- sp_selected_path_to_curves(current_desktop, false);
+ sp_selected_path_to_curves(sel, current_desktop, false);
item = sel->singleItem(); // get new item
}
@@ -448,9 +448,9 @@ LivePathEffectEditor::onAdd()
// run sp_selection_clone_original_path_lpe
sp_selection_clone_original_path_lpe(current_desktop);
- item = sel->singleItem();
- item->getRepr()->setAttribute("id", id);
- item->getRepr()->setAttribute("transform", transform);
+ SPItem *new_item = sel->singleItem();
+ new_item->getRepr()->setAttribute("id", id);
+ new_item->getRepr()->setAttribute("transform", transform);
g_free(id);
g_free(transform);
diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp
new file mode 100644
index 000000000..2595e2cf5
--- /dev/null
+++ b/src/ui/dialog/new-from-template.cpp
@@ -0,0 +1,59 @@
+/** @file
+ * @brief New From Template main dialog - implementation
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+
+#include "new-from-template.h"
+#include "file.h"
+
+#include <gtkmm/alignment.h>
+#include <glibmm/i18n.h>
+
+
+namespace Inkscape {
+namespace UI {
+
+
+NewFromTemplate::NewFromTemplate()
+ : _create_template_button(_("Create from template"))
+{
+ set_title(_("New From Template"));
+ resize(400, 400);
+
+ get_vbox()->pack_start(_main_widget);
+
+ Gtk::Alignment *align;
+ align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0));
+ get_vbox()->pack_end(*align, Gtk::PACK_SHRINK);
+ align->set_padding(0, 0, 0, 15);
+ align->add(_create_template_button);
+
+ _create_template_button.signal_pressed().connect(
+ sigc::mem_fun(*this, &NewFromTemplate::_createFromTemplate));
+
+ show_all();
+}
+
+
+void NewFromTemplate::_createFromTemplate()
+{
+ _main_widget.createTemplate();
+
+ response(0);
+}
+
+
+void NewFromTemplate::load_new_from_template()
+{
+ NewFromTemplate dl;
+ dl.run();
+}
+
+}
+}
diff --git a/src/ui/dialog/new-from-template.h b/src/ui/dialog/new-from-template.h
new file mode 100644
index 000000000..8ebcb2863
--- /dev/null
+++ b/src/ui/dialog/new-from-template.h
@@ -0,0 +1,39 @@
+/** @file
+ * @brief New From Template main dialog
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_SEEN_UI_DIALOG_NEW_FROM_TEMPLATE_H
+#define INKSCAPE_SEEN_UI_DIALOG_NEW_FROM_TEMPLATE_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/button.h>
+
+#include "template-load-tab.h"
+
+
+namespace Inkscape {
+namespace UI {
+
+
+class NewFromTemplate : public Gtk::Dialog
+{
+public:
+ static void load_new_from_template();
+
+private:
+ NewFromTemplate();
+ Gtk::Button _create_template_button;
+ TemplateLoadTab _main_widget;
+
+ void _createFromTemplate();
+};
+
+}
+}
+#endif
diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp
index 2ab8cf121..4c8c77f96 100644
--- a/src/ui/dialog/print.cpp
+++ b/src/ui/dialog/print.cpp
@@ -26,7 +26,7 @@
#include "ui/widget/rendering-options.h"
#include "document.h"
-#include "unit-constants.h"
+#include "util/units.h"
#include "helper/png-write.h"
#include "svg/svg-color.h"
#include "io/sys.h"
@@ -72,8 +72,8 @@ static void draw_page(
sp_export_png_file(junk->_doc, tmp_png.c_str(), 0.0, 0.0,
width, height,
- (unsigned long)(width * dpi / PX_PER_IN),
- (unsigned long)(height * dpi / PX_PER_IN),
+ (unsigned long)(width * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")),
+ (unsigned long)(height * dpi / Inkscape::Util::Quantity::convert(1, "in", "px")),
dpi, dpi, bgcolor, NULL, NULL, true, NULL);
// This doesn't seem to work:
@@ -90,7 +90,7 @@ static void draw_page(
cairo_t *cr = gtk_print_context_get_cairo_context (context);
cairo_matrix_t m;
cairo_get_matrix(cr, &m);
- cairo_scale(cr, PT_PER_IN / dpi, PT_PER_IN / dpi);
+ 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_paint(cr);
@@ -195,8 +195,8 @@ Print::Print(SPDocument *doc, SPItem *base) :
// set up paper size to match the document size
gtk_print_operation_set_unit (_printop, GTK_UNIT_POINTS);
GtkPageSetup *page_setup = gtk_page_setup_new();
- gdouble doc_width = _doc->getWidth() * PT_PER_PX;
- gdouble doc_height = _doc->getHeight() * PT_PER_PX;
+ gdouble doc_width = _doc->getWidth() * Inkscape::Util::Quantity::convert(1, "px", "pt");
+ gdouble doc_height = _doc->getHeight() * Inkscape::Util::Quantity::convert(1, "px", "pt");
GtkPaperSize *paper_size;
if (doc_width > doc_height) {
gtk_page_setup_set_orientation (page_setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
diff --git a/src/ui/dialog/scriptdialog.cpp b/src/ui/dialog/scriptdialog.cpp
deleted file mode 100644
index 87794a3ce..000000000
--- a/src/ui/dialog/scriptdialog.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/**
- * @file
- * Dialog for executing and monitoring script execution.
- */
-/* Author:
- * Bob Jamison
- *
- * Copyright (C) 2004-2008 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "scriptdialog.h"
-#include <glibmm/i18n.h>
-#include <gtkmm/menubar.h>
-#include <gtkmm/frame.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/textview.h>
-
-#include <extension/script/InkscapeScript.h>
-
-
-
-namespace Inkscape
-{
-namespace UI
-{
-namespace Dialog
-{
-
-
-
-//#########################################################################
-//## I M P L E M E N T A T I O N
-//#########################################################################
-
-/**
- * A script editor/executor
- */
-class ScriptDialogImpl : public ScriptDialog
-{
-
- public:
- ScriptDialogImpl();
- ~ScriptDialogImpl()
- {}
-
-
- /**
- * Remove all text from the dialog.
- */
- void clear();
-
- /**
- * Execute a script in the dialog.
- *
- * @param lang language in which the script is programmed
- */
- void execute(Inkscape::Extension::Script::InkscapeScript::ScriptLanguage lang);
-
- /**
- * Execute a Javascript script
- */
- void executeJavascript();
-
- /**
- * Execute a Python script
- */
- void executePython();
-
- /**
- * Execute a Ruby script
- */
- void executeRuby();
-
-
-
- private:
- Gtk::MenuBar menuBar;
- Gtk::Menu fileMenu;
-
- //## Script text
- Gtk::Frame scriptTextFrame;
- Gtk::ScrolledWindow scriptTextScroll;
- Gtk::TextView scriptText;
-
- //## Output text
- Gtk::Frame outputTextFrame;
- Gtk::ScrolledWindow outputTextScroll;
- Gtk::TextView outputText;
-
- //## Error text
- Gtk::Frame errorTextFrame;
- Gtk::ScrolledWindow errorTextScroll;
- Gtk::TextView errorText;
-
-
-
-};
-
-static const char *defaultCodeStr =
- "/**\n"
- " * This is some example Javascript.\n"
- " * Try 'Execute Javascript'\n"
- " */\n"
- "importPackage(javax.swing);\n"
- "function sayHello() {\n"
- " JOptionPane.showMessageDialog(null, 'Hello, world!',\n"
- " 'Welcome to Inkscape', JOptionPane.WARNING_MESSAGE);\n"
- "}\n"
- "\n"
- "sayHello();\n"
- "\n";
-
-
-
-
-//#########################################################################
-//## E V E N T S
-//#########################################################################
-
-static void textViewClear(Gtk::TextView &view)
-{
- Glib::RefPtr<Gtk::TextBuffer> buffer = view.get_buffer();
- buffer->erase(buffer->begin(), buffer->end());
-}
-
-void ScriptDialogImpl::clear()
-{
- textViewClear(scriptText);
- textViewClear(outputText);
- textViewClear(errorText);
-}
-
-void ScriptDialogImpl::execute(Inkscape::Extension::Script::InkscapeScript::ScriptLanguage lang)
-{
- Glib::ustring script = scriptText.get_buffer()->get_text(true);
- Glib::ustring output;
- Glib::ustring error;
- Inkscape::Extension::Script::InkscapeScript engine;
- bool ok = engine.interpretScript(script, output, error, lang);
- outputText.get_buffer()->set_text(output);
- errorText.get_buffer()->set_text(error);
- if (!ok)
- {
- //do we want something here?
- }
-}
-
-void ScriptDialogImpl::executeJavascript()
-{
- execute(Inkscape::Extension::Script::InkscapeScript::JAVASCRIPT);
-}
-
-void ScriptDialogImpl::executePython()
-{
- execute(Inkscape::Extension::Script::InkscapeScript::PYTHON);
-}
-
-void ScriptDialogImpl::executeRuby()
-{
- execute(Inkscape::Extension::Script::InkscapeScript::RUBY);
-}
-
-
-//#########################################################################
-//## C O N S T R U C T O R / D E S T R U C T O R
-//#########################################################################
-ScriptDialogImpl::ScriptDialogImpl() :
- ScriptDialog()
-{
- Gtk::Box *contents = _getContents();
-
- //## Add a menu for clear()
- Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem(_("File"), true));
- item->set_submenu(fileMenu);
- menuBar.append(*item);
-
- item = Gtk::manage(new Gtk::MenuItem(_("_Clear"), true));
- item->signal_activate().connect(sigc::mem_fun(*this, &ScriptDialogImpl::clear));
- fileMenu.append(*item);
-
- item = Gtk::manage(new Gtk::MenuItem(_("_Execute Javascript"), true));
- item->signal_activate().connect(sigc::mem_fun(*this, &ScriptDialogImpl::executeJavascript));
- fileMenu.append(*item);
-
- item = Gtk::manage(new Gtk::MenuItem(_("_Execute Python"), true));
- item->signal_activate().connect(sigc::mem_fun(*this, &ScriptDialogImpl::executePython));
- fileMenu.append(*item);
-
- item = Gtk::manage(new Gtk::MenuItem(_("_Execute Ruby"), true));
- item->signal_activate().connect(sigc::mem_fun(*this, &ScriptDialogImpl::executeRuby));
- fileMenu.append(*item);
-
- contents->pack_start(menuBar, Gtk::PACK_SHRINK);
-
- //### Set up the script field
- scriptText.set_editable(true);
- scriptText.get_buffer()->set_text(defaultCodeStr);
- scriptTextScroll.add(scriptText);
- scriptTextScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
- scriptTextFrame.set_label(_("Script"));
- scriptTextFrame.set_shadow_type(Gtk::SHADOW_NONE);
- scriptTextFrame.add(scriptTextScroll);
- contents->pack_start(scriptTextFrame);
-
- //### Set up the output field
- outputText.set_editable(true);
- outputText.get_buffer()->set_text("");
- outputTextScroll.add(outputText);
- outputTextScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
- outputTextFrame.set_label(_("Output"));
- outputTextFrame.set_shadow_type(Gtk::SHADOW_NONE);
- outputTextFrame.add(outputTextScroll);
- contents->pack_start(outputTextFrame);
-
- //### Set up the error field
- errorText.set_editable(true);
- errorText.get_buffer()->set_text("");
- errorTextScroll.add(errorText);
- errorTextScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
- errorTextFrame.set_label(_("Errors"));
- errorTextFrame.set_shadow_type(Gtk::SHADOW_NONE);
- errorTextFrame.add(errorTextScroll);
- contents->pack_start(errorTextFrame);
-
- // sick of this thing shrinking too much
- set_size_request(350, 400);
- show_all_children();
-
-}
-
-ScriptDialog &ScriptDialog::getInstance()
-{
- ScriptDialog *dialog = new ScriptDialogImpl();
- return *dialog;
-}
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/scriptdialog.h b/src/ui/dialog/scriptdialog.h
deleted file mode 100644
index d1962bf6f..000000000
--- a/src/ui/dialog/scriptdialog.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/** @file
- * @brief Script dialog
- *
- * This dialog is for launching scripts whose main purpose is
- * the scripting of Inkscape itself.
- */
-/* Authors:
- * Bob Jamison
- * Other dudes from The Inkscape Organization
- *
- * Copyright (C) 2004, 2005 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef __SCRIPTDIALOG_H__
-#define __SCRIPTDIALOG_H__
-
-#include "ui/widget/panel.h"
-#include "verbs.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialog {
-
-
-/**
- * A script editor, loader, and executor
- */
-class ScriptDialog : public UI::Widget::Panel
-{
-
- public:
- ScriptDialog() :
- UI::Widget::Panel("", "/dialogs/script", SP_VERB_DIALOG_SCRIPT)
- {}
-
- /**
- * Helper function which returns a new instance of the dialog.
- * getInstance is needed by the dialog manager (Inkscape::UI::Dialog::DialogManager).
- */
- static ScriptDialog &getInstance();
-
- virtual ~ScriptDialog() {};
-
-}; // class ScriptDialog
-
-
-} //namespace Dialog
-} //namespace UI
-} //namespace Inkscape
-
-#endif /* __DEBUGDIALOG_H__ */
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
index 90cb1cdc9..094a6fa6a 100644
--- a/src/ui/dialog/swatches.cpp
+++ b/src/ui/dialog/swatches.cpp
@@ -57,6 +57,7 @@
#include "verbs.h"
#include "gradient-chemistry.h"
#include "helper/action.h"
+#include "helper/action-context.h"
namespace Inkscape {
namespace UI {
@@ -154,7 +155,7 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr )
// Invoke the gradient tool
Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT );
if ( verb ) {
- SPAction *action = verb->get_action( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP);
+ SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) );
if ( action ) {
sp_action_perform( action, NULL );
}
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index 5eb7084d6..26bc52947 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -26,6 +26,7 @@
#include <gtkmm/label.h>
#if WITH_GTKMM_3_0
+# include <gtkmm/togglebutton.h>
# include <gtkmm/grid.h>
#else
# include <gtkmm/table.h>
@@ -66,6 +67,7 @@
#include "verbs.h"
#include "helper/action.h"
+#include "helper/action-context.h"
#include "xml/repr.h"
namespace Inkscape {
@@ -328,13 +330,13 @@ void SymbolsDialog::rebuild() {
void SymbolsDialog::insertSymbol() {
Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_SYMBOL );
- SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->currentDesktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) this->currentDesktop) );
sp_action_perform (action, NULL);
}
void SymbolsDialog::revertSymbol() {
Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_EDIT_UNSYMBOL );
- SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->currentDesktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext( (Inkscape::UI::View::View *) this->currentDesktop ) );
sp_action_perform (action, NULL);
}
diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp
new file mode 100644
index 000000000..265ee8026
--- /dev/null
+++ b/src/ui/dialog/template-load-tab.cpp
@@ -0,0 +1,281 @@
+/** @file
+ * @brief New From Template abstract tab implementation
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "template-widget.h"
+
+#include "template-load-tab.h"
+
+#include <gtkmm/messagedialog.h>
+#include <gtkmm/scrolledwindow.h>
+#include <glibmm/i18n.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
+#include <glibmm/stringutils.h>
+
+#include "interface.h"
+#include "file.h"
+#include "path-prefix.h"
+#include "preferences.h"
+#include "inkscape.h"
+#include "xml/repr.h"
+#include "xml/document.h"
+#include "xml/node.h"
+
+
+namespace Inkscape {
+namespace UI {
+
+
+TemplateLoadTab::TemplateLoadTab()
+ : _current_keyword("")
+ , _keywords_combo(true)
+ , _current_search_type(ALL)
+{
+ set_border_width(10);
+
+ _info_widget = manage(new TemplateWidget());
+
+ Gtk::Label *title;
+ title = manage(new Gtk::Label(_("Search:")));
+ _search_box.pack_start(*title, Gtk::PACK_SHRINK);
+ _search_box.pack_start(_keywords_combo, Gtk::PACK_SHRINK, 5);
+
+ _tlist_box.pack_start(_search_box, Gtk::PACK_SHRINK, 10);
+
+ pack_start(_tlist_box, Gtk::PACK_SHRINK);
+ pack_start(*_info_widget, Gtk::PACK_EXPAND_WIDGET, 5);
+
+ Gtk::ScrolledWindow *scrolled;
+ scrolled = manage(new Gtk::ScrolledWindow());
+ scrolled->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ scrolled->add(_tlist_view);
+ _tlist_box.pack_start(*scrolled, Gtk::PACK_EXPAND_WIDGET, 5);
+
+ _keywords_combo.signal_changed().connect(
+ sigc::mem_fun(*this, &TemplateLoadTab::_keywordSelected));
+ this->show_all();
+
+ _loading_path = "";
+ _loadTemplates();
+ _initLists();
+}
+
+
+TemplateLoadTab::~TemplateLoadTab()
+{
+}
+
+
+void TemplateLoadTab::createTemplate()
+{
+ _info_widget->create();
+}
+
+
+void TemplateLoadTab::_displayTemplateInfo()
+{
+ Glib::RefPtr<Gtk::TreeSelection> templateSelectionRef = _tlist_view.get_selection();
+ if (templateSelectionRef->get_selected()) {
+ _current_template = (*templateSelectionRef->get_selected())[_columns.textValue];
+
+ _info_widget->display(_tdata[_current_template]);
+ }
+
+}
+
+
+void TemplateLoadTab::_initKeywordsList()
+{
+ _keywords_combo.append(_("All"));
+
+ for (std::set<Glib::ustring>::iterator it = _keywords.begin() ; it != _keywords.end() ; ++it){
+ _keywords_combo.append(*it);
+ }
+}
+
+
+void TemplateLoadTab::_initLists()
+{
+ _tlist_store = Gtk::ListStore::create(_columns);
+ _tlist_view.set_model(_tlist_store);
+ _tlist_view.append_column("", _columns.textValue);
+ _tlist_view.set_headers_visible(false);
+
+ _initKeywordsList();
+ _refreshTemplatesList();
+
+ Glib::RefPtr<Gtk::TreeSelection> templateSelectionRef =
+ _tlist_view.get_selection();
+ templateSelectionRef->signal_changed().connect(
+ sigc::mem_fun(*this, &TemplateLoadTab::_displayTemplateInfo));
+}
+
+
+void TemplateLoadTab::_keywordSelected()
+{
+ _current_keyword = _keywords_combo.get_active_text();
+ if (_current_keyword == ""){
+ _current_keyword = _keywords_combo.get_entry_text();
+ _current_search_type = USER_SPECIFIED;
+ }
+ else
+ _current_search_type = LIST_KEYWORD;
+
+ if (_current_keyword == "" || _current_keyword == _("All"))
+ _current_search_type = ALL;
+
+ _refreshTemplatesList();
+}
+
+
+void TemplateLoadTab::_refreshTemplatesList()
+{
+ _tlist_store->clear();
+
+ switch (_current_search_type){
+ case ALL :{
+
+ for (std::map<Glib::ustring, TemplateData>::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) {
+ Gtk::TreeModel::iterator iter = _tlist_store->append();
+ Gtk::TreeModel::Row row = *iter;
+ row[_columns.textValue] = it->first;
+ }
+ break;
+ }
+
+ case LIST_KEYWORD: {
+ for (std::map<Glib::ustring, TemplateData>::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) {
+ if (it->second.keywords.count(_current_keyword) != 0){
+ Gtk::TreeModel::iterator iter = _tlist_store->append();
+ Gtk::TreeModel::Row row = *iter;
+ row[_columns.textValue] = it->first;
+ }
+ }
+ break;
+ }
+
+ case USER_SPECIFIED : {
+ for (std::map<Glib::ustring, TemplateData>::iterator it = _tdata.begin() ; it != _tdata.end() ; ++it) {
+ if (it->second.keywords.count(_current_keyword) != 0 ||
+ it->second.display_name.find(_current_keyword) != Glib::ustring::npos ||
+ it->second.author.find(_current_keyword) != Glib::ustring::npos ||
+ it->second.short_description.find(_current_keyword) != Glib::ustring::npos ||
+ it->second.long_description.find(_current_keyword) != Glib::ustring::npos )
+ {
+ Gtk::TreeModel::iterator iter = _tlist_store->append();
+ Gtk::TreeModel::Row row = *iter;
+ row[_columns.textValue] = it->first;
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+void TemplateLoadTab::_loadTemplates()
+{
+ // user's local dir
+ _getTemplatesFromDir(profile_path("templates") + _loading_path);
+
+ // system templates dir
+ _getTemplatesFromDir(INKSCAPE_TEMPLATESDIR + _loading_path);
+}
+
+
+TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const Glib::ustring &path)
+{
+ TemplateData result;
+ result.path = path;
+ result.is_procedural = false;
+ result.preview_name = "";
+
+ // convert path into valid template name
+ result.display_name = Glib::path_get_basename(path);
+ gsize n = 0;
+ while ((n = result.display_name.find_first_of("_", 0)) < Glib::ustring::npos){
+ result.display_name.replace(n, 1, 1, ' ');
+ }
+ n = result.display_name.rfind(".svg");
+ result.display_name.replace(n, 4, 1, ' ');
+
+ Inkscape::XML::Document *rdoc;
+ rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI);
+ Inkscape::XML::Node *myRoot;
+ Inkscape::XML::Node *dataNode;
+
+ if (rdoc){
+ myRoot = rdoc->root();
+ if (strcmp(myRoot->name(), "svg:svg") != 0){ // Wrong file format
+ return result;
+ }
+
+ myRoot = sp_repr_lookup_name(myRoot, "inkscape:_templateinfo");
+
+ if (myRoot == NULL) // No template info
+ return result;
+
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_name")) != NULL)
+ result.display_name = dgettext("Document template name", dataNode->firstChild()->content());
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:author")) != NULL)
+ result.author = dataNode->firstChild()->content();
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_short")) != NULL)
+ result.short_description = dgettext("Document template short description", dataNode->firstChild()->content());
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_long") )!= NULL)
+ result.long_description = dgettext("Document template long description", dataNode->firstChild()->content());
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:preview")) != NULL)
+ result.preview_name = dataNode->firstChild()->content();
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:date")) != NULL){
+ result.creation_date = dataNode->firstChild()->content();
+ }
+
+ if ((dataNode = sp_repr_lookup_name(myRoot, "inkscape:_keywords")) != NULL){
+ Glib::ustring data = dataNode->firstChild()->content();
+ while (!data.empty()){
+ std::size_t pos = data.find_first_of(" ");
+ if (pos == Glib::ustring::npos)
+ pos = data.size();
+
+ Glib::ustring keyword = dgettext("Document template keyword", data.substr(0, pos).data());
+ result.keywords.insert(keyword);
+ _keywords.insert(keyword);
+
+ if (pos == data.size())
+ break;
+ data.erase(0, pos+1);
+ }
+ }
+ }
+
+ return result;
+}
+
+
+void TemplateLoadTab::_getTemplatesFromDir(const Glib::ustring &path)
+{
+ if ( !Glib::file_test(path, Glib::FILE_TEST_EXISTS) ||
+ !Glib::file_test(path, Glib::FILE_TEST_IS_DIR))
+ return;
+
+ Glib::Dir dir(path);
+
+ Glib::ustring file = Glib::build_filename(path, dir.read_name());
+ while (file != path){
+ if (Glib::str_has_suffix(file, ".svg") && !Glib::str_has_prefix(Glib::path_get_basename(file), "default")){
+ TemplateData tmp = _processTemplateFile(file);
+ if (tmp.display_name != "")
+ _tdata[tmp.display_name] = tmp;
+ }
+ file = Glib::build_filename(path, dir.read_name());
+ }
+}
+
+}
+}
diff --git a/src/ui/dialog/template-load-tab.h b/src/ui/dialog/template-load-tab.h
new file mode 100644
index 000000000..50f3e0be2
--- /dev/null
+++ b/src/ui/dialog/template-load-tab.h
@@ -0,0 +1,102 @@
+/** @file
+ * @brief New From Template abstract tab class
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_SEEN_UI_DIALOG_TEMPLATE_LOAD_TAB_H
+#define INKSCAPE_SEEN_UI_DIALOG_TEMPLATE_LOAD_TAB_H
+
+#include <gtkmm/box.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <map>
+#include <set>
+
+
+namespace Inkscape {
+namespace UI {
+
+class TemplateWidget;
+
+class TemplateLoadTab : public Gtk::HBox
+{
+
+public:
+ struct TemplateData
+ {
+ bool is_procedural;
+ Glib::ustring path;
+ Glib::ustring display_name;
+ Glib::ustring author;
+ Glib::ustring short_description;
+ Glib::ustring long_description;
+ Glib::ustring preview_name;
+ Glib::ustring creation_date;
+ std::set<Glib::ustring> keywords;
+ };
+
+ TemplateLoadTab();
+ virtual ~TemplateLoadTab();
+ virtual void createTemplate();
+
+protected:
+ class StringModelColumns : public Gtk::TreeModelColumnRecord
+ {
+ public:
+ StringModelColumns()
+ {
+ add(textValue);
+ }
+
+ Gtk::TreeModelColumn<Glib::ustring> textValue;
+ };
+
+ Glib::ustring _current_keyword;
+ Glib::ustring _current_template;
+ Glib::ustring _loading_path;
+ std::map<Glib::ustring, TemplateData> _tdata;
+ std::set<Glib::ustring> _keywords;
+
+
+ virtual void _displayTemplateInfo();
+ virtual void _initKeywordsList();
+ virtual void _refreshTemplatesList();
+ void _loadTemplates();
+ void _initLists();
+
+ Gtk::VBox _tlist_box;
+ Gtk::HBox _search_box;
+ TemplateWidget *_info_widget;
+
+ Gtk::ComboBoxText _keywords_combo;
+
+ Gtk::TreeView _tlist_view;
+ Glib::RefPtr<Gtk::ListStore> _tlist_store;
+ StringModelColumns _columns;
+
+private:
+ enum SearchType
+ {
+ LIST_KEYWORD,
+ USER_SPECIFIED,
+ ALL
+ };
+
+ SearchType _current_search_type;
+
+ void _getTemplatesFromDir(const Glib::ustring &);
+ void _keywordSelected();
+ TemplateData _processTemplateFile(const Glib::ustring &);
+};
+
+}
+}
+
+#endif
diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp
new file mode 100644
index 000000000..be7e2b515
--- /dev/null
+++ b/src/ui/dialog/template-widget.cpp
@@ -0,0 +1,117 @@
+/** @file
+ * @brief New From Template - templates widget - implementation
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "template-widget.h"
+
+#include <gtkmm/alignment.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+#include <gtkmm/messagedialog.h>
+
+#include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
+
+#include "template-load-tab.h"
+#include "file.h"
+
+namespace Inkscape {
+namespace UI {
+
+
+TemplateWidget::TemplateWidget()
+ : _more_info_button(_("More info"))
+ , _short_description_label(_(" "))
+ , _template_author_label(_(" "))
+ , _template_name_label(_("no template selected"))
+{
+ pack_start(_template_name_label, Gtk::PACK_SHRINK, 10);
+ pack_start(_template_author_label, Gtk::PACK_SHRINK, 0);
+ pack_start(_preview_box, Gtk::PACK_SHRINK, 0);
+
+ _preview_box.pack_start(_preview_image, Gtk::PACK_EXPAND_PADDING, 15);
+ _preview_box.pack_start(_preview_render, Gtk::PACK_EXPAND_PADDING, 10);
+
+ _short_description_label.set_line_wrap(true);
+ //_short_description_label.set_size_request(200);
+
+ Gtk::Alignment *align;
+ align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0));
+ pack_end(*align, Gtk::PACK_SHRINK);
+ align->add(_more_info_button);
+
+ pack_end(_short_description_label, Gtk::PACK_SHRINK, 5);
+
+ _more_info_button.signal_pressed().connect(
+ sigc::mem_fun(*this, &TemplateWidget::_displayTemplateDetails));
+}
+
+
+void TemplateWidget::create()
+{
+ if (_current_template.path == "")
+ return;
+
+ if (_current_template.is_procedural) {}
+ else {
+ sp_file_new(_current_template.path);
+ }
+}
+
+
+void TemplateWidget::display(TemplateLoadTab::TemplateData data)
+{
+ _current_template = data;
+ if (data.is_procedural){}
+ else{
+ _template_name_label.set_text(_current_template.display_name);
+ _template_author_label.set_text(_current_template.author);
+ _short_description_label.set_text(_current_template.short_description);
+
+ Glib::ustring imagePath = Glib::build_filename(Glib::path_get_dirname(_current_template.path), _current_template.preview_name);
+ if (data.preview_name != ""){
+ _preview_image.set(imagePath);
+ _preview_image.show();
+ _preview_render.hide();
+ }
+ else{
+ _preview_render.showImage(data.path);
+ _preview_render.show();
+ _preview_image.hide();
+ }
+ }
+}
+
+
+void TemplateWidget::_displayTemplateDetails()
+{
+ if (_current_template.path == "")
+ return;
+
+ Glib::ustring message = _current_template.display_name + "\n\n" +
+ _("Path: ") + _current_template.path + "\n\n";
+
+ if (_current_template.long_description != "")
+ message += _("Description: ") + _current_template.long_description + "\n\n";
+ if (_current_template.keywords.size() > 0){
+ message += _("Keywords: ");
+ for (std::set<Glib::ustring>::iterator it = _current_template.keywords.begin(); it != _current_template.keywords.end(); ++it)
+ message += *it + " ";
+ message += "\n\n";
+ }
+
+ if (_current_template.author != "")
+ message += _("By: ") + _current_template.author + " " + _current_template.creation_date + "\n\n";
+
+ Gtk::MessageDialog dl(message, false, Gtk::MESSAGE_OTHER);
+ dl.run();
+}
+
+}
+}
diff --git a/src/ui/dialog/template-widget.h b/src/ui/dialog/template-widget.h
new file mode 100644
index 000000000..f7e1267ce
--- /dev/null
+++ b/src/ui/dialog/template-widget.h
@@ -0,0 +1,48 @@
+/** @file
+ * @brief New From Template - template widget
+ */
+/* Authors:
+ * Jan Darowski <jan.darowski@gmail.com>, supervised by Krzysztof Kosiński
+ *
+ * Copyright (C) 2013 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_SEEN_UI_DIALOG_TEMPLATE_WIDGET_H
+#define INKSCAPE_SEEN_UI_DIALOG_TEMPLATE_WIDGET_H
+
+#include "filedialogimpl-gtkmm.h"
+
+#include <gtkmm/box.h>
+
+#include "template-load-tab.h"
+
+namespace Inkscape {
+namespace UI {
+
+
+class TemplateWidget : public Gtk::VBox
+{
+public:
+ TemplateWidget ();
+ void create();
+ void display(TemplateLoadTab::TemplateData);
+
+private:
+ TemplateLoadTab::TemplateData _current_template;
+
+ Gtk::Button _more_info_button;
+ Gtk::HBox _preview_box;
+ Gtk::Image _preview_image;
+ Dialog::SVGPreview _preview_render;
+ Gtk::Label _short_description_label;
+ Gtk::Label _template_author_label;
+ Gtk::Label _template_name_label;
+
+ void _displayTemplateDetails();
+};
+
+}
+}
+
+#endif
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index a662495a0..4a25f723b 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -58,7 +58,7 @@ extern "C" {
#include "widgets/font-selector.h"
#include <glibmm/i18n.h>
#include <glibmm/markup.h>
-#include "unit-constants.h"
+#include "util/units.h"
#include "sp-textpath.h"
namespace Inkscape {
@@ -401,7 +401,7 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * PT_PER_PX;
+ double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * Inkscape::Util::Quantity::convert(1, "px", "pt");
// Pango font size is in 1024ths of a point
// C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE );
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 4aa972296..ce8af3f1f 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -31,6 +31,7 @@
#include "inkscape.h"
#include "selection.h"
#include "selection-chemistry.h"
+#include "message-stack.h"
#include "verbs.h"
#include "preferences.h"
#include "sp-namedview.h"
@@ -762,7 +763,7 @@ void Transformation::applyPageMove(Inkscape::Selection *selection)
double move = x;
for ( std::vector<BBoxSort> ::iterator it (sorted.begin());
it < sorted.end();
- it ++ )
+ ++it )
{
sp_item_move_rel(it->item, Geom::Translate(move, 0));
// move each next object by x relative to previous
@@ -786,7 +787,7 @@ void Transformation::applyPageMove(Inkscape::Selection *selection)
double move = y;
for ( std::vector<BBoxSort> ::iterator it (sorted.begin());
it < sorted.end();
- it ++ )
+ ++it )
{
sp_item_move_rel(it->item, Geom::Translate(0, move));
// move each next object by x relative to previous
@@ -902,10 +903,21 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection)
if (!_units_skew.isAbsolute()) { // percentage
double skewX = _scalar_skew_horizontal.getValue("%");
double skewY = _scalar_skew_vertical.getValue("%");
+ if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
sp_item_skew_rel (item, 0.01*skewX, 0.01*skewY);
} else if (_units_skew.isRadial()) { //deg or rad
double angleX = _scalar_skew_horizontal.getValue("rad");
double angleY = _scalar_skew_vertical.getValue("rad");
+ if ((fabs(angleX - angleY + M_PI/2) < Geom::EPSILON)
+ || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON)
+ || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON)
+ || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
double skewX = tan(-angleX);
double skewY = tan(angleY);
sp_item_skew_rel (item, skewX, skewY);
@@ -916,6 +928,10 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection)
if (bbox) {
double width = bbox->dimensions()[Geom::X];
double height = bbox->dimensions()[Geom::Y];
+ if (fabs(skewX*skewY - width*height) < Geom::EPSILON) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
sp_item_skew_rel (item, skewX/height, skewY/width);
}
}
@@ -931,16 +947,31 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection)
if (!_units_skew.isAbsolute()) { // percentage
double skewX = _scalar_skew_horizontal.getValue("%");
double skewY = _scalar_skew_vertical.getValue("%");
+ if (fabs(0.01*skewX*0.01*skewY - 1.0) < Geom::EPSILON) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY);
} else if (_units_skew.isRadial()) { //deg or rad
double angleX = _scalar_skew_horizontal.getValue("rad");
double angleY = _scalar_skew_vertical.getValue("rad");
+ if ((fabs(angleX - angleY + M_PI/2) < Geom::EPSILON)
+ || (fabs(angleX - angleY - M_PI/2) < Geom::EPSILON)
+ || (fabs((angleX - angleY)/3 + M_PI/2) < Geom::EPSILON)
+ || (fabs((angleX - angleY)/3 - M_PI/2) < Geom::EPSILON)) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
double skewX = tan(-angleX);
double skewY = tan(angleY);
sp_selection_skew_relative(selection, *center, skewX, skewY);
} else { // absolute displacement
double skewX = _scalar_skew_horizontal.getValue("px");
double skewY = _scalar_skew_vertical.getValue("px");
+ if (fabs(skewX*skewY - width*height) < Geom::EPSILON) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
sp_selection_skew_relative(selection, *center, skewX/height, skewY/width);
}
}
@@ -961,6 +992,10 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection)
double f = _scalar_transform_f.getValue();
Geom::Affine displayed(a, b, c, d, e, f);
+ if (displayed.isSingular()) {
+ sp_desktop_message_stack(getDesktop())->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>."));
+ return;
+ }
if (_check_replace_matrix.get_active()) {
for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index 70bd0e859..5d5ea2adc 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -224,10 +224,12 @@ void MultiPathManipulator::shiftSelection(int dir)
SubpathList::iterator last_j;
NodeList::iterator last_k;
bool anything_found = false;
+ bool anynode_found = false;
for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) {
SubpathList &sp = i->second->subpathList();
for (SubpathList::iterator j = sp.begin(); j != sp.end(); ++j) {
+ anynode_found = true;
for (NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k) {
if (k->selected()) {
last_i = i;
@@ -249,10 +251,12 @@ void MultiPathManipulator::shiftSelection(int dir)
if (!anything_found) {
// select first / last node
// this should never fail because there must be at least 1 non-empty manipulator
- if (dir == 1) {
+ if (anynode_found) {
+ if (dir == 1) {
_selection.insert((*_mmap.begin()->second->subpathList().begin())->begin().ptr());
- } else {
+ } else {
_selection.insert((--(*--(--_mmap.end())->second->subpathList().end())->end()).ptr());
+ }
}
return;
}
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index dc6e0fbae..82eb697bd 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -22,7 +22,6 @@
#include "preferences.h"
#include "snap.h"
#include "snap-preferences.h"
-#include "sp-metrics.h"
#include "sp-namedview.h"
#include "ui/control-manager.h"
#include "ui/tool/control-point-selection.h"
@@ -490,9 +489,13 @@ Glib::ustring Handle::_getDragTip(GdkEventMotion */*event*/) const
double angle = Geom::angle_between(Geom::Point(-1,0), position() - _parent->position());
angle += M_PI; // angle is (-M_PI...M_PI] - offset by +pi and scale to 0...360
angle *= 360.0 / (2 * M_PI);
- GString *x = SP_PX_TO_METRIC_STRING(dist[Geom::X], _desktop->namedview->getDefaultMetric());
- GString *y = SP_PX_TO_METRIC_STRING(dist[Geom::Y], _desktop->namedview->getDefaultMetric());
- GString *len = SP_PX_TO_METRIC_STRING(length(), _desktop->namedview->getDefaultMetric());
+
+ Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px");
+ Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px");
+ Inkscape::Util::Quantity len_q = Inkscape::Util::Quantity(length(), "px");
+ GString *x = g_string_new(x_q.string(*_desktop->namedview->doc_units).c_str());
+ GString *y = g_string_new(y_q.string(*_desktop->namedview->doc_units).c_str());
+ GString *len = g_string_new(len_q.string(*_desktop->namedview->doc_units).c_str());
Glib::ustring ret = format_tip(C_("Path handle tip",
"Move handle by %s, %s; angle %.2f°, length %s"), x->str, y->str, angle, len->str);
g_string_free(x, TRUE);
@@ -1294,8 +1297,11 @@ Glib::ustring Node::_getTip(unsigned state) const
Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) const
{
Geom::Point dist = position() - _last_drag_origin();
- GString *x = SP_PX_TO_METRIC_STRING(dist[Geom::X], _desktop->namedview->getDefaultMetric());
- GString *y = SP_PX_TO_METRIC_STRING(dist[Geom::Y], _desktop->namedview->getDefaultMetric());
+
+ Inkscape::Util::Quantity x_q = Inkscape::Util::Quantity(dist[Geom::X], "px");
+ Inkscape::Util::Quantity y_q = Inkscape::Util::Quantity(dist[Geom::Y], "px");
+ GString *x = g_string_new(x_q.string(*_desktop->namedview->doc_units).c_str());
+ GString *y = g_string_new(y_q.string(*_desktop->namedview->doc_units).c_str());
Glib::ustring ret = format_tip(C_("Path node tip", "Move node by %s, %s"),
x->str, y->str);
g_string_free(x, TRUE);
diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp
index f0bf149f4..30963cabd 100644
--- a/src/ui/tool/transform-handle-set.cpp
+++ b/src/ui/tool/transform-handle-set.cpp
@@ -458,9 +458,9 @@ private:
static Glib::RefPtr<Gdk::Pixbuf> _corner_to_pixbuf(unsigned c) {
sp_select_context_get_type();
switch (c % 4) {
- case 0: return Glib::wrap(handles[10], true);
- case 1: return Glib::wrap(handles[8], true);
- case 2: return Glib::wrap(handles[6], true);
+ case 0: return Glib::wrap(handles[7], true);
+ case 1: return Glib::wrap(handles[6], true);
+ case 2: return Glib::wrap(handles[5], true);
default: return Glib::wrap(handles[4], true);
}
}
@@ -605,9 +605,9 @@ private:
static Glib::RefPtr<Gdk::Pixbuf> _side_to_pixbuf(unsigned s) {
sp_select_context_get_type();
switch (s % 4) {
- case 0: return Glib::wrap(handles[9], true);
- case 1: return Glib::wrap(handles[7], true);
- case 2: return Glib::wrap(handles[5], true);
+ case 0: return Glib::wrap(handles[10], true);
+ case 1: return Glib::wrap(handles[9], true);
+ case 2: return Glib::wrap(handles[8], true);
default: return Glib::wrap(handles[11], true);
}
}
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert
index 2de954674..710b95c2b 100644
--- a/src/ui/widget/Makefile_insert
+++ b/src/ui/widget/Makefile_insert
@@ -79,5 +79,7 @@ ink_common_sources += \
ui/widget/tolerance-slider.cpp \
ui/widget/tolerance-slider.h \
ui/widget/unit-menu.cpp \
- ui/widget/unit-menu.h
+ ui/widget/unit-menu.h \
+ ui/widget/unit-tracker.h \
+ ui/widget/unit-tracker.cpp
diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp
index 2bfc7e0df..52e9ea605 100644
--- a/src/ui/widget/dock.cpp
+++ b/src/ui/widget/dock.cpp
@@ -48,11 +48,21 @@ const int Dock::_default_dock_bar_width = 36;
Dock::Dock(Gtk::Orientation orientation)
- : _gdl_dock (GDL_DOCK (gdl_dock_new())),
- _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
+ : _gdl_dock(gdl_dock_new()),
+#if WITH_GDL_3_6
+ _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(G_OBJECT(_gdl_dock)))),
+#else
+ _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
+#endif
_scrolled_window (Gtk::manage(new Gtk::ScrolledWindow))
{
- gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation));
+#if WITH_GDL_3_6
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(_gdl_dock_bar),
+ static_cast<GtkOrientation>(orientation));
+#else
+ gdl_dock_bar_set_orientation(_gdl_dock_bar,
+ static_cast<GtkOrientation>(orientation));
+#endif
#if WITH_GTKMM_3_0
switch(orientation) {
@@ -127,7 +137,9 @@ Dock::~Dock()
void Dock::addItem(DockItem& item, DockItem::Placement placement)
{
_dock_items.push_back(&item);
- gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement);
+ gdl_dock_add_item(GDL_DOCK(_gdl_dock),
+ GDL_DOCK_ITEM(item.gobj()),
+ (GdlDockPlacement)placement);
// FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done
// initially as the paned doesn't exist.
diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h
index 611c10f46..33e60b836 100644
--- a/src/ui/widget/dock.h
+++ b/src/ui/widget/dock.h
@@ -74,11 +74,11 @@ protected:
/** Interface widgets, will be packed like
* _scrolled_window -> (_dock_box -> (_paned -> (_dock -> _filler) | _dock_bar))
*/
- Gtk::Box *_dock_box;
- Gtk::Paned* _paned;
- GdlDock *_gdl_dock;
- GdlDockBar *_gdl_dock_bar;
- Gtk::VBox _filler;
+ Gtk::Box *_dock_box;
+ Gtk::Paned *_paned;
+ GtkWidget *_gdl_dock;
+ GdlDockBar *_gdl_dock_bar;
+ Gtk::VBox _filler;
Gtk::ScrolledWindow *_scrolled_window;
/** Internal signal handlers */
diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index fa3f8e3a1..8287452d7 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -36,7 +36,8 @@
#include "document.h"
#include "desktop.h"
#include "helper/action.h"
-#include "helper/units.h"
+#include "helper/action-context.h"
+#include "util/units.h"
#include "inkscape.h"
#include "sp-namedview.h"
#include "sp-root.h"
@@ -47,6 +48,7 @@
#include "xml/repr.h"
using std::pair;
+using Inkscape::Util::unit_table;
namespace Inkscape {
namespace UI {
@@ -95,7 +97,7 @@ struct PaperSizeRec {
char const * const name; //name
double const smaller; //lesser dimension
double const larger; //greater dimension
- SPUnitId const unit; //units
+ Glib::ustring const unit; //units
};
// list of page formats that should be in landscape automatically
@@ -113,31 +115,31 @@ fill_landscape_papers() {
}
static PaperSizeRec const inkscape_papers[] = {
- { "A4", 210, 297, SP_UNIT_MM },
- { "US Letter", 8.5, 11, SP_UNIT_IN },
- { "US Legal", 8.5, 14, SP_UNIT_IN },
- { "US Executive", 7.25, 10.5, SP_UNIT_IN },
- { "A0", 841, 1189, SP_UNIT_MM },
- { "A1", 594, 841, SP_UNIT_MM },
- { "A2", 420, 594, SP_UNIT_MM },
- { "A3", 297, 420, SP_UNIT_MM },
- { "A5", 148, 210, SP_UNIT_MM },
- { "A6", 105, 148, SP_UNIT_MM },
- { "A7", 74, 105, SP_UNIT_MM },
- { "A8", 52, 74, SP_UNIT_MM },
- { "A9", 37, 52, SP_UNIT_MM },
- { "A10", 26, 37, SP_UNIT_MM },
- { "B0", 1000, 1414, SP_UNIT_MM },
- { "B1", 707, 1000, SP_UNIT_MM },
- { "B2", 500, 707, SP_UNIT_MM },
- { "B3", 353, 500, SP_UNIT_MM },
- { "B4", 250, 353, SP_UNIT_MM },
- { "B5", 176, 250, SP_UNIT_MM },
- { "B6", 125, 176, SP_UNIT_MM },
- { "B7", 88, 125, SP_UNIT_MM },
- { "B8", 62, 88, SP_UNIT_MM },
- { "B9", 44, 62, SP_UNIT_MM },
- { "B10", 31, 44, SP_UNIT_MM },
+ { "A4", 210, 297, "mm" },
+ { "US Letter", 8.5, 11, "in" },
+ { "US Legal", 8.5, 14, "in" },
+ { "US Executive", 7.25, 10.5, "in" },
+ { "A0", 841, 1189, "mm" },
+ { "A1", 594, 841, "mm" },
+ { "A2", 420, 594, "mm" },
+ { "A3", 297, 420, "mm" },
+ { "A5", 148, 210, "mm" },
+ { "A6", 105, 148, "mm" },
+ { "A7", 74, 105, "mm" },
+ { "A8", 52, 74, "mm" },
+ { "A9", 37, 52, "mm" },
+ { "A10", 26, 37, "mm" },
+ { "B0", 1000, 1414, "mm" },
+ { "B1", 707, 1000, "mm" },
+ { "B2", 500, 707, "mm" },
+ { "B3", 353, 500, "mm" },
+ { "B4", 250, 353, "mm" },
+ { "B5", 176, 250, "mm" },
+ { "B6", 125, 176, "mm" },
+ { "B7", 88, 125, "mm" },
+ { "B8", 62, 88, "mm" },
+ { "B9", 44, 62, "mm" },
+ { "B10", 31, 44, "mm" },
@@ -149,63 +151,63 @@ static PaperSizeRec const inkscape_papers[] = {
don't know what D and E series are used for.
*/
- { "C0", 917, 1297, SP_UNIT_MM },
- { "C1", 648, 917, SP_UNIT_MM },
- { "C2", 458, 648, SP_UNIT_MM },
- { "C3", 324, 458, SP_UNIT_MM },
- { "C4", 229, 324, SP_UNIT_MM },
- { "C5", 162, 229, SP_UNIT_MM },
- { "C6", 114, 162, SP_UNIT_MM },
- { "C7", 81, 114, SP_UNIT_MM },
- { "C8", 57, 81, SP_UNIT_MM },
- { "C9", 40, 57, SP_UNIT_MM },
- { "C10", 28, 40, SP_UNIT_MM },
- { "D1", 545, 771, SP_UNIT_MM },
- { "D2", 385, 545, SP_UNIT_MM },
- { "D3", 272, 385, SP_UNIT_MM },
- { "D4", 192, 272, SP_UNIT_MM },
- { "D5", 136, 192, SP_UNIT_MM },
- { "D6", 96, 136, SP_UNIT_MM },
- { "D7", 68, 96, SP_UNIT_MM },
- { "E3", 400, 560, SP_UNIT_MM },
- { "E4", 280, 400, SP_UNIT_MM },
- { "E5", 200, 280, SP_UNIT_MM },
- { "E6", 140, 200, SP_UNIT_MM },
+ { "C0", 917, 1297, "mm" },
+ { "C1", 648, 917, "mm" },
+ { "C2", 458, 648, "mm" },
+ { "C3", 324, 458, "mm" },
+ { "C4", 229, 324, "mm" },
+ { "C5", 162, 229, "mm" },
+ { "C6", 114, 162, "mm" },
+ { "C7", 81, 114, "mm" },
+ { "C8", 57, 81, "mm" },
+ { "C9", 40, 57, "mm" },
+ { "C10", 28, 40, "mm" },
+ { "D1", 545, 771, "mm" },
+ { "D2", 385, 545, "mm" },
+ { "D3", 272, 385, "mm" },
+ { "D4", 192, 272, "mm" },
+ { "D5", 136, 192, "mm" },
+ { "D6", 96, 136, "mm" },
+ { "D7", 68, 96, "mm" },
+ { "E3", 400, 560, "mm" },
+ { "E4", 280, 400, "mm" },
+ { "E5", 200, 280, "mm" },
+ { "E6", 140, 200, "mm" },
//#endif
- { "CSE", 462, 649, SP_UNIT_PT },
- { "US #10 Envelope", 4.125, 9.5, SP_UNIT_IN },
+ { "CSE", 462, 649, "pt" },
+ { "US #10 Envelope", 4.125, 9.5, "in" },
/* See http://www.hbp.com/content/PCR_envelopes.cfm for a much larger list of US envelope
sizes. */
- { "DL Envelope", 110, 220, SP_UNIT_MM },
- { "Ledger/Tabloid", 11, 17, SP_UNIT_IN },
+ { "DL Envelope", 110, 220, "mm" },
+ { "Ledger/Tabloid", 11, 17, "in" },
/* Note that `Folio' (used in QPrinter/KPrinter) is deliberately absent from this list, as it
means different sizes to different people: different people may expect the width to be
either 8, 8.25 or 8.5 inches, and the height to be either 13 or 13.5 inches, even
restricting our interpretation to foolscap folio. If you wish to introduce a folio-like
page size to the list, then please consider using a name more specific than just `Folio' or
`Foolscap Folio'. */
- { "Banner 468x60", 60, 468, SP_UNIT_PX },
- { "Icon 16x16", 16, 16, SP_UNIT_PX },
- { "Icon 32x32", 32, 32, SP_UNIT_PX },
- { "Icon 48x48", 48, 48, SP_UNIT_PX },
+ { "Banner 468x60", 60, 468, "px" },
+ { "Icon 16x16", 16, 16, "px" },
+ { "Icon 32x32", 32, 32, "px" },
+ { "Icon 48x48", 48, 48, "px" },
/* business cards */
- { "Business Card (ISO 7810)", 53.98, 85.60, SP_UNIT_MM },
- { "Business Card (US)", 2, 3.5, SP_UNIT_IN },
- { "Business Card (Europe)", 55, 85, SP_UNIT_MM },
- { "Business Card (Aus/NZ)", 55, 90, SP_UNIT_MM },
+ { "Business Card (ISO 7810)", 53.98, 85.60, "mm" },
+ { "Business Card (US)", 2, 3.5, "in" },
+ { "Business Card (Europe)", 55, 85, "mm" },
+ { "Business Card (Aus/NZ)", 55, 90, "mm" },
// Start Arch Series List
- { "Arch A", 9, 12, SP_UNIT_IN }, // 229 x 305 mm
- { "Arch B", 12, 18, SP_UNIT_IN }, // 305 x 457 mm
- { "Arch C", 18, 24, SP_UNIT_IN }, // 457 x 610 mm
- { "Arch D", 24, 36, SP_UNIT_IN }, // 610 x 914 mm
- { "Arch E", 36, 48, SP_UNIT_IN }, // 914 x 1219 mm
- { "Arch E1", 30, 42, SP_UNIT_IN }, // 762 x 1067 mm
+ { "Arch A", 9, 12, "in" }, // 229 x 305 mm
+ { "Arch B", 12, 18, "in" }, // 305 x 457 mm
+ { "Arch C", 18, 24, "in" }, // 457 x 610 mm
+ { "Arch D", 24, 36, "in" }, // 610 x 914 mm
+ { "Arch E", 36, 48, "in" }, // 914 x 1219 mm
+ { "Arch E1", 30, 42, "in" }, // 762 x 1067 mm
/*
* The above list of Arch sizes were taken from the following site:
@@ -216,7 +218,7 @@ static PaperSizeRec const inkscape_papers[] = {
* September 2009 - DAK
*/
- { NULL, 0, 0, SP_UNIT_PX },
+ { NULL, 0, 0, "px" },
};
@@ -225,10 +227,6 @@ static PaperSizeRec const inkscape_papers[] = {
//# P A G E S I Z E R
//########################################################################
-//The default unit for this widget and its calculations
-static const SPUnit _px_unit = sp_unit_get_by_id (SP_UNIT_PX);
-
-
/**
* Constructor
*/
@@ -279,13 +277,8 @@ PageSizer::PageSizer(Registry & _wr)
char formatBuf[80];
snprintf(formatBuf, 79, "%0.1f x %0.1f", p->smaller, p->larger);
Glib::ustring desc = formatBuf;
- if (p->unit == SP_UNIT_IN)
- desc.append(" in");
- else if (p->unit == SP_UNIT_MM)
- desc.append(" mm");
- else if (p->unit == SP_UNIT_PX)
- desc.append(" px");
- PaperSize paper(name, p->smaller, p->larger, p->unit);
+ desc.append(" " + p->unit);
+ PaperSize paper(name, p->smaller, p->larger, unit_table.getUnit(p->unit));
_paperSizeTable[name] = paper;
Gtk::TreeModel::Row row = *(_paperSizeListStore->append());
row[_paperSizeListColumns.nameColumn] = name;
@@ -319,9 +312,9 @@ PageSizer::PageSizer(Registry & _wr)
SPNamedView *nv = sp_desktop_namedview(dt);
_wr.setUpdating (true);
if (nv->units) {
- _dimensionUnits.setUnit(nv->units);
+ _dimensionUnits.setUnit(nv->units->abbr);
} else if (nv->doc_units) {
- _dimensionUnits.setUnit(nv->doc_units);
+ _dimensionUnits.setUnit(nv->doc_units->abbr);
}
_wr.setUpdating (false);
@@ -483,8 +476,8 @@ PageSizer::setDim (double w, double h, bool changeList)
if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) {
SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
double const old_height = doc->getHeight();
- doc->setWidth (w, &_px_unit);
- doc->setHeight (h, &_px_unit);
+ doc->setWidth (Inkscape::Util::Quantity(w, "px"));
+ doc->setHeight (Inkscape::Util::Quantity(h, "px"));
// The origin for the user is in the lower left corner; this point should remain stationary when
// changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this
Geom::Translate const vert_offset(Geom::Point(0, (old_height - h)));
@@ -568,9 +561,9 @@ PageSizer::find_paper_size (double w, double h) const
for (iter = _paperSizeTable.begin() ;
iter != _paperSizeTable.end() ; ++iter) {
PaperSize paper = iter->second;
- SPUnit const &i_unit = sp_unit_get_by_id(paper.unit);
- double smallX = sp_units_get_pixels(paper.smaller, i_unit);
- double largeX = sp_units_get_pixels(paper.larger, i_unit);
+ Inkscape::Util::Unit const &i_unit = paper.unit;
+ double smallX = Inkscape::Util::Quantity::convert(paper.smaller, i_unit, "px");
+ double largeX = Inkscape::Util::Quantity::convert(paper.larger, i_unit, "px");
g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
@@ -619,7 +612,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing()
Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING );
if (verb) {
- SPAction *action = verb->get_action(dt);
+ SPAction *action = verb->get_action(Inkscape::ActionContext(dt));
if (action) {
sp_action_perform(action, NULL);
}
@@ -661,9 +654,8 @@ PageSizer::on_paper_size_list_changed()
_landscape = _landscapeButton.get_active();
}
- SPUnit const &src_unit = sp_unit_get_by_id (paper.unit);
- sp_convert_distance (&w, &src_unit, &_px_unit);
- sp_convert_distance (&h, &src_unit, &_px_unit);
+ w = Inkscape::Util::Quantity::convert(w, paper.unit, "px");
+ h = Inkscape::Util::Quantity::convert(h, paper.unit, "px");
if (_landscape)
setDim (h, w, false);
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index d1fbb56e0..34ed7592d 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -18,7 +18,7 @@
#include "ui/widget/registered-widget.h"
#include <sigc++/sigc++.h>
-#include "helper/units.h"
+#include "util/units.h"
#include <gtkmm/alignment.h>
#include <gtkmm/expander.h>
@@ -64,7 +64,7 @@ public:
PaperSize(const Glib::ustring &nameArg,
double smallerArg,
double largerArg,
- SPUnitId unitArg)
+ Inkscape::Util::Unit unitArg)
{
name = nameArg;
smaller = smallerArg;
@@ -108,7 +108,7 @@ public:
/**
* The units (px, pt, mm, etc) of this specification
*/
- SPUnitId unit;
+ Inkscape::Util::Unit unit;
private:
@@ -117,7 +117,7 @@ private:
name = "";
smaller = 0.0;
larger = 0.0;
- unit = SP_UNIT_PX;
+ unit = unit_table.getUnit("px");
}
void assign(const PaperSize &other)
diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp
index ea2bac867..ae6a7d1e0 100644
--- a/src/ui/widget/registered-widget.cpp
+++ b/src/ui/widget/registered-widget.cpp
@@ -27,7 +27,6 @@
#include "ui/widget/random.h"
#include "widgets/spinbutton-events.h"
-#include "helper/units.h"
#include "xml/repr.h"
#include "svg/svg-color.h"
#include "svg/stringstream.h"
@@ -118,9 +117,9 @@ RegisteredUnitMenu::RegisteredUnitMenu (const Glib::ustring& label, const Glib::
}
void
-RegisteredUnitMenu::setUnit (const SPUnit* unit)
+RegisteredUnitMenu::setUnit (Glib::ustring unit)
{
- getUnitMenu()->setUnit (sp_unit_get_abbreviation (unit));
+ getUnitMenu()->setUnit(unit);
}
void
diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h
index fa35b815e..93b0cef4e 100644
--- a/src/ui/widget/registered-widget.h
+++ b/src/ui/widget/registered-widget.h
@@ -32,7 +32,6 @@
#include <gtkmm/checkbutton.h>
-struct SPUnit;
class SPDocument;
namespace Gtk {
@@ -128,6 +127,7 @@ private:
repr = NULL;
doc = NULL;
write_undo = false;
+ event_type = -1;
}
};
@@ -166,7 +166,7 @@ public:
Inkscape::XML::Node* repr_in = NULL,
SPDocument *doc_in = NULL );
- void setUnit (const SPUnit*);
+ void setUnit (const Glib::ustring);
Unit getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
UnitMenu* getUnitMenu() const { return static_cast<UnitMenu*>(_widget); };
sigc::connection _changed_connection;
diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp
index f26e71553..d6248df69 100644
--- a/src/ui/widget/rendering-options.cpp
+++ b/src/ui/widget/rendering-options.cpp
@@ -13,7 +13,7 @@
#endif
#include "rendering-options.h"
-#include "unit-constants.h"
+#include "util/units.h"
#include <glibmm/i18n.h>
namespace Inkscape {
@@ -59,8 +59,8 @@ RenderingOptions::RenderingOptions () :
_radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled));
// configure default DPI
- _dpi.setRange(PT_PER_IN,2400.0);
- _dpi.setValue(PT_PER_IN);
+ _dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0);
+ _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt"));
_dpi.setIncrements(1.0,10.0);
_dpi.setDigits(0);
_dpi.update();
diff --git a/src/ui/widget/scalar-unit.cpp b/src/ui/widget/scalar-unit.cpp
index 99ff70846..2f4c1f341 100644
--- a/src/ui/widget/scalar-unit.cpp
+++ b/src/ui/widget/scalar-unit.cpp
@@ -16,6 +16,8 @@
#include "scalar-unit.h"
#include "spinbutton.h"
+using Inkscape::Util::unit_table;
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -226,9 +228,8 @@ void ScalarUnit::on_unit_changed()
Glib::ustring abbr = _unit_menu->getUnitAbbr();
_suffix->set_label(abbr);
- Inkscape::Util::UnitTable &table = _unit_menu->getUnitTable();
- Inkscape::Util::Unit new_unit = (table.getUnit(abbr));
- Inkscape::Util::Unit old_unit = (table.getUnit(lastUnits));
+ Inkscape::Util::Unit new_unit = (unit_table.getUnit(abbr));
+ Inkscape::Util::Unit old_unit = (unit_table.getUnit(lastUnits));
double convertedVal = 0;
if (old_unit.type == UNIT_TYPE_DIMENSIONLESS && new_unit.type == UNIT_TYPE_LINEAR) {
diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
index 18dbb984b..388a0bcea 100644
--- a/src/ui/widget/selected-style.cpp
+++ b/src/ui/widget/selected-style.cpp
@@ -50,6 +50,9 @@
#include "pixmaps/cursor-adj-a.xpm"
#include "sp-cursor.h"
#include "gradient-chemistry.h"
+#include "util/units.h"
+
+using Inkscape::Util::unit_table;
static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 };
static gchar const *const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"};
@@ -306,15 +309,17 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
{
int row = 0;
- // List of units should match with Fill/Stroke dialog stroke style width list
- for (GSList *l = sp_unit_get_list(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); l != NULL; l = l->next) {
- SPUnit const *u = static_cast<SPUnit*>(l->data);
+ Inkscape::Util::UnitTable::UnitMap m = unit_table.units(Inkscape::Util::UNIT_TYPE_LINEAR);
+ Inkscape::Util::UnitTable::UnitMap::iterator iter = m.begin();
+ while(iter != m.end()) {
Gtk::RadioMenuItem *mi = Gtk::manage(new Gtk::RadioMenuItem(_sw_group));
- mi->add(*(new Gtk::Label(u->abbr, 0.0, 0.5)));
+ mi->add(*(new Gtk::Label((*iter).first, 0.0, 0.5)));
_unit_mis = g_slist_append(_unit_mis, mi);
- mi->signal_activate().connect(sigc::bind<SPUnitId>(sigc::mem_fun(*this, &SelectedStyle::on_popup_units), u->unit_id));
+ Inkscape::Util::Unit const *u = new Inkscape::Util::Unit(unit_table.getUnit(iter->first));
+ mi->signal_activate().connect(sigc::bind<Inkscape::Util::Unit>(sigc::mem_fun(*this, &SelectedStyle::on_popup_units), *u));
_popup_sw.attach(*mi, 0,1, row, row+1);
row++;
+ ++iter;
}
_popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, row, row+1);
@@ -476,13 +481,13 @@ SelectedStyle::setDesktop(SPDesktop *desktop)
this )
));
- _sw_unit = const_cast<SPUnit*>(sp_desktop_namedview(desktop)->doc_units);
+ _sw_unit = const_cast<Inkscape::Util::Unit*>(sp_desktop_namedview(desktop)->doc_units);
// Set the doc default unit active in the units list
gint length = g_slist_length(_unit_mis);
for (int i = 0; i < length; i++) {
Gtk::RadioMenuItem *mi = (Gtk::RadioMenuItem *) g_slist_nth_data(_unit_mis, i);
- if (mi && mi->get_label() == Glib::ustring(_sw_unit->abbr)) {
+ if (mi && mi->get_label() == _sw_unit->abbr) {
mi->set_active();
break;
}
@@ -926,8 +931,8 @@ SelectedStyle::on_opacity_click(GdkEventButton *event)
return false;
}
-void SelectedStyle::on_popup_units(SPUnitId id) {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(id));
+void SelectedStyle::on_popup_units(Inkscape::Util::Unit &unit) {
+ _sw_unit = new Inkscape::Util::Unit(unit);
update();
}
@@ -935,7 +940,7 @@ void SelectedStyle::on_popup_preset(int i) {
SPCSSAttr *css = sp_repr_css_attr_new ();
gdouble w;
if (_sw_unit) {
- w = sp_units_get_pixels (_sw_presets[i], *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(_sw_presets[i], *_sw_unit, "px");
} else {
w = _sw_presets[i];
}
@@ -1114,7 +1119,7 @@ SelectedStyle::update()
{
double w;
if (_sw_unit) {
- w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", *_sw_unit);
} else {
w = query->stroke_width.computed;
}
@@ -1128,7 +1133,7 @@ SelectedStyle::update()
{
gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"),
w,
- _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px",
+ _sw_unit? _sw_unit->abbr.c_str() : "px",
(result_sw == QUERY_STYLE_MULTIPLE_AVERAGED)?
_(" (averaged)") : "");
_stroke_width_place.set_tooltip_text(str);
diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h
index e5bc4f883..0a907f1fd 100644
--- a/src/ui/widget/selected-style.h
+++ b/src/ui/widget/selected-style.h
@@ -41,12 +41,15 @@
#include <sigc++/sigc++.h>
#include "rotateable.h"
-#include "helper/units.h"
class SPDesktop;
-struct SPUnit;
namespace Inkscape {
+
+namespace Util {
+ class Unit;
+}
+
namespace UI {
namespace Widget {
@@ -273,11 +276,11 @@ protected:
Gtk::Menu _popup_sw;
Gtk::RadioButtonGroup _sw_group;
GSList *_unit_mis;
- void on_popup_units(SPUnitId id);
+ void on_popup_units(Inkscape::Util::Unit &u);
void on_popup_preset(int i);
Gtk::MenuItem _popup_sw_remove;
- SPUnit *_sw_unit;
+ Inkscape::Util::Unit *_sw_unit;
void *_drop[2];
bool _dropEnabled[2];
diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp
index a89f42575..682457bed 100644
--- a/src/ui/widget/style-swatch.cpp
+++ b/src/ui/widget/style-swatch.cpp
@@ -26,8 +26,9 @@
#include "xml/repr.h"
#include "xml/sp-css-attr.h"
#include "widgets/widget-sizes.h"
-#include "helper/units.h"
+#include "util/units.h"
#include "helper/action.h"
+#include "helper/action-context.h"
#include "preferences.h"
#include "inkscape.h"
#include "verbs.h"
@@ -200,7 +201,7 @@ StyleSwatch::on_click(GdkEventButton */*event*/)
{
if (this->_desktop && this->_verb_t != SP_VERB_NONE) {
Inkscape::Verb *verb = Inkscape::Verb::get(this->_verb_t);
- SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->_desktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext((Inkscape::UI::View::View *) this->_desktop));
sp_action_perform (action, NULL);
return true;
}
@@ -332,7 +333,7 @@ void StyleSwatch::setStyle(SPStyle *query)
if (has_stroke) {
double w;
if (_sw_unit) {
- w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", *_sw_unit);
} else {
w = query->stroke_width.computed;
}
@@ -345,7 +346,7 @@ void StyleSwatch::setStyle(SPStyle *query)
{
gchar *str = g_strdup_printf(_("Stroke width: %.5g%s"),
w,
- _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px");
+ _sw_unit? _sw_unit->abbr.c_str() : "px");
_stroke_width_place.set_tooltip_text(str);
g_free (str);
}
diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h
index 6bdb5e248..6da58a2dd 100644
--- a/src/ui/widget/style-swatch.h
+++ b/src/ui/widget/style-swatch.h
@@ -30,7 +30,6 @@
#include "button.h"
#include "preferences.h"
-struct SPUnit;
struct SPStyle;
class SPCSSAttr;
@@ -43,6 +42,11 @@ class Table;
}
namespace Inkscape {
+
+namespace Util {
+ class Unit;
+}
+
namespace UI {
namespace Widget {
@@ -93,7 +97,7 @@ private:
Gtk::EventBox _stroke_width_place;
Gtk::Label _stroke_width;
- SPUnit *_sw_unit;
+ Inkscape::Util::Unit *_sw_unit;
friend class ToolObserver;
};
diff --git a/src/ui/widget/unit-menu.cpp b/src/ui/widget/unit-menu.cpp
index 18b7bcab9..111226774 100644
--- a/src/ui/widget/unit-menu.cpp
+++ b/src/ui/widget/unit-menu.cpp
@@ -15,6 +15,8 @@
#include "unit-menu.h"
+using Inkscape::Util::unit_table;
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -30,7 +32,7 @@ UnitMenu::~UnitMenu() {
bool UnitMenu::setUnitType(UnitType unit_type)
{
// Expand the unit widget with unit entries from the unit table
- UnitTable::UnitMap m = _unit_table.units(unit_type);
+ UnitTable::UnitMap m = unit_table.units(unit_type);
UnitTable::UnitMap::iterator iter = m.begin();
while(iter != m.end()) {
Glib::ustring text = (*iter).first;
@@ -38,7 +40,7 @@ bool UnitMenu::setUnitType(UnitType unit_type)
++iter;
}
_type = unit_type;
- set_active_text(_unit_table.primary(unit_type));
+ set_active_text(unit_table.primary(unit_type));
return true;
}
@@ -52,7 +54,7 @@ bool UnitMenu::resetUnitType(UnitType unit_type)
void UnitMenu::addUnit(Unit const& u)
{
- _unit_table.addUnit(u, false);
+ unit_table.addUnit(u, false);
append(u.abbr);
}
@@ -60,9 +62,9 @@ Unit UnitMenu::getUnit() const
{
if (get_active_text() == "") {
g_assert(_type != UNIT_TYPE_NONE);
- return _unit_table.getUnit(_unit_table.primary(_type));
+ return unit_table.getUnit(unit_table.primary(_type));
}
- return _unit_table.getUnit(get_active_text());
+ return unit_table.getUnit(get_active_text());
}
bool UnitMenu::setUnit(Glib::ustring const & unit)
@@ -112,8 +114,8 @@ double UnitMenu::getConversion(Glib::ustring const &new_unit_abbr, Glib::ustring
{
double old_factor = getUnit().factor;
if (old_unit_abbr != "no_unit")
- old_factor = _unit_table.getUnit(old_unit_abbr).factor;
- Unit new_unit = _unit_table.getUnit(new_unit_abbr);
+ old_factor = unit_table.getUnit(old_unit_abbr).factor;
+ Unit new_unit = unit_table.getUnit(new_unit_abbr);
// Catch the case of zero or negative unit factors (error!)
if (old_factor < 0.0000001 ||
diff --git a/src/ui/widget/unit-menu.h b/src/ui/widget/unit-menu.h
index 3104d5aef..3f4df6bf9 100644
--- a/src/ui/widget/unit-menu.h
+++ b/src/ui/widget/unit-menu.h
@@ -127,10 +127,7 @@ public:
*/
bool isRadial() const;
- UnitTable &getUnitTable() {return _unit_table;}
-
protected:
- UnitTable _unit_table;
UnitType _type;
};
diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp
new file mode 100644
index 000000000..5b2dc031b
--- /dev/null
+++ b/src/ui/widget/unit-tracker.cpp
@@ -0,0 +1,263 @@
+/*
+ * Inkscape::UI::Widget::UnitTracker
+ * Simple mediator to synchronize changes to unit menus
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ * Matthew Petroff <matthew@mpetroff.net>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2013 Matthew Petroff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "unit-tracker.h"
+#include "ege-select-one-action.h"
+
+#define COLUMN_STRING 0
+
+using Inkscape::Util::UnitTable;
+using Inkscape::Util::unit_table;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+UnitTracker::UnitTracker(UnitType unit_type) :
+ _active(0),
+ _isUpdating(false),
+ _activeUnitInitialized(false),
+ _store(0),
+ _unitList(0),
+ _actionList(0),
+ _adjList(0),
+ _priorValues()
+{
+ _store = gtk_list_store_new(1, G_TYPE_STRING);
+
+ GtkTreeIter iter;
+ UnitTable::UnitMap m = unit_table.units(unit_type);
+ UnitTable::UnitMap::iterator m_iter = m.begin();
+ while(m_iter != m.end()) {
+ Glib::ustring text = (*m_iter).first;
+ m_iter++;
+ gtk_list_store_append(_store, &iter);
+ gtk_list_store_set(_store, &iter, COLUMN_STRING, text.c_str(), -1);
+ }
+ gint count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(_store), 0);
+ if ((count > 0) && (_active > count)) {
+ _setActive(--count);
+ } else {
+ _setActive(_active);
+ }
+}
+
+UnitTracker::~UnitTracker()
+{
+ // Unhook weak references to GtkActions
+ while (_actionList) {
+ g_signal_handlers_disconnect_by_func(G_OBJECT(_actionList->data), (gpointer) _unitChangedCB, this);
+ g_object_weak_unref(G_OBJECT(_actionList->data), _actionFinalizedCB, this);
+ _actionList = g_slist_delete_link(_actionList, _actionList);
+ }
+
+ // Unhook weak references to GtkAdjustments
+ while (_adjList) {
+ g_object_weak_unref(G_OBJECT(_adjList->data), _adjustmentFinalizedCB, this);
+ _adjList = g_slist_delete_link(_adjList, _adjList);
+ }
+}
+
+bool UnitTracker::isUpdating() const
+{
+ return _isUpdating;
+}
+
+Inkscape::Util::Unit UnitTracker::getActiveUnit() const
+{
+ return _activeUnit;
+}
+
+void UnitTracker::setActiveUnit(Inkscape::Util::Unit const *unit)
+{
+ if (unit) {
+ GtkTreeIter iter;
+ int index = 0;
+ gboolean found = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(_store), &iter);
+ while (found) {
+ gchar *storedUnit = 0;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &storedUnit, -1);
+ if (storedUnit && (!unit->abbr.compare(storedUnit))) {
+ _setActive(index);
+ break;
+ }
+
+ found = gtk_tree_model_iter_next(GTK_TREE_MODEL(_store), &iter);
+ index++;
+ }
+ }
+}
+
+void UnitTracker::setActiveUnitByAbbr(gchar const *abbr)
+{
+ Inkscape::Util::Unit u = unit_table.getUnit(abbr);
+ setActiveUnit(&u);
+}
+
+void UnitTracker::addAdjustment(GtkAdjustment *adj)
+{
+ if (!g_slist_find(_adjList, adj)) {
+ g_object_weak_ref(G_OBJECT(adj), _adjustmentFinalizedCB, this);
+ _adjList = g_slist_append(_adjList, adj);
+ }
+}
+
+void UnitTracker::addUnit(Inkscape::Util::Unit const &u)
+{
+ GtkTreeIter iter;
+ gtk_list_store_append(_store, &iter);
+ gtk_list_store_set(_store, &iter, COLUMN_STRING, u.abbr.c_str(), -1);
+}
+
+void UnitTracker::setFullVal(GtkAdjustment *adj, gdouble val)
+{
+ _priorValues[adj] = val;
+}
+
+GtkAction *UnitTracker::createAction(gchar const *name, gchar const *label, gchar const *tooltip)
+{
+ EgeSelectOneAction *act1 = ege_select_one_action_new(name, label, tooltip, NULL, GTK_TREE_MODEL(_store));
+ ege_select_one_action_set_label_column(act1, COLUMN_STRING);
+ if (_active) {
+ ege_select_one_action_set_active(act1, _active);
+ }
+
+ ege_select_one_action_set_appearance(act1, "minimal");
+ g_object_weak_ref(G_OBJECT(act1), _actionFinalizedCB, this);
+ g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(_unitChangedCB), this);
+ _actionList = g_slist_append(_actionList, act1);
+
+ return GTK_ACTION(act1);
+}
+
+void UnitTracker::_unitChangedCB(GtkAction *action, gpointer data)
+{
+ if (action && data) {
+ EgeSelectOneAction *act = EGE_SELECT_ONE_ACTION(action);
+ gint active = ege_select_one_action_get_active(act);
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_setActive(active);
+ }
+}
+
+void UnitTracker::_actionFinalizedCB(gpointer data, GObject *where_the_object_was)
+{
+ if (data && where_the_object_was) {
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_actionFinalized(where_the_object_was);
+ }
+}
+
+void UnitTracker::_adjustmentFinalizedCB(gpointer data, GObject *where_the_object_was)
+{
+ if (data && where_the_object_was) {
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_adjustmentFinalized(where_the_object_was);
+ }
+}
+
+void UnitTracker::_actionFinalized(GObject *where_the_object_was)
+{
+ GSList *target = g_slist_find(_actionList, where_the_object_was);
+ if (target) {
+ _actionList = g_slist_remove(_actionList, where_the_object_was);
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was);
+ }
+}
+
+void UnitTracker::_adjustmentFinalized(GObject *where_the_object_was)
+{
+ GSList *target = g_slist_find(_adjList, where_the_object_was);
+ if (target) {
+ _adjList = g_slist_remove(_adjList, where_the_object_was);
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was);
+ }
+}
+
+void UnitTracker::_setActive(gint active)
+{
+ if ( active != _active || !_activeUnitInitialized ) {
+ gint oldActive = _active;
+
+ GtkTreeIter iter;
+ gboolean found = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(_store), &iter, NULL, oldActive);
+ if (found) {
+ gchar *abbr;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &abbr, -1);
+ Inkscape::Util::Unit unit = unit_table.getUnit(abbr);
+
+ found = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(_store), &iter, NULL, active);
+ if (found) {
+ gchar *newAbbr;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &newAbbr, -1);
+ Inkscape::Util::Unit newUnit = unit_table.getUnit(newAbbr);
+ _activeUnit = newUnit;
+
+ if (_adjList) {
+ _fixupAdjustments(unit, newUnit);
+ }
+
+ } else {
+ g_warning("Did not find new unit");
+ }
+ } else {
+ g_warning("Did not find old unit");
+ }
+
+ _active = active;
+
+ for ( GSList *cur = _actionList ; cur ; cur = g_slist_next(cur) ) {
+ if (IS_EGE_SELECT_ONE_ACTION(cur->data)) {
+ EgeSelectOneAction *act = EGE_SELECT_ONE_ACTION(cur->data);
+ ege_select_one_action_set_active(act, active);
+ }
+ }
+
+ _activeUnitInitialized = true;
+ }
+}
+
+void UnitTracker::_fixupAdjustments(Inkscape::Util::Unit const oldUnit, Inkscape::Util::Unit const newUnit)
+{
+ _isUpdating = true;
+ for ( GSList *cur = _adjList ; cur ; cur = g_slist_next(cur) ) {
+ GtkAdjustment *adj = GTK_ADJUSTMENT(cur->data);
+ gdouble oldVal = gtk_adjustment_get_value(adj);
+ gdouble val = oldVal;
+
+ if ( (oldUnit.type != Inkscape::Util::UNIT_TYPE_DIMENSIONLESS)
+ && (newUnit.type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) )
+ {
+ val = newUnit.factor * 100;
+ _priorValues[adj] = Inkscape::Util::Quantity::convert(oldVal, oldUnit, "px");
+ } else if ( (oldUnit.type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS)
+ && (newUnit.type != Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) )
+ {
+ if (_priorValues.find(adj) != _priorValues.end()) {
+ val = Inkscape::Util::Quantity::convert(_priorValues[adj], "px", newUnit);
+ }
+ } else {
+ val = Inkscape::Util::Quantity::convert(oldVal, oldUnit, newUnit);
+ }
+
+ gtk_adjustment_set_value(adj, val);
+ }
+ _isUpdating = false;
+}
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h
new file mode 100644
index 000000000..19559ae1c
--- /dev/null
+++ b/src/ui/widget/unit-tracker.h
@@ -0,0 +1,74 @@
+/*
+ * Inkscape::UI::Widget::UnitTracker
+ * Simple mediator to synchronize changes to unit menus
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ * Matthew Petroff <matthew@mpetroff.net>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2013 Matthew Petroff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_UNIT_TRACKER_H
+#define INKSCAPE_UI_WIDGET_UNIT_TRACKER_H
+
+#include <map>
+#include <gtk/gtk.h>
+
+#include "util/units.h"
+
+using Inkscape::Util::Unit;
+using Inkscape::Util::UnitType;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class UnitTracker {
+public:
+ UnitTracker(UnitType unit_type);
+ virtual ~UnitTracker();
+
+ bool isUpdating() const;
+
+ void setActiveUnit(Inkscape::Util::Unit const *unit);
+ void setActiveUnitByAbbr(gchar const *abbr);
+ Inkscape::Util::Unit getActiveUnit() const;
+
+ void addUnit(Inkscape::Util::Unit const &u);
+ void addAdjustment(GtkAdjustment *adj);
+ void setFullVal(GtkAdjustment *adj, gdouble val);
+
+ GtkAction *createAction(gchar const *name, gchar const *label, gchar const *tooltip);
+
+protected:
+ UnitType _type;
+
+private:
+ static void _unitChangedCB(GtkAction *action, gpointer data);
+ static void _actionFinalizedCB(gpointer data, GObject *where_the_object_was);
+ static void _adjustmentFinalizedCB(gpointer data, GObject *where_the_object_was);
+ void _setActive(gint index);
+ void _fixupAdjustments(Inkscape::Util::Unit const oldUnit, Inkscape::Util::Unit const newUnit);
+ void _actionFinalized(GObject *where_the_object_was);
+ void _adjustmentFinalized(GObject *where_the_object_was);
+
+ gint _active;
+ bool _isUpdating;
+ Inkscape::Util::Unit _activeUnit;
+ bool _activeUnitInitialized;
+ GtkListStore *_store;
+ GSList *_unitList;
+ GSList *_actionList;
+ GSList *_adjList;
+ std::map <GtkAdjustment *, gdouble> _priorValues;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_UNIT_TRACKER_H