summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
committerMarkus Engel <markus.engel@tum.de>2013-03-29 23:52:42 +0000
commita168040d5a452544328a1e6ad35aaac351f94d44 (patch)
treefae1ba829f543a473da281bd5fa6e4deabbf6912 /src/ui
parentRemoved function pointers from SPObject and subclasses. (diff)
parentDutch translation update (diff)
downloadinkscape-a168040d5a452544328a1e6ad35aaac351f94d44.tar.gz
inkscape-a168040d5a452544328a1e6ad35aaac351f94d44.zip
merged from trunk
(bzr r11608.1.56)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt11
-rw-r--r--src/ui/cache/svg_preview_cache.cpp8
-rw-r--r--src/ui/cache/svg_preview_cache.h1
-rw-r--r--src/ui/clipboard.cpp52
-rw-r--r--src/ui/clipboard.h2
-rw-r--r--src/ui/control-manager.cpp15
-rw-r--r--src/ui/dialog/Makefile_insert2
-rw-r--r--src/ui/dialog/aboutbox.cpp29
-rw-r--r--src/ui/dialog/align-and-distribute.cpp434
-rw-r--r--src/ui/dialog/align-and-distribute.h93
-rw-r--r--src/ui/dialog/calligraphic-profile-rename.cpp77
-rw-r--r--src/ui/dialog/calligraphic-profile-rename.h30
-rw-r--r--src/ui/dialog/clonetiler.cpp67
-rw-r--r--src/ui/dialog/color-item.cpp82
-rw-r--r--src/ui/dialog/color-item.h4
-rw-r--r--src/ui/dialog/debug.cpp16
-rw-r--r--src/ui/dialog/desktop-tracker.h2
-rw-r--r--src/ui/dialog/dialog-manager.cpp10
-rw-r--r--src/ui/dialog/dialog.cpp4
-rw-r--r--src/ui/dialog/dialog.h2
-rw-r--r--src/ui/dialog/document-metadata.cpp112
-rw-r--r--src/ui/dialog/document-metadata.h21
-rw-r--r--src/ui/dialog/document-properties.cpp457
-rw-r--r--src/ui/dialog/document-properties.h22
-rw-r--r--src/ui/dialog/export.cpp137
-rw-r--r--src/ui/dialog/export.h29
-rw-r--r--src/ui/dialog/filedialog.cpp5
-rw-r--r--src/ui/dialog/filedialog.h5
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.cpp65
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.h3
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp94
-rw-r--r--src/ui/dialog/filedialogimpl-win32.h6
-rw-r--r--src/ui/dialog/fill-and-stroke.cpp63
-rw-r--r--src/ui/dialog/fill-and-stroke.h18
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp462
-rw-r--r--src/ui/dialog/filter-effects-dialog.h32
-rw-r--r--src/ui/dialog/find.cpp14
-rw-r--r--src/ui/dialog/find.h16
-rw-r--r--src/ui/dialog/floating-behavior.cpp9
-rw-r--r--src/ui/dialog/font-substitution.cpp8
-rw-r--r--src/ui/dialog/glyphs.cpp81
-rw-r--r--src/ui/dialog/glyphs.h4
-rw-r--r--src/ui/dialog/guides.cpp89
-rw-r--r--src/ui/dialog/guides.h16
-rw-r--r--src/ui/dialog/icon-preview.cpp4
-rw-r--r--src/ui/dialog/icon-preview.h5
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp524
-rw-r--r--src/ui/dialog/inkscape-preferences.h87
-rw-r--r--src/ui/dialog/input.cpp593
-rw-r--r--src/ui/dialog/layer-properties.cpp201
-rw-r--r--src/ui/dialog/layer-properties.h64
-rw-r--r--src/ui/dialog/layers.cpp160
-rw-r--r--src/ui/dialog/layers.h11
-rw-r--r--src/ui/dialog/livepatheffect-add.cpp8
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp2
-rw-r--r--src/ui/dialog/object-attributes.cpp18
-rw-r--r--src/ui/dialog/object-attributes.h5
-rw-r--r--src/ui/dialog/object-properties.cpp209
-rw-r--r--src/ui/dialog/object-properties.h34
-rw-r--r--src/ui/dialog/ocaldialogs.cpp89
-rw-r--r--src/ui/dialog/ocaldialogs.h19
-rw-r--r--src/ui/dialog/print.cpp2
-rw-r--r--src/ui/dialog/spellcheck.cpp22
-rw-r--r--src/ui/dialog/spellcheck.h10
-rw-r--r--src/ui/dialog/svg-fonts-dialog.cpp44
-rw-r--r--src/ui/dialog/svg-fonts-dialog.h20
-rw-r--r--src/ui/dialog/swatches.cpp92
-rw-r--r--src/ui/dialog/symbols.cpp762
-rw-r--r--src/ui/dialog/symbols.h115
-rw-r--r--src/ui/dialog/text-edit.cpp154
-rw-r--r--src/ui/dialog/text-edit.h29
-rw-r--r--src/ui/dialog/tile.cpp59
-rw-r--r--src/ui/dialog/tile.h17
-rw-r--r--src/ui/dialog/tracedialog.cpp168
-rw-r--r--src/ui/dialog/transformation.cpp113
-rw-r--r--src/ui/dialog/transformation.h14
-rw-r--r--src/ui/dialog/undo-history.cpp41
-rw-r--r--src/ui/dialog/undo-history.h7
-rw-r--r--src/ui/dialog/xml-tree.cpp10
-rw-r--r--src/ui/dialog/xml-tree.h19
-rw-r--r--src/ui/previewable.h3
-rw-r--r--src/ui/previewfillable.h3
-rw-r--r--src/ui/previewholder.cpp295
-rw-r--r--src/ui/previewholder.h24
-rw-r--r--src/ui/tool/control-point.cpp2
-rw-r--r--src/ui/tool/control-point.h2
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp7
-rw-r--r--src/ui/tool/node-tool.cpp85
-rw-r--r--src/ui/tool/node-tool.h3
-rw-r--r--src/ui/tool/node.cpp2
-rw-r--r--src/ui/tool/path-manipulator.cpp1
-rw-r--r--src/ui/tool/path-manipulator.h4
-rw-r--r--src/ui/view/edit-widget-interface.h3
-rw-r--r--src/ui/view/view-widget.h2
-rw-r--r--src/ui/view/view.cpp17
-rw-r--r--src/ui/view/view.h5
-rw-r--r--src/ui/widget/Makefile_insert6
-rw-r--r--src/ui/widget/color-picker.cpp8
-rw-r--r--src/ui/widget/color-preview.cpp90
-rw-r--r--src/ui/widget/color-preview.h19
-rw-r--r--src/ui/widget/dock-item.cpp1
-rw-r--r--src/ui/widget/dock.cpp24
-rw-r--r--src/ui/widget/entry.cpp2
-rw-r--r--src/ui/widget/entry.h6
-rw-r--r--src/ui/widget/filter-effect-chooser.cpp15
-rw-r--r--src/ui/widget/filter-effect-chooser.h8
-rw-r--r--src/ui/widget/frame.cpp2
-rw-r--r--src/ui/widget/frame.h8
-rw-r--r--src/ui/widget/gimpcolorwheel.c1598
-rw-r--r--src/ui/widget/gimpcolorwheel.h95
-rw-r--r--src/ui/widget/gimpspinscale.c1092
-rw-r--r--src/ui/widget/gimpspinscale.h76
-rw-r--r--src/ui/widget/imageicon.cpp6
-rw-r--r--src/ui/widget/imageicon.h3
-rw-r--r--src/ui/widget/imagetoggler.h2
-rw-r--r--src/ui/widget/labelled.cpp5
-rw-r--r--src/ui/widget/labelled.h4
-rw-r--r--src/ui/widget/layer-selector.cpp49
-rw-r--r--src/ui/widget/layer-selector.h5
-rw-r--r--src/ui/widget/licensor.cpp21
-rw-r--r--src/ui/widget/notebook-page.cpp27
-rw-r--r--src/ui/widget/notebook-page.h26
-rw-r--r--src/ui/widget/object-composite-settings.cpp62
-rw-r--r--src/ui/widget/object-composite-settings.h16
-rw-r--r--src/ui/widget/page-sizer.cpp56
-rw-r--r--src/ui/widget/page-sizer.h24
-rw-r--r--src/ui/widget/panel.cpp124
-rw-r--r--src/ui/widget/panel.h22
-rw-r--r--src/ui/widget/point.h2
-rw-r--r--src/ui/widget/preferences-widget.cpp305
-rw-r--r--src/ui/widget/preferences-widget.h48
-rw-r--r--src/ui/widget/registered-widget.h2
-rw-r--r--src/ui/widget/rendering-options.cpp5
-rw-r--r--src/ui/widget/rotateable.cpp31
-rw-r--r--src/ui/widget/rotateable.h3
-rw-r--r--src/ui/widget/scalar.cpp2
-rw-r--r--src/ui/widget/selected-style.cpp221
-rw-r--r--src/ui/widget/selected-style.h30
-rw-r--r--src/ui/widget/spin-scale.cpp246
-rw-r--r--src/ui/widget/spin-scale.h117
-rw-r--r--src/ui/widget/spin-slider.cpp16
-rw-r--r--src/ui/widget/spin-slider.h8
-rw-r--r--src/ui/widget/style-subject.h2
-rw-r--r--src/ui/widget/style-swatch.cpp77
-rw-r--r--src/ui/widget/style-swatch.h25
-rw-r--r--src/ui/widget/tolerance-slider.cpp9
-rw-r--r--src/ui/widget/tolerance-slider.h13
-rw-r--r--src/ui/widget/unit-menu.cpp14
148 files changed, 9577 insertions, 1999 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index b3bcb3fdd..f3c3b8473 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -42,6 +42,7 @@ set(ui_SRC
dialog/filter-effects-dialog.cpp
dialog/find.cpp
dialog/floating-behavior.cpp
+ dialog/font-substitution.cpp
dialog/glyphs.cpp
dialog/guides.cpp
dialog/icon-preview.cpp
@@ -59,6 +60,7 @@ set(ui_SRC
dialog/print-colors-preview-dialog.cpp
dialog/print.cpp
dialog/scriptdialog.cpp
+ dialog/symbols.cpp
dialog/xml-tree.cpp
# dialog/session-player.cpp
dialog/spellcheck.cpp
@@ -82,6 +84,8 @@ set(ui_SRC
widget/entry.cpp
widget/filter-effect-chooser.cpp
widget/frame.cpp
+ widget/gimpcolorwheel.c
+ widget/gimpspinscale.c
widget/imageicon.cpp
widget/imagetoggler.cpp
widget/labelled.cpp
@@ -101,6 +105,7 @@ set(ui_SRC
widget/scalar-unit.cpp
widget/scalar.cpp
widget/selected-style.cpp
+ widget/spin-scale.cpp
widget/spin-slider.cpp
widget/spinbutton.cpp
widget/style-subject.cpp
@@ -117,6 +122,7 @@ set(ui_SRC
# Headers
clipboard.h
control-manager.h
+ control-types.h
icon-names.h
previewable.h
previewfillable.h
@@ -148,6 +154,7 @@ set(ui_SRC
dialog/filter-effects-dialog.h
dialog/find.h
dialog/floating-behavior.h
+ dialog/font-substitution.h
dialog/glyphs.h
dialog/guides.h
dialog/icon-preview.h
@@ -169,6 +176,7 @@ set(ui_SRC
dialog/spellcheck.h
dialog/svg-fonts-dialog.h
dialog/swatches.h
+ dialog/symbols.h
dialog/text-edit.h
dialog/tile.h
dialog/tracedialog.h
@@ -204,6 +212,8 @@ set(ui_SRC
widget/entry.h
widget/filter-effect-chooser.h
widget/frame.h
+ widget/gimpspinscale.h
+ widget/gimpcolorwheel.h
widget/imageicon.h
widget/imagetoggler.h
widget/labelled.h
@@ -224,6 +234,7 @@ set(ui_SRC
widget/scalar-unit.h
widget/scalar.h
widget/selected-style.h
+ widget/spin-scale.h
widget/spin-slider.h
widget/spinbutton.h
widget/style-subject.h
diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp
index f8a806a13..7842bd5b3 100644
--- a/src/ui/cache/svg_preview_cache.cpp
+++ b/src/ui/cache/svg_preview_cache.cpp
@@ -121,6 +121,14 @@ GdkPixbuf* SvgPreview::get_preview(const gchar* uri, const gchar* id, Inkscape::
return px;
}
+void SvgPreview::remove_preview_from_cache(const Glib::ustring& key) {
+ std::map<Glib::ustring, GdkPixbuf *>::iterator found = _pixmap_cache.find(key);
+ if ( found != _pixmap_cache.end() ) {
+ _pixmap_cache.erase(key);
+ }
+}
+
+
}
}
}
diff --git a/src/ui/cache/svg_preview_cache.h b/src/ui/cache/svg_preview_cache.h
index 11d26fe22..b04a82350 100644
--- a/src/ui/cache/svg_preview_cache.h
+++ b/src/ui/cache/svg_preview_cache.h
@@ -40,6 +40,7 @@ class SvgPreview {
GdkPixbuf* get_preview_from_cache(const Glib::ustring& key);
void set_preview_in_cache(const Glib::ustring& key, GdkPixbuf* px);
GdkPixbuf* get_preview(const gchar* uri, const gchar* id, Inkscape::DrawingItem *root, double scale_factor, unsigned int psize);
+ void remove_preview_from_cache(const Glib::ustring& key);
};
}; // namespace Cache
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index f1f6c4ab4..f2b9fb02a 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -7,9 +7,11 @@
* Jon A. Cruz <jon@joncruz.org>
* Incorporates some code from selection-chemistry.cpp, see that file for more credits.
* Abhishek Sharma
+ * Tavmjong Bah
*
* Copyright (C) 2008 authors
* Copyright (C) 2010 Jon A. Cruz
+ * Copyright (C) 2012 Tavmjong Bah (Symbol additions)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,6 +21,7 @@
* See the file COPYING for details.
*/
+#include <gtkmm/clipboard.h>
#include "ui/clipboard.h"
// TODO: reduce header bloat if possible
@@ -26,7 +29,6 @@
#include "file.h" // for file_import, used in _pasteImage
#include <list>
#include <algorithm>
-#include <gtkmm/clipboard.h>
#include <glibmm/ustring.h>
#include <glibmm/i18n.h>
#include <glib/gstdio.h> // for g_file_set_contents etc., used in _onGet and paste
@@ -66,6 +68,8 @@
#include "sp-mask.h"
#include "sp-textpath.h"
#include "sp-rect.h"
+#include "sp-use.h"
+#include "sp-symbol.h"
#include "live_effects/lpeobject.h"
#include "live_effects/lpeobject-reference.h"
#include "live_effects/parameter/path.h"
@@ -109,6 +113,7 @@ class ClipboardManagerImpl : public ClipboardManager {
public:
virtual void copy(SPDesktop *desktop);
virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *);
+ virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style);
virtual bool paste(SPDesktop *desktop, bool in_place);
virtual bool pasteStyle(SPDesktop *desktop);
virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y);
@@ -295,6 +300,43 @@ void ClipboardManagerImpl::copyPathParameter(Inkscape::LivePathEffect::PathParam
}
/**
+ * Copy a symbol from the symbol dialog.
+ * @param symbol The Inkscape::XML::Node for the symbol.
+ */
+void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* style)
+{
+ //std::cout << "ClipboardManagerImpl::copySymbol" << std::endl;
+ if ( symbol == NULL ) {
+ return;
+ }
+
+ _discardInternalClipboard();
+ _createInternalClipboard();
+
+ // We add "_duplicate" to have a well defined symbol name that
+ // bypasses the "prevent_id_classes" routine. We'll get rid of it
+ // when we paste.
+ Inkscape::XML::Node *repr = symbol->duplicate(_doc);
+ Glib::ustring symbol_name = repr->attribute("id");
+
+ symbol_name += "_inkscape_duplicate";
+ repr->setAttribute("id", symbol_name.c_str());
+ _defs->appendChild(repr);
+
+ Glib::ustring id("#");
+ id += symbol->attribute("id");
+
+ Inkscape::XML::Node *use = _doc->createElement("svg:use");
+ use->setAttribute("xlink:href", id.c_str() );
+ // Set a default style in <use> rather than <symbol> so it can be changed.
+ use->setAttribute("style", style );
+ _root->appendChild(use);
+
+ fit_canvas_to_drawing(_clipboardSPDoc);
+ _setClipboardTargets();
+}
+
+/**
* Paste from the system clipboard into the active desktop.
* @param in_place Whether to put the contents where they were when copied.
*/
@@ -725,6 +767,14 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item)
}
}
+ // Copy symbols: We may want to be more clever...
+ // if (SP_IS_USE(item)) {
+ // SPObject *symbol = SP_USE(item)->child;
+ // if( symbol && SP_IS_SYMBOL(symbol) ) {
+ // _copyNode(symbol->getRepr(), _doc, _defs);
+ // }
+ // }
+
// recurse
for (SPObject *o = item->children ; o != NULL ; o = o->next) {
if (SP_IS_ITEM(o)) {
diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h
index fb28bfc14..b565740c3 100644
--- a/src/ui/clipboard.h
+++ b/src/ui/clipboard.h
@@ -25,6 +25,7 @@
class SPDesktop;
namespace Inkscape {
class Selection;
+namespace XML { class Node; }
namespace LivePathEffect { class PathParam; }
namespace UI {
@@ -43,6 +44,7 @@ class ClipboardManager {
public:
virtual void copy(SPDesktop *desktop) = 0;
virtual void copyPathParameter(Inkscape::LivePathEffect::PathParam *) = 0;
+ virtual void copySymbol(Inkscape::XML::Node* symbol, gchar const* style) = 0;
virtual bool paste(SPDesktop *desktop, bool in_place = false) = 0;
virtual bool pasteStyle(SPDesktop *desktop) = 0;
virtual bool pasteSize(SPDesktop *desktop, bool separately, bool apply_x, bool apply_y) = 0;
diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp
index b14f27b8b..62e6ce3a3 100644
--- a/src/ui/control-manager.cpp
+++ b/src/ui/control-manager.cpp
@@ -31,29 +31,18 @@ namespace {
std::map<Inkscape::ControlType, std::vector<int> > sizeTable;
// Note: The following operator overloads are local to this file at the moment to discourage flag manipulation elsewhere.
-
+/*
ControlFlags operator |(ControlFlags lhs, ControlFlags rhs)
{
return static_cast<ControlFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
-
-ControlFlags& operator |=(ControlFlags &lhs, ControlFlags rhs)
-{
- lhs = lhs | rhs;
- return lhs;
-}
+*/
ControlFlags operator &(ControlFlags lhs, ControlFlags rhs)
{
return static_cast<ControlFlags>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
-ControlFlags& operator &=(ControlFlags &lhs, ControlFlags rhs)
-{
- lhs = lhs & rhs;
- return lhs;
-}
-
ControlFlags operator ^(ControlFlags lhs, ControlFlags rhs)
{
return static_cast<ControlFlags>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert
index ba2f53a9e..580b47522 100644
--- a/src/ui/dialog/Makefile_insert
+++ b/src/ui/dialog/Makefile_insert
@@ -89,6 +89,8 @@ ink_common_sources += \
ui/dialog/svg-fonts-dialog.h \
ui/dialog/swatches.cpp \
ui/dialog/swatches.h \
+ ui/dialog/symbols.cpp \
+ ui/dialog/symbols.h \
ui/dialog/text-edit.cpp \
ui/dialog/text-edit.h \
ui/dialog/tile.cpp \
diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp
index efb4c1fd6..ba9670d86 100644
--- a/src/ui/dialog/aboutbox.cpp
+++ b/src/ui/dialog/aboutbox.cpp
@@ -97,7 +97,12 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) {
tabs->append_page(*manage(
make_scrolled_text(license_text)), _("_License"), true);
+#if WITH_GTKMM_3_0
+ get_content_area()->pack_end(*manage(tabs), true, true);
+#else
get_vbox()->pack_end(*manage(tabs), true, true);
+#endif
+
tabs->show_all();
add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
@@ -114,7 +119,11 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) {
label->set_selectable(true);
label->show();
+#if WITH_GTKMM_3_0
+ get_content_area()->pack_start(*manage(label), false, false);
+#else
get_vbox()->pack_start(*manage(label), false, false);
+#endif
Gtk::Requisition requisition;
#if GTK_CHECK_VERSION(3,0,0)
@@ -243,6 +252,7 @@ void AboutBox::initStrings() {
"Arpad Biro\n"
"Nicholas Bishop\n"
"Joshua L. Blocher\n"
+"Hanno Böck\n"
"Henrik Bohre\n"
"Boldewyn\n"
"Daniel Borgmann\n"
@@ -437,7 +447,7 @@ void AboutBox::initStrings() {
"Aleksandar Urošević <urke@users.sourceforge.net>, 2004-2006.\n"
"Alessio Frusciante <algol@firenze.linux.it>, 2002, 2003.\n"
"Alexander Shopov <ash@contact.bg>, 2006.\n"
-"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005, 2010-2011.\n"
+"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005, 2010-2013.\n"
"Alexey Remizov <alexey@remizov.pp.ru>, 2004.\n"
"Ali Ghanavatian <ghanvatian.ali@gmail.com>, 2010.\n"
"Álvaro Lopes <alvieboy@alvie.com>, 2001, 2002.\n"
@@ -458,14 +468,14 @@ void AboutBox::initStrings() {
"Christian Meyer <chrisime@gnome.org>, 2000-2002.\n"
"Christian Neumair <chris@gnome-de.org>, 2002, 2003.\n"
"Christian Rose <menthos@menthos.com>, 2000-2003.\n"
-"Cristian Secară <cristi@secarica.ro>, 2010.\n"
+"Cristian Secară <cristi@secarica.ro>, 2010-2013.\n"
"Christophe Merlet (RedFox) <redfox@redfoxcenter.org>, 2000-2002.\n"
"Clytie Siddall <clytie@riverland.net.au>, 2004-2008.\n"
"Colin Marquardt <colin@marquardt-home.de>, 2004-2006.\n"
"Cédric Gemy <radar.map35@free.fr>, 2006.\n"
"Daniel Díaz <yosoy@danieldiaz.org>, 2004.\n"
"Didier Conchaudron <conchaudron@free.fr>, 2003.\n"
-"Dimitris Spingos <dmtrs32@gmail.com>, 2011.\n"
+"Dimitris Spingos <dmtrs32@gmail.com>, 2011-2013.\n"
"Dorji Tashi <dorjee_doss@hotmail.com>, 2006.\n"
"Duarte Loreto <happyguy_pt@hotmail.com> 2002, 2003 (Maintainer).\n"
"Elias Norberg <elno0959 at student.su.se>, 2009.\n"
@@ -483,6 +493,7 @@ void AboutBox::initStrings() {
"Ilia Penev <lichopicho@gmail.com>, 2006.\n"
"Ivan Masár <helix84@centrum.sk>, 2006-2010. \n"
"Iñaki Larrañaga <dooteo@euskalgnu.org>, 2006.\n"
+"Jānis Eisaks <jancs@dv.lv>, 2012, 2013.\n"
"Jeffrey Steve Borbón Sanabria <jeff_kerokid@yahoo.com>, 2005.\n"
"Jesper Öqvist <jesper@llbit.se>, 2010, 2011.\n"
"Joaquim Perez i Noguer <noguer@gmail.com>, 2008-2009.\n"
@@ -504,16 +515,16 @@ void AboutBox::initStrings() {
"Kingsley Turner <kingsley@maddogsbreakfast.com.au>, 2006.\n"
"Kitae <bluetux@gmail.com>, 2006.\n"
"Kjartan Maraas <kmaraas@gnome.org>, 2000-2002.\n"
-"Kris De Gussem <kris.DeGussem@gmail.com>, 2008-2011.\n"
+"Kris De Gussem <Kris.DeGussem@gmail.com>, 2008-2013.\n"
"Lauris Kaplinski <lauris@ariman.ee>, 2000.\n"
"Leandro Regueiro <leandro.regueiro@gmail.com>, 2006-2008, 2010.\n"
"Liu Xiaoqin <liuxqsmile@gmail.com>, 2008.\n"
"Luca Bruno <luca.br@uno.it>, 2005.\n"
-"Lucas Vieites Fariña<lucas@codexion.com>, 2003-2010.\n"
+"Lucas Vieites Fariña<lucas@codexion.com>, 2003-2013.\n"
"Mahesh subedi <submanesh@hotmail.com>, 2006.\n"
"Martin Srebotnjak, <miles@filmsi.net>, 2005, 2010.\n"
"Masatake YAMATO <jet@gyve.org>, 2002.\n"
-"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2011.\n"
+"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2012.\n"
"Matiphas <matiphas _a_ free _point_ fr>, 2004-2006.\n"
"Mattias Hultgren <mattias_hultgren@tele2.se>, 2005, 2006.\n"
"Maxim Dziumanenko <mvd@mylinux.com.ua>, 2004.\n"
@@ -524,7 +535,7 @@ void AboutBox::initStrings() {
"Muhammad Bashir Al-Noimi <mhdbnoimi@gmail.com>, 2008.\n"
"Myckel Habets <myckel@sdf.lonestar.org>, 2008.\n"
"Nguyen Dinh Trung <nguyendinhtrung141@gmail.com>, 2007, 2008.\n"
-"Nicolas Dufour <nicoduf@yahoo.fr>, 2008-2011.\n"
+"Nicolas Dufour <nicoduf@yahoo.fr>, 2008-2013.\n"
"Pawan Chitrakar <pchitrakar@gmail.com>, 2006.\n"
"Przemysław Loesch <p_loesch@poczta.onet.pl>, 2005.\n"
"Quico Llach <quico@softcatala.org>, 2000. Traducció sodipodi.\n"
@@ -545,7 +556,7 @@ void AboutBox::initStrings() {
"Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n"
"Toshifumi Sato <sato@centrosystem.com>, 2005.\n"
"Jon South <striker@lunar-linux.org>, 2006. \n"
-"Uwe Schöler <oss@oss-marketplace.com>, 2006-2011.\n"
+"Uwe Schöler <oss@oss-marketplace.com>, 2006-2013.\n"
"Valek Filippov <frob@df.ru>, 2000, 2003.\n"
"Victor Dachev <vdachev@gmail.com>, 2006.\n"
"Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu>, 2003.\n"
@@ -560,7 +571,7 @@ void AboutBox::initStrings() {
"Yaron Shahrabani <sh.yaron@gmail.com>, 2009.\n"
"Yukihiro Nakai <nakai@gnome.gr.jp>, 2000, 2003.\n"
"Yuri Beznos <zhiz0id@gmail.com>, 2006.\n"
-"Yuri Chornoivan <yurchor@ukr.net>, 2007-2011.\n"
+"Yuri Chornoivan <yurchor@ukr.net>, 2007-2013.\n"
"Yuri Syrota <rasta@renome.rovno.ua>, 2000.\n"
"Yves Guillou <yvesguillou@users.sourceforge.net>, 2004.\n"
"Zdenko Podobný <zdpo@mailbox.sk>, 2003, 2004."
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index f8d63aade..dbd06d9e8 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -57,227 +57,201 @@ namespace Dialog {
/////////helper classes//////////////////////////////////
-class Action {
-public :
- Action(const Glib::ustring &id,
- const Glib::ustring &tiptext,
- guint row, guint column,
+Action::Action(const Glib::ustring &id,
+ const Glib::ustring &tiptext,
+ guint row, guint column,
#if WITH_GTKMM_3_0
- Gtk::Grid &parent,
+ Gtk::Grid &parent,
#else
- Gtk::Table &parent,
+ Gtk::Table &parent,
#endif
- AlignAndDistribute &dialog):
- _dialog(dialog),
- _id(id),
- _parent(parent)
- {
- Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( _id, Inkscape::ICON_SIZE_LARGE_TOOLBAR) );
- Gtk::Button * pButton = Gtk::manage(new Gtk::Button());
- pButton->set_relief(Gtk::RELIEF_NONE);
- pIcon->show();
- pButton->add(*pIcon);
- pButton->show();
-
- pButton->signal_clicked()
- .connect(sigc::mem_fun(*this, &Action::on_button_click));
- pButton->set_tooltip_text(tiptext);
+ AlignAndDistribute &dialog):
+ _dialog(dialog),
+ _id(id),
+ _parent(parent)
+{
+ Gtk::Widget* pIcon = Gtk::manage( sp_icon_get_icon( _id, Inkscape::ICON_SIZE_LARGE_TOOLBAR) );
+ Gtk::Button * pButton = Gtk::manage(new Gtk::Button());
+ pButton->set_relief(Gtk::RELIEF_NONE);
+ pIcon->show();
+ pButton->add(*pIcon);
+ pButton->show();
+
+ pButton->signal_clicked()
+ .connect(sigc::mem_fun(*this, &Action::on_button_click));
+ pButton->set_tooltip_text(tiptext);
#if WITH_GTKMM_3_0
- parent.attach(*pButton, column, row, 1, 1);
+ parent.attach(*pButton, column, row, 1, 1);
#else
- parent.attach(*pButton, column, column+1, row, row+1, Gtk::FILL, Gtk::FILL);
+ parent.attach(*pButton, column, column+1, row, row+1, Gtk::FILL, Gtk::FILL);
#endif
- }
- virtual ~Action(){}
-
- AlignAndDistribute &_dialog;
-
-private :
- virtual void on_button_click(){}
+}
- Glib::ustring _id;
-#if WITH_GTKMM_3_0
- Gtk::Grid &_parent;
-#else
- Gtk::Table &_parent;
-#endif
-};
+void ActionAlign::do_action(SPDesktop *desktop, int index) {
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
+ if (!selection) return;
-class ActionAlign : public Action {
-public :
- struct Coeffs {
- double mx0, mx1, my0, my1;
- double sx0, sx1, sy0, sy1;
- };
- ActionAlign(const Glib::ustring &id,
- const Glib::ustring &tiptext,
- guint row, guint column,
- AlignAndDistribute &dialog,
- guint coeffIndex):
- Action(id, tiptext, row, column,
- dialog.align_table(), dialog),
- _index(coeffIndex),
- _dialog(dialog)
- {}
-
-private :
-
- virtual void on_button_click() {
- //Retreive selected objects
- SPDesktop *desktop = _dialog.getDesktop();
- if (!desktop) 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");
- Inkscape::Selection *selection = sp_desktop_selection(desktop);
- if (!selection) return;
+ using Inkscape::Util::GSListConstIterator;
+ std::list<SPItem *> selected;
+ selected.insert<GSListConstIterator<SPItem *> >(selected.end(), selection->itemList(), NULL);
+ if (selected.empty()) 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");
+ 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:
+ {
+ //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;
+ }
+ break;
+ }
- using Inkscape::Util::GSListConstIterator;
- std::list<SPItem *> selected;
- selected.insert<GSListConstIterator<SPItem *> >(selected.end(), selection->itemList(), NULL);
- if (selected.empty()) return;
+ case AlignAndDistribute::PAGE:
+ mp = Geom::Point(a.mx1 * sp_desktop_document(desktop)->getWidth(),
+ a.my1 * sp_desktop_document(desktop)->getHeight());
+ break;
- Geom::Point mp; //Anchor point
- AlignAndDistribute::AlignTarget target = _dialog.getAlignTarget();
- const Coeffs &a= _allCoeffs[_index];
- switch (target)
- {
- case AlignAndDistribute::LAST:
- case AlignAndDistribute::FIRST:
- case AlignAndDistribute::BIGGEST:
- case AlignAndDistribute::SMALLEST:
- {
- //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(
- _dialog.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;
- }
- 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;
}
+ break;
+ }
- case AlignAndDistribute::PAGE:
- mp = Geom::Point(a.mx1 * sp_desktop_document(desktop)->getWidth(),
- a.my1 * sp_desktop_document(desktop)->getHeight());
- 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;
- }
- 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;
}
+ 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;
+ default:
+ g_assert_not_reached ();
+ break;
+ }; // end of switch
+
+ // 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);
+
+ bool changed = false;
+ Geom::OptRect b;
+ if (sel_as_group)
+ b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds();
+
+ //Move each item in the selected list separately
+ for (std::list<SPItem *>::iterator it(selected.begin());
+ it != selected.end();
+ it++)
+ {
+ sp_desktop_document (desktop)->ensureUpToDate();
+ if (!sel_as_group)
+ b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds();
+ if (b) {
+ 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 );
+ if (LInfty(mp_rel) > 1e-9) {
+ sp_item_move_rel(*it, Geom::Translate(mp_rel));
+ changed = true;
}
- break;
}
+ }
- default:
- g_assert_not_reached ();
- break;
- }; // end of switch
-
- // 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);
+ // restore compensation setting
+ prefs->setInt("/options/clonecompensation/value", saved_compensation);
- bool changed = false;
- Geom::OptRect b;
- if (sel_as_group)
- b = !prefs_bbox ? selection->visualBounds() : selection->geometricBounds();
+ if (changed) {
+ DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
+ _("Align"));
+ }
- //Move each item in the selected list separately
- for (std::list<SPItem *>::iterator it(selected.begin());
- it != selected.end();
- it++)
- {
- sp_desktop_document (desktop)->ensureUpToDate();
- if (!sel_as_group)
- b = !prefs_bbox ? (*it)->desktopVisualBounds() : (*it)->desktopGeometricBounds();
- if (b) {
- 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 );
- if (LInfty(mp_rel) > 1e-9) {
- sp_item_move_rel(*it, Geom::Translate(mp_rel));
- changed = true;
- }
- }
- }
- // restore compensation setting
- prefs->setInt("/options/clonecompensation/value", saved_compensation);
+}
- if (changed) {
- DocumentUndo::done( sp_desktop_document(desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
- _("Align"));
- }
+ActionAlign::Coeffs const ActionAlign::_allCoeffs[11] = {
+ {1., 0., 0., 0., 0., 1., 0., 0., SP_VERB_ALIGN_HORIZONTAL_RIGHT_TO_ANCHOR},
+ {1., 0., 0., 0., 1., 0., 0., 0., SP_VERB_ALIGN_HORIZONTAL_LEFT},
+ {.5, .5, 0., 0., .5, .5, 0., 0., SP_VERB_ALIGN_HORIZONTAL_CENTER},
+ {0., 1., 0., 0., 0., 1., 0., 0., SP_VERB_ALIGN_HORIZONTAL_RIGHT},
+ {0., 1., 0., 0., 1., 0., 0., 0., SP_VERB_ALIGN_HORIZONTAL_LEFT_TO_ANCHOR},
+ {0., 0., 0., 1., 0., 0., 1., 0., SP_VERB_ALIGN_VERTICAL_BOTTOM_TO_ANCHOR},
+ {0., 0., 0., 1., 0., 0., 0., 1., SP_VERB_ALIGN_VERTICAL_TOP},
+ {0., 0., .5, .5, 0., 0., .5, .5, SP_VERB_ALIGN_VERTICAL_CENTER},
+ {0., 0., 1., 0., 0., 0., 1., 0., SP_VERB_ALIGN_VERTICAL_BOTTOM},
+ {0., 0., 1., 0., 0., 0., 0., 1., SP_VERB_ALIGN_VERTICAL_TOP_TO_ANCHOR},
+ {.5, .5, .5, .5, .5, .5, .5, .5, SP_VERB_ALIGN_VERTICAL_HORIZONTAL_CENTER}
+};
- }
- guint _index;
- AlignAndDistribute &_dialog;
+void ActionAlign::do_verb_action(SPDesktop *desktop, int verb)
+{
+ do_action(desktop, verb_to_coeff(verb));
+}
- static const Coeffs _allCoeffs[10];
+int ActionAlign::verb_to_coeff(int verb) {
-};
-ActionAlign::Coeffs const ActionAlign::_allCoeffs[10] = {
- {1., 0., 0., 0., 0., 1., 0., 0.},
- {1., 0., 0., 0., 1., 0., 0., 0.},
- {.5, .5, 0., 0., .5, .5, 0., 0.},
- {0., 1., 0., 0., 0., 1., 0., 0.},
- {0., 1., 0., 0., 1., 0., 0., 0.},
- {0., 0., 0., 1., 0., 0., 1., 0.},
- {0., 0., 0., 1., 0., 0., 0., 1.},
- {0., 0., .5, .5, 0., 0., .5, .5},
- {0., 0., 1., 0., 0., 0., 1., 0.},
- {0., 0., 1., 0., 0., 0., 0., 1.}
-};
+ for(guint i = 0; i < G_N_ELEMENTS(_allCoeffs); i++) {
+ if (_allCoeffs[i].verb_id == verb) {
+ return i;
+ }
+ }
+
+ return -1;
+}
BBoxSort::BBoxSort(SPItem *pItem, Geom::Rect const &bounds, Geom::Dim2 orientation, double kBegin, double kEnd) :
item(pItem),
@@ -781,7 +755,7 @@ struct Baselines
{}
};
-bool operator< (const Baselines &a, const Baselines &b)
+static bool operator< (const Baselines &a, const Baselines &b)
{
return (a._base[a._orientation] < b._base[b._orientation]);
}
@@ -899,14 +873,14 @@ private :
-void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*context*/, AlignAndDistribute *daad)
+static void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*context*/, AlignAndDistribute *daad)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop && sp_desktop_event_context(desktop))
daad->setMode(tools_active(desktop) == TOOLS_NODES);
}
-void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
+static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
{
daad->randomize_bbox = Geom::OptRect();
}
@@ -1066,7 +1040,6 @@ AlignAndDistribute::AlignAndDistribute()
//Rest of the widgetry
-#if WITH_GTKMM_2_24
_combo.append(_("Last selected"));
_combo.append(_("First selected"));
_combo.append(_("Biggest object"));
@@ -1074,36 +1047,34 @@ AlignAndDistribute::AlignAndDistribute()
_combo.append(_("Page"));
_combo.append(_("Drawing"));
_combo.append(_("Selection"));
-#else
- _combo.append_text(_("Last selected"));
- _combo.append_text(_("First selected"));
- _combo.append_text(_("Biggest object"));
- _combo.append_text(_("Smallest object"));
- _combo.append_text(_("Page"));
- _combo.append_text(_("Drawing"));
- _combo.append_text(_("Selection"));
-#endif
_combo.set_active(prefs->getInt("/dialogs/align/align-to", 6));
_combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change));
- _anchorBox.pack_start(_anchorLabel);
- _anchorBox.pack_start(_combo);
+ _anchorBox.pack_end(_combo, false, false);
+ _anchorBox.pack_end(_anchorLabel, false, false);
_selgrpLabel.set_mnemonic_widget(_selgrp);
- _selgrpBox.pack_start(_selgrpLabel);
- _selgrpBox.pack_start(_selgrp);
+ _selgrpBox.pack_end(_selgrp, false, false);
+ _selgrpBox.pack_end(_selgrpLabel, false, false);
_selgrp.set_active(prefs->getBool("/dialogs/align/sel-as-groups"));
_selgrp.signal_toggled().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_selgrp_toggled));
+ // Right align the buttons
+ _alignTableBox.pack_end(_alignTable, false, false);
+ _distributeTableBox.pack_end(_distributeTable, false, false);
+ _rearrangeTableBox.pack_end(_rearrangeTable, false, false);
+ _removeOverlapTableBox.pack_end(_removeOverlapTable, false, false);
+ _nodesTableBox.pack_end(_nodesTable, false, false);
+
_alignBox.pack_start(_anchorBox);
_alignBox.pack_start(_selgrpBox);
- _alignBox.pack_start(_alignTable);
+ _alignBox.pack_start(_alignTableBox);
_alignFrame.add(_alignBox);
- _distributeFrame.add(_distributeTable);
- _rearrangeFrame.add(_rearrangeTable);
- _removeOverlapFrame.add(_removeOverlapTable);
- _nodesFrame.add(_nodesTable);
+ _distributeFrame.add(_distributeTableBox);
+ _rearrangeFrame.add(_rearrangeTableBox);
+ _removeOverlapFrame.add(_removeOverlapTableBox);
+ _nodesFrame.add(_nodesTableBox);
Gtk::Box *contents = _getContents();
contents->set_spacing(4);
@@ -1123,6 +1094,9 @@ AlignAndDistribute::AlignAndDistribute()
g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this);
randomize_bbox = Geom::OptRect();
+ _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &AlignAndDistribute::setDesktop) );
+ _deskTrack.connect(GTK_WIDGET(gobj()));
+
show_all_children();
on_tool_changed (NULL, NULL, this); // set current mode
@@ -1133,11 +1107,23 @@ AlignAndDistribute::~AlignAndDistribute()
sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this);
for (std::list<Action *>::iterator it = _actionList.begin();
- it != _actionList.end();
- ++it)
+ it != _actionList.end(); ++it) {
delete *it;
+ }
+
+ _desktopChangeConn.disconnect();
+ _deskTrack.disconnect();
+}
+
+void AlignAndDistribute::setTargetDesktop(SPDesktop *desktop)
+{
+ if (_desktop != desktop) {
+ _desktop = desktop;
+ on_tool_changed (NULL, NULL, this);
+ }
}
+
void AlignAndDistribute::on_ref_change(){
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setInt("/dialogs/align/align-to", _combo.get_active_row_number());
@@ -1158,21 +1144,12 @@ void AlignAndDistribute::on_selgrp_toggled(){
void AlignAndDistribute::setMode(bool nodeEdit)
{
//Act on widgets used in node mode
-#if WITH_GTKMM_2_24
void ( Gtk::Widget::*mNode) () = nodeEdit ?
&Gtk::Widget::show_all : &Gtk::Widget::hide;
//Act on widgets used in selection mode
void ( Gtk::Widget::*mSel) () = nodeEdit ?
&Gtk::Widget::hide : &Gtk::Widget::show_all;
-#else
- void ( Gtk::Widget::*mNode) () = nodeEdit ?
- &Gtk::Widget::show_all : &Gtk::Widget::hide_all;
-
- //Act on widgets used in selection mode
- void ( Gtk::Widget::*mSel) () = nodeEdit ?
- &Gtk::Widget::hide_all : &Gtk::Widget::show_all;
-#endif
((_alignFrame).*(mSel))();
((_distributeFrame).*(mSel))();
@@ -1318,7 +1295,6 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
}
}
return master;
- break;
}
case SMALLEST:
@@ -1335,7 +1311,6 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
}
}
return master;
- break;
}
default:
@@ -1346,8 +1321,9 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
return master;
}
-AlignAndDistribute::AlignTarget AlignAndDistribute::getAlignTarget()const {
- return AlignTarget(_combo.get_active_row_number());
+AlignAndDistribute::AlignTarget AlignAndDistribute::getAlignTarget() {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ return AlignTarget(prefs->getInt("/dialogs/align/align-to", 6));
}
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index 59cc0dba4..c9165a83e 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -22,6 +22,7 @@
#include <gtkmm/comboboxtext.h>
#include <gtkmm/label.h>
#include "2geom/rect.h"
+#include "ui/dialog/desktop-tracker.h"
#if WITH_GTKMM_3_0
#include <gtkmm/checkbutton.h>
@@ -48,7 +49,9 @@ public:
enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION };
- AlignTarget getAlignTarget() const;
+
+
+ static AlignTarget getAlignTarget();
#if WITH_GTKMM_3_0
Gtk::Grid &align_table(){return _alignTable;}
@@ -64,7 +67,7 @@ public:
Gtk::Table &nodes_table(){return _nodesTable;}
#endif
- std::list<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal);
+ static std::list<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal);
void setMode(bool nodeEdit);
Geom::OptRect randomize_bbox;
@@ -106,6 +109,7 @@ protected:
void addBaselineButton(const Glib::ustring &id, const Glib::ustring tiptext,
guint row, guint col, Gtk::Table &table, Geom::Dim2 orientation, bool distribute);
#endif
+ void setTargetDesktop(SPDesktop *desktop);
std::list<Action *> _actionList;
UI::Widget::Frame _alignFrame, _distributeFrame, _rearrangeFrame, _removeOverlapFrame, _nodesFrame;
@@ -117,11 +121,20 @@ protected:
Gtk::HBox _anchorBox;
Gtk::HBox _selgrpBox;
Gtk::VBox _alignBox;
+ Gtk::HBox _alignTableBox;
+ Gtk::HBox _distributeTableBox;
+ Gtk::HBox _rearrangeTableBox;
+ Gtk::HBox _removeOverlapTableBox;
+ Gtk::HBox _nodesTableBox;
Gtk::Label _anchorLabel;
Gtk::Label _selgrpLabel;
Gtk::CheckButton _selgrp;
Gtk::ComboBoxText _combo;
+ SPDesktop *_desktop;
+ DesktopTracker _deskTrack;
+ sigc::connection _desktopChangeConn;
+
private:
AlignAndDistribute(AlignAndDistribute const &d);
AlignAndDistribute& operator=(AlignAndDistribute const &d);
@@ -138,6 +151,82 @@ struct BBoxSort
};
bool operator< (const BBoxSort &a, const BBoxSort &b);
+
+class Action {
+public :
+
+ Action(const Glib::ustring &id,
+ const Glib::ustring &tiptext,
+ guint row, guint column,
+ #if WITH_GTKMM_3_0
+ Gtk::Grid &parent,
+ #else
+ Gtk::Table &parent,
+ #endif
+ AlignAndDistribute &dialog);
+
+ virtual ~Action(){}
+
+ AlignAndDistribute &_dialog;
+
+private :
+ virtual void on_button_click(){}
+
+ Glib::ustring _id;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid &_parent;
+#else
+ Gtk::Table &_parent;
+#endif
+};
+
+
+class ActionAlign : public Action {
+public :
+ struct Coeffs {
+ double mx0, mx1, my0, my1;
+ double sx0, sx1, sy0, sy1;
+ int verb_id;
+ };
+ ActionAlign(const Glib::ustring &id,
+ const Glib::ustring &tiptext,
+ guint row, guint column,
+ AlignAndDistribute &dialog,
+ guint coeffIndex):
+ Action(id, tiptext, row, column,
+ dialog.align_table(), dialog),
+ _index(coeffIndex),
+ _dialog(dialog)
+ {}
+
+ /*
+ * Static function called to align from a keyboard shortcut
+ */
+ static void do_verb_action(SPDesktop *desktop, int verb);
+
+private :
+
+
+ virtual void on_button_click() {
+ //Retreive selected objects
+ SPDesktop *desktop = _dialog.getDesktop();
+ if (!desktop) return;
+
+ do_action(desktop, _index);
+ }
+
+ static void do_action(SPDesktop *desktop, int index);
+ static int verb_to_coeff(int verb);
+
+ guint _index;
+ AlignAndDistribute &_dialog;
+
+ static const Coeffs _allCoeffs[11];
+
+};
+
+
} // namespace Dialog
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/dialog/calligraphic-profile-rename.cpp b/src/ui/dialog/calligraphic-profile-rename.cpp
index c6633df0b..9ae22db2d 100644
--- a/src/ui/dialog/calligraphic-profile-rename.cpp
+++ b/src/ui/dialog/calligraphic-profile-rename.cpp
@@ -13,14 +13,16 @@
* Released under GNU GPL. Read the file 'COPYING' for more information
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "calligraphic-profile-rename.h"
#include <glibmm/i18n.h>
#include <gtkmm/stock.h>
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include "desktop.h"
namespace Inkscape {
@@ -28,40 +30,68 @@ namespace UI {
namespace Dialog {
CalligraphicProfileRename::CalligraphicProfileRename() :
+#if WITH_GTKMM_3_0
+ _layout_table(Gtk::manage(new Gtk::Grid())),
+#else
+ _layout_table(Gtk::manage(new Gtk::Table(1, 2))),
+#endif
_applied(false)
{
+ set_title(_("Edit profile"));
+
+#if WITH_GTKMM_3_0
+ Gtk::Box *mainVBox = get_content_area();
+ _layout_table->set_column_spacing(4);
+ _layout_table->set_row_spacing(4);
+#else
Gtk::Box *mainVBox = get_vbox();
- _layout_table.set_spacings(4);
- _layout_table.resize (1, 2);
+ _layout_table->set_spacings(4);
+#endif
_profile_name_entry.set_activates_default(true);
_profile_name_label.set_label(_("Profile name:"));
_profile_name_label.set_alignment(1.0, 0.5);
- _layout_table.attach(_profile_name_label,
+#if WITH_GTKMM_3_0
+ _layout_table->attach(_profile_name_label, 0, 0, 1, 1);
+
+ _profile_name_entry.set_hexpand();
+ _layout_table->attach(_profile_name_entry, 1, 0, 1, 1);
+#else
+ _layout_table->attach(_profile_name_label,
0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
- _layout_table.attach(_profile_name_entry,
+ _layout_table->attach(_profile_name_entry,
1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
- mainVBox->pack_start(_layout_table, false, false, 4);
+#endif
+
+ mainVBox->pack_start(*_layout_table, false, false, 4);
// Buttons
_close_button.set_use_stock(true);
_close_button.set_label(Gtk::Stock::CANCEL.id);
_close_button.set_can_default();
+ _delete_button.set_use_underline(true);
+ _delete_button.set_label(_("Delete"));
+ _delete_button.set_can_default();
+ _delete_button.set_visible(false);
+
_apply_button.set_use_underline(true);
_apply_button.set_label(_("Save"));
_apply_button.set_can_default();
_close_button.signal_clicked()
- .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_close));
+ .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_close));
+ _delete_button.signal_clicked()
+ .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_delete));
_apply_button.signal_clicked()
- .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_apply));
+ .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_apply));
signal_delete_event().connect( sigc::bind_return(
sigc::hide(sigc::mem_fun(*this, &CalligraphicProfileRename::_close)), true ) );
add_action_widget(_close_button, Gtk::RESPONSE_CLOSE);
+ add_action_widget(_delete_button, Gtk::RESPONSE_DELETE_EVENT);
add_action_widget(_apply_button, Gtk::RESPONSE_APPLY);
_apply_button.grab_default();
@@ -73,6 +103,15 @@ void CalligraphicProfileRename::_apply()
{
_profile_name = _profile_name_entry.get_text();
_applied = true;
+ _deleted = false;
+ _close();
+}
+
+void CalligraphicProfileRename::_delete()
+{
+ _profile_name = _profile_name_entry.get_text();
+ _applied = true;
+ _deleted = true;
_close();
}
@@ -81,11 +120,25 @@ void CalligraphicProfileRename::_close()
this->Gtk::Dialog::hide();
}
-void CalligraphicProfileRename::show(SPDesktop *desktop)
+void CalligraphicProfileRename::show(SPDesktop *desktop, const Glib::ustring profile_name)
{
CalligraphicProfileRename &dial = instance();
dial._applied=false;
+ dial._deleted=false;
dial.set_modal(true);
+
+ dial._profile_name = profile_name;
+ dial._profile_name_entry.set_text(profile_name);
+
+ if (profile_name.empty()) {
+ dial.set_title(_("Add profile"));
+ dial._delete_button.set_visible(false);
+
+ } else {
+ dial.set_title(_("Edit profile"));
+ dial._delete_button.set_visible(true);
+ }
+
desktop->setWindowTransient (dial.gobj());
dial.property_destroy_with_parent() = true;
// dial.Gtk::Dialog::show();
diff --git a/src/ui/dialog/calligraphic-profile-rename.h b/src/ui/dialog/calligraphic-profile-rename.h
index f0eb0b491..4ef71900b 100644
--- a/src/ui/dialog/calligraphic-profile-rename.h
+++ b/src/ui/dialog/calligraphic-profile-rename.h
@@ -11,10 +11,22 @@
#ifndef INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
#define INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <gtkmm/dialog.h>
#include <gtkmm/entry.h>
#include <gtkmm/label.h>
-#include <gtkmm/table.h>
+
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
+
class SPDesktop;
namespace Inkscape {
@@ -29,10 +41,13 @@ public:
return "CalligraphicProfileRename";
}
- static void show(SPDesktop *desktop);
+ static void show(SPDesktop *desktop, const Glib::ustring profile_name);
static bool applied() {
return instance()._applied;
}
+ static bool deleted() {
+ return instance()._deleted;
+ }
static Glib::ustring getProfileName() {
return instance()._profile_name;
}
@@ -40,14 +55,23 @@ public:
protected:
void _close();
void _apply();
+ void _delete();
Gtk::Label _profile_name_label;
Gtk::Entry _profile_name_entry;
- Gtk::Table _layout_table;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid* _layout_table;
+#else
+ Gtk::Table* _layout_table;
+#endif
+
Gtk::Button _close_button;
+ Gtk::Button _delete_button;
Gtk::Button _apply_button;
Glib::ustring _profile_name;
bool _applied;
+ bool _deleted;
private:
static CalligraphicProfileRename &instance() {
static CalligraphicProfileRename instance_;
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index 47ec03b30..e971cfb09 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -815,9 +815,15 @@ CloneTiler::CloneTiler (void) :
GtkWidget *frame = gtk_frame_new (_("1. Pick from the drawing:"));
gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *table = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(table), 4);
+ gtk_grid_set_column_spacing(GTK_GRID(table), 6);
+#else
GtkWidget *table = gtk_table_new (3, 3, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+#endif
gtk_container_add(GTK_CONTAINER(frame), table);
@@ -893,9 +899,16 @@ CloneTiler::CloneTiler (void) :
GtkWidget *frame = gtk_frame_new (_("2. Tweak the picked value:"));
gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, VB_MARGIN);
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *table = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(table), 4);
+ gtk_grid_set_column_spacing(GTK_GRID(table), 6);
+#else
GtkWidget *table = gtk_table_new (4, 2, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+#endif
+
gtk_container_add(GTK_CONTAINER(frame), table);
{
@@ -935,10 +948,15 @@ CloneTiler::CloneTiler (void) :
GtkWidget *frame = gtk_frame_new (_("3. Apply the value to the clones':"));
gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0);
-
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *table = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(table), 4);
+ gtk_grid_set_column_spacing(GTK_GRID(table), 6);
+#else
GtkWidget *table = gtk_table_new (2, 2, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+#endif
gtk_container_add(GTK_CONTAINER(frame), table);
{
@@ -987,10 +1005,17 @@ CloneTiler::CloneTiler (void) :
// Rows/columns, width/height
{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *table = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(table), 4);
+ gtk_grid_set_column_spacing(GTK_GRID(table), 6);
+#else
GtkWidget *table = gtk_table_new (2, 2, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN);
gtk_table_set_row_spacings (GTK_TABLE (table), 4);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+#endif
+
+ gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN);
gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0);
{
@@ -1326,8 +1351,8 @@ void CloneTiler::on_picker_color_changed(guint rgba)
void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg)
{
- GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles");
- GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status");
+ GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles"));
+ GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status"));
if (selection->isEmpty()) {
gtk_widget_set_sensitive (buttons, FALSE);
@@ -2204,7 +2229,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
desktop->setWaitingCursor();
// set statusbar text
- GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status");
+ GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status"));
gtk_label_set_markup (GTK_LABEL(status), _("<small>Creating tiled clones...</small>"));
gtk_widget_queue_draw(GTK_WIDGET(status));
gdk_window_process_all_updates();
@@ -2807,15 +2832,29 @@ void CloneTiler::clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, fl
{
GtkWidget *a = gtk_alignment_new (align, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(a), widget);
- gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, (GtkAttachOptions)4, (GtkAttachOptions)0, 0, 0 );
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_set_halign(table, GTK_ALIGN_FILL);
+ gtk_widget_set_valign(table, GTK_ALIGN_CENTER);
+ gtk_grid_attach(GTK_GRID(table), a, col, row, 1, 1);
+#else
+ gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, GTK_FILL, (GtkAttachOptions)0, 0, 0 );
+#endif
}
GtkWidget * CloneTiler::clonetiler_table_x_y_rand(int values)
{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *table = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(table), 6);
+ gtk_grid_set_column_spacing(GTK_GRID(table), 8);
+#else
GtkWidget *table = gtk_table_new (values + 2, 5, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN);
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
gtk_table_set_col_spacings (GTK_TABLE (table), 8);
+#endif
+
+ gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN);
{
#if GTK_CHECK_VERSION(3,0,0)
@@ -2870,10 +2909,10 @@ void CloneTiler::clonetiler_pick_switched(GtkToggleButton */*tb*/, gpointer data
}
-void CloneTiler::clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg)
+void CloneTiler::clonetiler_switch_to_create(GtkToggleButton * /*tb*/, GtkWidget *dlg)
{
- GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols");
- GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight");
+ GtkWidget *rowscols = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "rowscols"));
+ GtkWidget *widthheight = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "widthheight"));
if (rowscols) {
gtk_widget_set_sensitive (rowscols, TRUE);
@@ -2887,10 +2926,10 @@ void CloneTiler::clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget
}
-void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg)
+void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton * /*tb*/, GtkWidget *dlg)
{
- GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols");
- GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight");
+ GtkWidget *rowscols = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "rowscols"));
+ GtkWidget *widthheight = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "widthheight"));
if (rowscols) {
gtk_widget_set_sensitive (rowscols, FALSE);
@@ -2929,7 +2968,7 @@ void CloneTiler::clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u
void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg)
{
- GtkWidget *vvb = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "dotrace");
+ GtkWidget *vvb = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "dotrace"));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setBool(prefs_path + "dotrace", gtk_toggle_button_get_active (tb));
diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp
index b0da4aecc..e09d9b1d1 100644
--- a/src/ui/dialog/color-item.cpp
+++ b/src/ui/dialog/color-item.cpp
@@ -12,8 +12,8 @@
*/
#include <errno.h>
-#include <glibmm/i18n.h>
#include <gtkmm/label.h>
+#include <glibmm/i18n.h>
#include <cairo.h>
#include <gtk/gtk.h>
@@ -35,6 +35,7 @@
#include "xml/node.h"
#include "xml/repr.h"
#include "verbs.h"
+#include "widgets/gradient-vector.h"
#include "color.h" // for SP_RGBA32_U_COMPOSE
@@ -143,7 +144,7 @@ static void dieDieDie( GObject *obj, gpointer user_data )
g_message("die die die %p %p", obj, user_data );
}
-static bool getBlock( std::string& dst, guchar ch, std::string const str )
+static bool getBlock( std::string& dst, guchar ch, std::string const & str )
{
bool good = false;
std::string::size_type pos = str.find(ch);
@@ -355,6 +356,23 @@ void ColorItem::setGradient(SPGradient *grad)
_grad = grad;
// TODO regen and push to listeners
}
+
+ setName( gr_prepare_label(_grad) );
+}
+
+void ColorItem::setName(const Glib::ustring name)
+{
+ //def.descr = name;
+
+ for ( std::vector<Gtk::Widget*>::iterator it = _previews.begin(); it != _previews.end(); ++it ) {
+ Gtk::Widget* widget = *it;
+ if ( IS_EEK_PREVIEW(widget->gobj()) ) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str());
+ }
+ else if ( GTK_IS_LABEL(widget->gobj()) ) {
+ gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str());
+ }
+ }
}
void ColorItem::setPattern(cairo_pattern_t *pattern)
@@ -366,6 +384,7 @@ void ColorItem::setPattern(cairo_pattern_t *pattern)
cairo_pattern_destroy(_pattern);
}
_pattern = pattern;
+
_updatePreviews();
}
@@ -546,7 +565,7 @@ void ColorItem::_regenPreview(EekPreview * preview)
| (_isLive ? PREVIEW_LINK_OTHER:0)) );
}
-Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio)
+Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border)
{
Gtk::Widget* widget = 0;
if ( style == PREVIEW_STYLE_BLURB) {
@@ -554,46 +573,21 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewS
lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
widget = lbl;
} else {
-// Glib::ustring blank(" ");
-// if ( size == Inkscape::ICON_SIZE_MENU || size == Inkscape::ICON_SIZE_DECORATION ) {
-// blank = " ";
-// }
-
GtkWidget* eekWidget = eek_preview_new();
EekPreview * preview = EEK_PREVIEW(eekWidget);
Gtk::Widget* newBlot = Glib::wrap(eekWidget);
-
_regenPreview(preview);
- eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::PreviewSize)size, ratio );
+ eek_preview_set_details( preview,
+ (::ViewType)view,
+ (::PreviewSize)size,
+ ratio,
+ border );
def.addCallback( _colorDefChanged, this );
-
- GValue val = {0, {{0}, {0}}};
- g_value_init( &val, G_TYPE_BOOLEAN );
- g_value_set_boolean( &val, FALSE );
- g_object_set_property( G_OBJECT(preview), "focus-on-click", &val );
-
-/*
- Gtk::Button *btn = new Gtk::Button(blank);
- Gdk::Color color;
- color.set_rgb((_r << 8)|_r, (_g << 8)|_g, (_b << 8)|_b);
- btn->modify_bg(Gtk::STATE_NORMAL, color);
- btn->modify_bg(Gtk::STATE_ACTIVE, color);
- btn->modify_bg(Gtk::STATE_PRELIGHT, color);
- btn->modify_bg(Gtk::STATE_SELECTED, color);
-
- Gtk::Widget* newBlot = btn;
-*/
-
+ eek_preview_set_focus_on_click(preview, FALSE);
newBlot->set_tooltip_text(def.descr);
-/*
- newBlot->signal_clicked().connect( sigc::mem_fun(*this, &ColorItem::buttonClicked) );
-
- sigc::signal<void> type_signal_something;
-*/
-
g_signal_connect( G_OBJECT(newBlot->gobj()),
"clicked",
G_CALLBACK(handleClick),
@@ -655,26 +649,6 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewS
G_CALLBACK(handleLeaveNotify),
this);
-// g_signal_connect( G_OBJECT(newBlot->gobj()),
-// "drag-drop",
-// G_CALLBACK(dragDropColorData),
-// this);
-
- if ( def.isEditable() )
- {
-// gtk_drag_dest_set( GTK_WIDGET(newBlot->gobj()),
-// GTK_DEST_DEFAULT_ALL,
-// destColorTargets,
-// G_N_ELEMENTS(destColorTargets),
-// GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
-
-
-// g_signal_connect( G_OBJECT(newBlot->gobj()),
-// "drag-data-received",
-// G_CALLBACK(_dropDataIn),
-// this );
- }
-
g_signal_connect( G_OBJECT(newBlot->gobj()),
"destroy",
G_CALLBACK(dieDieDie),
diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h
index e6f5c7b76..3a0b33193 100644
--- a/src/ui/dialog/color-item.h
+++ b/src/ui/dialog/color-item.h
@@ -53,12 +53,14 @@ public:
virtual Gtk::Widget* getPreview(PreviewStyle style,
ViewType view,
::PreviewSize size,
- guint ratio);
+ guint ratio,
+ guint border);
void buttonClicked(bool secondary = false);
void setGradient(SPGradient *grad);
SPGradient * getGradient() const { return _grad; }
void setPattern(cairo_pattern_t *pattern);
+ void setName(const Glib::ustring name);
void setState( bool fill, bool stroke );
bool isFill() { return _isFill; }
diff --git a/src/ui/dialog/debug.cpp b/src/ui/dialog/debug.cpp
index a026f3501..d127261c0 100644
--- a/src/ui/dialog/debug.cpp
+++ b/src/ui/dialog/debug.cpp
@@ -13,13 +13,13 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
#include <gtkmm/box.h>
#include <gtkmm/dialog.h>
#include <gtkmm/textview.h>
#include <gtkmm/button.h>
#include <gtkmm/menubar.h>
#include <gtkmm/scrolledwindow.h>
+#include <glibmm/i18n.h>
#include "debug.h"
@@ -69,7 +69,11 @@ DebugDialogImpl::DebugDialogImpl()
set_title(_("Messages"));
set_size_request(300, 400);
+#if WITH_GTKMM_3_0
+ Gtk::Box *mainVBox = get_content_area();
+#else
Gtk::Box *mainVBox = get_vbox();
+#endif
//## Add a menu for clear()
Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem(_("_File"), true));
@@ -126,7 +130,7 @@ void DebugDialogImpl::show()
{
//call super()
Gtk::Dialog::show();
- //sp_transientize((GtkWidget *)gobj()); //Make transient
+ //sp_transientize(GTK_WIDGET(gobj())); //Make transient
raise();
Gtk::Dialog::present();
}
@@ -171,10 +175,10 @@ void DebugDialog::showInstance()
/*##### THIS IS THE IMPORTANT PART ##### */
-void dialogLoggingFunction(const gchar */*log_domain*/,
- GLogLevelFlags /*log_level*/,
- const gchar *messageText,
- gpointer user_data)
+static void dialogLoggingFunction(const gchar */*log_domain*/,
+ GLogLevelFlags /*log_level*/,
+ const gchar *messageText,
+ gpointer user_data)
{
DebugDialogImpl *dlg = static_cast<DebugDialogImpl *>(user_data);
dlg->message(messageText);
diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h
index 0c8af66bf..c219e8d98 100644
--- a/src/ui/dialog/desktop-tracker.h
+++ b/src/ui/dialog/desktop-tracker.h
@@ -16,7 +16,7 @@ class SPDesktop;
namespace Inkscape {
-class Application;
+struct Application;
namespace UI {
namespace Dialog {
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index 60011ca9d..993f48d8f 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -33,6 +33,7 @@
#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"
#include "ui/dialog/transformation.h"
@@ -52,10 +53,7 @@
#include "ui/dialog/export.h"
#include "ui/dialog/xml-tree.h"
#include "ui/dialog/clonetiler.h"
-
-#ifdef ENABLE_SVG_FONTS
#include "ui/dialog/svg-fonts-dialog.h"
-#endif // ENABLE_SVG_FONTS
namespace Inkscape {
namespace UI {
@@ -117,10 +115,9 @@ DialogManager::DialogManager() {
registerFactory("ObjectProperties", &create<ObjectProperties, FloatingBehavior>);
// registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>);
registerFactory("Script", &create<ScriptDialog, FloatingBehavior>);
-#ifdef ENABLE_SVG_FONTS
registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>);
-#endif
registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>);
+ registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>);
registerFactory("TileDialog", &create<TileDialog, FloatingBehavior>);
registerFactory("Trace", &create<TraceDialog, FloatingBehavior>);
registerFactory("Transformation", &create<Transformation, FloatingBehavior>);
@@ -152,10 +149,9 @@ DialogManager::DialogManager() {
registerFactory("ObjectProperties", &create<ObjectProperties, DockBehavior>);
// registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>);
registerFactory("Script", &create<ScriptDialog, DockBehavior>);
-#ifdef ENABLE_SVG_FONTS
registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>);
-#endif
registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>);
+ registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>);
registerFactory("TileDialog", &create<TileDialog, DockBehavior>);
registerFactory("Trace", &create<TraceDialog, DockBehavior>);
registerFactory("Transformation", &create<Transformation, DockBehavior>);
diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp
index f5f712103..f27d344fa 100644
--- a/src/ui/dialog/dialog.cpp
+++ b/src/ui/dialog/dialog.cpp
@@ -61,7 +61,7 @@ void sp_dialog_shutdown(GObject * /*object*/, gpointer dlgPtr)
}
-void hideCallback(GObject * /*object*/, gpointer dlgPtr)
+static void hideCallback(GObject * /*object*/, gpointer dlgPtr)
{
g_return_if_fail( dlgPtr != NULL );
@@ -69,7 +69,7 @@ void hideCallback(GObject * /*object*/, gpointer dlgPtr)
dlg->onHideF12();
}
-void unhideCallback(GObject * /*object*/, gpointer dlgPtr)
+static void unhideCallback(GObject * /*object*/, gpointer dlgPtr)
{
g_return_if_fail( dlgPtr != NULL );
diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h
index 025e9eb58..ec5d203bc 100644
--- a/src/ui/dialog/dialog.h
+++ b/src/ui/dialog/dialog.h
@@ -21,7 +21,7 @@ class SPDesktop;
namespace Inkscape {
class Selection;
-class Application;
+struct Application;
}
namespace Inkscape {
diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp
index 6318ffbbb..efe25d843 100644
--- a/src/ui/dialog/document-metadata.cpp
+++ b/src/ui/dialog/document-metadata.cpp
@@ -61,13 +61,30 @@ DocumentMetadata::getInstance()
DocumentMetadata::DocumentMetadata()
+#if WITH_GTKMM_3_0
+ : UI::Widget::Panel ("", "/dialogs/documentmetadata", SP_VERB_DIALOG_METADATA)
+#else
: UI::Widget::Panel ("", "/dialogs/documentmetadata", SP_VERB_DIALOG_METADATA),
_page_metadata1(1, 1), _page_metadata2(1, 1)
+#endif
{
hide();
_getContents()->set_spacing (4);
_getContents()->pack_start(_notebook, true, true);
+ _page_metadata1.set_border_width(2);
+ _page_metadata2.set_border_width(2);
+
+#if WITH_GTKMM_3_0
+ _page_metadata1.set_column_spacing(2);
+ _page_metadata2.set_column_spacing(2);
+ _page_metadata1.set_row_spacing(2);
+ _page_metadata2.set_row_spacing(2);
+#else
+ _page_metadata1.set_spacings(2);
+ _page_metadata2.set_spacings(2);
+#endif
+
_notebook.append_page(_page_metadata1, _("Metadata"));
_notebook.append_page(_page_metadata2, _("License"));
@@ -98,50 +115,6 @@ DocumentMetadata::~DocumentMetadata()
delete (*it);
}
-//========================================================================
-
-/**
- * Helper function that attachs widgets in a 3xn table. The widgets come in an
- * array that has two entries per table row. The two entries code for four
- * possible cases: (0,0) means insert space in first column; (0, non-0) means
- * widget in columns 2-3; (non-0, 0) means label in columns 1-3; and
- * (non-0, non-0) means two widgets in columns 2 and 3.
- */
-inline void attach_all(Gtk::Table &table, const Gtk::Widget *arr[], unsigned size, int start = 0)
-{
- for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2)
- {
- if (arr[i] && arr[i+1])
- {
- table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- }
- else
- {
- if (arr[i+1])
- table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- else if (arr[i])
- {
- Gtk::Label& label = static_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i]));
- label.set_alignment (0.0);
- table.attach (label, 0, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- }
- else
- {
- Gtk::HBox *space = manage (new Gtk::HBox);
- space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- table.attach (*space, 0, 1, r, r+1,
- (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0);
- }
- }
- ++r;
- }
-}
-
void
DocumentMetadata::build_metadata()
{
@@ -152,7 +125,14 @@ DocumentMetadata::build_metadata()
Gtk::Label *label = manage (new Gtk::Label);
label->set_markup (_("<b>Dublin Core Entities</b>"));
label->set_alignment (0.0);
- _page_metadata1.table().attach (*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ label->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1.attach(*label, 0, 0, 3, 1);
+#else
+ _page_metadata1.attach(*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
+
/* add generic metadata entry areas */
struct rdf_work_entity_t * entity;
int row = 1;
@@ -162,9 +142,22 @@ DocumentMetadata::build_metadata()
_rdflist.push_back (w);
Gtk::HBox *space = manage (new Gtk::HBox);
space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_metadata1.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata1.table().attach (w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata1.table().attach (*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ space->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1.attach(*space, 0, row, 1, 1);
+
+ w->_label.set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1.attach(w->_label, 1, row, 1, 1);
+
+ w->_packable->set_hexpand();
+ w->_packable->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1.attach(*w->_packable, 2, row, 1, 1);
+#else
+ _page_metadata1.attach(*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata1.attach(w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata1.attach(*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+#endif
}
}
@@ -174,14 +167,31 @@ DocumentMetadata::build_metadata()
Gtk::Label *llabel = manage (new Gtk::Label);
llabel->set_markup (_("<b>License</b>"));
llabel->set_alignment (0.0);
- _page_metadata2.table().attach (*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ llabel->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2.attach(*llabel, 0, row, 3, 1);
+#else
+ _page_metadata2.attach(*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
+
/* add license selector pull-down and URI */
++row;
_licensor.init (_wr);
Gtk::HBox *space = manage (new Gtk::HBox);
space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_metadata2.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata2.table().attach (_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ space->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2.attach(*space, 0, row, 1, 1);
+
+ _licensor.set_hexpand();
+ _licensor.set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2.attach(_licensor, 1, row, 2, 1);
+#else
+ _page_metadata2.attach(*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata2.attach(_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
}
/**
diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h
index f201679b5..3b7ed1ec8 100644
--- a/src/ui/dialog/document-metadata.h
+++ b/src/ui/dialog/document-metadata.h
@@ -13,12 +13,22 @@
#ifndef INKSCAPE_UI_DIALOG_DOCUMENT_METADATA_H
#define INKSCAPE_UI_DIALOG_DOCUMENT_METADATA_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <list>
#include <stddef.h>
#include "ui/widget/panel.h"
#include <gtkmm/notebook.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include "ui/widget/licensor.h"
-#include "ui/widget/notebook-page.h"
#include "ui/widget/registry.h"
namespace Inkscape {
@@ -51,8 +61,13 @@ protected:
Gtk::Notebook _notebook;
- UI::Widget::NotebookPage _page_metadata1;
- UI::Widget::NotebookPage _page_metadata2;
+#if WITH_GTKMM_3_0
+ Gtk::Grid _page_metadata1;
+ Gtk::Grid _page_metadata2;
+#else
+ Gtk::Table _page_metadata1;
+ Gtk::Table _page_metadata2;
+#endif
//---------------------------------------------------------------
RDElist _rdflist;
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 2d79c6dd7..d335fb303 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -22,6 +22,7 @@
# include <config.h>
#endif
+#include "ui/widget/notebook-page.h"
#include "document-properties.h"
#include "display/canvas-grid.h"
#include "document.h"
@@ -50,8 +51,9 @@
#include "color-profile.h"
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-#include <gtkmm/stock.h>
#include <gtkmm/imagemenuitem.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
using std::pair;
@@ -90,20 +92,20 @@ DocumentProperties& DocumentProperties::getInstance()
DocumentProperties::DocumentProperties()
: UI::Widget::Panel ("", "/dialogs/documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
- _page_page(1, 1, true, true),
- _page_guides(1, 1),
- _page_snap(1, 1),
- _page_cms(1, 1),
- _page_scripting(1, 1),
- _page_external_scripts(1, 1),
- _page_embedded_scripts(1, 1),
- _page_metadata1(1, 1),
- _page_metadata2(1, 1),
+ _page_page(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))),
+ _page_guides(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_snap(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_cms(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_scripting(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_external_scripts(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_embedded_scripts(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_metadata1(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
+ _page_metadata2(Gtk::manage(new UI::Widget::NotebookPage(1, 1))),
//---------------------------------------------------------------
_rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false),
_rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false),
_rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false),
- _rcp_bg(_("Back_ground:"), _("Background color"), _("Color and transparency of the page background (also used for bitmap export)"), "pagecolor", "inkscape:pageopacity", _wr),
+ _rcp_bg(_("Back_ground color:"), _("Background color"), _("Color of the page background. Note: transparency setting ignored while editing but used when exporting to bitmap."), "pagecolor", "inkscape:pageopacity", _wr),
_rcp_bord(_("Border _color:"), _("Page border color"), _("Color of the page border"), "bordercolor", "borderopacity", _wr),
_rum_deflt(_("Default _units:"), "inkscape:document-units", _wr),
_page_sizer(_wr),
@@ -141,15 +143,16 @@ DocumentProperties::DocumentProperties()
_getContents()->set_spacing (4);
_getContents()->pack_start(_notebook, true, true);
- _notebook.append_page(_page_page, _("Page"));
- _notebook.append_page(_page_guides, _("Guides"));
+ _notebook.append_page(*_page_page, _("Page"));
+ _notebook.append_page(*_page_guides, _("Guides"));
_notebook.append_page(_grids_vbox, _("Grids"));
- _notebook.append_page(_page_snap, _("Snap"));
- _notebook.append_page(_page_cms, _("Color"));
- _notebook.append_page(_page_scripting, _("Scripting"));
- _notebook.append_page(_page_metadata1, _("Metadata"));
- _notebook.append_page(_page_metadata2, _("License"));
+ _notebook.append_page(*_page_snap, _("Snap"));
+ _notebook.append_page(*_page_cms, _("Color"));
+ _notebook.append_page(*_page_scripting, _("Scripting"));
+ _notebook.append_page(*_page_metadata1, _("Metadata"));
+ _notebook.append_page(*_page_metadata2, _("License"));
+ _wr.setUpdating (true);
build_page();
build_guides();
build_gridspage();
@@ -159,6 +162,7 @@ DocumentProperties::DocumentProperties()
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
build_scripting();
build_metadata();
+ _wr.setUpdating (false);
_grids_button_new.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onNewGrid));
_grids_button_remove.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onRemoveGrid));
@@ -201,41 +205,98 @@ DocumentProperties::~DocumentProperties()
* widget in columns 2-3; (non-0, 0) means label in columns 1-3; and
* (non-0, non-0) means two widgets in columns 2 and 3.
*/
-inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned const n, int start = 0)
+#if WITH_GTKMM_3_0
+inline void attach_all(Gtk::Grid &table, Gtk::Widget *const arr[], unsigned const n, int start = 0, int docum_prop_flag = 0)
+#else
+inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned const n, int start = 0, int docum_prop_flag = 0)
+#endif
{
- for (unsigned i = 0, r = start; i < n; i += 2)
- {
- if (arr[i] && arr[i+1])
- {
- table.attach(*arr[i], 1, 2, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- table.attach(*arr[i+1], 2, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- }
- else
- {
+ for (unsigned i = 0, r = start; i < n; i += 2) {
+ if (arr[i] && arr[i+1]) {
+#if WITH_GTKMM_3_0
+ arr[i]->set_hexpand();
+ arr[i+1]->set_hexpand();
+ arr[i]->set_valign(Gtk::ALIGN_CENTER);
+ arr[i+1]->set_valign(Gtk::ALIGN_CENTER);
+ table.attach(*arr[i], 1, r, 1, 1);
+ table.attach(*arr[i+1], 2, r, 1, 1);
+#else
+ table.attach(*arr[i], 1, 2, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+ table.attach(*arr[i+1], 2, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+#endif
+ } else {
if (arr[i+1]) {
Gtk::AttachOptions yoptions = (Gtk::AttachOptions)0;
if (dynamic_cast<Inkscape::UI::Widget::PageSizer*>(arr[i+1])) {
// only the PageSizer in Document Properties|Page should be stretched vertically
yoptions = Gtk::FILL|Gtk::EXPAND;
}
- table.attach(*arr[i+1], 1, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, yoptions, 0,0);
- }
- else if (arr[i])
- {
+ if (docum_prop_flag) {
+ if( i==(n-4) || i==(n-6) ) {
+#if WITH_GTKMM_3_0
+ arr[i+1]->set_hexpand();
+ arr[i+1]->set_margin_left(20);
+ arr[i+1]->set_margin_right(20);
+
+ if (yoptions & Gtk::EXPAND)
+ arr[i+1]->set_vexpand();
+ else
+ arr[i+1]->set_valign(Gtk::ALIGN_CENTER);
+
+ table.attach(*arr[i+1], 1, r, 2, 1);
+#else
+ table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 20,0);
+#endif
+ } else {
+#if WITH_GTKMM_3_0
+ arr[i+1]->set_hexpand();
+
+ if (yoptions & Gtk::EXPAND)
+ arr[i+1]->set_vexpand();
+ else
+ arr[i+1]->set_valign(Gtk::ALIGN_CENTER);
+
+ table.attach(*arr[i+1], 1, r, 2, 1);
+#else
+ table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 0,0);
+#endif
+ }
+ } else {
+#if WITH_GTKMM_3_0
+ arr[i+1]->set_hexpand();
+
+ if (yoptions & Gtk::EXPAND)
+ arr[i+1]->set_vexpand();
+ else
+ arr[i+1]->set_valign(Gtk::ALIGN_CENTER);
+
+ table.attach(*arr[i+1], 1, r, 2, 1);
+#else
+ table.attach(*arr[i+1], 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, yoptions, 0,0);
+#endif
+ }
+ } else if (arr[i]) {
Gtk::Label& label = reinterpret_cast<Gtk::Label&>(*arr[i]);
label.set_alignment (0.0);
- table.attach (label, 0, 3, r, r+1,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
- }
- else
- {
+
+#if WITH_GTKMM_3_0
+ label.set_hexpand();
+ label.set_valign(Gtk::ALIGN_CENTER);
+ table.attach(label, 0, r, 3, 1);
+#else
+ table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+#endif
+ } else {
Gtk::HBox *space = manage (new Gtk::HBox);
space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- table.attach (*space, 0, 1, r, r+1,
- (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ space->set_halign(Gtk::ALIGN_CENTER);
+ space->set_valign(Gtk::ALIGN_CENTER);
+ table.attach(*space, 0, r, 1, 1);
+#else
+ table.attach (*space, 0, 1, r, r+1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0);
+#endif
}
}
++r;
@@ -244,10 +305,12 @@ inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned con
void DocumentProperties::build_page()
{
- _page_page.show();
+ _page_page->show();
Gtk::Label* label_gen = manage (new Gtk::Label);
label_gen->set_markup (_("<b>General</b>"));
+ Gtk::Label* label_col = manage (new Gtk::Label);
+ label_col->set_markup (_("<b>Color</b>"));
Gtk::Label* label_bor = manage (new Gtk::Label);
label_bor->set_markup (_("<b>Border</b>"));
Gtk::Label *label_for = manage (new Gtk::Label);
@@ -258,6 +321,7 @@ void DocumentProperties::build_page()
{
label_gen, 0,
0, &_rum_deflt,
+ label_col, 0,
_rcp_bg._label, &_rcp_bg,
0, 0,
label_for, 0,
@@ -270,12 +334,17 @@ void DocumentProperties::build_page()
_rcp_bord._label, &_rcp_bord,
};
- attach_all(_page_page.table(), widget_array, G_N_ELEMENTS(widget_array));
+ std::list<Gtk::Widget*> _slaveList;
+ _slaveList.push_back(&_rcb_bord);
+ _slaveList.push_back(&_rcb_shad);
+ _rcb_canb.setSlaveWidgets(_slaveList);
+
+ attach_all(_page_page->table(), widget_array, G_N_ELEMENTS(widget_array),0,1);
}
void DocumentProperties::build_guides()
{
- _page_guides.show();
+ _page_guides->show();
Gtk::Label *label_gui = manage (new Gtk::Label);
label_gui->set_markup (_("<b>Guides</b>"));
@@ -288,12 +357,12 @@ void DocumentProperties::build_guides()
_rcp_hgui._label, &_rcp_hgui
};
- attach_all(_page_guides.table(), widget_array, G_N_ELEMENTS(widget_array));
+ attach_all(_page_guides->table(), widget_array, G_N_ELEMENTS(widget_array));
}
void DocumentProperties::build_snap()
{
- _page_snap.show();
+ _page_snap->show();
Gtk::Label *label_o = manage (new Gtk::Label);
label_o->set_markup (_("<b>Snap to objects</b>"));
@@ -322,27 +391,19 @@ void DocumentProperties::build_snap()
0, &_rcb_tang
};
- attach_all(_page_snap.table(), array, G_N_ELEMENTS(array));
+ attach_all(_page_snap->table(), array, G_N_ELEMENTS(array));
}
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
/// Populates the available color profiles combo box
void DocumentProperties::populate_available_profiles(){
-#if WITH_GTKMM_2_24
_combo_avail.remove_all(); // Clear any existing items in the combo box
-#else
- _combo_avail.clear_items(); // Clear any existing items in the combo box
-#endif
// Iterate through the list of profiles and add the name to the combo box.
std::vector<std::pair<Glib::ustring, Glib::ustring> > pairs = ColorProfile::getProfileFilesWithNames();
for ( std::vector<std::pair<Glib::ustring, Glib::ustring> >::const_iterator it = pairs.begin(); it != pairs.end(); ++it ) {
Glib::ustring name = it->second;
-#if WITH_GTKMM_2_24
_combo_avail.append(name);
-#else
- _combo_avail.append_text(name);
-#endif
}
}
@@ -535,7 +596,7 @@ void DocumentProperties::removeSelectedProfile(){
void DocumentProperties::build_cms()
{
- _page_cms.show();
+ _page_cms->show();
Gtk::Label *label_link= manage (new Gtk::Label("", Gtk::ALIGN_START));
label_link->set_markup (_("<b>Linked Color Profiles:</b>"));
Gtk::Label *label_avail = manage (new Gtk::Label("", Gtk::ALIGN_START));
@@ -547,26 +608,75 @@ void DocumentProperties::build_cms()
_unlink_btn.set_tooltip_text(_("Unlink Profile"));
_unlink_btn.set_image(*manage(Glib::wrap(gtk_image_new_from_stock ( GTK_STOCK_REMOVE, GTK_ICON_SIZE_SMALL_TOOLBAR ) )));
- _page_cms.set_spacing(4);
+ _page_cms->set_spacing(4);
gint row = 0;
label_link->set_alignment(0.0);
- _page_cms.table().attach(*label_link, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_link->set_hexpand();
+ label_link->set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(*label_link, 0, row, 3, 1);
+#else
+ _page_cms->table().attach(*label_link, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_cms.table().attach(_LinkedProfilesListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ _LinkedProfilesListScroller.set_hexpand();
+ _LinkedProfilesListScroller.set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(_LinkedProfilesListScroller, 0, row, 3, 1);
+#else
+ _page_cms->table().attach(_LinkedProfilesListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
Gtk::HBox* spacer = Gtk::manage(new Gtk::HBox());
spacer->set_size_request(SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_cms.table().attach(*spacer, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ spacer->set_hexpand();
+ spacer->set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(*spacer, 0, row, 3, 1);
+#else
+ _page_cms->table().attach(*spacer, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
label_avail->set_alignment(0.0);
- _page_cms.table().attach(*label_avail, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_avail->set_hexpand();
+ label_avail->set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(*label_avail, 0, row, 3, 1);
+#else
+ _page_cms->table().attach(*label_avail, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_cms.table().attach(_combo_avail, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
- _page_cms.table().attach(_link_btn, 1, 2, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 2, 0);
- _page_cms.table().attach(_unlink_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ _combo_avail.set_hexpand();
+ _combo_avail.set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(_combo_avail, 0, row, 1, 1);
+
+ _link_btn.set_halign(Gtk::ALIGN_CENTER);
+ _link_btn.set_valign(Gtk::ALIGN_CENTER);
+ _link_btn.set_margin_left(2);
+ _link_btn.set_margin_right(2);
+ _page_cms->table().attach(_link_btn, 1, row, 1, 1);
+
+ _unlink_btn.set_halign(Gtk::ALIGN_CENTER);
+ _unlink_btn.set_valign(Gtk::ALIGN_CENTER);
+ _page_cms->table().attach(_unlink_btn, 2, row, 1, 1);
+#else
+ _page_cms->table().attach(_combo_avail, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+ _page_cms->table().attach(_link_btn, 1, 2, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 2, 0);
+ _page_cms->table().attach(_unlink_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0);
+#endif
populate_available_profiles();
@@ -604,16 +714,16 @@ void DocumentProperties::build_cms()
void DocumentProperties::build_scripting()
{
- _page_scripting.show();
+ _page_scripting->show();
- _page_scripting.set_spacing (4);
- _page_scripting.pack_start(_scripting_notebook, true, true);
+ _page_scripting->set_spacing (4);
+ _page_scripting->pack_start(_scripting_notebook, true, true);
- _scripting_notebook.append_page(_page_external_scripts, _("External scripts"));
- _scripting_notebook.append_page(_page_embedded_scripts, _("Embedded scripts"));
+ _scripting_notebook.append_page(*_page_external_scripts, _("External scripts"));
+ _scripting_notebook.append_page(*_page_embedded_scripts, _("Embedded scripts"));
//# External scripts tab
- _page_external_scripts.show();
+ _page_external_scripts->show();
Gtk::Label *label_external= manage (new Gtk::Label("", Gtk::ALIGN_START));
label_external->set_markup (_("<b>External script files:</b>"));
@@ -624,25 +734,64 @@ void DocumentProperties::build_scripting()
_external_remove_btn.set_image(*manage(Glib::wrap(gtk_image_new_from_stock ( GTK_STOCK_REMOVE, GTK_ICON_SIZE_SMALL_TOOLBAR ) )));
- _page_external_scripts.set_spacing(4);
+ _page_external_scripts->set_spacing(4);
gint row = 0;
label_external->set_alignment(0.0);
- _page_external_scripts.table().attach(*label_external, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_external->set_hexpand();
+ label_external->set_valign(Gtk::ALIGN_CENTER);
+ _page_external_scripts->table().attach(*label_external, 0, row, 3, 1);
+#else
+ _page_external_scripts->table().attach(*label_external, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_external_scripts.table().attach(_ExternalScriptsListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ _ExternalScriptsListScroller.set_hexpand();
+ _ExternalScriptsListScroller.set_valign(Gtk::ALIGN_CENTER);
+ _page_external_scripts->table().attach(_ExternalScriptsListScroller, 0, row, 3, 1);
+#else
+ _page_external_scripts->table().attach(_ExternalScriptsListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
Gtk::HBox* spacer_external = Gtk::manage(new Gtk::HBox());
spacer_external->set_size_request(SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_external_scripts.table().attach(*spacer_external, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
- row++;
- _page_external_scripts.table().attach(_script_entry, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
- _page_external_scripts.table().attach(_external_add_btn, 1, 2, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 2, 0);
- _page_external_scripts.table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0);
+#if WITH_GTKMM_3_0
+ spacer_external->set_hexpand();
+ spacer_external->set_valign(Gtk::ALIGN_CENTER);
+ _page_external_scripts->table().attach(*spacer_external, 0, row, 3, 1);
+#else
+ _page_external_scripts->table().attach(*spacer_external, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
+#if WITH_GTKMM_3_0
+ _script_entry.set_hexpand();
+ _script_entry.set_valign(Gtk::ALIGN_CENTER);
+ _page_external_scripts->table().attach(_script_entry, 0, row, 1, 1);
+
+ _external_add_btn.set_halign(Gtk::ALIGN_CENTER);
+ _external_add_btn.set_valign(Gtk::ALIGN_CENTER);
+ _external_add_btn.set_margin_left(2);
+ _external_add_btn.set_margin_right(2);
+ _page_external_scripts->table().attach(_external_add_btn, 1, row, 1, 1);
+
+ _external_remove_btn.set_halign(Gtk::ALIGN_CENTER);
+ _external_remove_btn.set_valign(Gtk::ALIGN_CENTER);
+ _page_external_scripts->table().attach(_external_remove_btn, 2, row, 1, 1);
+#else
+ _page_external_scripts->table().attach(_script_entry, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+ _page_external_scripts->table().attach(_external_add_btn, 1, 2, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 2, 0);
+ _page_external_scripts->table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
//# Set up the External Scripts box
_ExternalScriptsListStore = Gtk::ListStore::create(_ExternalScriptsListColumns);
_ExternalScriptsList.set_model(_ExternalScriptsListStore);
@@ -652,7 +801,7 @@ void DocumentProperties::build_scripting()
//# Embedded scripts tab
- _page_embedded_scripts.show();
+ _page_embedded_scripts->show();
Gtk::Label *label_embedded= manage (new Gtk::Label("", Gtk::ALIGN_START));
label_embedded->set_markup (_("<b>Embedded script files:</b>"));
@@ -672,21 +821,52 @@ void DocumentProperties::build_scripting()
_embed_button_box.add(_embed_new_btn);
_embed_button_box.add(_embed_remove_btn);
- _page_embedded_scripts.set_spacing(4);
+ _page_embedded_scripts->set_spacing(4);
row = 0;
label_embedded->set_alignment(0.0);
- _page_embedded_scripts.table().attach(*label_embedded, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_embedded->set_hexpand();
+ label_embedded->set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(*label_embedded, 0, row, 3, 1);
+#else
+ _page_embedded_scripts->table().attach(*label_embedded, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_embedded_scripts.table().attach(_EmbeddedScriptsListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ _EmbeddedScriptsListScroller.set_hexpand();
+ _EmbeddedScriptsListScroller.set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(_EmbeddedScriptsListScroller, 0, row, 3, 1);
+#else
+ _page_embedded_scripts->table().attach(_EmbeddedScriptsListScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_embedded_scripts.table().attach(_embed_button_box, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#if WITH_GTKMM_3_0
+ _embed_button_box.set_hexpand();
+ _embed_button_box.set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(_embed_button_box, 0, row, 1, 1);
+#else
+ _page_embedded_scripts->table().attach(_embed_button_box, 0, 1, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
Gtk::HBox* spacer_embedded = Gtk::manage(new Gtk::HBox());
spacer_embedded->set_size_request(SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_embedded_scripts.table().attach(*spacer_embedded, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ spacer_embedded->set_hexpand();
+ spacer_embedded->set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(*spacer_embedded, 0, row, 3, 1);
+#else
+ _page_embedded_scripts->table().attach(*spacer_embedded, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
//# Set up the Embedded Scripts box
@@ -701,10 +881,24 @@ void DocumentProperties::build_scripting()
label_embedded_content->set_markup (_("<b>Content:</b>"));
label_embedded_content->set_alignment(0.0);
- _page_embedded_scripts.table().attach(*label_embedded_content, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_embedded_content->set_hexpand();
+ label_embedded_content->set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(*label_embedded_content, 0, row, 3, 1);
+#else
+ _page_embedded_scripts->table().attach(*label_embedded_content, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
+
row++;
- _page_embedded_scripts.table().attach(_EmbeddedContentScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#if WITH_GTKMM_3_0
+ _EmbeddedContentScroller.set_hexpand();
+ _EmbeddedContentScroller.set_valign(Gtk::ALIGN_CENTER);
+ _page_embedded_scripts->table().attach(_EmbeddedContentScroller, 0, row, 3, 1);
+#else
+ _page_embedded_scripts->table().attach(_EmbeddedContentScroller, 0, 3, row, row + 1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0, 0, 0);
+#endif
_EmbeddedContentScroller.add(_EmbeddedContent);
_EmbeddedContentScroller.set_shadow_type(Gtk::SHADOW_IN);
@@ -760,12 +954,19 @@ void DocumentProperties::build_metadata()
{
using Inkscape::UI::Widget::EntityEntry;
- _page_metadata1.show();
+ _page_metadata1->show();
Gtk::Label *label = manage (new Gtk::Label);
label->set_markup (_("<b>Dublin Core Entities</b>"));
label->set_alignment (0.0);
- _page_metadata1.table().attach (*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ label->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1->table().attach (*label, 0,0,3,1);
+#else
+ _page_metadata1->table().attach (*label, 0,3,0,1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
+
/* add generic metadata entry areas */
struct rdf_work_entity_t * entity;
int row = 1;
@@ -775,9 +976,22 @@ void DocumentProperties::build_metadata()
_rdflist.push_back (w);
Gtk::HBox *space = manage (new Gtk::HBox);
space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_metadata1.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata1.table().attach (w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata1.table().attach (*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ space->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1->table().attach(*space, 0, row, 1, 1);
+
+ w->_label.set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1->table().attach(w->_label, 1, row, 1, 1);
+
+ w->_packable->set_hexpand();
+ w->_packable->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata1->table().attach(*w->_packable, 2, row, 1, 1);
+#else
+ _page_metadata1->table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata1->table().attach (w->_label, 1,2, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata1->table().attach (*w->_packable, 2,3, row, row+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+#endif
}
}
@@ -785,30 +999,53 @@ void DocumentProperties::build_metadata()
button_save->set_tooltip_text(_("Save this metadata as the default metadata"));
Gtk::Button *button_load = manage (new Gtk::Button(_("Use _default"),1));
button_load->set_tooltip_text(_("Use the previously saved default metadata here"));
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *box_buttons = manage (new Gtk::ButtonBox);
+#else
Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox);
+#endif
+
box_buttons->set_layout(Gtk::BUTTONBOX_END);
box_buttons->set_spacing(4);
box_buttons->pack_start(*button_save, true, true, 6);
box_buttons->pack_start(*button_load, true, true, 6);
- _page_metadata1.pack_end(*box_buttons, false, false, 0);
+ _page_metadata1->pack_end(*box_buttons, false, false, 0);
button_save->signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::save_default_metadata));
button_load->signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::load_default_metadata));
- _page_metadata2.show();
+ _page_metadata2->show();
row = 0;
Gtk::Label *llabel = manage (new Gtk::Label);
llabel->set_markup (_("<b>License</b>"));
llabel->set_alignment (0.0);
- _page_metadata2.table().attach (*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ llabel->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2->table().attach(*llabel, 0, row, 3, 1);
+#else
+ _page_metadata2->table().attach (*llabel, 0,3, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
+
/* add license selector pull-down and URI */
++row;
_licensor.init (_wr);
Gtk::HBox *space = manage (new Gtk::HBox);
space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
- _page_metadata2.table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
- _page_metadata2.table().attach (_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+
+#if WITH_GTKMM_3_0
+ space->set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2->table().attach(*space, 0, row, 1, 1);
+
+ _licensor.set_hexpand();
+ _licensor.set_valign(Gtk::ALIGN_CENTER);
+ _page_metadata2->table().attach(_licensor, 1, row, 3, 1);
+#else
+ _page_metadata2->table().attach (*space, 0,1, row, row+1, Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+ _page_metadata2->table().attach (_licensor, 1,3, row, row+1, Gtk::EXPAND|Gtk::FILL, (Gtk::AttachOptions)0,0,0);
+#endif
}
void DocumentProperties::addExternalScript(){
@@ -923,7 +1160,7 @@ void DocumentProperties::removeExternalScript(){
while ( current ) {
if (current->data && SP_IS_OBJECT(current->data)) {
SPObject* obj = SP_OBJECT(current->data);
- SPScript* script = (SPScript*) obj;
+ SPScript* script = SP_SCRIPT(obj);
if (name == script->xlinkhref){
//XML Tree being used directly here while it shouldn't be.
@@ -956,16 +1193,18 @@ void DocumentProperties::removeEmbeddedScript(){
const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" );
while ( current ) {
- SPObject* obj = SP_OBJECT(current->data);
- if (id == obj->getId()){
+ if (current->data && SP_IS_OBJECT(current->data)) {
+ SPObject* obj = SP_OBJECT(current->data);
+ if (id == obj->getId()){
- //XML Tree being used directly here while it shouldn't be.
- Inkscape::XML::Node *repr = obj->getRepr();
- if (repr){
- sp_repr_unparent(repr);
+ //XML Tree being used directly here while it shouldn't be.
+ Inkscape::XML::Node *repr = obj->getRepr();
+ if (repr){
+ sp_repr_unparent(repr);
- // inform the document, so we can undo
- DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script"));
+ // inform the document, so we can undo
+ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script"));
+ }
}
}
current = g_slist_next(current);
@@ -1078,7 +1317,7 @@ void DocumentProperties::populate_script_lists(){
if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent);
while ( current ) {
SPObject* obj = SP_OBJECT(current->data);
- SPScript* script = (SPScript*) obj;
+ SPScript* script = SP_SCRIPT(obj);
if (script->xlinkhref)
{
Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append());
@@ -1153,11 +1392,7 @@ void DocumentProperties::build_gridspage()
_grids_hbox_crea.pack_start(_grids_button_new, true, true);
for (gint t = 0; t <= GRID_MAXTYPENR; t++) {
-#if WITH_GTKMM_2_24
_grids_combo_gridtype.append( CanvasGrid::getName( (GridType) t ) );
-#else
- _grids_combo_gridtype.append_text( CanvasGrid::getName( (GridType) t ) );
-#endif
}
_grids_combo_gridtype.set_active_text( CanvasGrid::getName(GRID_RECTANGULAR) );
diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h
index 5bafddc32..56fed30c4 100644
--- a/src/ui/dialog/document-properties.h
+++ b/src/ui/dialog/document-properties.h
@@ -15,8 +15,7 @@
#define INKSCAPE_UI_DIALOG_DOCUMENT_PREFERENCES_H
#include <stddef.h>
-#include <sigc++/sigc++.h>//
-#include "ui/widget/notebook-page.h"
+#include <sigc++/sigc++.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/liststore.h>
#include <gtkmm/notebook.h>
@@ -39,6 +38,7 @@ namespace Inkscape {
namespace UI {
namespace Widget {
class EntityEntry;
+ class NotebookPage;
}
namespace Dialog {
@@ -100,18 +100,18 @@ protected:
Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer;
Gtk::Notebook _notebook;
- UI::Widget::NotebookPage _page_page;
- UI::Widget::NotebookPage _page_guides;
- UI::Widget::NotebookPage _page_snap;
- UI::Widget::NotebookPage _page_cms;
- UI::Widget::NotebookPage _page_scripting;
+ UI::Widget::NotebookPage *_page_page;
+ UI::Widget::NotebookPage *_page_guides;
+ UI::Widget::NotebookPage *_page_snap;
+ UI::Widget::NotebookPage *_page_cms;
+ UI::Widget::NotebookPage *_page_scripting;
Gtk::Notebook _scripting_notebook;
- UI::Widget::NotebookPage _page_external_scripts;
- UI::Widget::NotebookPage _page_embedded_scripts;
+ UI::Widget::NotebookPage *_page_external_scripts;
+ UI::Widget::NotebookPage *_page_embedded_scripts;
- UI::Widget::NotebookPage _page_metadata1;
- UI::Widget::NotebookPage _page_metadata2;
+ UI::Widget::NotebookPage *_page_metadata1;
+ UI::Widget::NotebookPage *_page_metadata2;
Gtk::VBox _grids_vbox;
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 6247b0523..3017dc117 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -22,19 +22,28 @@
#include <gtkmm/box.h>
#include <gtkmm/buttonbox.h>
-#include <gtkmm/label.h>
-#include <gtkmm/widget.h>
-#include <gtkmm/togglebutton.h>
+#include <gtkmm/dialog.h>
#include <gtkmm/entry.h>
#include <gtkmm/image.h>
-#include <gtkmm/stockid.h>
+#include <gtkmm/label.h>
+#include <gtkmm/spinbutton.h>
#include <gtkmm/stock.h>
-#include <gtkmm/table.h>
+#include <gtkmm/stockid.h>
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/widget.h>
+
#ifdef WITH_GNOME_VFS
# include <libgnomevfs/gnome-vfs-init.h> // gnome_vfs_initialized
#endif
#include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
+
#include "helper/unit-menu.h"
#include "helper/units.h"
#include "unit-constants.h"
@@ -63,7 +72,12 @@
#include "helper/png-write.h"
+#if WITH_EXT_GDL
+#include <gdl/gdl-dock-item.h>
+#else
#include "libgdl/gdl-dock-item.h"
+#endif
+
// required to set status message after export
#include "desktop.h"
@@ -121,6 +135,15 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
+/** A list of strings that is used both in the preferences, and in the
+ data fields to describe the various values of \c selection_type. */
+static const char * selection_names[SELECTION_NUMBER_OF] = {
+ "page", "drawing", "selection", "custom"};
+
+/** The names on the buttons for the various selection types. */
+static const char * selection_labels[SELECTION_NUMBER_OF] = {
+ N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")};
+
Export::Export (void) :
UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT),
current_key(SELECTION_PAGE),
@@ -137,14 +160,14 @@ Export::Export (void) :
unitbox(false, 0),
units_label(_("Units:")),
filename_box(false, 5),
- browse_label(_("_Browse..."), 1),
+ browse_label(_("_Export As..."), 1),
browse_image(Gtk::StockID(Gtk::Stock::INDEX), Gtk::ICON_SIZE_BUTTON),
batch_box(false, 5),
batch_export(_("B_atch export all selected objects"), _("Export each selected object into its own PNG file, using export hints if any (caution, overwrites without asking!)")),
hide_box(false, 5),
hide_export(_("Hide a_ll except selected"), _("In the exported image, hide all objects except those that are selected")),
- closeWhenDone(_("Close this dialog when complete"), _("Once the export completes, close this dialog")),
- button_box(Gtk::BUTTONBOX_END),
+ closeWhenDone(_("Close when complete"), _("Once the export completes, close this dialog")),
+ button_box(false, 3),
export_label(_("_Export"), 1),
export_image(Gtk::StockID(Gtk::Stock::APPLY), Gtk::ICON_SIZE_BUTTON),
_prog(),
@@ -163,7 +186,7 @@ Export::Export (void) :
/* Export area frame */
{
- Gtk::Label* lbl = new Gtk::Label(_("<big><b>Export area</b></big>"), Gtk::ALIGN_START);
+ Gtk::Label* lbl = new Gtk::Label(_("<b>Export area</b>"), Gtk::ALIGN_START);
lbl->set_use_markup(true);
area_box.pack_start(*lbl);
@@ -188,9 +211,15 @@ Export::Export (void) :
selectiontype_buttons[i]->signal_clicked().connect(sigc::mem_fun(*this, &Export::onAreaToggled));
}
+#if WITH_GTKMM_3_0
+ Gtk::Grid* t = new Gtk::Grid();
+ t->set_row_spacing(4);
+ t->set_column_spacing(4);
+#else
Gtk::Table* t = new Gtk::Table(3, 4, false);
t->set_row_spacings (4);
t->set_col_spacings (4);
+#endif
x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, unit_selector->gobj(),
t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1,
@@ -228,12 +257,20 @@ Export::Export (void) :
/* Bitmap size frame */
{
size_box.set_border_width(3);
- bm_label = new Gtk::Label(_("<big><b>Bitmap size</b></big>"), Gtk::ALIGN_START);
+ bm_label = new Gtk::Label(_("<b>Image size</b>"), Gtk::ALIGN_START);
bm_label->set_use_markup(true);
size_box.pack_start(*bm_label, false, false, 0);
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *t = new Gtk::Grid();
+ t->set_row_spacing(4);
+ t->set_column_spacing(4);
+#else
Gtk::Table *t = new Gtk::Table(2, 5, false);
t->set_row_spacings (4);
t->set_col_spacings (4);
+#endif
+
size_box.pack_start(*t);
bmwidth_adj = createSpinbutton ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0,
@@ -265,7 +302,7 @@ Export::Export (void) :
/* File entry */
{
file_box.set_border_width(3);
- flabel = new Gtk::Label(_("<big><b>_Filename</b></big>"), Gtk::ALIGN_START, Gtk::ALIGN_CENTER, true);
+ flabel = new Gtk::Label(_("<b>_Filename</b>"), Gtk::ALIGN_START, Gtk::ALIGN_CENTER, true);
flabel->set_use_markup(true);
file_box.pack_start(*flabel, false, false, 0);
@@ -296,11 +333,9 @@ Export::Export (void) :
batch_box.pack_start(batch_export, false, false);
hide_export.set_sensitive(true);
- hide_export.set_active (true);
+ hide_export.set_active (prefs->getBool("/dialogs/export/hideexceptselected/value", false));
hide_box.pack_start(hide_export, false, false);
- Gtk::HBox *closeWhenBox = Gtk::manage(new Gtk::HBox(false, 5));
- closeWhenBox->pack_start(closeWhenDone, Gtk::PACK_SHRINK);
/* Export Button row */
button_box.set_border_width(3);
@@ -310,8 +345,9 @@ Export::Export (void) :
export_button.add(*export_image_label);
export_button.set_tooltip_text (_("Export the bitmap file with these settings"));
- button_box.pack_end(export_button, Gtk::PACK_SHRINK);
+ button_box.pack_start(closeWhenDone, true, true, 0 );
+ button_box.pack_end(export_button, false, false, 0);
/* Main dialog */
Gtk::Box *contents = _getContents();
@@ -319,8 +355,7 @@ Export::Export (void) :
contents->pack_start(singleexport_box);
contents->pack_start(batch_box);
contents->pack_start(hide_box);
- contents->pack_start(*closeWhenBox);
- contents->pack_end(button_box, Gtk::PACK_SHRINK);
+ contents->pack_end(button_box, false, 0);
contents->pack_end(_prog, Gtk::PACK_EXPAND_WIDGET);
/* Signal handlers */
@@ -330,6 +365,7 @@ Export::Export (void) :
browse_button.signal_clicked().connect(sigc::mem_fun(*this, &Export::onBrowse));
batch_export.signal_clicked().connect(sigc::mem_fun(*this, &Export::onBatchClicked));
export_button.signal_clicked().connect(sigc::mem_fun(*this, &Export::onExport));
+ hide_export.signal_clicked().connect(sigc::mem_fun(*this, &Export::onHideExceptSelected));
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Export::setTargetDesktop) );
deskTrack.connect(GTK_WIDGET(gobj()));
@@ -394,7 +430,6 @@ void Export::set_default_filename () {
if ( SP_ACTIVE_DOCUMENT && SP_ACTIVE_DOCUMENT->getURI() )
{
- gchar *name;
SPDocument * doc = SP_ACTIVE_DOCUMENT;
const gchar *uri = doc->getURI();
const gchar *text_extension = get_file_save_extension (Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS).c_str();
@@ -417,13 +452,16 @@ void Export::set_default_filename () {
final_name = g_strconcat(uri_copy, ".png", NULL);
filename_entry.set_text(final_name);
+ filename_entry.set_position(strlen(final_name));
g_free(final_name);
g_free(uri_copy);
}
} else {
- name = g_strconcat(uri, ".png", NULL);
+ gchar *name = g_strconcat(uri, ".png", NULL);
filename_entry.set_text(name);
+ filename_entry.set_position(strlen(name));
+
g_free(name);
}
@@ -435,7 +473,7 @@ void Export::set_default_filename () {
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max,
float step, float page, GtkWidget *us,
- Gtk::Table *t, int x, int y,
+ Gtk::Grid *t, int x, int y,
const Glib::ustring ll, const Glib::ustring lr,
int digits, unsigned int sensitive,
void (Export::*cb)() )
@@ -463,17 +501,29 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
if (!ll.empty()) {
l = new Gtk::Label(ll,true);
l->set_alignment (1.0, 0.5);
+
+#if WITH_GTKMM_3_0
+ l->set_hexpand();
+ l->set_vexpand();
+ t->attach(*l, x + pos, y, 1, 1);
+#else
t->attach (*l, x + pos, x + pos + 1, y, y + 1, Gtk::EXPAND, Gtk::EXPAND, 0, 0 );
+#endif
+
l->set_sensitive(sensitive);
pos++;
}
#if WITH_GTKMM_3_0
Gtk::SpinButton *sb = new Gtk::SpinButton(adj, 1.0, digits);
+ sb->set_hexpand();
+ sb->set_vexpand();
+ t->attach(*sb, x + pos, y, 1, 1);
#else
Gtk::SpinButton *sb = new Gtk::SpinButton(*adj, 1.0, digits);
-#endif
t->attach (*sb, x + pos, x + pos + 1, y, y + 1, Gtk::EXPAND, Gtk::EXPAND, 0, 0 );
+#endif
+
sb->set_width_chars(7);
sb->set_sensitive (sensitive);
pos++;
@@ -483,7 +533,15 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
if (!lr.empty()) {
l = new Gtk::Label(lr,true);
l->set_alignment (0.0, 0.5);
+
+#if WITH_GTKMM_3_0
+ l->set_hexpand();
+ l->set_vexpand();
+ t->attach(*l, x + pos, y, 1, 1);
+#else
t->attach (*l, x + pos, x + pos + 1, y, y + 1, Gtk::EXPAND, Gtk::EXPAND, 0, 0 );
+#endif
+
l->set_sensitive (sensitive);
pos++;
l->set_mnemonic_widget (*sb);
@@ -546,7 +604,7 @@ void Export::updateCheckbuttons ()
batch_export.set_sensitive(false);
}
- hide_export.set_sensitive (num > 0 && current_key == SELECTION_SELECTION);
+ //hide_export.set_sensitive (num > 0);
}
inline void Export::findDefaultSelection()
@@ -770,6 +828,7 @@ void Export::onAreaToggled ()
if (!filename.empty()) {
original_name = filename;
filename_entry.set_text(filename);
+ filename_entry.set_position(filename.length());
}
if (xdpi != 0.0) {
@@ -784,8 +843,6 @@ void Export::onAreaToggled ()
}
}
- hide_export.set_sensitive (key == SELECTION_SELECTION);
-
return;
} // end of sp_export_area_toggled()
@@ -917,6 +974,11 @@ Glib::ustring Export::absolutize_path_from_document_location (SPDocument *doc, c
return path;
}
+void Export::onHideExceptSelected ()
+{
+ prefs->setBool("/dialogs/export/hideexceptselected/value", hide_export.get_active());
+}
+
/// Called when export button is clicked
void Export::onExport ()
{
@@ -1045,6 +1107,7 @@ void Export::onExport ()
// make sure that .png is the extension of the file:
Glib::ustring const filename_ext = filename_add_extension(filename, "png");
filename_entry.set_text(filename_ext);
+ filename_entry.set_position(filename_ext.length());
Glib::ustring path = absolutize_path_from_document_location(doc, filename_ext);
Glib::ustring dirname = Glib::path_get_dirname(path);
@@ -1253,10 +1316,18 @@ void Export::onBrowse ()
WCHAR* title_string = (WCHAR*)g_utf8_to_utf16(_("Select a filename for exporting"), -1, NULL, NULL, NULL);
WCHAR* extension_string = (WCHAR*)g_utf8_to_utf16("*.png", -1, NULL, NULL, NULL);
// Copy the selected file name, converting from UTF-8 to UTF-16
+ std::string dirname = Glib::path_get_dirname(filename.raw());
+ if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) ||
+ Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) ||
+ dirname.empty() )
+ {
+ Glib::ustring tmp;
+ filename = create_filepath_from_id(tmp, tmp);
+ }
WCHAR _filename[_MAX_PATH + 1];
memset(_filename, 0, sizeof(_filename));
gunichar2* utf16_path_string = g_utf8_to_utf16(filename.c_str(), -1, NULL, NULL, NULL);
- wcsncpy(_filename, (wchar_t*)utf16_path_string, _MAX_PATH);
+ wcsncpy(_filename, reinterpret_cast<wchar_t*>(utf16_path_string), _MAX_PATH);
g_free(utf16_path_string);
opf.hwndOwner = (HWND)(GDK_WINDOW_HWND(gtk_widget_get_window(GTK_WIDGET(this))));
@@ -1282,6 +1353,7 @@ void Export::onBrowse ()
// Copy the selected file name, converting from UTF-16 to UTF-8
gchar *utf8string = g_utf16_to_utf8((const gunichar2*)opf.lpstrFile, _MAX_PATH, NULL, NULL, NULL);
filename_entry.set_text(utf8string);
+ filename_entry.set_position(strlen(utf8string));
g_free(utf8string);
}
@@ -1297,6 +1369,7 @@ void Export::onBrowse ()
gchar * utf8file = g_filename_to_utf8( file, -1, NULL, NULL, NULL );
filename_entry.set_text (utf8file);
+ filename_entry.set_position(strlen(utf8file));
g_free(utf8file);
g_free(file);
@@ -1429,7 +1502,7 @@ void Export::areaXChange (Gtk::Adjustment *adj)
return;
}
- if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) {
+ if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
return;
}
@@ -1476,7 +1549,7 @@ void Export::areaYChange (Gtk::Adjustment *adj)
return;
}
- if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) {
+ if (sp_unit_selector_update_test (SP_UNIT_SELECTOR(unit_selector->gobj()))) {
return;
}
@@ -1631,7 +1704,7 @@ void Export::onBitmapWidthChange ()
return;
}
- if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) {
+ if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
return;
}
@@ -1665,7 +1738,7 @@ void Export::onBitmapHeightChange ()
return;
}
- if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) {
+ if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
return;
}
@@ -1725,7 +1798,7 @@ void Export::onExportXdpiChange()
return;
}
- if (sp_unit_selector_update_test ((SPUnitSelector *)unit_selector->gobj())) {
+ if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(unit_selector->gobj()))) {
return;
}
@@ -1827,7 +1900,7 @@ 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 ((SPUnitSelector *)unit_selector->gobj() );
+ const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj()) );
setValue(adj, sp_pixels_get_units (val, *unit));
@@ -1877,7 +1950,7 @@ float Export::getValuePx( Gtk::Adjustment *adj )
#endif
{
float value = getValue( adj);
- const SPUnit *unit = sp_unit_selector_get_unit ((SPUnitSelector *)unit_selector->gobj());
+ const SPUnit *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unit_selector->gobj()));
return sp_units_get_pixels (value, *unit);
} // end of sp_export_value_get_px()
diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h
index 6dc063c0c..b10c98fd2 100644
--- a/src/ui/dialog/export.h
+++ b/src/ui/dialog/export.h
@@ -14,23 +14,27 @@
#include <gtk/gtk.h>
#include <glibmm/i18n.h>
+
+#include <gtkmm/comboboxtext.h>
#include <gtkmm/expander.h>
#include <gtkmm/frame.h>
+#include <gtkmm/progressbar.h>
#include <gtkmm/textview.h>
-#include <gtkmm/comboboxtext.h>
#include "desktop.h"
#include "ui/dialog/desktop-tracker.h"
#include "ui/widget/panel.h"
#include "ui/widget/button.h"
#include "ui/widget/entry.h"
-#include "widgets/sp-attribute-widget.h"
+
+namespace Gtk {
+class Dialog;
+}
namespace Inkscape {
namespace UI {
namespace Dialog {
-
/** What type of button is being pressed */
enum selection_type {
SELECTION_PAGE = 0, /**< Export the whole page */
@@ -40,16 +44,6 @@ enum selection_type {
SELECTION_NUMBER_OF /**< A counter for the number of these guys */
};
-/** A list of strings that is used both in the preferences, and in the
- data fields to describe the various values of \c selection_type. */
-static const char * selection_names[SELECTION_NUMBER_OF] = {
- "page", "drawing", "selection", "custom"};
-
-/** The names on the buttons for the various selection types. */
-static const char * selection_labels[SELECTION_NUMBER_OF] = {
- N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")};
-
-
/**
* A dialog widget to export to various image formats such as bitmap and png.
*
@@ -127,7 +121,7 @@ private:
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> createSpinbutton( gchar const *key, float val, float min, float max,
float step, float page, GtkWidget *us,
- Gtk::Table *t, int x, int y,
+ Gtk::Grid *t, int x, int y,
const Glib::ustring ll, const Glib::ustring lr,
int digits, unsigned int sensitive,
void (Export::*cb)() );
@@ -178,6 +172,11 @@ private:
#endif
/**
+ * Hide except selected callback
+ */
+ void onHideExceptSelected ();
+
+ /**
* Area width value changed callback
*/
void onAreaWidthChange ();
@@ -349,7 +348,7 @@ private:
Inkscape::UI::Widget::CheckButton closeWhenDone;
/* Export Button widgets */
- Gtk::HButtonBox button_box;
+ Gtk::HBox button_box;
Gtk::Button export_button;
Gtk::Label export_label;
Gtk::Image export_image;
diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp
index 47ba6c748..3413b0b0d 100644
--- a/src/ui/dialog/filedialog.cpp
+++ b/src/ui/dialog/filedialog.cpp
@@ -24,6 +24,8 @@
#include "extension/output.h"
#include "preferences.h"
+#include <glibmm/convert.h>
+
namespace Inkscape
{
namespace UI
@@ -152,6 +154,9 @@ Glib::ustring FileSaveDialog::getDocTitle()
void FileSaveDialog::appendExtension(Glib::ustring& path, Inkscape::Extension::Output* outputExtension)
{
+ if (!outputExtension)
+ return;
+
try {
bool appendExtension = true;
Glib::ustring utf8Name = Glib::filename_to_utf8( path );
diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h
index 6a3436aea..8dfcf5dce 100644
--- a/src/ui/dialog/filedialog.h
+++ b/src/ui/dialog/filedialog.h
@@ -16,12 +16,13 @@
#ifndef __FILE_DIALOG_H__
#define __FILE_DIALOG_H__
-#include <glibmm.h>
#include <vector>
#include <set>
#include "extension/system.h"
+#include <glibmm/ustring.h>
+
class SPDocument;
namespace Inkscape {
@@ -208,6 +209,8 @@ public:
virtual Glib::ustring getCurrentDirectory() = 0;
+ virtual void addFileType(Glib::ustring name, Glib::ustring pattern) = 0;
+
protected:
/**
diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp
index 1663eb0b6..5808d7d21 100644
--- a/src/ui/dialog/filedialogimpl-gtkmm.cpp
+++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp
@@ -34,7 +34,12 @@
#include <gtkmm/expander.h>
#include <gtkmm/stock.h>
+
+#include <glibmm/convert.h>
+#include <glibmm/fileutils.h>
#include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
+
#include "extension/input.h"
#include "extension/output.h"
#include "extension/db.h"
@@ -100,9 +105,9 @@ findEntryWidgets(Gtk::Container *parent,
Gtk::Widget *child = children[i];
GtkWidget *wid = child->gobj();
if (GTK_IS_ENTRY(wid))
- result.push_back((Gtk::Entry *)child);
+ result.push_back(dynamic_cast<Gtk::Entry *>(child));
else if (GTK_IS_CONTAINER(wid))
- findEntryWidgets((Gtk::Container *)child, result);
+ findEntryWidgets(dynamic_cast<Gtk::Container *>(child), result);
}
}
@@ -119,9 +124,9 @@ findExpanderWidgets(Gtk::Container *parent,
Gtk::Widget *child = children[i];
GtkWidget *wid = child->gobj();
if (GTK_IS_EXPANDER(wid))
- result.push_back((Gtk::Expander *)child);
+ result.push_back(dynamic_cast<Gtk::Expander *>(child));
else if (GTK_IS_CONTAINER(wid))
- findExpanderWidgets((Gtk::Container *)child, result);
+ findExpanderWidgets(dynamic_cast<Gtk::Container *>(child), result);
}
}
@@ -141,13 +146,12 @@ bool SVGPreview::setDocument(SPDocument *doc)
//This should remove it from the box, and free resources
if (viewerGtk)
- gtk_widget_destroy(viewerGtk);
-
- viewerGtk = sp_svg_view_widget_new(doc);
- GtkWidget *vbox = (GtkWidget *)gobj();
- gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0);
- gtk_widget_show(viewerGtk);
+ Gtk::Container::remove(*viewerGtk);
+ viewerGtk = Glib::wrap(sp_svg_view_widget_new(doc));
+ Gtk::VBox *vbox = Glib::wrap(gobj());
+ vbox->pack_start(*viewerGtk, TRUE, TRUE, 0);
+ viewerGtk->show();
return true;
}
@@ -523,7 +527,7 @@ bool SVGPreview::set(Glib::ustring &fileName, int dialogType)
if (Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR))
{
Glib::ustring fileNameUtf8 = Glib::filename_to_utf8(fileName);
- gchar *fName = (gchar *)fileNameUtf8.c_str();
+ gchar *fName = const_cast<gchar *>(fileNameUtf8.c_str());
struct stat info;
if (g_stat(fName, &info))
{
@@ -899,7 +903,7 @@ bool
FileOpenDialogImplGtk::show()
{
set_modal (TRUE); //Window
- sp_transientize((GtkWidget *)gobj()); //Make transient
+ sp_transientize(GTK_WIDGET(gobj())); //Make transient
gint b = run(); //Dialog
svgPreview.showNoPreview();
hide();
@@ -1048,7 +1052,9 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow,
fileTypeCheckbox.set_active(prefs->getBool("/dialogs/save_as/append_extension", true));
}
- createFileTypeMenu();
+ if (_dialogType != CUSTOM_TYPE)
+ createFileTypeMenu();
+
fileTypeComboBox.set_size_request(200,40);
fileTypeComboBox.signal_changed().connect(
sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileTypeChangedCallback) );
@@ -1067,7 +1073,7 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow,
std::vector<Gtk::Entry *> entries;
findEntryWidgets(cont, entries);
//g_message("Found %d entry widgets\n", entries.size());
- if (entries.size() >=1 )
+ if (!entries.empty())
{
//Catch when user hits [return] on the text field
fileNameEntry = entries[0];
@@ -1079,7 +1085,7 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow,
std::vector<Gtk::Expander *> expanders;
findExpanderWidgets(cont, expanders);
//g_message("Found %d expander widgets\n", expanders.size());
- if (expanders.size() >=1 )
+ if (!expanders.empty())
{
//Always show the file list
Gtk::Expander *expander = expanders[0];
@@ -1175,8 +1181,21 @@ void FileSaveDialogImplGtk::fileTypeChangedCallback()
updateNameAndExtension();
}
+void FileSaveDialogImplGtk::addFileType(Glib::ustring name, Glib::ustring pattern)
+{
+ //#Let user choose
+ FileType guessType;
+ guessType.name = name;
+ guessType.pattern = pattern;
+ guessType.extension = NULL;
+ fileTypeComboBox.append(guessType.name);
+ fileTypes.push_back(guessType);
+ fileTypeComboBox.set_active(0);
+ fileTypeChangedCallback(); //call at least once to set the filter
+}
+
void FileSaveDialogImplGtk::createFileTypeMenu()
{
Inkscape::Extension::DB::OutputList extension_list;
@@ -1198,11 +1217,7 @@ void FileSaveDialogImplGtk::createFileTypeMenu()
knownExtensions.insert( extension.casefold() );
fileDialogExtensionToPattern (type.pattern, extension);
type.extension= omod;
-#if WITH_GTKMM_2_24
fileTypeComboBox.append(type.name);
-#else
- fileTypeComboBox.append_text(type.name);
-#endif
fileTypes.push_back(type);
}
@@ -1211,11 +1226,7 @@ void FileSaveDialogImplGtk::createFileTypeMenu()
guessType.name = _("Guess from extension");
guessType.pattern = "*";
guessType.extension = NULL;
-#if WITH_GTKMM_2_24
fileTypeComboBox.append(guessType.name);
-#else
- fileTypeComboBox.append_text(guessType.name);
-#endif
fileTypes.push_back(guessType);
@@ -1235,7 +1246,7 @@ FileSaveDialogImplGtk::show()
{
change_path(myFilename);
set_modal (TRUE); //Window
- sp_transientize((GtkWidget *)gobj()); //Make transient
+ sp_transientize(GTK_WIDGET(gobj())); //Make transient
gint b = run(); //Dialog
svgPreview.showNoPreview();
set_preview_widget_active(false);
@@ -1633,7 +1644,7 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow,
std::vector<Gtk::Entry *> entries;
findEntryWidgets(cont, entries);
//g_message("Found %d entry widgets\n", entries.size());
- if (entries.size() >=1 )
+ if (!entries.empty())
{
//Catch when user hits [return] on the text field
fileNameEntry = entries[0];
@@ -1645,7 +1656,7 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow,
std::vector<Gtk::Expander *> expanders;
findExpanderWidgets(cont, expanders);
//g_message("Found %d expander widgets\n", expanders.size());
- if (expanders.size() >=1 )
+ if (!expanders.empty())
{
//Always show the file list
Gtk::Expander *expander = expanders[0];
@@ -1682,7 +1693,7 @@ FileExportDialogImpl::show()
s = getcwd (NULL, 0);
set_current_folder(Glib::filename_from_utf8(s)); //hack to force initial dir listing
set_modal (TRUE); //Window
- sp_transientize((GtkWidget *)gobj()); //Make transient
+ sp_transientize(GTK_WIDGET(gobj())); //Make transient
gint b = run(); //Dialog
svgPreview.showNoPreview();
hide();
diff --git a/src/ui/dialog/filedialogimpl-gtkmm.h b/src/ui/dialog/filedialogimpl-gtkmm.h
index 2c22e7367..7501b5e14 100644
--- a/src/ui/dialog/filedialogimpl-gtkmm.h
+++ b/src/ui/dialog/filedialogimpl-gtkmm.h
@@ -121,7 +121,7 @@ private:
/**
* The sp_svg_view widget
*/
- GtkWidget *viewerGtk;
+ Gtk::Widget *viewerGtk;
/**
* are we currently showing the "no preview" image?
@@ -291,6 +291,7 @@ public:
virtual void setSelectionType( Inkscape::Extension::Extension * key );
Glib::ustring getCurrentDirectory();
+ void addFileType(Glib::ustring name, Glib::ustring pattern);
private:
//void change_title(const Glib::ustring& title);
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index 5891f25ac..496836c4d 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -26,6 +26,9 @@
#include <gdk/gdkwin32.h>
#include <glib/gstdio.h>
#include <glibmm/i18n.h>
+#if GLIB_CHECK_VERSION(2,32,0)
+#include <glibmm/thread.h>
+#endif
#include <gtkmm/window.h>
//Inkscape includes
@@ -133,7 +136,11 @@ FileDialogBaseWin32::FileDialogBaseWin32(Gtk::Window &parent,
Glib::RefPtr<const Gdk::Window> parentWindow = parent.get_window();
g_assert(parentWindow->gobj() != NULL);
+#if WITH_GTKMM_3_0
+ _ownerHwnd = (HWND)gdk_win32_window_get_handle((GdkWindow*)parentWindow->gobj());
+#else
_ownerHwnd = (HWND)gdk_win32_drawable_get_handle((GdkDrawable*)parentWindow->gobj());
+#endif
}
FileDialogBaseWin32::~FileDialogBaseWin32()
@@ -188,7 +195,8 @@ FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent,
_mutex = NULL;
- createFilterMenu();
+ if (dialogType != CUSTOM_TYPE)
+ createFilterMenu();
}
@@ -1575,16 +1583,23 @@ FileOpenDialogImplWin32::show()
// We can only run one worker thread at a time
if(_mutex != NULL) return false;
+#if !GLIB_CHECK_VERSION(2,32,0)
if(!Glib::thread_supported())
Glib::thread_init();
+#endif
_result = false;
_finished = false;
_file_selected = false;
- _mutex = new Glib::Mutex();
_main_loop = g_main_loop_new(g_main_context_default(), FALSE);
+#if GLIB_CHECK_VERSION(2,32,0)
+ _mutex = new Glib::Threads::Mutex();
+ if(Glib::Threads::Thread::create(sigc::mem_fun(*this, &FileOpenDialogImplWin32::GetOpenFileName_thread)))
+#else
+ _mutex = new Glib::Mutex();
if(Glib::Thread::create(sigc::mem_fun(*this, &FileOpenDialogImplWin32::GetOpenFileName_thread), true))
+#endif
{
while(1)
{
@@ -1748,6 +1763,72 @@ void FileSaveDialogImplWin32::createFilterMenu()
_filter_index = 1; // A value of 1 selects the 1st filter - NOT the 2nd
}
+
+void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring pattern)
+{
+ list<Filter> filter_list;
+
+ knownExtensions.clear();
+
+ int extension_index = 0;
+ int filter_length = 1;
+
+ ustring all_exe_files_filter = pattern;
+ Filter all_exe_files;
+
+ const gchar *all_exe_files_filter_name = name.data();
+
+ // Calculate the amount of memory required
+ int filter_count = 1;
+
+
+ // Filter Executable Files
+ all_exe_files.name = g_utf8_to_utf16(all_exe_files_filter_name,
+ -1, NULL, &all_exe_files.name_length, NULL);
+ all_exe_files.filter = g_utf8_to_utf16(all_exe_files_filter.data(),
+ -1, NULL, &all_exe_files.filter_length, NULL);
+ all_exe_files.mod = NULL;
+ filter_list.push_front(all_exe_files);
+
+ knownExtensions.insert( Glib::ustring(all_exe_files_filter).casefold() );
+
+ _extension_map = new Inkscape::Extension::Extension*[filter_count];
+
+ _filter = new wchar_t[filter_length];
+ wchar_t *filterptr = _filter;
+
+ for(list<Filter>::iterator filter_iterator = filter_list.begin();
+ filter_iterator != filter_list.end(); ++filter_iterator)
+ {
+ const Filter &filter = *filter_iterator;
+
+ wcsncpy(filterptr, (wchar_t*)filter.name, filter.name_length);
+ filterptr += filter.name_length;
+ g_free(filter.name);
+
+ *(filterptr++) = L'\0';
+ *(filterptr++) = L'*';
+
+ if(filter.filter != NULL)
+ {
+ wcsncpy(filterptr, (wchar_t*)filter.filter, filter.filter_length);
+ filterptr += filter.filter_length;
+ g_free(filter.filter);
+ }
+
+ *(filterptr++) = L'\0';
+
+ // Associate this input extension with the file type name
+ _extension_map[extension_index++] = filter.mod;
+ }
+ *(filterptr++) = L'\0';
+
+ _filter_count = extension_index;
+ _filter_index = 1; // Select the 1st filter in the list
+
+
+}
+
void FileSaveDialogImplWin32::GetSaveFileName_thread()
{
OPENFILENAMEEXW ofn;
@@ -1803,18 +1884,24 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread()
bool
FileSaveDialogImplWin32::show()
{
+#if !GLIB_CHECK_VERSION(2,32,0)
if(!Glib::thread_supported())
Glib::thread_init();
+#endif
_result = false;
_main_loop = g_main_loop_new(g_main_context_default(), FALSE);
if(_main_loop != NULL)
{
+#if GLIB_CHECK_VERSION(2,32,0)
+ if(Glib::Threads::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread)))
+#else
if(Glib::Thread::create(sigc::mem_fun(*this, &FileSaveDialogImplWin32::GetSaveFileName_thread), true))
+#endif
g_main_loop_run(_main_loop);
- if(_result)
+ if(_result && _extension)
appendExtension(myFilename, (Inkscape::Extension::Output*)_extension);
}
@@ -1827,6 +1914,7 @@ void FileSaveDialogImplWin32::setSelectionType( Inkscape::Extension::Extension *
}
+
UINT_PTR CALLBACK FileSaveDialogImplWin32::GetSaveFileName_hookproc(
HWND hdlg, UINT uiMsg, WPARAM, LPARAM lParam)
{
diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h
index d016b0a24..e9d8829f7 100644
--- a/src/ui/dialog/filedialogimpl-win32.h
+++ b/src/ui/dialog/filedialogimpl-win32.h
@@ -226,7 +226,11 @@ private:
/// This mutex is used to ensure that the worker thread
/// that calls GetOpenFileName cannot collide with the
/// main Inkscape thread
+#if GLIB_CHECK_VERSION(2,32,0)
+ Glib::Threads::Mutex *_mutex;
+#else
Glib::Mutex *_mutex;
+#endif
/// The controller function for the thread which calls
@@ -343,6 +347,8 @@ public:
virtual void setSelectionType( Inkscape::Extension::Extension *key );
+ virtual void addFileType(Glib::ustring name, Glib::ustring pattern);
+
private:
/// A handle to the title label and edit box
HWND _title_label;
diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp
index 74c19fea7..19b873d54 100644
--- a/src/ui/dialog/fill-and-stroke.cpp
+++ b/src/ui/dialog/fill-and-stroke.cpp
@@ -15,6 +15,7 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
+#include "ui/widget/notebook-page.h"
#include "desktop-handles.h"
#include "desktop-style.h"
#include "document.h"
@@ -22,6 +23,7 @@
#include "filter-chemistry.h"
#include "inkscape.h"
#include "selection.h"
+#include "preferences.h"
#include "style.h"
#include "svg/css-ostringstream.h"
#include "ui/icon-names.h"
@@ -34,15 +36,17 @@
#include "ui/view/view-widget.h"
+#include <gtkmm/table.h>
+
namespace Inkscape {
namespace UI {
namespace Dialog {
FillAndStroke::FillAndStroke()
: UI::Widget::Panel ("", "/dialogs/fillstroke", SP_VERB_DIALOG_FILL_STROKE),
- _page_fill(1, 1, true, true),
- _page_stroke_paint(1, 1, true, true),
- _page_stroke_style(1, 1, true, true),
+ _page_fill(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))),
+ _page_stroke_paint(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))),
+ _page_stroke_style(Gtk::manage(new UI::Widget::NotebookPage(1, 1, true, true))),
_composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", UI::Widget::SimpleFilterModifier::BLUR),
deskTrack(),
targetDesktop(0),
@@ -55,15 +59,17 @@ FillAndStroke::FillAndStroke()
contents->pack_start(_notebook, true, true);
- _notebook.append_page(_page_fill, _createPageTabLabel(_("_Fill"), INKSCAPE_ICON("object-fill")));
- _notebook.append_page(_page_stroke_paint, _createPageTabLabel(_("Stroke _paint"), INKSCAPE_ICON("object-stroke")));
- _notebook.append_page(_page_stroke_style, _createPageTabLabel(_("Stroke st_yle"), INKSCAPE_ICON("object-stroke-style")));
+ _notebook.append_page(*_page_fill, _createPageTabLabel(_("_Fill"), INKSCAPE_ICON("object-fill")));
+ _notebook.append_page(*_page_stroke_paint, _createPageTabLabel(_("Stroke _paint"), INKSCAPE_ICON("object-stroke")));
+ _notebook.append_page(*_page_stroke_style, _createPageTabLabel(_("Stroke st_yle"), INKSCAPE_ICON("object-stroke-style")));
+
+ _notebook.signal_switch_page().connect(sigc::mem_fun(this, &FillAndStroke::_onSwitchPage));
_layoutPageFill();
_layoutPageStrokePaint();
_layoutPageStrokeStyle();
- contents->pack_start(_composite_settings, false, false, 0);
+ contents->pack_start(_composite_settings, true, true, 0);
show_all_children();
@@ -105,18 +111,45 @@ void FillAndStroke::setTargetDesktop(SPDesktop *desktop)
}
}
+#if WITH_GTKMM_3_0
+void FillAndStroke::_onSwitchPage(Gtk::Widget * /*page*/, guint pagenum)
+#else
+void FillAndStroke::_onSwitchPage(GtkNotebookPage * /*page*/, guint pagenum)
+#endif
+{
+ _savePagePref(pagenum);
+}
+
+void
+FillAndStroke::_savePagePref(guint page_num)
+{
+ // remember the current page
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt("/dialogs/fillstroke/page", page_num);
+}
+
void
FillAndStroke::_layoutPageFill()
{
fillWdgt = manage(sp_fill_style_widget_new());
- _page_fill.table().attach(*fillWdgt, 0, 1, 0, 1);
+
+#if WITH_GTKMM_3_0
+ _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1);
+#else
+ _page_fill->table().attach(*fillWdgt, 0, 1, 0, 1);
+#endif
}
void
FillAndStroke::_layoutPageStrokePaint()
{
strokeWdgt = manage(sp_stroke_style_paint_widget_new());
- _page_stroke_paint.table().attach(*strokeWdgt, 0, 1, 0, 1);
+
+#if WITH_GTKMM_3_0
+ _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1);
+#else
+ _page_stroke_paint->table().attach(*strokeWdgt, 0, 1, 0, 1);
+#endif
}
void
@@ -125,7 +158,12 @@ FillAndStroke::_layoutPageStrokeStyle()
//Gtk::Widget *strokeStyleWdgt = manage(Glib::wrap(sp_stroke_style_line_widget_new()));
//Gtk::Widget *strokeStyleWdgt = static_cast<Gtk::Widget *>(sp_stroke_style_line_widget_new());
strokeStyleWdgt = sp_stroke_style_line_widget_new();
- _page_stroke_style.table().attach(*strokeStyleWdgt, 0, 1, 0, 1);
+
+#if WITH_GTKMM_3_0
+ _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 0, 1, 1);
+#else
+ _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 1, 0, 1);
+#endif
}
void
@@ -133,6 +171,8 @@ FillAndStroke::showPageFill()
{
present();
_notebook.set_current_page(0);
+ _savePagePref(0);
+
}
void
@@ -140,6 +180,7 @@ FillAndStroke::showPageStrokePaint()
{
present();
_notebook.set_current_page(1);
+ _savePagePref(1);
}
void
@@ -147,6 +188,8 @@ FillAndStroke::showPageStrokeStyle()
{
present();
_notebook.set_current_page(2);
+ _savePagePref(2);
+
}
Gtk::HBox&
diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h
index 596205c58..340cb860f 100644
--- a/src/ui/dialog/fill-and-stroke.h
+++ b/src/ui/dialog/fill-and-stroke.h
@@ -16,7 +16,6 @@
#define INKSCAPE_UI_DIALOG_FILL_AND_STROKE_H
#include "ui/widget/panel.h"
-#include "ui/widget/notebook-page.h"
#include "ui/widget/object-composite-settings.h"
#include "ui/dialog/desktop-tracker.h"
@@ -25,6 +24,11 @@
namespace Inkscape {
namespace UI {
+
+namespace Widget {
+class NotebookPage;
+}
+
namespace Dialog {
class FillAndStroke : public UI::Widget::Panel {
@@ -47,9 +51,9 @@ public:
protected:
Gtk::Notebook _notebook;
- UI::Widget::NotebookPage _page_fill;
- UI::Widget::NotebookPage _page_stroke_paint;
- UI::Widget::NotebookPage _page_stroke_style;
+ UI::Widget::NotebookPage *_page_fill;
+ UI::Widget::NotebookPage *_page_stroke_paint;
+ UI::Widget::NotebookPage *_page_stroke_style;
UI::Widget::StyleSubject::Selection _subject;
UI::Widget::ObjectCompositeSettings _composite_settings;
@@ -60,6 +64,12 @@ protected:
void _layoutPageFill();
void _layoutPageStrokePaint();
void _layoutPageStrokeStyle();
+ void _savePagePref(guint page_num);
+#if WITH_GTKMM_3_0
+ void _onSwitchPage(Gtk::Widget *page, guint pagenum);
+#else
+ void _onSwitchPage(GtkNotebookPage *page, guint pagenum);
+#endif
private:
FillAndStroke(FillAndStroke const &d);
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 317cb2773..0d2d0757c 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -20,8 +20,17 @@
#include "dialog-manager.h"
#include <gtkmm/imagemenuitem.h>
+
+#if GTK_CHECK_VERSION(3,0,0)
+# include <gdkmm/devicemanager.h>
+#endif
+
#include "ui/widget/spinbutton.h"
+
+#include <glibmm/convert.h>
#include <glibmm/i18n.h>
+#include <glibmm/main.h>
+#include <glibmm/stringutils.h>
#include "desktop.h"
#include "desktop-handles.h"
@@ -62,6 +71,7 @@
#include "io/sys.h"
#include <iostream>
+#include "selection-chemistry.h"
#include <gtkmm/checkbutton.h>
#include <gtkmm/colorbutton.h>
@@ -78,12 +88,12 @@ namespace Dialog {
using Inkscape::UI::Widget::AttrWidget;
using Inkscape::UI::Widget::ComboBoxEnum;
-using Inkscape::UI::Widget::DualSpinSlider;
-using Inkscape::UI::Widget::SpinSlider;
+using Inkscape::UI::Widget::DualSpinScale;
+using Inkscape::UI::Widget::SpinScale;
// Returns the number of inputs available for the filter primitive type
-int input_count(const SPFilterPrimitive* prim)
+static int input_count(const SPFilterPrimitive* prim)
{
if(!prim)
return 0;
@@ -307,9 +317,15 @@ public:
set_tooltip_text(tip_text);
}
+#if WITH_GTKMM_3_0
+ Gdk::RGBA col;
+ col.set_rgba_u(65535, 65535, 65535);
+ set_rgba(col);
+#else
Gdk::Color col;
col.set_rgb(65535, 65535, 65535);
set_color(col);
+#endif
}
// Returns the color in 'rgb(r,g,b)' form.
@@ -317,8 +333,14 @@ public:
{
// no doubles here, so we can use the standard string stream.
std::ostringstream os;
+
+#if WITH_GTKMM_3_0
+ const Gdk::RGBA c = get_rgba();
+ const int r = c.get_red_u() / 257, g = c.get_green_u() / 257, b = c.get_blue_u() / 257;//TO-DO: verify this. This sounds a lot strange! shouldn't it be 256?
+#else
const Gdk::Color c = get_color();
const int r = c.get_red() / 257, g = c.get_green() / 257, b = c.get_blue() / 257;//TO-DO: verify this. This sounds a lot strange! shouldn't it be 256?
+#endif
os << "rgb(" << r << "," << g << "," << b << ")";
return os.str();
}
@@ -334,9 +356,16 @@ public:
i = (guint32) get_default()->as_uint();
}
const int r = SP_RGBA32_R_U(i), g = SP_RGBA32_G_U(i), b = SP_RGBA32_B_U(i);
+
+#if WITH_GTKMM_3_0
+ Gdk::RGBA col;
+ col.set_rgba_u(r * 256, g * 256, b * 256);
+ set_rgba(col);
+#else
Gdk::Color col;
col.set_rgb(r * 256, g * 256, b * 256);
set_color(col);
+#endif
}
};
@@ -484,8 +513,8 @@ public:
: AttrWidget(SP_ATTR_VALUES),
// TRANSLATORS: this dialog is accessible via menu Filters - Filter editor
_matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on color space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")),
- _saturation(0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES),
- _angle(0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES),
+ _saturation("", 0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES),
+ _angle("", 0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES),
_label(_("None"), Gtk::ALIGN_START),
_use_stored(false),
_saturation_store(0),
@@ -567,8 +596,8 @@ private:
}
MatrixAttr _matrix;
- SpinSlider _saturation;
- SpinSlider _angle;
+ SpinScale _saturation;
+ SpinScale _angle;
Gtk::Label _label;
// Store separate values for the different color modes
@@ -808,22 +837,22 @@ public:
return cmv;
}
- // SpinSlider
- SpinSlider* add_spinslider(double def, const SPAttributeEnum attr, const Glib::ustring& label,
+ // SpinScale
+ SpinScale* add_spinscale(double def, const SPAttributeEnum attr, const Glib::ustring& label,
const double lo, const double hi, const double step_inc, const double climb, const int digits, char* tip_text = NULL)
{
- SpinSlider* spinslider = new SpinSlider(def, lo, hi, step_inc, climb, digits, attr, tip_text);
+ SpinScale* spinslider = new SpinScale("", def, lo, hi, step_inc, climb, digits, attr, tip_text);
add_widget(spinslider, label);
add_attr_widget(spinslider);
return spinslider;
}
- // DualSpinSlider
- DualSpinSlider* add_dualspinslider(const SPAttributeEnum attr, const Glib::ustring& label,
+ // DualSpinScale
+ DualSpinScale* add_dualspinscale(const SPAttributeEnum attr, const Glib::ustring& label,
const double lo, const double hi, const double step_inc,
const double climb, const int digits, char* tip_text1 = NULL, char* tip_text2 = NULL)
{
- DualSpinSlider* dss = new DualSpinSlider(lo, lo, hi, step_inc, climb, digits, attr, tip_text1, tip_text2);
+ DualSpinScale* dss = new DualSpinScale("", "", lo, lo, hi, step_inc, climb, digits, attr, tip_text1, tip_text2);
add_widget(dss, label);
add_attr_widget(dss);
return dss;
@@ -920,13 +949,11 @@ private:
and all widgets within the setting group are aligned automatically. */
void add_widget(Gtk::Widget* w, const Glib::ustring& label)
{
- Gtk::Label *lbl = 0;
Gtk::HBox *hb = Gtk::manage(new Gtk::HBox);
hb->set_spacing(12);
if(label != "") {
- //lbl = Gtk::manage(new Gtk::Label(label + (label == "" ? "" : ":"), Gtk::ALIGN_LEFT)); colon now in label (LP #358921)
- lbl = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START));
+ Gtk::Label *lbl = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START));
hb->pack_start(*lbl, false, false);
_size_group->add_widget(*lbl);
lbl->show();
@@ -971,8 +998,8 @@ public:
// FIXME: these range values are complete crap
_settings.type(LIGHT_DISTANT);
- _settings.add_spinslider(0, SP_ATTR_AZIMUTH, _("Azimuth"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the XY plane, in degrees"));
- _settings.add_spinslider(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees"));
+ _settings.add_spinscale(0, SP_ATTR_AZIMUTH, _("Azimuth"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the XY plane, in degrees"));
+ _settings.add_spinscale(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees"));
_settings.type(LIGHT_POINT);
_settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate"));
@@ -982,9 +1009,9 @@ public:
_settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0,
SP_ATTR_POINTSATX, SP_ATTR_POINTSATY, SP_ATTR_POINTSATZ,
_("Points At"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate"));
- _settings.add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Specular Exponent"), 1, 100, 1, 1, 0, _("Exponent value controlling the focus for the light source"));
+ _settings.add_spinscale(1, SP_ATTR_SPECULAREXPONENT, _("Specular Exponent"), 1, 100, 1, 1, 0, _("Exponent value controlling the focus for the light source"));
//TODO: here I have used 100 degrees as default value. But spec says that if not specified, no limiting cone is applied. So, there should be a way for the user to set a "no limiting cone" option.
- _settings.add_spinslider(100, SP_ATTR_LIMITINGCONEANGLE, _("Cone Angle"), 1, 100, 1, 1, 0, _("This is the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. No light is projected outside this cone."));
+ _settings.add_spinscale(100, SP_ATTR_LIMITINGCONEANGLE, _("Cone Angle"), 1, 100, 1, 1, 0, _("This is the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. No light is projected outside this cone."));
}
Gtk::VBox& get_box()
@@ -1057,11 +1084,7 @@ private:
void update()
{
-#if WITH_GTKMM_2_24
- _box.hide();
-#else
- _box.hide_all();
-#endif
+ _box.hide();
_box.show();
_light_box.show_all();
@@ -1087,8 +1110,8 @@ FilterEffectsDialog::LightSourceControl* FilterEffectsDialog::Settings::add_ligh
return ls;
}
-Glib::RefPtr<Gtk::Menu> create_popup_menu(Gtk::Widget& parent, sigc::slot<void> dup,
- sigc::slot<void> rem)
+static Glib::RefPtr<Gtk::Menu> create_popup_menu(Gtk::Widget& parent, sigc::slot<void> dup,
+ sigc::slot<void> rem)
{
Glib::RefPtr<Gtk::Menu> menu(new Gtk::Menu);
@@ -1127,15 +1150,12 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d)
if(col)
col->add_attribute(_cell_toggle.property_active(), _columns.sel);
_list.append_column_editable(_("_Filter"), _columns.label);
-#if WITH_GTKMM_2_24
((Gtk::CellRendererText*)_list.get_column(1)->get_first_cell())->
signal_edited().connect(sigc::mem_fun(*this, &FilterEffectsDialog::FilterModifier::on_name_edited));
-#else
- ((Gtk::CellRendererText*)_list.get_column(1)->get_first_cell_renderer())->
- signal_edited().connect(sigc::mem_fun(*this, &FilterEffectsDialog::FilterModifier::on_name_edited));
-#endif
- sw->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ _list.get_column(1)->set_resizable(true);
+
sw->set_shadow_type(Gtk::SHADOW_IN);
show_all_children();
_add.signal_clicked().connect(sigc::mem_fun(*this, &FilterModifier::add_filter));
@@ -1193,6 +1213,17 @@ void FilterEffectsDialog::FilterModifier::setTargetDesktop(SPDesktop *desktop)
}
}
+// When the document changes, update connection to resources
+void FilterEffectsDialog::FilterModifier::on_document_replaced(SPDesktop * /*desktop*/, SPDocument *document)
+{
+ if (_resource_changed) {
+ _resource_changed.disconnect();
+ }
+ _resource_changed = document->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters));
+
+ update_filters();
+}
+
// When the selection changes, show the active filter(s) in the dialog
void FilterEffectsDialog::FilterModifier::on_change_selection()
{
@@ -1316,7 +1347,7 @@ void FilterEffectsDialog::FilterModifier::update_filters()
for(const GSList *l = filters; l; l = l->next) {
Gtk::TreeModel::Row row = *_model->append();
- SPFilter* f = (SPFilter*)l->data;
+ SPFilter* f = SP_FILTER(l->data);
row[_columns.filter] = f;
const gchar* lbl = f->label();
const gchar* id = f->getId();
@@ -1387,6 +1418,29 @@ void FilterEffectsDialog::FilterModifier::remove_filter()
if(filter) {
SPDocument* doc = filter->document;
+ // Delete all references to this filter
+ GSList *all = get_all_items(NULL, _desktop->currentRoot(), _desktop, false, false, true, NULL);
+ for (GSList *i = all; i != NULL; i = i->next) {
+ if (!SP_IS_ITEM(i->data)) {
+ continue;
+ }
+ SPItem *item = SP_ITEM(i->data);
+ if (!item->style) {
+ continue;
+ }
+
+ const SPIFilter *ifilter = &(item->style->filter);
+ if (ifilter && ifilter->href) {
+ const SPObject *obj = ifilter->href->getObject();
+ if (obj && obj == (SPObject *)filter) {
+ ::remove_filter(item, false);
+ }
+ }
+ }
+ if (all) {
+ g_slist_free(all);
+ }
+
//XML Tree being used directly here while it shouldn't be.
sp_repr_unparent(filter->getRepr());
@@ -1428,6 +1482,41 @@ Glib::PropertyProxy<void*> FilterEffectsDialog::CellRendererConnection::property
return _primitive.get_proxy();
}
+#if WITH_GTKMM_3_0
+void FilterEffectsDialog::CellRendererConnection::get_preferred_width_vfunc(Gtk::Widget& widget,
+ int& minimum_width,
+ int& natural_width) const
+{
+ PrimitiveList& primlist = dynamic_cast<PrimitiveList&>(widget);
+ minimum_width = natural_width = size * primlist.primitive_count() + primlist.get_input_type_width() * 6;
+}
+
+void FilterEffectsDialog::CellRendererConnection::get_preferred_width_for_height_vfunc(Gtk::Widget& widget,
+ int /* height */,
+ int& minimum_width,
+ int& natural_width) const
+{
+ get_preferred_width(widget, minimum_width, natural_width);
+}
+
+void FilterEffectsDialog::CellRendererConnection::get_preferred_height_vfunc(Gtk::Widget& widget,
+ int& minimum_height,
+ int& natural_height) const
+{
+ // Scale the height depending on the number of inputs, unless it's
+ // the first primitive, in which case there are no connections
+ SPFilterPrimitive* prim = SP_FILTER_PRIMITIVE(_primitive.get_value());
+ minimum_height = natural_height = size * input_count(prim);
+}
+
+void FilterEffectsDialog::CellRendererConnection::get_preferred_height_for_width_vfunc(Gtk::Widget& widget,
+ int /* width */,
+ int& minimum_height,
+ int& natural_height) const
+{
+ get_preferred_height(widget, minimum_height, natural_height);
+}
+#else
void FilterEffectsDialog::CellRendererConnection::get_size_vfunc(
Gtk::Widget& widget, const Gdk::Rectangle* /*cell_area*/,
int* x_offset, int* y_offset, int* width, int* height) const
@@ -1443,10 +1532,11 @@ void FilterEffectsDialog::CellRendererConnection::get_size_vfunc(
if(height) {
// Scale the height depending on the number of inputs, unless it's
// the first primitive, in which case there are no connections
- SPFilterPrimitive* prim = (SPFilterPrimitive*)_primitive.get_value();
+ SPFilterPrimitive* prim = SP_FILTER_PRIMITIVE(_primitive.get_value());
(*height) = size * input_count(prim);
}
}
+#endif
/*** PrimitiveList ***/
FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d)
@@ -1455,8 +1545,8 @@ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d)
_observer(new Inkscape::XML::SignalObserver)
{
#if WITH_GTKMM_3_0
- d.signal_draw().connect(sigc::mem_fun(*this, &PrimitiveList::on_draw));
- signal_draw().connect(sigc::mem_fun(*this, &PrimitiveList::on_draw));
+ d.signal_draw().connect(sigc::mem_fun(*this, &PrimitiveList::on_draw_signal));
+ signal_draw().connect(sigc::mem_fun(*this, &PrimitiveList::on_draw_signal));
#else
d.signal_expose_event().connect(sigc::mem_fun(*this, &PrimitiveList::on_expose_signal));
signal_expose_event().connect(sigc::mem_fun(*this, &PrimitiveList::on_expose_signal));
@@ -1470,6 +1560,8 @@ FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d)
set_model(_model);
append_column(_("_Effect"), _columns.type);
+ get_column(0)->set_resizable(true);
+ set_headers_visible();
_observer->signal_changed().connect(signal_primitive_changed().make_slot());
get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PrimitiveList::on_primitive_selection_changed));
@@ -1525,11 +1617,10 @@ void FilterEffectsDialog::PrimitiveList::update()
{
SPFilter* f = _dialog._filter_modifier.get_selected_filter();
const SPFilterPrimitive* active_prim = get_selected();
- bool active_found = false;
-
_model->clear();
if(f) {
+ bool active_found = false;
_dialog._primitive_box.set_sensitive(true);
_dialog.update_filter_general_settings_view();
for(SPObject *prim_obj = f->children;
@@ -1623,20 +1714,52 @@ void FilterEffectsDialog::PrimitiveList::remove_selected()
}
#if !WITH_GTKMM_3_0
-bool FilterEffectsDialog::PrimitiveList::on_expose_signal(GdkEventExpose* /*e*/)
+bool FilterEffectsDialog::PrimitiveList::on_expose_signal(GdkEventExpose * /*evt*/)
{
- Glib::RefPtr<Gdk::Window> win = get_bin_window();
- Cairo::RefPtr<Cairo::Context> cr = win->create_cairo_context();
- return on_draw(cr);
+ bool result = false;
+
+ if (get_is_drawable())
+ {
+ Cairo::RefPtr<Cairo::Context> cr = get_bin_window()->create_cairo_context();
+ result = on_draw_signal(cr);
+ }
+
+ return result;
}
#endif
-bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
+bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtr<Cairo::Context> & cr)
{
cr->set_line_width(1.0);
-
- // TODO: Use Gtk::StyleContext instead
+#if GTK_CHECK_VERSION(3,0,0)
+ // In GTK+ 3, the draw function receives the widget window, not the
+ // bin_window (i.e., just the area under the column headers). We
+ // therefore translate the origin of our coordinate system to account for this
+ int x_origin, y_origin;
+ convert_bin_window_to_widget_coords(0,0,x_origin,y_origin);
+ cr->translate(x_origin, y_origin);
+
+ GtkStyleContext *sc = gtk_widget_get_style_context(GTK_WIDGET(gobj()));
+ GdkRGBA bg_color, fg_color;
+ gtk_style_context_get_background_color(sc, GTK_STATE_FLAG_NORMAL, &bg_color);
+ gtk_style_context_get_color(sc, GTK_STATE_FLAG_NORMAL, &fg_color);
+
+ GdkRGBA mid_color = {(bg_color.red + fg_color.red)/2.0,
+ (bg_color.green + fg_color.green)/2.0,
+ (bg_color.blue + fg_color.blue)/2.0,
+ (bg_color.alpha + fg_color.alpha)/2.0};
+
+ GdkRGBA bg_color_active, fg_color_active;
+ gtk_style_context_get_background_color(sc, GTK_STATE_FLAG_ACTIVE, &bg_color_active);
+ gtk_style_context_get_color(sc, GTK_STATE_FLAG_ACTIVE, &fg_color_active);
+
+ GdkRGBA mid_color_active = {(bg_color_active.red + fg_color_active.red)/2.0,
+ (bg_color_active.green + fg_color_active.green)/2.0,
+ (bg_color_active.blue + fg_color_active.blue)/2.0,
+ (bg_color_active.alpha + fg_color_active.alpha)/2.0};
+#else
GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(gobj()));
+#endif
SPFilterPrimitive* prim = get_selected();
int row_count = get_model()->children().size();
@@ -1655,13 +1778,25 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
const int x = text_start_x + get_input_type_width() * i;
cr->save();
cr->rectangle(x, 0, get_input_type_width(), vis.get_height());
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(), &bg_color);
+ cr->fill_preserve();
+
+ gdk_cairo_set_source_rgba(cr->cobj(), &fg_color);
+#else
gdk_cairo_set_source_color(cr->cobj(), &(style->bg[GTK_STATE_NORMAL]));
cr->fill_preserve();
gdk_cairo_set_source_color(cr->cobj(), &(style->text[GTK_STATE_NORMAL]));
+#endif
cr->move_to(x+get_input_type_width(), 0);
cr->rotate_degrees(90);
_vertical_layout->show_in_cairo_context(cr);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(), &mid_color);
+#else
gdk_cairo_set_source_color(cr->cobj(), &(style->dark[GTK_STATE_NORMAL]));
+#endif
cr->move_to(x, 0);
cr->line_to(x, vis.get_height());
cr->stroke();
@@ -1677,12 +1812,26 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
// Check mouse state
int mx, my;
Gdk::ModifierType mask;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ Glib::RefPtr<Gdk::Display> display = get_bin_window()->get_display();
+ Glib::RefPtr<Gdk::DeviceManager> dm = display->get_device_manager();
+ Glib::RefPtr<const Gdk::Device> device = dm->get_client_pointer();
+ get_bin_window()->get_device_position(device, mx, my, mask);
+#else
get_bin_window()->get_pointer(mx, my, mask);
+#endif
// Outline the bottom of the connection area
const int outline_x = x + fheight * (row_count - row_index);
cr->save();
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(), &mid_color);
+#else
gdk_cairo_set_source_color(cr->cobj(), &(style->dark[GTK_STATE_NORMAL]));
+#endif
+
cr->move_to(x, y + h);
cr->line_to(outline_x, y + h);
// Side outline
@@ -1693,6 +1842,7 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
std::vector<Gdk::Point> con_poly;
int con_drag_y = 0;
+ int con_drag_x = 0;
bool inside;
const SPFilterPrimitive* row_prim = (*row)[_columns.primitive];
const int inputs = input_count(row_prim);
@@ -1703,33 +1853,53 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
cr->save();
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(),
+ inside && mask & GDK_BUTTON1_MASK ?
+ &mid_color :
+ &mid_color_active);
+#else
gdk_cairo_set_source_color(cr->cobj(),
inside && mask & GDK_BUTTON1_MASK ?
&(style->dark[GTK_STATE_NORMAL]) :
&(style->dark[GTK_STATE_ACTIVE]));
+#endif
draw_connection_node(cr, con_poly, inside);
cr->restore();
if(_in_drag == (i + 1))
+ {
con_drag_y = con_poly[2].get_y();
+ con_drag_x = con_poly[2].get_x();
+ }
if(_in_drag != (i + 1) || row_prim != prim)
+ {
draw_connection(cr, row, i, text_start_x, outline_x, con_poly[2].get_y(), row_count);
+ }
}
}
else {
// Draw "in" shape
inside = do_connection_node(row, 0, con_poly, mx, my);
con_drag_y = con_poly[2].get_y();
+ con_drag_x = con_poly[2].get_x();
cr->save();
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(),
+ inside && mask & GDK_BUTTON1_MASK ?
+ &mid_color :
+ &mid_color_active);
+#else
gdk_cairo_set_source_color(cr->cobj(),
inside && mask & GDK_BUTTON1_MASK ?
&(style->dark[GTK_STATE_NORMAL]) :
&(style->dark[GTK_STATE_ACTIVE]));
+#endif
draw_connection_node(cr, con_poly, inside);
@@ -1737,20 +1907,32 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
// Draw "in" connection
if(_in_drag != 1 || row_prim != prim)
+ {
draw_connection(cr, row, SP_ATTR_IN, text_start_x, outline_x, con_poly[2].get_y(), row_count);
+ }
if(inputs == 2) {
// Draw "in2" shape
inside = do_connection_node(row, 1, con_poly, mx, my);
if(_in_drag == 2)
+ {
con_drag_y = con_poly[2].get_y();
+ con_drag_x = con_poly[2].get_x();
+ }
cr->save();
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(),
+ inside && mask & GDK_BUTTON1_MASK ?
+ &mid_color :
+ &mid_color_active);
+#else
gdk_cairo_set_source_color(cr->cobj(),
inside && mask & GDK_BUTTON1_MASK ?
&(style->dark[GTK_STATE_NORMAL]) :
&(style->dark[GTK_STATE_ACTIVE]));
+#endif
draw_connection_node(cr, con_poly, inside);
@@ -1758,16 +1940,18 @@ bool FilterEffectsDialog::PrimitiveList::on_draw(const Cairo::RefPtr<Cairo::Cont
// Draw "in2" connection
if(_in_drag != 2 || row_prim != prim)
+ {
draw_connection(cr, row, SP_ATTR_IN2, text_start_x, outline_x, con_poly[2].get_y(), row_count);
+ }
}
}
// Draw drag connection
if(row_prim == prim && _in_drag) {
cr->save();
- gdk_cairo_set_source_color(cr->cobj(), &(style->black));
- cr->move_to(outline_x, con_drag_y);
- cr->line_to(mx, con_drag_y);
+ cr->set_source_rgb(0.0, 0.0, 0.0);
+ cr->move_to(con_drag_x, con_drag_y);
+ cr->line_to(mx, con_drag_y);
cr->line_to(mx, my);
cr->stroke();
cr->restore();
@@ -1784,8 +1968,20 @@ void FilterEffectsDialog::PrimitiveList::draw_connection(const Cairo::RefPtr<Cai
{
cr->save();
- // TODO: Use Gtk::StyleContext instead
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *sc = gtk_widget_get_style_context(GTK_WIDGET(gobj()));
+
+ GdkRGBA bg_color, fg_color;
+ gtk_style_context_get_background_color(sc, GTK_STATE_FLAG_NORMAL, &bg_color);
+ gtk_style_context_get_color(sc, GTK_STATE_FLAG_NORMAL, &fg_color);
+
+ GdkRGBA mid_color = {(bg_color.red + fg_color.red)/2.0,
+ (bg_color.green + fg_color.green)/2.0,
+ (bg_color.blue + fg_color.blue)/2.0,
+ (bg_color.alpha + fg_color.alpha)/2.0};
+#else
GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(gobj()));
+#endif
int src_id = 0;
Gtk::TreeIter res = find_result(input, attr, src_id);
@@ -1801,9 +1997,13 @@ void FilterEffectsDialog::PrimitiveList::draw_connection(const Cairo::RefPtr<Cai
gint end_x = text_start_x + tw * src_id + (int)(tw * 0.5f) + 1;
if(use_default && is_first)
- gdk_cairo_set_source_color(cr->cobj(), &(style->dark[GTK_STATE_NORMAL]));
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_cairo_set_source_rgba(cr->cobj(), &mid_color);
+#else
+ gdk_cairo_set_source_color(cr->cobj(), &(style->dark[GTK_STATE_NORMAL]));
+#endif
else
- gdk_cairo_set_source_color(cr->cobj(), &(style->black));
+ cr->set_source_rgb(0.0, 0.0, 0.0);
cr->rectangle(end_x-2, y1-2, 5, 5);
cr->fill_preserve();
@@ -1831,7 +2031,7 @@ void FilterEffectsDialog::PrimitiveList::draw_connection(const Cairo::RefPtr<Cai
const int y2 = rct.get_y() + rct.get_height();
// Draw a bevelled 'L'-shaped connection
- gdk_cairo_set_source_color(cr->cobj(), &(style->black));
+ cr->set_source_rgb(0.0, 0.0, 0.0);
cr->move_to(x1, y1);
cr->line_to(x2-fheight/4, y1);
cr->line_to(x2, y1-fheight/4);
@@ -1973,7 +2173,8 @@ bool FilterEffectsDialog::PrimitiveList::on_button_press_event(GdkEventButton* e
if(_in_drag) {
_scroll_connection = Glib::signal_timeout().connect(sigc::mem_fun(*this, &PrimitiveList::on_scroll_timeout), 150);
- _autoscroll = 0;
+ _autoscroll_x = 0;
+ _autoscroll_y = 0;
get_selection()->select(path);
return true;
}
@@ -1989,22 +2190,43 @@ bool FilterEffectsDialog::PrimitiveList::on_motion_notify_event(GdkEventMotion*
Gdk::Rectangle vis;
get_visible_rect(vis);
int vis_x, vis_y;
+
+ int vis_x2, vis_y2; // NOTE: insaner added -- necessary to get the scrolling while dragging to work
+ convert_widget_to_tree_coords(vis.get_x(), vis.get_y(), vis_x2, vis_y2);
+
convert_tree_to_widget_coords(vis.get_x(), vis.get_y(), vis_x, vis_y);
const int top = vis_y + vis.get_height();
+ const int right_edge = vis_x + vis.get_width();
// When autoscrolling during a connection drag, set the speed based on
// where the mouse is in relation to the edges.
if(e->y < vis_y)
- _autoscroll = -(int)(speed + (vis_y - e->y) / 5);
+ _autoscroll_y = -(int)(speed + (vis_y - e->y) / 5);
else if(e->y < vis_y + limit)
- _autoscroll = -speed;
+ _autoscroll_y = -speed;
else if(e->y > top)
- _autoscroll = (int)(speed + (e->y - top) / 5);
+ _autoscroll_y = (int)(speed + (e->y - top) / 5);
else if(e->y > top - limit)
- _autoscroll = speed;
+ _autoscroll_y = speed;
else
- _autoscroll = 0;
-
+ _autoscroll_y = 0;
+
+ // NOTE: insaner added -- necessary to get the scrolling while dragging to work
+ double e2 = ( e->x - vis_x2/2);
+ // horizontal scrolling
+ if(e2 < vis_x)
+ _autoscroll_x = -(int)(speed + (vis_x - e2) / 5);
+ else if(e2 < vis_x + limit)
+ _autoscroll_x = -speed;
+ else if(e2 > right_edge)
+ _autoscroll_x = (int)(speed + (e2 - right_edge) / 5);
+ else if(e2 > right_edge - limit)
+ _autoscroll_x = speed;
+ else
+ _autoscroll_x = 0;
+
+
+
queue_draw();
return Gtk::TreeView::on_motion_notify_event(e);
@@ -2123,7 +2345,7 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton*
}
// Checks all of prim's inputs, removes any that use result
-void check_single_connection(SPFilterPrimitive* prim, const int result)
+static void check_single_connection(SPFilterPrimitive* prim, const int result)
{
if (prim && (result >= 0)) {
if (prim->image_in == result) {
@@ -2199,10 +2421,10 @@ void FilterEffectsDialog::PrimitiveList::on_drag_end(const Glib::RefPtr<Gdk::Dra
// If a connection is dragged towards the top or bottom of the list, the list should scroll to follow.
bool FilterEffectsDialog::PrimitiveList::on_scroll_timeout()
{
- if(_autoscroll) {
+ if(_autoscroll_y) {
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> a = dynamic_cast<Gtk::ScrolledWindow*>(get_parent())->get_vadjustment();
- double v = a->get_value() + _autoscroll;
+ double v = a->get_value() + _autoscroll_y;
if(v < 0)
v = 0;
@@ -2212,7 +2434,7 @@ bool FilterEffectsDialog::PrimitiveList::on_scroll_timeout()
a->set_value(v);
#else
Gtk::Adjustment& a = *dynamic_cast<Gtk::ScrolledWindow*>(get_parent())->get_vadjustment();
- double v = a.get_value() + _autoscroll;
+ double v = a.get_value() + _autoscroll_y;
if(v < 0)
v = 0;
@@ -2225,6 +2447,34 @@ bool FilterEffectsDialog::PrimitiveList::on_scroll_timeout()
queue_draw();
}
+
+ if(_autoscroll_x) {
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> a_h = dynamic_cast<Gtk::ScrolledWindow*>(get_parent())->get_hadjustment();
+ double h = a_h->get_value() + _autoscroll_x;
+
+ if(h < 0)
+ h = 0;
+ if(h > a_h->get_upper() - a_h->get_page_size())
+ h = a_h->get_upper() - a_h->get_page_size();
+
+ a_h->set_value(h);
+#else
+ Gtk::Adjustment& a_h = *dynamic_cast<Gtk::ScrolledWindow*>(get_parent())->get_hadjustment();
+ double h = a_h.get_value() + _autoscroll_x;
+
+ if(h < 0)
+ h = 0;
+ if(h > a_h.get_upper() - a_h.get_page_size())
+ h = a_h.get_upper() - a_h.get_page_size();
+
+ a_h.set_value(h);
+
+#endif
+
+ queue_draw();
+ }
+
return true;
}
@@ -2265,8 +2515,14 @@ FilterEffectsDialog::FilterEffectsDialog()
_add_primitive_type.remove_row(NR_FILTER_COMPONENTTRANSFER);
// Initialize widget hierarchy
+#if WITH_GTKMM_3_0
+ Gtk::Paned* hpaned = Gtk::manage(new Gtk::Paned);
+#else
Gtk::HPaned* hpaned = Gtk::manage(new Gtk::HPaned);
+#endif
+
Gtk::ScrolledWindow* sw_prims = Gtk::manage(new Gtk::ScrolledWindow);
+ Gtk::ScrolledWindow* sw_infobox = Gtk::manage(new Gtk::ScrolledWindow);
Gtk::HBox* infobox = Gtk::manage(new Gtk::HBox(/*homogeneous:*/false, /*spacing:*/4));
Gtk::HBox* hb_prims = Gtk::manage(new Gtk::HBox);
@@ -2275,13 +2531,15 @@ FilterEffectsDialog::FilterEffectsDialog()
hpaned->pack2(_primitive_box);
_primitive_box.pack_start(*sw_prims);
_primitive_box.pack_start(*hb_prims, false, false);
- _primitive_box.pack_start(*infobox,false, false);
+ _primitive_box.pack_start(*sw_infobox, false, false);
sw_prims->add(_primitive_list);
+ sw_infobox->add(*infobox);
infobox->pack_start(_infobox_icon, false, false);
infobox->pack_start(_infobox_desc, false, false);
_infobox_desc.set_line_wrap(true);
_infobox_desc.set_size_request(200, -1);
+
hb_prims->pack_start(_add_primitive, false, false);
hb_prims->pack_start(_add_primitive_type, false, false);
_getContents()->pack_start(_settings_tabs, false, false);
@@ -2296,8 +2554,10 @@ FilterEffectsDialog::FilterEffectsDialog()
_add_primitive_type.signal_changed().connect(
sigc::mem_fun(*this, &FilterEffectsDialog::update_primitive_infobox));
- sw_prims->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ sw_prims->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); /* NOTE: insaner -- SCROLL the connections panel thing!!! */
sw_prims->set_shadow_type(Gtk::SHADOW_IN);
+ sw_infobox->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER);
+
// al_settings->set_padding(0, 0, 12, 0);
// fr_settings->set_shadow_type(Gtk::SHADOW_NONE);
// ((Gtk::Label*)fr_settings->get_label_widget())->set_use_markup();
@@ -2331,7 +2591,7 @@ void FilterEffectsDialog::show_all_vfunc()
void FilterEffectsDialog::init_settings_widgets()
{
- // TODO: Find better range/climb-rate/digits values for the SpinSliders,
+ // TODO: Find better range/climb-rate/digits values for the SpinScales,
// most of the current values are complete guesses!
_empty_settings.set_sensitive(false);
@@ -2358,18 +2618,18 @@ void FilterEffectsDialog::init_settings_widgets()
/*
//TRANSLATORS: for info on "Slope" and "Intercept", see http://id.mind.net/~zona/mmts/functionInstitute/linearFunctions/lsif.html
_settings->add_combo(COMPONENTTRANSFER_TYPE_IDENTITY, SP_ATTR_TYPE, _("Type"), ComponentTransferTypeConverter);
- _ct_slope = _settings->add_spinslider(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2);
- _ct_intercept = _settings->add_spinslider(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2);
- _ct_amplitude = _settings->add_spinslider(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2);
- _ct_exponent = _settings->add_spinslider(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2);
- _ct_offset = _settings->add_spinslider(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/
+ _ct_slope = _settings->add_spinscale(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2);
+ _ct_intercept = _settings->add_spinscale(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2);
+ _ct_amplitude = _settings->add_spinscale(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2);
+ _ct_exponent = _settings->add_spinscale(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2);
+ _ct_offset = _settings->add_spinscale(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/
_settings->type(NR_FILTER_COMPOSITE);
_settings->add_combo(COMPOSITE_OVER, SP_ATTR_OPERATOR, _("Operator:"), CompositeOperatorConverter);
- _k1 = _settings->add_spinslider(0, SP_ATTR_K1, _("K1:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
- _k2 = _settings->add_spinslider(0, SP_ATTR_K2, _("K2:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
- _k3 = _settings->add_spinslider(0, SP_ATTR_K3, _("K3:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
- _k4 = _settings->add_spinslider(0, SP_ATTR_K4, _("K4:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+ _k1 = _settings->add_spinscale(0, SP_ATTR_K1, _("K1:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+ _k2 = _settings->add_spinscale(0, SP_ATTR_K2, _("K2:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+ _k3 = _settings->add_spinscale(0, SP_ATTR_K3, _("K3:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+ _k4 = _settings->add_spinscale(0, SP_ATTR_K4, _("K4:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
_settings->type(NR_FILTER_CONVOLVEMATRIX);
_convolve_order = _settings->add_dualspinbutton((char*)"3", SP_ATTR_ORDER, _("Size:"), 1, 5, 1, 1, 0, _("width of the convolve matrix"), _("height of the convolve matrix"));
@@ -2377,50 +2637,50 @@ void FilterEffectsDialog::init_settings_widgets()
//TRANSLATORS: for info on "Kernel", see http://en.wikipedia.org/wiki/Kernel_(matrix)
_convolve_matrix = _settings->add_matrix(SP_ATTR_KERNELMATRIX, _("Kernel:"), _("This matrix describes the convolve operation that is applied to the input image in order to calculate the pixel colors at the output. Different arrangements of values in this matrix result in various possible visual effects. An identity matrix would lead to a motion blur effect (parallel to the matrix diagonal) while a matrix filled with a constant non-zero value would lead to a common blur effect."));
_convolve_order->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::convolve_order_changed));
- _settings->add_spinslider(0, SP_ATTR_DIVISOR, _("Divisor:"), 0, 1000, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result."));
- _settings->add_spinslider(0, SP_ATTR_BIAS, _("Bias:"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter."));
+ _settings->add_spinscale(0, SP_ATTR_DIVISOR, _("Divisor:"), 0, 1000, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result."));
+ _settings->add_spinscale(0, SP_ATTR_BIAS, _("Bias:"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter."));
_settings->add_combo(CONVOLVEMATRIX_EDGEMODE_DUPLICATE, SP_ATTR_EDGEMODE, _("Edge Mode:"), ConvolveMatrixEdgeModeConverter, _("Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image."));
_settings->add_checkbutton(false, SP_ATTR_PRESERVEALPHA, _("Preserve Alpha"), "true", "false", _("If set, the alpha channel won't be altered by this filter primitive."));
_settings->type(NR_FILTER_DIFFUSELIGHTING);
_settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Diffuse Color:"), _("Defines the color of the light source"));
- _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.01, 0.001, 3, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
- _settings->add_spinslider(1, SP_ATTR_DIFFUSECONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
- _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
+ _settings->add_spinscale(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.01, 0.001, 3, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
+ _settings->add_spinscale(1, SP_ATTR_DIFFUSECONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
+ _settings->add_dualspinscale(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
_settings->add_lightsource();
_settings->type(NR_FILTER_DISPLACEMENTMAP);
- _settings->add_spinslider(0, SP_ATTR_SCALE, _("Scale:"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect."));
+ _settings->add_spinscale(0, SP_ATTR_SCALE, _("Scale:"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect."));
_settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_XCHANNELSELECTOR, _("X displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the X direction"));
_settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_YCHANNELSELECTOR, _("Y displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the Y direction"));
_settings->type(NR_FILTER_FLOOD);
_settings->add_color(/*default: black*/ 0, SP_PROP_FLOOD_COLOR, _("Flood Color:"), _("The whole filter region will be filled with this color."));
- _settings->add_spinslider(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2);
+ _settings->add_spinscale(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2);
_settings->type(NR_FILTER_GAUSSIANBLUR);
- _settings->add_dualspinslider(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation."));
+ _settings->add_dualspinscale(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation."));
_settings->type(NR_FILTER_MERGE);
_settings->add_no_params();
_settings->type(NR_FILTER_MORPHOLOGY);
_settings->add_combo(MORPHOLOGY_OPERATOR_ERODE, SP_ATTR_OPERATOR, _("Operator:"), MorphologyOperatorConverter, _("Erode: performs \"thinning\" of input image.\nDilate: performs \"fattenning\" of input image."));
- _settings->add_dualspinslider(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1);
+ _settings->add_dualspinscale(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1);
_settings->type(NR_FILTER_IMAGE);
_settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image:"));
_settings->type(NR_FILTER_OFFSET);
- _settings->add_spinslider(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right"));
- _settings->add_spinslider(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards"));
+ _settings->add_spinscale(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right"));
+ _settings->add_spinscale(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards"));
_settings->type(NR_FILTER_SPECULARLIGHTING);
_settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Specular Color:"), _("Defines the color of the light source"));
- _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.1, 0.01, 2, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
- _settings->add_spinslider(1, SP_ATTR_SPECULARCONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
- _settings->add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Exponent:"), 1, 50, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\"."));
- _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
+ _settings->add_spinscale(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.1, 0.01, 2, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
+ _settings->add_spinscale(1, SP_ATTR_SPECULARCONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
+ _settings->add_spinscale(1, SP_ATTR_SPECULAREXPONENT, _("Exponent:"), 1, 50, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\"."));
+ _settings->add_dualspinscale(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
_settings->add_lightsource();
_settings->type(NR_FILTER_TILE);
@@ -2429,9 +2689,9 @@ void FilterEffectsDialog::init_settings_widgets()
_settings->type(NR_FILTER_TURBULENCE);
// _settings->add_checkbutton(false, SP_ATTR_STITCHTILES, _("Stitch Tiles"), "stitch", "noStitch");
_settings->add_combo(TURBULENCE_TURBULENCE, SP_ATTR_TYPE, _("Type:"), TurbulenceTypeConverter, _("Indicates whether the filter primitive should perform a noise or turbulence function."));
- _settings->add_dualspinslider(SP_ATTR_BASEFREQUENCY, _("Base Frequency:"), 0, 1, 0.001, 0.01, 3);
- _settings->add_spinslider(1, SP_ATTR_NUMOCTAVES, _("Octaves:"), 1, 10, 1, 1, 0);
- _settings->add_spinslider(0, SP_ATTR_SEED, _("Seed:"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator."));
+ _settings->add_dualspinscale(SP_ATTR_BASEFREQUENCY, _("Base Frequency:"), 0, 1, 0.001, 0.01, 3);
+ _settings->add_spinscale(1, SP_ATTR_NUMOCTAVES, _("Octaves:"), 1, 10, 1, 1, 0);
+ _settings->add_spinscale(0, SP_ATTR_SEED, _("Seed:"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator."));
}
void FilterEffectsDialog::add_primitive()
@@ -2512,7 +2772,7 @@ void FilterEffectsDialog::update_primitive_infobox()
break;
case(NR_FILTER_SPECULARLIGHTING):
_infobox_icon.set_from_icon_name("feSpecularLighting-icon", Gtk::ICON_SIZE_DIALOG);
- _infobox_desc.set_markup(_("The feDiffuseLighting and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
+ _infobox_desc.set_markup(_("The <b>feDiffuseLighting</b> and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
break;
case(NR_FILTER_TILE):
_infobox_icon.set_from_icon_name("feTile-icon", Gtk::ICON_SIZE_DIALOG);
@@ -2614,11 +2874,7 @@ void FilterEffectsDialog::update_filter_general_settings_view()
}
else {
std::vector<Gtk::Widget*> vect = _settings_tab2.get_children();
-#if WITH_GTKMM_2_24
vect[0]->hide();
-#else
- vect[0]->hide_all();
-#endif
_no_filter_selected.show();
}
@@ -2637,11 +2893,7 @@ void FilterEffectsDialog::update_settings_view()
std::vector<Gtk::Widget*> vect1 = _settings_tab1.get_children();
for(unsigned int i=0; i<vect1.size(); i++)
-#if WITH_GTKMM_2_24
vect1[i]->hide();
-#else
- vect1[i]->hide_all();
-#endif
_empty_settings.show();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -2665,11 +2917,7 @@ void FilterEffectsDialog::update_settings_view()
//Second Tab
std::vector<Gtk::Widget*> vect2 = _settings_tab2.get_children();
-#if WITH_GTKMM_2_24
vect2[0]->hide();
-#else
- vect2[0]->hide_all();
-#endif
_no_filter_selected.show();
SPFilter* filter = _filter_modifier.get_selected_filter();
diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h
index 38811354e..658aac790 100644
--- a/src/ui/dialog/filter-effects-dialog.h
+++ b/src/ui/dialog/filter-effects-dialog.h
@@ -20,6 +20,7 @@
#include "sp-filter.h"
#include "ui/widget/combo-enums.h"
#include "ui/widget/spin-slider.h"
+#include "ui/widget/spin-scale.h"
#include "xml/helper-observer.h"
#include "ui/dialog/desktop-tracker.h"
@@ -76,12 +77,8 @@ private:
};
void setTargetDesktop(SPDesktop *desktop);
-
- void on_document_replaced(SPDesktop*, SPDocument*)
- {
- update_filters();
- }
+ void on_document_replaced(SPDesktop *desktop, SPDocument *document);
void on_change_selection();
void on_modified_selection( guint flags );
@@ -154,8 +151,28 @@ private:
static const int size = 24;
protected:
+#if WITH_GTKMM_3_0
+ virtual void get_preferred_width_vfunc(Gtk::Widget& widget,
+ int& minimum_width,
+ int& natural_width) const;
+
+ virtual void get_preferred_width_for_height_vfunc(Gtk::Widget& widget,
+ int height,
+ int& minimum_width,
+ int& natural_width) const;
+
+ virtual void get_preferred_height_vfunc(Gtk::Widget& widget,
+ int& minimum_height,
+ int& natural_height) const;
+
+ virtual void get_preferred_height_for_width_vfunc(Gtk::Widget& widget,
+ int width,
+ int& minimum_height,
+ int& natural_height) const;
+#else
virtual void get_size_vfunc(Gtk::Widget& widget, const Gdk::Rectangle* cell_area,
int* x_offset, int* y_offset, int* width, int* height) const;
+#endif
private:
// void* should be SPFilterPrimitive*, some weirdness with properties prevents this
Glib::Property<void*> _primitive;
@@ -180,7 +197,7 @@ private:
int get_input_type_width() const;
protected:
- bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr);
+ bool on_draw_signal(const Cairo::RefPtr<Cairo::Context> &cr);
#if !WITH_GTKMM_3_0
bool on_expose_signal(GdkEventExpose*);
@@ -219,7 +236,8 @@ private:
SPFilterPrimitive* _drag_prim;
sigc::signal<void> _signal_primitive_changed;
sigc::connection _scroll_connection;
- int _autoscroll;
+ int _autoscroll_y;
+ int _autoscroll_x;
std::auto_ptr<Inkscape::XML::SignalObserver> _observer;
int _input_type_width;
int _input_type_height;
diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp
index ec75304a5..def7b5bdb 100644
--- a/src/ui/dialog/find.cpp
+++ b/src/ui/dialog/find.cpp
@@ -15,7 +15,10 @@
#endif
#include "find.h"
+
+#include <gtkmm/entry.h>
#include <gtkmm/widget.h>
+
#include "verbs.h"
#include "message-stack.h"
@@ -56,6 +59,7 @@
#include "xml/attribute-record.h"
#include <glibmm/i18n.h>
+#include <glibmm/regex.h>
namespace Inkscape {
namespace UI {
@@ -65,12 +69,12 @@ Find::Find()
: UI::Widget::Panel("", "/dialogs/find", SP_VERB_DIALOG_FIND),
entry_find(_("F_ind:"), _("Find objects by their content or properties (exact or partial match)")),
- entry_replace(_("Re_place:"), _("Replace match with this value")),
+ entry_replace(_("R_eplace:"), _("Replace match with this value")),
check_scope_all(_("_All"), _("Search in all layers")),
check_scope_layer(_("Current _layer"), _("Limit search to the current layer")),
- check_scope_selection(_("S_election"), _("Limit search to the current selection")),
- check_searchin_text(_("Te_xt"), _("Search in text objects")),
+ check_scope_selection(_("Sele_ction"), _("Limit search to the current selection")),
+ check_searchin_text(_("_Text"), _("Search in text objects")),
check_searchin_property(_("_Properties"), _("Search in object properties, styles, attributes and IDs")),
vbox_searchin(0, false),
frame_searchin(_("Search in")),
@@ -85,9 +89,9 @@ Find::Find()
check_ids(_("_ID"), _("Search id name"), true),
check_attributename(_("Attribute _name"), _("Search attribute name"), false),
- check_attributevalue(_("Attribute _value"), _("Search attribute value"), true),
+ check_attributevalue(_("Attri_bute value"), _("Search attribute value"), true),
check_style(_("_Style"), _("Search style"), true),
- check_font(_("_Font"), _("Search fonts"), false),
+ check_font(_("F_ont"), _("Search fonts"), false),
frame_properties(_("Properties")),
check_alltypes(_("All types"), _("Search all object types"), true),
diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h
index 64fb4cc3d..14d54b8d4 100644
--- a/src/ui/dialog/find.h
+++ b/src/ui/dialog/find.h
@@ -12,12 +12,20 @@
#ifndef INKSCAPE_UI_DIALOG_FIND_H
#define INKSCAPE_UI_DIALOG_FIND_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "ui/widget/panel.h"
#include "ui/widget/button.h"
#include "ui/widget/entry.h"
#include "ui/widget/frame.h"
#include <glib.h>
-#include <gtkmm.h>
+
+#include <gtkmm/box.h>
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/expander.h>
+#include <gtkmm/label.h>
#include "desktop.h"
#include "ui/dialog/desktop-tracker.h"
@@ -280,7 +288,13 @@ private:
Gtk::Label status;
UI::Widget::Button button_find;
UI::Widget::Button button_replace;
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox box_buttons;
+#else
Gtk::HButtonBox box_buttons;
+#endif
+
Gtk::HBox hboxbutton_row;
/**
diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp
index ba81c6d47..d70c5f187 100644
--- a/src/ui/dialog/floating-behavior.cpp
+++ b/src/ui/dialog/floating-behavior.cpp
@@ -12,6 +12,7 @@
#include <gtkmm/dialog.h>
#include <gtkmm/stock.h>
+#include <glibmm/main.h>
#include <gtk/gtk.h>
#include "floating-behavior.h"
@@ -134,7 +135,13 @@ FloatingBehavior::create(Dialog &dialog)
inline FloatingBehavior::operator Gtk::Widget &() { return *_d; }
inline GtkWidget *FloatingBehavior::gobj() { return GTK_WIDGET(_d->gobj()); }
-inline Gtk::Box* FloatingBehavior::get_vbox() { return _d->get_vbox(); }
+inline Gtk::Box* FloatingBehavior::get_vbox() {
+#if WITH_GTKMM_3_0
+ return _d->get_content_area();
+#else
+ return _d->get_vbox();
+#endif
+}
inline void FloatingBehavior::present() { _d->present(); }
inline void FloatingBehavior::hide() { _d->hide(); }
inline void FloatingBehavior::show() { _d->show(); }
diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp
index d449bad67..f0112f1d8 100644
--- a/src/ui/dialog/font-substitution.cpp
+++ b/src/ui/dialog/font-substitution.cpp
@@ -37,6 +37,8 @@
#include "libnrtype/FontFactory.h"
#include "libnrtype/font-instance.h"
+#include <glibmm/regex.h>
+
namespace Inkscape {
namespace UI {
namespace Dialog {
@@ -207,7 +209,7 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring *
// Check if any document styles are not in the actual layout
std::map<SPItem *, Glib::ustring>::const_iterator mapIter;
- for (mapIter = mapFontStyles.begin(); mapIter != mapFontStyles.end(); mapIter++) {
+ for (mapIter = mapFontStyles.begin(); mapIter != mapFontStyles.end(); ++mapIter) {
SPItem *item = mapIter->first;
Glib::ustring fonts = mapIter->second;
@@ -241,7 +243,7 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring *
}
std::set<Glib::ustring>::const_iterator setIter;
- for (setIter = setErrors.begin(); setIter != setErrors.end(); setIter++) {
+ for (setIter = setErrors.begin(); setIter != setErrors.end(); ++setIter) {
Glib::ustring err = (*setIter);
out->append(err + "\n");
g_warning("%s", err.c_str());
@@ -260,7 +262,7 @@ Glib::ustring FontSubstitution::getSubstituteFontName (Glib::ustring font)
font_instance *res = (font_factory::Default())->Face(descr);
if (res->pFont) {
PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont);
- out = pango_font_description_get_family(nFaceDesc);
+ out = sp_font_description_get_family(nFaceDesc);
}
pango_font_description_free(descr);
diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp
index 1eed8d804..9bad90e7c 100644
--- a/src/ui/dialog/glyphs.cpp
+++ b/src/ui/dialog/glyphs.cpp
@@ -1,6 +1,7 @@
/* Authors:
* Jon A. Cruz
* Abhishek Sharma
+ * Tavmjong Bah
*
* Copyright (C) 2010 Jon A. Cruz
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -18,7 +19,13 @@
#include <gtkmm/label.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/treemodelcolumn.h>
#include <gtkmm/widget.h>
@@ -335,7 +342,12 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
instanceConns(),
desktopConns()
{
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = new Gtk::Grid();
+#else
Gtk::Table *table = new Gtk::Table(3, 1, false);
+#endif
+
_getContents()->pack_start(*Gtk::manage(table), Gtk::PACK_EXPAND_WIDGET);
guint row = 0;
@@ -343,13 +355,19 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
GtkWidget *fontsel = sp_font_selector_new();
fsel = SP_FONT_SELECTOR(fontsel);
- sp_font_selector_set_font(fsel, sp_font_selector_get_font(fsel), 12.0);
+ sp_font_selector_set_fontspec( fsel, sp_font_selector_get_fontspec(fsel), 12.0 );
+
gtk_widget_set_size_request (fontsel, 0, 150);
g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this );
+#if WITH_GTKMM_3_0
+ table->attach(*Gtk::manage(Glib::wrap(fontsel)), 0, row, 3, 1);
+#else
table->attach(*Gtk::manage(Glib::wrap(fontsel)),
0, 3, row, row + 1,
Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL);
+#endif
+
row++;
@@ -357,28 +375,35 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
{
Gtk::Label *label = new Gtk::Label(_("Script: "));
+
+#if WITH_GTKMM_3_0
+ table->attach( *Gtk::manage(label), 0, row, 1, 1);
+#else
table->attach( *Gtk::manage(label),
0, 1, row, row + 1,
Gtk::SHRINK, Gtk::SHRINK);
+#endif
scriptCombo = new Gtk::ComboBoxText();
for (std::map<GUnicodeScript, Glib::ustring>::iterator it = getScriptToName().begin(); it != getScriptToName().end(); ++it)
{
-#if WITH_GTKMM_2_24
scriptCombo->append(it->second);
-#else
- scriptCombo->append_text(it->second);
-#endif
}
scriptCombo->set_active_text(getScriptToName()[G_UNICODE_SCRIPT_INVALID_CODE]);
sigc::connection conn = scriptCombo->signal_changed().connect(sigc::mem_fun(*this, &GlyphsPanel::rebuild));
instanceConns.push_back(conn);
- Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_START, Gtk::ALIGN_START, 0.0, 0.0);
+ Gtk::Alignment *align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_START, Gtk::ALIGN_START, 0.0, 0.0));
align->add(*Gtk::manage(scriptCombo));
- table->attach( *Gtk::manage(align),
+
+#if WITH_GTKMM_3_0
+ align->set_hexpand();
+ table->attach( *align, 1, row, 1, 1);
+#else
+ table->attach( *align,
1, 2, row, row + 1,
Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
+#endif
}
row++;
@@ -387,17 +412,18 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
{
Gtk::Label *label = new Gtk::Label(_("Range: "));
+
+#if WITH_GTKMM_3_0
+ table->attach( *Gtk::manage(label), 0, row, 1, 1);
+#else
table->attach( *Gtk::manage(label),
0, 1, row, row + 1,
Gtk::SHRINK, Gtk::SHRINK);
+#endif
rangeCombo = new Gtk::ComboBoxText();
for ( std::vector<NamedRange>::iterator it = getRanges().begin(); it != getRanges().end(); ++it ) {
-#if WITH_GTKMM_2_24
rangeCombo->append(it->second);
-#else
- rangeCombo->append_text(it->second);
-#endif
}
rangeCombo->set_active_text(getRanges()[1].second);
@@ -405,9 +431,15 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
instanceConns.push_back(conn);
Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_START, Gtk::ALIGN_START, 0.0, 0.0);
align->add(*Gtk::manage(rangeCombo));
+
+#if WITH_GTKMM_3_0
+ align->set_hexpand();
+ table->attach( *Gtk::manage(align), 1, row, 1, 1);
+#else
table->attach( *Gtk::manage(align),
1, 2, row, row + 1,
Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK);
+#endif
}
row++;
@@ -430,9 +462,17 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow();
scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
scroller->add(*Gtk::manage(iconView));
+
+#if WITH_GTKMM_3_0
+ scroller->set_hexpand();
+ scroller->set_vexpand();
+ table->attach(*Gtk::manage(scroller), 0, row, 3, 1);
+#else
table->attach(*Gtk::manage(scroller),
0, 3, row, row + 1,
Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL);
+#endif
+
row++;
// -------------------------------
@@ -462,9 +502,15 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
box->pack_end(*Gtk::manage(insertBtn), Gtk::PACK_SHRINK);
+#if WITH_GTKMM_3_0
+ box->set_hexpand();
+ table->attach( *Gtk::manage(box), 0, row, 3, 1);
+#else
table->attach( *Gtk::manage(box),
0, 3, row, row + 1,
Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK);
+#endif
+
row++;
// -------------------------------
@@ -528,6 +574,7 @@ void GlyphsPanel::setTargetDesktop(SPDesktop *desktop)
}
}
+// Append selected glyphs to selected text
void GlyphsPanel::insertText()
{
SPItem *textItem = 0;
@@ -619,7 +666,7 @@ void GlyphsPanel::glyphSelectionChanged()
calcCanInsert();
}
-void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, font_instance * /*font*/, GlyphsPanel *self)
+void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, Glib::ustring /*fontspec*/, GlyphsPanel *self)
{
if (self) {
self->rebuild();
@@ -675,7 +722,13 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ )
void GlyphsPanel::rebuild()
{
- font_instance *font = fsel ? sp_font_selector_get_font(fsel) : 0;
+ Glib::ustring fontspec = fsel ? sp_font_selector_get_fontspec(fsel) : "";
+
+ font_instance* font = 0;
+ if( !fontspec.empty() ) {
+ font = font_factory::Default()->FaceFromFontSpecification( fontspec.c_str() );
+ }
+
if (font) {
//double sp_font_selector_get_size (SPFontSelector *fsel);
diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h
index 162c7b296..3d0571244 100644
--- a/src/ui/dialog/glyphs.h
+++ b/src/ui/dialog/glyphs.h
@@ -20,7 +20,7 @@ class Label;
class ListStore;
}
-class SPFontSelector;
+struct SPFontSelector;
class font_instance;
@@ -54,7 +54,7 @@ private:
static GlyphColumns *getColumns();
- static void fontChangeCB(SPFontSelector *fontsel, font_instance *font, GlyphsPanel *self);
+ static void fontChangeCB(SPFontSelector *fontsel, Glib::ustring fontspec, GlyphsPanel *self);
void rebuild();
diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp
index d20f2a220..51bbc7d9a 100644
--- a/src/ui/dialog/guides.cpp
+++ b/src/ui/dialog/guides.cpp
@@ -45,8 +45,8 @@ namespace Dialogs {
GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop)
: _desktop(desktop), _guide(guide),
_relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")),
- _spin_button_x(_("_X:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu),
- _spin_button_y(_("_Y:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu),
+ _spin_button_x(C_("Guides", "_X:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu),
+ _spin_button_y(C_("Guides", "_Y:"), "", UNIT_TYPE_LINEAR, "", "", &_unit_menu),
_label_entry(_("_Label:"), _("Optionally give this guideline a name")),
_spin_angle(_("_Angle:"), "", UNIT_TYPE_RADIAL),
_mode(true), _oldpos(0.,0.), _oldangle(0.0)
@@ -70,9 +70,15 @@ void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) {
void GuidelinePropertiesDialog::_colorChanged()
{
+#if WITH_GTKMM_3_0
+ const Gdk::RGBA c = _color.get_rgba();
+ unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257;
+#else
const Gdk::Color c = _color.get_color();
unsigned r = c.get_red()/257, g = c.get_green()/257, b = c.get_blue()/257;
+#endif
//TODO: why 257? verify this!
+
sp_guide_set_color(*_guide, r, g, b, true);
}
@@ -166,32 +172,56 @@ void GuidelinePropertiesDialog::_setup() {
add_button(Gtk::Stock::DELETE, -12);
add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+#if WITH_GTKMM_3_0
+ Gtk::Box *mainVBox = get_content_area();
+ _layout_table.set_row_spacing(4);
+ _layout_table.set_column_spacing(4);
+#else
Gtk::Box *mainVBox = get_vbox();
-
_layout_table.set_spacings(4);
_layout_table.resize (3, 4);
+#endif
mainVBox->pack_start(_layout_table, false, false, 0);
_label_name.set_label("foo0");
- _layout_table.attach(_label_name,
- 0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
_label_name.set_alignment(0, 0.5);
_label_descr.set_label("foo1");
- _layout_table.attach(_label_descr,
- 0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
_label_descr.set_alignment(0, 0.5);
+
+#if WITH_GTKMM_3_0
+ _label_name.set_halign(Gtk::ALIGN_FILL);
+ _label_name.set_valign(Gtk::ALIGN_FILL);
+ _layout_table.attach(_label_name, 0, 0, 3, 1);
+
+ _label_descr.set_halign(Gtk::ALIGN_FILL);
+ _label_descr.set_valign(Gtk::ALIGN_FILL);
+ _layout_table.attach(_label_descr, 0, 1, 3, 1);
+
+ _label_entry.set_halign(Gtk::ALIGN_FILL);
+ _label_entry.set_valign(Gtk::ALIGN_FILL);
+ _label_entry.set_hexpand();
+ _layout_table.attach(_label_entry, 1, 2, 2, 1);
+
+ _color.set_halign(Gtk::ALIGN_FILL);
+ _color.set_valign(Gtk::ALIGN_FILL);
+ _color.set_hexpand();
+ _layout_table.attach(_color, 1, 3, 2, 1);
+#else
+ _layout_table.attach(_label_name,
+ 0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
- // indent
-// _layout_table.attach(*manage(new Gtk::Label(" ")),
-// 0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10);
+ _layout_table.attach(_label_descr,
+ 0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
_layout_table.attach(_label_entry,
1, 3, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
_layout_table.attach(_color,
1, 3, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+#endif
+
_color.signal_color_set().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_colorChanged));
@@ -211,6 +241,22 @@ void GuidelinePropertiesDialog::_setup() {
_spin_button_y.setDigits(3);
_spin_button_y.setIncrements(1.0, 10.0);
_spin_button_y.setRange(-1e6, 1e6);
+
+#if WITH_GTKMM_3_0
+ _spin_button_x.set_halign(Gtk::ALIGN_FILL);
+ _spin_button_x.set_valign(Gtk::ALIGN_FILL);
+ _spin_button_x.set_hexpand();
+ _layout_table.attach(_spin_button_x, 1, 4, 1, 1);
+
+ _spin_button_y.set_halign(Gtk::ALIGN_FILL);
+ _spin_button_y.set_valign(Gtk::ALIGN_FILL);
+ _spin_button_y.set_hexpand();
+ _layout_table.attach(_spin_button_y, 1, 5, 1, 1);
+
+ _unit_menu.set_halign(Gtk::ALIGN_FILL);
+ _unit_menu.set_valign(Gtk::ALIGN_FILL);
+ _layout_table.attach(_unit_menu, 2, 4, 1, 1);
+#else
_layout_table.attach(_spin_button_x,
1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
_layout_table.attach(_spin_button_y,
@@ -218,17 +264,33 @@ void GuidelinePropertiesDialog::_setup() {
_layout_table.attach(_unit_menu,
2, 3, 4, 5, Gtk::FILL, Gtk::FILL);
+#endif
// angle spinbutton
_spin_angle.setDigits(3);
_spin_angle.setIncrements(1.0, 10.0);
_spin_angle.setRange(-3600., 3600.);
+
+#if WITH_GTKMM_3_0
+ _spin_angle.set_halign(Gtk::ALIGN_FILL);
+ _spin_angle.set_valign(Gtk::ALIGN_FILL);
+ _spin_angle.set_hexpand();
+ _layout_table.attach(_spin_angle, 1, 6, 2, 1);
+
+ // mode radio button
+ _relative_toggle.set_halign(Gtk::ALIGN_FILL);
+ _relative_toggle.set_valign(Gtk::ALIGN_FILL);
+ _relative_toggle.set_hexpand();
+ _layout_table.attach(_relative_toggle, 1, 7, 2, 1);
+#else
_layout_table.attach(_spin_angle,
1, 3, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
// mode radio button
_layout_table.attach(_relative_toggle,
1, 3, 7, 8, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+#endif
+
_relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
_relative_toggle.set_active(_relative_toggle_status);
@@ -272,9 +334,16 @@ void GuidelinePropertiesDialog::_setup() {
// init name entry
_label_entry.getEntry()->set_text(_guide->label ? _guide->label : "");
+
+#if WITH_GTKMM_3_0
+ Gdk::RGBA c;
+ c.set_rgba(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0);
+ _color.set_rgba(c);
+#else
Gdk::Color c;
c.set_rgb_p(((_guide->color>>24)&0xff) / 255.0, ((_guide->color>>16)&0xff) / 255.0, ((_guide->color>>8)&0xff) / 255.0);
_color.set_color(c);
+#endif
_modeChanged(); // sets values of spinboxes.
diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h
index d06c3afc8..a15667152 100644
--- a/src/ui/dialog/guides.h
+++ b/src/ui/dialog/guides.h
@@ -11,8 +11,18 @@
#ifndef INKSCAPE_DIALOG_GUIDELINE_H
#define INKSCAPE_DIALOG_GUIDELINE_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/dialog.h>
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
#include <gtkmm/table.h>
+#endif
+
#include <gtkmm/label.h>
#include <gtkmm/colorbutton.h>
#include "ui/widget/button.h"
@@ -62,7 +72,13 @@ private:
SPDesktop *_desktop;
SPGuide *_guide;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _layout_table;
+#else
Gtk::Table _layout_table;
+#endif
+
Gtk::Label _label_name;
Gtk::Label _label_descr;
Inkscape::UI::Widget::CheckButton _relative_toggle;
diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp
index de213ca85..801ab2922 100644
--- a/src/ui/dialog/icon-preview.cpp
+++ b/src/ui/dialog/icon-preview.cpp
@@ -20,7 +20,11 @@
#include <gtkmm/buttonbox.h>
#include <boost/scoped_ptr.hpp>
#include <glib.h>
+
#include <glibmm/i18n.h>
+#include <glibmm/main.h>
+#include <glibmm/timer.h>
+
#include <gtkmm/alignment.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/frame.h>
diff --git a/src/ui/dialog/icon-preview.h b/src/ui/dialog/icon-preview.h
index 42f9176b0..8a6e19a25 100644
--- a/src/ui/dialog/icon-preview.h
+++ b/src/ui/dialog/icon-preview.h
@@ -66,7 +66,12 @@ private:
gdouble minDelay;
Gtk::VBox iconBox;
+
+#if WITH_GTKMM_3_0
+ Gtk::Paned splitter;
+#else
Gtk::HPaned splitter;
+#endif
Glib::ustring targetId;
int hot;
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 0e4d7fd56..65c6a20fe 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -17,9 +17,9 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
-
#include "inkscape-preferences.h"
+#include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
#include <gtkmm/main.h>
#include <gtkmm/frame.h>
#include <gtkmm/scrolledwindow.h>
@@ -47,7 +47,11 @@
#include "display/canvas-grid.h"
#include "path-prefix.h"
#include "io/resource.h"
+#include "io/sys.h"
#include "inkscape.h"
+#include "shortcuts.h"
+#include "document.h"
+
#ifdef HAVE_ASPELL
# include <aspell.h>
@@ -137,6 +141,7 @@ InkscapePreferences::InkscapePreferences()
initPageRendering();
initPageSpellcheck();
+
signalPresent().connect(sigc::mem_fun(*this, &InkscapePreferences::_presentPages));
//calculate the size request for this dialog
@@ -194,13 +199,13 @@ void InkscapePreferences::AddDotSizeSpinbutton(DialogPage &p, Glib::ustring cons
{
PrefSpinButton* sb = Gtk::manage( new PrefSpinButton);
sb->init ( prefs_path + "/dot-size", 0.0, 1000.0, 0.1, 10.0, def_value, false, false);
- p.add_line( false, _("Ctrl+click dot size:"), *sb, _("times current stroke width"),
+ p.add_line( false, _("Ctrl+click _dot size:"), *sb, _("times current stroke width"),
_("Size of dots created with Ctrl+click (relative to current stroke width)"),
false );
}
-void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatch *swatch)
+static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatch *swatch)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop == NULL)
@@ -315,6 +320,7 @@ void InkscapePreferences::initPageTools()
AddSelcueCheckbox(_page_selector, "/tools/select", false);
+ AddGradientCheckbox(_page_selector, "/tools/select", false);
_page_selector.add_group_header( _("When transforming, show"));
_t_sel_trans_obj.init ( _("Objects"), "/tools/select/show", "content", true, 0);
_page_selector.add_line( true, "", _t_sel_trans_obj, "",
@@ -353,7 +359,7 @@ void InkscapePreferences::initPageTools()
_t_node_pathflash_selected.init ( _("Show temporary outline for selected paths"), "/tools/nodes/pathflash_selected", false);
_page_node.add_line( true, "", _t_node_pathflash_selected, "", _("Show temporary outline even when a path is selected for editing"));
_t_node_pathflash_timeout.init("/tools/nodes/pathflash_timeout", 0, 10000.0, 100.0, 100.0, 1000.0, true, false);
- _page_node.add_line( false, _("Flash time:"), _t_node_pathflash_timeout, "ms", _("Specifies how long the path outline will be visible after a mouse-over (in milliseconds); specify 0 to have the outline shown until mouse leaves the path"), false);
+ _page_node.add_line( false, _("_Flash time:"), _t_node_pathflash_timeout, "ms", _("Specifies how long the path outline will be visible after a mouse-over (in milliseconds); specify 0 to have the outline shown until mouse leaves the path"), false);
_page_node.add_group_header(_("Editing preferences"));
_t_node_single_node_transform_handles.init(_("Show transform handles for single nodes"), "/tools/nodes/single_node_transform_handles", false);
_page_node.add_line( true, "", _t_node_single_node_transform_handles, "", _("Show transform handles even when only a single node is selected"));
@@ -445,9 +451,12 @@ void InkscapePreferences::initPageTools()
Glib::ustring sizeLabels[] = {_("Pixel"), _("Point"), _("Pica"), _("Millimeter"), _("Centimeter"), _("Inch"), _("Em square")/*, _("Ex square"), _("Percent")*/};
int sizeValues[] = {SP_CSS_UNIT_PX, SP_CSS_UNIT_PT, SP_CSS_UNIT_PC, SP_CSS_UNIT_MM, SP_CSS_UNIT_CM, SP_CSS_UNIT_IN, SP_CSS_UNIT_EM/*, SP_CSS_UNIT_EX, SP_CSS_UNIT_PERCENT*/};
+ _page_text.add_group_header( _("Text units"));
_font_unit_type.init( "/options/font/unitType", sizeLabels, sizeValues, G_N_ELEMENTS(sizeLabels), SP_CSS_UNIT_PT );
_page_text.add_line( false, _("Text size unit type:"), _font_unit_type, "",
_("Set the type of unit used in the text toolbar and text dialogs"), false);
+ _font_output_px.init ( _("Always output text size in pixels (px)"), "/options/font/textOutputPx", true);
+ _page_text.add_line( false, "", _font_output_px, "", _("Always convert the text size units above into pixels (px) before saving to file"));
this->AddNewObjectsStyle(_page_text, "/tools/text");
@@ -475,6 +484,11 @@ void InkscapePreferences::initPageTools()
_page_gradient.add_line( false, "", _misc_gradienteditor, "",
_("When on, the Gradient Edit button in the Fill & Stroke dialog will show the legacy Gradient Editor dialog, when off the Gradient Tool will be used"), true);
+ _misc_gradientangle.init("/dialogs/gradienteditor/angle", -359, 359, 1, 90, 0, false, false);
+ _page_gradient.add_line( false, _("Linear gradient _angle:"), _misc_gradientangle, "",
+ _("Default angle of new linear gradients in degrees (clockwise from horizontal)"), false);
+
+
//Dropper
this->AddPage(_page_dropper, _("Dropper"), iter_tools, PREFS_PAGE_TOOLS_DROPPER);
this->AddSelcueCheckbox(_page_dropper, "/tools/dropper", true);
@@ -567,17 +581,14 @@ void InkscapePreferences::initPageUI()
_misc_recent.init("/options/maxrecentdocuments/value", 0.0, 1000.0, 1.0, 1.0, 1.0, true, false);
- Gtk::HBox* recent_hbox = Gtk::manage(new Gtk::HBox());
Gtk::Button* reset_recent = Gtk::manage(new Gtk::Button(_("Clear list")));
reset_recent->signal_clicked().connect(sigc::mem_fun(*this, &InkscapePreferences::on_reset_open_recent_clicked));
- recent_hbox->pack_start(_misc_recent, false, false);
- recent_hbox->pack_start(*reset_recent, false, false);
- _page_ui.add_line( false, _("Maximum documents in Open Recent:"), *recent_hbox, "",
- _("Set the maximum length of the Open Recent list in the File menu, or clear the list"), false);
+ _page_ui.add_line( false, _("Maximum documents in Open _Recent:"), _misc_recent, "",
+ _("Set the maximum length of the Open Recent list in the File menu, or clear the list"), false, reset_recent);
_ui_zoom_correction.init(300, 30, 1.00, 200.0, 1.0, 10.0, 1.0);
- _page_ui.add_line( false, _("Zoom correction factor (in %):"), _ui_zoom_correction, "",
+ _page_ui.add_line( false, _("_Zoom correction factor (in %):"), _ui_zoom_correction, "",
_("Adjust the slider until the length of the ruler on your screen matches its real length. This information is used when zooming to 1:1, 1:2, etc., to display objects in their true sizes"), true);
@@ -586,10 +597,28 @@ void InkscapePreferences::initPageUI()
_("When on, will allow dynamic layout of components that are not completely finished being refactored"), true);
/* show infobox */
- _show_filters_info_box.init( _("Show filter primitives infobox"), "/options/showfiltersinfobox/value", true);
+ _show_filters_info_box.init( _("Show filter primitives infobox (requires restart)"), "/options/showfiltersinfobox/value", true);
_page_ui.add_line(false, "", _show_filters_info_box, "",
_("Show icons and descriptions for the filter primitives available at the filter effects dialog"));
+ {
+ Glib::ustring dockbarstyleLabels[] = {_("Icons only"), _("Text only"), _("Icons and text")};
+ int dockbarstyleValues[] = {0, 1, 2};
+
+ /* dockbar style */
+ _dockbar_style.init( "/options/dock/dockbarstyle", dockbarstyleLabels, dockbarstyleValues, G_N_ELEMENTS(dockbarstyleLabels), 0);
+ _page_ui.add_line(false, _("Dockbar style (requires restart):"), _dockbar_style, "",
+ _("Selects whether the vertical bars on the dockbar will show text labels, icons, or both"), false);
+
+ Glib::ustring switcherstyleLabels[] = {_("Text only"), _("Icons only"), _("Icons and text")}; /* see bug #1098437 */
+ int switcherstyleValues[] = {0, 1, 2};
+
+ /* switcher style */
+ _switcher_style.init( "/options/dock/switcherstyle", switcherstyleLabels, switcherstyleValues, G_N_ELEMENTS(switcherstyleLabels), 0);
+ _page_ui.add_line(false, _("Switcher style (requires restart):"), _switcher_style, "",
+ _("Selects whether the dockbar switcher will show text labels, icons, or both"), false);
+ }
+
// Windows
_win_save_geom.init ( _("Save and restore window geometry for each document"), "/options/savewindowgeometry/value", 1, true, 0);
_win_save_geom_prefs.init ( _("Remember and use last window's geometry"), "/options/savewindowgeometry/value", 2, false, &_win_save_geom);
@@ -601,10 +630,12 @@ void InkscapePreferences::initPageUI()
_win_dockable.init ( _("Dockable"), "/options/dialogtype/value", 1, true, 0);
_win_floating.init ( _("Floating"), "/options/dialogtype/value", 0, false, &_win_dockable);
+
_win_native.init ( _("Native open/save dialogs"), "/options/desktopintegration/value", 1, true, 0);
_win_gtk.init ( _("GTK open/save dialogs"), "/options/desktopintegration/value", 0, false, &_win_native);
_win_hide_task.init ( _("Dialogs are hidden in taskbar"), "/options/dialogsskiptaskbar/value", true);
+ _win_save_viewport.init ( _("Save and restore documents viewport"), "/options/savedocviewport/value", true);
_win_zoom_resize.init ( _("Zoom when window is resized"), "/options/stickyzoom/value", false);
_win_show_close.init ( _("Show close button on dialogs"), "/dialogs/showclose", false);
_win_ontop_none.init ( _("None"), "/options/transientpolicy/value", 0, false, 0);
@@ -625,6 +656,8 @@ void InkscapePreferences::initPageUI()
_page_windows.add_line( true, "", _win_save_dialog_pos_on, "",
_("Save and restore dialogs status (the last open windows dialogs are saved when it closes)"));
+
+
_page_windows.add_group_header( _("Dialog behavior (requires restart)"));
_page_windows.add_line( true, "", _win_dockable, "",
_("Dockable"));
@@ -651,11 +684,12 @@ void InkscapePreferences::initPageUI()
_page_windows.add_group_header( _("Dialog Transparency"));
_win_trans_focus.init("/dialogs/transparency/on-focus", 0.5, 1.0, 0.01, 0.1, 1.0, false, false);
- _page_windows.add_line( true, _("Opacity when focused:"), _win_trans_focus, "", "");
+ _page_windows.add_line( true, _("_Opacity when focused:"), _win_trans_focus, "", "", false);
_win_trans_blur.init("/dialogs/transparency/on-blur", 0.0, 1.0, 0.01, 0.1, 0.5, false, false);
- _page_windows.add_line( true, _("Opacity when unfocused:"), _win_trans_blur, "", "");
+ _page_windows.add_line( true, _("Opacity when _unfocused:"), _win_trans_blur, "", "", false);
_win_trans_time.init("/dialogs/transparency/animate-time", 0, 1000, 10, 100, 100, true, false);
- _page_windows.add_line( true, _("Time of opacity change animation:"), _win_trans_time, "ms", "");
+ _page_windows.add_line( true, _("_Time of opacity change animation:"), _win_trans_time, "ms", "", false);
+
_page_windows.add_group_header( _("Miscellaneous"));
#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs
@@ -664,6 +698,8 @@ void InkscapePreferences::initPageUI()
#endif
_page_windows.add_line( true, "", _win_zoom_resize, "",
_("Zoom drawing when document window is resized, to keep the same area visible (this is the default which can be changed in any window using the button above the right scrollbar)"));
+ _page_windows.add_line( true, "", _win_save_viewport, "",
+ _("Save documents viewport (zoom and panning position). Useful to turn off when sharing version controlled files."));
_page_windows.add_line( true, "", _win_show_close, "",
_("Whether dialog windows have a close button (requires restart)"));
this->AddPage(_page_windows, _("Windows"), iter_ui, PREFS_PAGE_UI_WINDOWS);
@@ -729,6 +765,8 @@ void InkscapePreferences::initPageUI()
_grids_axonom.add_line( false, _("Major grid line every:"), _grids_axonom_empspacing, "", "", false);
this->AddPage(_page_grids, _("Grids"), iter_ui, PREFS_PAGE_UI_GRIDS);
+
+ initKeyboardShortcuts(iter_ui);
}
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
@@ -760,10 +798,17 @@ static void proofComboChanged( Gtk::ComboBoxText* combo )
}
static void gamutColorChanged( Gtk::ColorButton* btn ) {
+#if WITH_GTKMM_3_0
+ Gdk::RGBA rgba = btn->get_rgba();
+ gushort r = rgba.get_red_u();
+ gushort g = rgba.get_green_u();
+ gushort b = rgba.get_blue_u();
+#else
Gdk::Color color = btn->get_color();
gushort r = color.get_red();
gushort g = color.get_green();
gushort b = color.get_blue();
+#endif
gchar* tmp = g_strdup_printf("#%02x%02x%02x", (r >> 8), (g >> 8), (b >> 8) );
@@ -792,14 +837,14 @@ void InkscapePreferences::initPageIO()
// Input devices options
_mouse_sens.init ( "/options/cursortolerance/value", 0.0, 30.0, 1.0, 1.0, 8.0, true, false);
- _page_mouse.add_line( false, _("Grab sensitivity:"), _mouse_sens, _("pixels"),
+ _page_mouse.add_line( false, _("_Grab sensitivity:"), _mouse_sens, _("pixels (requires restart)"),
_("How close on the screen you need to be to an object to be able to grab it with mouse (in screen pixels)"), false);
_mouse_thres.init ( "/options/dragtolerance/value", 0.0, 20.0, 1.0, 1.0, 4.0, true, false);
- _page_mouse.add_line( false, _("Click/drag threshold:"), _mouse_thres, _("pixels"),
+ _page_mouse.add_line( false, _("_Click/drag threshold:"), _mouse_thres, _("pixels"),
_("Maximum mouse drag (in screen pixels) which is considered a click, not a drag"), false);
_mouse_grabsize.init("/options/grabsize/value", 1, 7, 1, 2, 3, 0);
- _page_mouse.add_line(false, _("Handle size"), _mouse_grabsize, "",
+ _page_mouse.add_line(false, _("_Handle size:"), _mouse_grabsize, "",
_("Set the relative size of node handles"), true);
_mouse_use_ext_input.init( _("Use pressure-sensitive tablet (requires restart)"), "/options/useextinput/value", true);
@@ -821,7 +866,7 @@ void InkscapePreferences::initPageIO()
_page_svgoutput.add_line( true, "", _svgoutput_inlineattrs, "", _("Put attributes on the same line as the element tag"), false);
_svgoutput_indent.init("/options/svgoutput/indent", 0.0, 1000.0, 1.0, 2.0, 2.0, true, false);
- _page_svgoutput.add_line( true, _("Indent, spaces:"), _svgoutput_indent, "", _("The number of spaces to use for indenting nested elements; set to 0 for no indentation"), false);
+ _page_svgoutput.add_line( true, _("_Indent, spaces:"), _svgoutput_indent, "", _("The number of spaces to use for indenting nested elements; set to 0 for no indentation"), false);
_page_svgoutput.add_group_header( _("Path data"));
@@ -834,10 +879,10 @@ void InkscapePreferences::initPageIO()
_page_svgoutput.add_group_header( _("Numbers"));
_svgoutput_numericprecision.init("/options/svgoutput/numericprecision", 1.0, 16.0, 1.0, 2.0, 8.0, true, false);
- _page_svgoutput.add_line( true, _("Numeric precision:"), _svgoutput_numericprecision, "", _("Significant figures of the values written to the SVG file"), false);
+ _page_svgoutput.add_line( true, _("_Numeric precision:"), _svgoutput_numericprecision, "", _("Significant figures of the values written to the SVG file"), false);
_svgoutput_minimumexponent.init("/options/svgoutput/minimumexponent", -32.0, -1, 1.0, 2.0, -8.0, true, false);
- _page_svgoutput.add_line( true, _("Minimum exponent:"), _svgoutput_minimumexponent, "", _("The smallest number written to SVG is 10 to the power of this exponent; anything smaller is written as zero"), false);
+ _page_svgoutput.add_line( true, _("Minimum _exponent:"), _svgoutput_minimumexponent, "", _("The smallest number written to SVG is 10 to the power of this exponent; anything smaller is written as zero"), false);
/* Code to add controls for attribute checking options */
@@ -928,8 +973,15 @@ void InkscapePreferences::initPageIO()
_("Highlights colors that are out of gamut for the target device"), false);
Glib::ustring colorStr = prefs->getString("/options/softproof/gamutcolor");
+
+#if WITH_GTKMM_3_0
+ Gdk::RGBA tmpColor( colorStr.empty() ? "#00ff00" : colorStr);
+ _cms_gamutcolor.set_rgba( tmpColor );
+#else
Gdk::Color tmpColor( colorStr.empty() ? "#00ff00" : colorStr);
_cms_gamutcolor.set_color( tmpColor );
+#endif
+
_page_cms.add_line( true, _("Out of gamut warning color:"), _cms_gamutcolor, "",
_("Selects the color used for out of gamut warning"), false);
@@ -967,18 +1019,10 @@ void InkscapePreferences::initPageIO()
Glib::ustring current = prefs->getString( "/options/displayprofile/uri" );
gint index = 0;
-#if WITH_GTKMM_2_24
_cms_display_profile.append(_("<none>"));
-#else
- _cms_display_profile.append_text(_("<none>"));
-#endif
index++;
for ( std::vector<Glib::ustring>::iterator it = names.begin(); it != names.end(); ++it ) {
-#if WITH_GTKMM_2_24
_cms_display_profile.append( *it );
-#else
- _cms_display_profile.append_text( *it );
-#endif
Glib::ustring path = CMSSystem::getPathForProfile(*it);
if ( !path.empty() && path == current ) {
_cms_display_profile.set_active(index);
@@ -993,11 +1037,7 @@ void InkscapePreferences::initPageIO()
current = prefs->getString("/options/softproof/uri");
index = 0;
for ( std::vector<Glib::ustring>::iterator it = names.begin(); it != names.end(); ++it ) {
-#if WITH_GTKMM_2_24
_cms_proof_profile.append( *it );
-#else
- _cms_proof_profile.append_text( *it );
-#endif
Glib::ustring path = CMSSystem::getPathForProfile(*it);
if ( !path.empty() && path == current ) {
_cms_proof_profile.set_active(index);
@@ -1029,12 +1069,16 @@ void InkscapePreferences::initPageIO()
// Autosave options
_save_autosave_enable.init( _("Enable autosave (requires restart)"), "/options/autosave/enable", false);
_page_autosave.add_line(false, "", _save_autosave_enable, "", _("Automatically save the current document(s) at a given interval, thus minimizing loss in case of a crash"), false);
- _save_autosave_interval.init("/options/autosave/interval", 1.0, 10800.0, 1.0, 10.0, 10.0, true, false);
- _page_autosave.add_line(false, _("Interval (in minutes):"), _save_autosave_interval, "", _("Interval (in minutes) at which document will be autosaved"), false);
_save_autosave_path.init("/options/autosave/path", true);
- _page_autosave.add_line(false, C_("Filesystem", "Path:"), _save_autosave_path, "", _("The directory where autosaves will be written"), false);
+ if (prefs->getString("/options/autosave/path").empty()) {
+ // Show the default fallback "tmp dir" if autosave path is not set.
+ _save_autosave_path.set_text(Glib::get_tmp_dir());
+ }
+ _page_autosave.add_line(false, C_("Filesystem", "Autosave _directory:"), _save_autosave_path, "", _("The directory where autosaves will be written. This should be an absolute path (starts with / on UNIX or a drive letter such as C: on Windows). "), false);
+ _save_autosave_interval.init("/options/autosave/interval", 1.0, 10800.0, 1.0, 10.0, 10.0, true, false);
+ _page_autosave.add_line(false, _("_Interval (in minutes):"), _save_autosave_interval, "", _("Interval (in minutes) at which document will be autosaved"), false);
_save_autosave_max.init("/options/autosave/max", 1.0, 100.0, 1.0, 10.0, 10.0, true, false);
- _page_autosave.add_line(false, _("Maximum number of autosaves:"), _save_autosave_max, "", _("Maximum number of autosaved files; use this to limit the storage space used"), false);
+ _page_autosave.add_line(false, _("_Maximum number of autosaves:"), _save_autosave_max, "", _("Maximum number of autosaved files; use this to limit the storage space used"), false);
/* When changing the interval or enabling/disabling the autosave function,
* update our running configuration
@@ -1053,13 +1097,13 @@ void InkscapePreferences::initPageIO()
// Open Clip Art options
_importexport_ocal_url.init("/options/ocalurl/str", true, g_strdup_printf("openclipart.org"));
- _page_openclipart.add_line( false, _("Open Clip Art Library Server Name:"), _importexport_ocal_url, "",
+ _page_openclipart.add_line( false, _("Open Clip Art Library _Server Name:"), _importexport_ocal_url, "",
_("The server name of the Open Clip Art Library webdav server; it's used by the Import and Export to OCAL function"), true);
_importexport_ocal_username.init("/options/ocalusername/str", true);
- _page_openclipart.add_line( false, _("Open Clip Art Library Username:"), _importexport_ocal_username, "",
+ _page_openclipart.add_line( false, _("Open Clip Art Library _Username:"), _importexport_ocal_username, "",
_("The username used to log into Open Clip Art Library"), true);
_importexport_ocal_password.init("/options/ocalpassword/str", false);
- _page_openclipart.add_line( false, _("Open Clip Art Library Password:"), _importexport_ocal_password, "",
+ _page_openclipart.add_line( false, _("Open Clip Art Library _Password:"), _importexport_ocal_password, "",
_("The password used to log into Open Clip Art Library"), true);
this->AddPage(_page_openclipart, _("Open Clip Art"), iter_io, PREFS_PAGE_IO_OPENCLIPART);
}
@@ -1070,9 +1114,13 @@ void InkscapePreferences::initPageBehavior()
_path_behavior = _page_list.get_model()->get_path(iter_behavior);
_misc_simpl.init("/options/simplifythreshold/value", 0.0001, 1.0, 0.0001, 0.0010, 0.0010, false, false);
- _page_behavior.add_line( false, _("Simplification threshold:"), _misc_simpl, "",
+ _page_behavior.add_line( false, _("_Simplification threshold:"), _misc_simpl, "",
_("How strong is the Node tool's Simplify command by default. If you invoke this command several times in quick succession, it will act more and more aggressively; invoking it again after a pause restores the default threshold."), false);
+ _markers_color_stock.init ( _("Color stock markers the same color as object"), "/options/markers/colorStockMarkers", true);
+ _markers_color_custom.init ( _("Color custom markers the same color as object"), "/options/markers/colorCustomMarkers", false);
+ _markers_color_update.init ( _("Update marker color when object color changes"), "/options/markers/colorUpdateMarkers", true);
+
// Selecting options
_sel_all.init ( _("Select in all layers"), "/options/kbselection/inlayer", PREFS_SELECTION_ALL, false, 0);
_sel_current.init ( _("Select only within current layer"), "/options/kbselection/inlayer", PREFS_SELECTION_LAYER, true, &_sel_all);
@@ -1081,6 +1129,9 @@ void InkscapePreferences::initPageBehavior()
_sel_locked.init ( _("Ignore locked objects and layers"), "/options/kbselection/onlysensitive", true);
_sel_layer_deselects.init ( _("Deselect upon layer change"), "/options/selection/layerdeselect", true);
+ _page_select.add_line( false, "", _sel_layer_deselects, "",
+ _("Uncheck this to be able to keep the current objects selected when the current layer changes"));
+
_page_select.add_group_header( _("Ctrl+A, Tab, Shift+Tab"));
_page_select.add_line( true, "", _sel_all, "",
_("Make keyboard selection commands work on objects in all layers"));
@@ -1093,10 +1144,6 @@ void InkscapePreferences::initPageBehavior()
_page_select.add_line( true, "", _sel_locked, "",
_("Uncheck this to be able to select objects that are locked (either by themselves or by being in a locked layer)"));
- _page_select.add_line( false, "", _sel_layer_deselects, "",
- _("Uncheck this to be able to keep the current objects selected when the current layer changes"));
-
-
_sel_cycle.init ( _("Wrap when cycling objects in z-order"), "/options/selection/cycleWrap", true);
_page_select.add_group_header( _("Alt+Scroll Wheel"));
@@ -1131,25 +1178,27 @@ void InkscapePreferences::initPageBehavior()
// Scrolling options
_scroll_wheel.init ( "/options/wheelscroll/value", 0.0, 1000.0, 1.0, 1.0, 40.0, true, false);
- _page_scrolling.add_line( false, _("Mouse wheel scrolls by:"), _scroll_wheel, _("pixels"),
+ _page_scrolling.add_line( false, _("Mouse _wheel scrolls by:"), _scroll_wheel, _("pixels"),
_("One mouse wheel notch scrolls by this distance in screen pixels (horizontally with Shift)"), false);
_page_scrolling.add_group_header( _("Ctrl+arrows"));
_scroll_arrow_px.init ( "/options/keyscroll/value", 0.0, 1000.0, 1.0, 1.0, 10.0, true, false);
- _page_scrolling.add_line( true, _("Scroll by:"), _scroll_arrow_px, _("pixels"),
+ _page_scrolling.add_line( true, _("Sc_roll by:"), _scroll_arrow_px, _("pixels"),
_("Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)"), false);
_scroll_arrow_acc.init ( "/options/scrollingacceleration/value", 0.0, 5.0, 0.01, 1.0, 0.35, false, false);
- _page_scrolling.add_line( true, _("Acceleration:"), _scroll_arrow_acc, "",
+ _page_scrolling.add_line( true, _("_Acceleration:"), _scroll_arrow_acc, "",
_("Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no acceleration)"), false);
_page_scrolling.add_group_header( _("Autoscrolling"));
_scroll_auto_speed.init ( "/options/autoscrollspeed/value", 0.0, 5.0, 0.01, 1.0, 0.7, false, false);
- _page_scrolling.add_line( true, _("Speed:"), _scroll_auto_speed, "",
+ _page_scrolling.add_line( true, _("_Speed:"), _scroll_auto_speed, "",
_("How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn autoscroll off)"), false);
_scroll_auto_thres.init ( "/options/autoscrolldistance/value", -600.0, 600.0, 1.0, 1.0, -10.0, true, false);
- _page_scrolling.add_line( true, _("Threshold:"), _scroll_auto_thres, _("pixels"),
+ _page_scrolling.add_line( true, _("_Threshold:"), _scroll_auto_thres, _("pixels"),
_("How far (in screen pixels) you need to be from the canvas edge to trigger autoscroll; positive is outside the canvas, negative is within the canvas"), false);
+/*
_scroll_space.init ( _("Left mouse button pans when Space is pressed"), "/options/spacepans/value", false);
_page_scrolling.add_line( false, "", _scroll_space, "",
_("When on, pressing and holding Space and dragging with left mouse button pans canvas (as in Adobe Illustrator); when off, Space temporarily switches to Selector tool (default)"));
+*/
_wheel_zoom.init ( _("Mouse wheel zooms by default"), "/options/wheelzooms/value", false);
_page_scrolling.add_line( false, "", _wheel_zoom, "",
_("When on, mouse wheel zooms without Ctrl and scrolls canvas with Ctrl; when off, it zooms with Ctrl and scrolls without Ctrl"));
@@ -1161,7 +1210,7 @@ void InkscapePreferences::initPageBehavior()
_("After snapping, a symbol is drawn at the point that has snapped"));
_snap_delay.init("/options/snapdelay/value", 0, 1000, 50, 100, 300, 0);
- _page_snapping.add_line( false, _("Delay (in ms):"), _snap_delay, "",
+ _page_snapping.add_line( false, _("_Delay (in ms):"), _snap_delay, "",
_("Postpone snapping as long as the mouse is moving, and then wait an additional fraction of a second. This additional delay is specified here. When set to zero or to a very small number, snapping will be immediate."), true);
_snap_closest_only.init( _("Only snap the node closest to the pointer"), "/options/snapclosestonly/value", false);
@@ -1169,7 +1218,7 @@ void InkscapePreferences::initPageBehavior()
_("Only try to snap the node that is initially closest to the mouse pointer"));
_snap_weight.init("/options/snapweight/value", 0, 1, 0.1, 0.2, 0.5, 1);
- _page_snapping.add_line( false, _("Weight factor:"), _snap_weight, "",
+ _page_snapping.add_line( false, _("_Weight factor:"), _snap_weight, "",
_("When multiple snap solutions are found, then Inkscape can either prefer the closest transformation (when set to 0), or prefer the node that was initially the closest to the pointer (when set to 1)"), true);
_snap_mouse_pointer.init( _("Snap the mouse pointer when dragging a constrained knot"), "/options/snapmousepointer/value", false);
@@ -1181,14 +1230,14 @@ void InkscapePreferences::initPageBehavior()
// Steps options
_steps_arrow.init ( "/options/nudgedistance/value", 0.0, 1000.0, 0.01, 2.0, UNIT_TYPE_LINEAR, "px");
//nudgedistance is limited to 1000 in select-context.cpp: use the same limit here
- _page_steps.add_line( false, _("Arrow keys move by:"), _steps_arrow, "",
+ _page_steps.add_line( false, _("_Arrow keys move by:"), _steps_arrow, "",
_("Pressing an arrow key moves selected object(s) or node(s) by this distance"), false);
_steps_scale.init ( "/options/defaultscale/value", 0.0, 1000.0, 0.01, 2.0, UNIT_TYPE_LINEAR, "px");
//defaultscale is limited to 1000 in select-context.cpp: use the same limit here
- _page_steps.add_line( false, _("> and < scale by:"), _steps_scale, "",
+ _page_steps.add_line( false, _("> and < _scale by:"), _steps_scale, "",
_("Pressing > or < scales selection up or down by this increment"), false);
_steps_inset.init ( "/options/defaultoffsetwidth/value", 0.0, 3000.0, 0.01, 2.0, UNIT_TYPE_LINEAR, "px");
- _page_steps.add_line( false, _("Inset/Outset by:"), _steps_inset, "",
+ _page_steps.add_line( false, _("_Inset/Outset by:"), _steps_inset, "",
_("Inset and Outset commands displace the path by this distance"), false);
_steps_compass.init ( _("Compass-like display of angles"), "/options/compassangledisplay/value", true);
_page_steps.add_line( false, "", _steps_compass, "",
@@ -1198,13 +1247,13 @@ void InkscapePreferences::initPageBehavior()
int values[num_items] = {2, 3, 4, 5, 6, 8, 10, 12, 15, 18, 24, 30, 60, 90, 180, 360, 0};
_steps_rot_snap.set_size_request(_sb_width);
_steps_rot_snap.init("/options/rotationsnapsperpi/value", labels, values, num_items, 12);
- _page_steps.add_line( false, _("Rotation snaps every:"), _steps_rot_snap, _("degrees"),
+ _page_steps.add_line( false, _("_Rotation snaps every:"), _steps_rot_snap, _("degrees"),
_("Rotating with Ctrl pressed snaps every that much degrees; also, pressing [ or ] rotates by this amount"), false);
_steps_rot_relative.init ( _("Relative snapping of guideline angles"), "/options/relativeguiderotationsnap/value", false);
_page_steps.add_line( false, "", _steps_rot_relative, "",
_("When on, the snap angles when rotating a guideline will be relative to the original angle"));
_steps_zoom.init ( "/options/zoomincrement/value", 101.0, 500.0, 1.0, 1.0, 1.414213562, true, true);
- _page_steps.add_line( false, _("Zoom in/out by:"), _steps_zoom, _("%"),
+ _page_steps.add_line( false, _("_Zoom in/out by:"), _steps_zoom, _("%"),
_("Zoom tool click, +/- keys, and middle click zoom in and out by this multiplier"), false);
this->AddPage(_page_steps, _("Steps"), iter_behavior, PREFS_PAGE_BEHAVIOR_STEPS);
@@ -1253,7 +1302,7 @@ void InkscapePreferences::initPageBehavior()
_page_mask.add_group_header( _("Before applying"));
_mask_grouping_none.init( _("Do not group clipped/masked objects"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_NONE, true, 0);
- _mask_grouping_separate.init( _("Enclose every clipped/masked object in its own group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_SEPARATE, false, &_mask_grouping_none);
+ _mask_grouping_separate.init( _("Put every clipped/masked object in its own group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_SEPARATE, false, &_mask_grouping_none);
_mask_grouping_all.init( _("Put all clipped/masked objects into one group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_ALL, false, &_mask_grouping_none);
_page_mask.add_line(true, "", _mask_grouping_none, "",
@@ -1272,6 +1321,17 @@ void InkscapePreferences::initPageBehavior()
_("Ungroup groups created when setting clip/mask"));
this->AddPage(_page_mask, _("Clippaths and masks"), iter_behavior, PREFS_PAGE_BEHAVIOR_MASKS);
+
+
+ _page_markers.add_group_header( _("Stroke Style Markers"));
+ _page_markers.add_line( true, "", _markers_color_stock, "",
+ _("Stroke color same as object, fill color either object fill color or marker fill color"));
+ _page_markers.add_line( true, "", _markers_color_custom, "",
+ _("Stroke color same as object, fill color either object fill color or marker fill color"));
+ _page_markers.add_line( true, "", _markers_color_update, "",
+ _("Update marker color when object color changes"));
+
+ this->AddPage(_page_markers, _("Markers"), iter_behavior, PREFS_PAGE_BEHAVIOR_MARKERS);
}
void InkscapePreferences::initPageRendering()
@@ -1279,12 +1339,12 @@ void InkscapePreferences::initPageRendering()
/* threaded blur */ //related comments/widgets/functions should be renamed and option should be moved elsewhere when inkscape is fully multi-threaded
_filter_multi_threaded.init("/options/threading/numthreads", 1.0, 8.0, 1.0, 2.0, 4.0, true, false);
- _page_rendering.add_line( false, _("Number of Threads:"), _filter_multi_threaded, _("(requires restart)"),
+ _page_rendering.add_line( false, _("Number of _Threads:"), _filter_multi_threaded, _("(requires restart)"),
_("Configure number of processors/threads to use when rendering filters"), false);
// rendering cache
_rendering_cache_size.init("/options/renderingcache/size", 0.0, 4096.0, 1.0, 32.0, 64.0, true, false);
- _page_rendering.add_line( false, _("Rendering cache size:"), _rendering_cache_size, C_("mebibyte (2^20 bytes) abbreviation","MiB"), _("Set the amount of memory per document which can be used to store rendered parts of the drawing for later reuse; set to zero to disable caching"), false);
+ _page_rendering.add_line( false, _("Rendering _cache size:"), _rendering_cache_size, C_("mebibyte (2^20 bytes) abbreviation","MiB"), _("Set the amount of memory per document which can be used to store rendered parts of the drawing for later reuse; set to zero to disable caching"), false);
/* blur quality */
_blur_quality_best.init ( _("Best quality (slowest)"), "/options/blurquality/value",
@@ -1351,12 +1411,12 @@ void InkscapePreferences::initPageBitmaps()
_page_bitmaps.add_line( false, "", _misc_bitmap_autoreload, "",
_("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);
+ _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);
- _page_bitmaps.add_line( false, _("Default export resolution:"), _importexport_export_res, _("dpi"),
+ _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);
- _page_bitmaps.add_line( false, _("Resolution for Create Bitmap Copy:"), _bitmap_copy_res, _("dpi"),
+ _page_bitmaps.add_line( false, _("Resolution for Create Bitmap _Copy:"), _bitmap_copy_res, _("dpi"),
_("Resolution used by the Create Bitmap Copy command"), false);
{
Glib::ustring labels[] = {_("Always embed"), _("Always link"), _("Ask")};
@@ -1365,12 +1425,344 @@ void InkscapePreferences::initPageBitmaps()
_page_bitmaps.add_line( false, _("Bitmap import:"), _bitmap_import, "", "", false);
}
_importexport_import_res.init("/dialogs/import/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false);
- _page_bitmaps.add_line( false, _("Default import resolution:"), _importexport_import_res, _("dpi"),
+ _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);
+ _page_bitmaps.add_line( false, "", _importexport_import_res_override, "",
+ _("Use default bitmap resolution in favor of information from file"));
this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS);
}
+void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui)
+{
+ std::vector<Glib::ustring> fileNames;
+ std::vector<Glib::ustring> fileLabels;
+
+ sp_shortcut_get_file_names(&fileLabels, &fileNames);
+
+ _kb_filelist.init( "/options/kbshortcuts/shortcutfile", &fileLabels[0], &fileNames[0], fileLabels.size(), fileNames[0]);
+
+ Glib::ustring tooltip(_("Select a file of predefined shortcuts to use. Any customized shortcuts you create will be added seperately to "));
+ tooltip += Glib::ustring(IO::Resource::get_path(IO::Resource::USER, IO::Resource::KEYS, "default.xml"));
+
+ _page_keyshortcuts.add_line( false, _("Shortcut file:"), _kb_filelist, "", tooltip.c_str(), false);
+
+ _kb_search.init("/options/kbshortcuts/value", true);
+ _page_keyshortcuts.add_line( false, _("Search:"), _kb_search, "", "", true);
+
+ _kb_store = Gtk::TreeStore::create( _kb_columns );
+ _kb_store->set_sort_column (_kb_columns.id, Gtk::SORT_ASCENDING );
+
+ _kb_filter = Gtk::TreeModelFilter::create(_kb_store);
+ _kb_filter->set_visible_func (sigc::mem_fun(*this, &InkscapePreferences::onKBSearchFilter));
+
+ _kb_shortcut_renderer.property_editable() = true;
+
+ _kb_tree.set_model(_kb_filter);
+ _kb_tree.append_column(_("Name"), _kb_columns.name);
+ _kb_tree.append_column(_("Shortcut"), _kb_shortcut_renderer);
+ _kb_tree.append_column(_("Description"), _kb_columns.description);
+ _kb_tree.append_column(_("ID"), _kb_columns.id);
+
+ _kb_tree.set_expander_column(*_kb_tree.get_column(0));
+
+ _kb_tree.get_column(0)->set_resizable(true);
+ _kb_tree.get_column(0)->set_clickable(true);
+ _kb_tree.get_column(0)->set_fixed_width (200);
+
+ _kb_tree.get_column(1)->set_resizable(true);
+ _kb_tree.get_column(1)->set_clickable(true);
+ _kb_tree.get_column(1)->set_fixed_width (150);
+ //_kb_tree.get_column(1)->add_attribute(_kb_shortcut_renderer.property_text(), _kb_columns.shortcut);
+ _kb_tree.get_column(1)->set_cell_data_func(_kb_shortcut_renderer, sigc::ptr_fun(InkscapePreferences::onKBShortcutRenderer));
+
+ _kb_tree.get_column(2)->set_resizable(true);
+ _kb_tree.get_column(2)->set_clickable(true);
+
+ _kb_tree.get_column(3)->set_resizable(true);
+ _kb_tree.get_column(3)->set_clickable(true);
+
+ _kb_shortcut_renderer.signal_accel_edited().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBTreeEdited) );
+ _kb_shortcut_renderer.signal_accel_cleared().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBTreeCleared) );
+
+ Gtk::ScrolledWindow* scroller = new Gtk::ScrolledWindow();
+ scroller->add(_kb_tree);
+
+ int row = 3;
+
+#if WITH_GTKMM_3_0
+ scroller->set_hexpand();
+ scroller->set_vexpand();
+ _page_keyshortcuts.attach(*scroller, 0, row, 2, 1);
+#else
+ _page_keyshortcuts.attach(*scroller, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL);
+#endif
+
+ row++;
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *box_buttons = manage(new Gtk::ButtonBox);
+#else
+ Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox);
+#endif
+
+ box_buttons->set_layout(Gtk::BUTTONBOX_END);
+ box_buttons->set_spacing(4);
+
+#if WITH_GTKMM_3_0
+ box_buttons->set_hexpand();
+ _page_keyshortcuts.attach(*box_buttons, 0, row, 3, 1);
+#else
+ _page_keyshortcuts.attach(*box_buttons, 0, 3, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK);
+#endif
+
+ UI::Widget::Button *kb_reset = manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above")));
+ box_buttons->pack_start(*kb_reset, true, true, 6);
+ box_buttons->set_child_secondary(*kb_reset);
+
+ UI::Widget::Button *kb_import = manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file")));
+ box_buttons->pack_end(*kb_import, true, true, 6);
+
+ UI::Widget::Button *kb_export = manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file")));
+ box_buttons->pack_end(*kb_export, true, true, 6);
+
+ kb_reset->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBReset) );
+ kb_import->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBImport) );
+ kb_export->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBExport) );
+ _kb_search.signal_key_release_event().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBSearchKeyEvent) );
+ _kb_filelist.signal_changed().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBList) );
+ _page_keyshortcuts.signal_realize().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBRealize) );
+
+ this->AddPage(_page_keyshortcuts, _("Keyboard Shortcuts"), iter_ui, PREFS_PAGE_UI_KEYBOARD_SHORTCUTS);
+
+ _kb_shortcuts_loaded = false;
+ Gtk::TreeStore::iterator iter_group = _kb_store->append();
+ (*iter_group)[_kb_columns.name] = "Loading ...";
+ (*iter_group)[_kb_columns.shortcut] = "";
+ (*iter_group)[_kb_columns.id] = "";
+ (*iter_group)[_kb_columns.description] = "";
+ (*iter_group)[_kb_columns.shortcutid] = 0;
+ (*iter_group)[_kb_columns.user_set] = 0;
+
+}
+
+void InkscapePreferences::onKBList()
+{
+ sp_shortcut_init();
+ onKBListKeyboardShortcuts();
+}
+
+void InkscapePreferences::onKBReset()
+{
+ sp_shortcuts_delete_all_from_file();
+ sp_shortcut_init();
+ onKBListKeyboardShortcuts();
+}
+
+void InkscapePreferences::onKBImport()
+{
+ if (sp_shortcut_file_import()) {
+ onKBListKeyboardShortcuts();
+ }
+}
+
+void InkscapePreferences::onKBExport()
+{
+ sp_shortcut_file_export();
+}
+
+bool InkscapePreferences::onKBSearchKeyEvent(GdkEventKey * /*event*/)
+{
+ _kb_filter->refilter();
+ return FALSE;
+}
+
+void InkscapePreferences::onKBTreeCleared(const Glib::ustring& path)
+{
+ Gtk::TreeModel::iterator iter = _kb_filter->get_iter(path);
+ Glib::ustring id = (*iter)[_kb_columns.id];
+ unsigned int const current_shortcut_id = (*iter)[_kb_columns.shortcutid];
+
+ // Remove current shortcut from file
+ sp_shortcut_delete_from_file(id.c_str(), current_shortcut_id);
+
+ sp_shortcut_init();
+ onKBListKeyboardShortcuts();
+
+}
+
+void InkscapePreferences::onKBTreeEdited (const Glib::ustring& path, guint accel_key, Gdk::ModifierType accel_mods, guint hardware_keycode)
+{
+ Gtk::TreeModel::iterator iter = _kb_filter->get_iter(path);
+
+ Glib::ustring id = (*iter)[_kb_columns.id];
+ Glib::ustring current_shortcut = (*iter)[_kb_columns.shortcut];
+ unsigned int const current_shortcut_id = (*iter)[_kb_columns.shortcutid];
+
+ Inkscape::Verb *const verb = Inkscape::Verb::getbyid(id.c_str());
+ if (!verb) {
+ return;
+ }
+
+ unsigned int const new_shortcut_id = sp_gdkmodifier_to_shortcut(accel_key, accel_mods, hardware_keycode);
+ if (new_shortcut_id) {
+
+ // Delete current shortcut if it existed
+ sp_shortcut_delete_from_file(id.c_str(), current_shortcut_id);
+ // Delete any references to the new shortcut
+ sp_shortcut_delete_from_file(id.c_str(), new_shortcut_id);
+ // Add the new shortcut
+ sp_shortcut_add_to_file(id.c_str(), new_shortcut_id);
+
+ sp_shortcut_init();
+ onKBListKeyboardShortcuts();
+ }
+}
+
+bool InkscapePreferences::onKBSearchFilter(const Gtk::TreeModel::const_iterator& iter)
+{
+ Glib::ustring search = _kb_search.get_text().lowercase();
+ if (search.empty()) {
+ return TRUE;
+ }
+
+ Glib::ustring name = (*iter)[_kb_columns.name];
+ Glib::ustring desc = (*iter)[_kb_columns.description];
+ Glib::ustring shortcut = (*iter)[_kb_columns.shortcut];
+ Glib::ustring id = (*iter)[_kb_columns.id];
+
+ if (id.empty()) {
+ return TRUE; // Keep all group nodes visible
+ }
+
+ return (name.lowercase().find(search) != name.npos
+ || shortcut.lowercase().find(search) != name.npos
+ || desc.lowercase().find(search) != name.npos
+ || id.lowercase().find(search) != name.npos);
+}
+
+void InkscapePreferences::onKBRealize()
+{
+ if (!_kb_shortcuts_loaded /*&& _current_page == &_page_keyshortcuts*/) {
+ _kb_shortcuts_loaded = true;
+ onKBListKeyboardShortcuts();
+ }
+}
+
+InkscapePreferences::ModelColumns &InkscapePreferences::onKBGetCols()
+{
+ static InkscapePreferences::ModelColumns cols;
+ return cols;
+}
+
+void InkscapePreferences::onKBShortcutRenderer(Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter) {
+
+ Glib::ustring shortcut = (*iter)[onKBGetCols().shortcut];
+ unsigned int user_set = (*iter)[onKBGetCols().user_set];
+ Gtk::CellRendererAccel *accel = dynamic_cast<Gtk::CellRendererAccel *>(renderer);
+ if (user_set) {
+ accel->property_markup() = Glib::ustring("<span foreground=\"blue\"> " + shortcut + " </span>").c_str();
+ } else {
+ accel->property_markup() = Glib::ustring("<span> " + shortcut + " </span>").c_str();
+ }
+}
+
+void InkscapePreferences::onKBListKeyboardShortcuts()
+{
+ // Save the current selection
+ Gtk::TreeStore::iterator iter = _kb_tree.get_selection()->get_selected();
+ Glib::ustring selected_id = "";
+ if (iter) {
+ selected_id = (*iter)[_kb_columns.id];
+ }
+
+ _kb_store->clear();
+
+ std::vector<Verb *>verbs = Inkscape::Verb::getList();
+
+ for (unsigned int i = 0; i < verbs.size(); i++) {
+
+ Inkscape::Verb* verb = verbs[i];
+ if (!verb) {
+ continue;
+ }
+ if (!verb->get_name()){
+ continue;
+ }
+
+ Gtk::TreeStore::Path path;
+ if (_kb_store->iter_is_valid(_kb_store->get_iter("0"))) {
+ path = _kb_store->get_path(_kb_store->get_iter("0"));
+ }
+
+ // Find this group in the tree
+ Glib::ustring group = verb->get_group() ? _(verb->get_group()) : _("Misc");
+ Gtk::TreeStore::iterator iter_group;
+ bool found = false;
+ while (path) {
+ iter_group = _kb_store->get_iter(path);
+ if (!_kb_store->iter_is_valid(iter_group)) {
+ break;
+ }
+ Glib::ustring name = (*iter_group)[_kb_columns.name];
+ if ((*iter_group)[_kb_columns.name] == group) {
+ found = true;
+ break;
+ }
+ path.next();
+ }
+
+ if (!found) {
+ // Add the group if not there
+ iter_group = _kb_store->append();
+ (*iter_group)[_kb_columns.name] = group;
+ (*iter_group)[_kb_columns.shortcut] = "";
+ (*iter_group)[_kb_columns.id] = "";
+ (*iter_group)[_kb_columns.description] = "";
+ (*iter_group)[_kb_columns.shortcutid] = 0;
+ (*iter_group)[_kb_columns.user_set] = 0;
+ }
+
+ // Remove the key accelerators from the verb name
+ Glib::ustring name = _(verb->get_name());
+ std::string::size_type k = 0;
+ while((k=name.find('_',k))!=name.npos) {
+ name.erase(k, 1);
+ }
+
+ // Get the shortcut label
+ unsigned int shortcut_id = sp_shortcut_get_primary(verb);
+ Glib::ustring shortcut_label = "";
+ if (shortcut_id != GDK_KEY_VoidSymbol) {
+ gchar* str = sp_shortcut_get_label(shortcut_id);
+ if (str) {
+ shortcut_label = str;
+ g_free(str);
+ str = 0;
+ }
+ }
+ // Add the verb to the group
+ Gtk::TreeStore::iterator row = _kb_store->append(iter_group->children());
+ (*row)[_kb_columns.name] = name;
+ (*row)[_kb_columns.shortcut] = shortcut_label;
+ (*row)[_kb_columns.description] = verb->get_short_tip() ? _(verb->get_short_tip()) : "";
+ (*row)[_kb_columns.shortcutid] = shortcut_id;
+ (*row)[_kb_columns.id] = verb->get_id();
+ (*row)[_kb_columns.user_set] = sp_shortcut_is_user_set(verb);
+
+ if (selected_id == verb->get_id()) {
+ Gtk::TreeStore::Path sel_path = _kb_filter->convert_child_path_to_path(_kb_store->get_path(row));
+ _kb_tree.expand_to_path(sel_path);
+ _kb_tree.get_selection()->select(sel_path);
+ }
+ }
+
+ if (selected_id.empty()) {
+ _kb_tree.expand_to_path(_kb_store->get_path(_kb_store->get_iter("0:1")));
+ }
+
+}
void InkscapePreferences::initPageSpellcheck()
{
@@ -1462,7 +1854,7 @@ static void appendList( Glib::ustring& tmp, const gchar* const*listing )
void InkscapePreferences::initPageSystem()
{
_misc_latency_skew.init("/debug/latency/skew", 0.5, 2.0, 0.01, 0.10, 1.0, false, false);
- _page_system.add_line( false, _("Latency skew:"), _misc_latency_skew, _("(requires restart)"),
+ _page_system.add_line( false, _("Latency _skew:"), _misc_latency_skew, _("(requires restart)"),
_("Factor by which the event clock is skewed from the actual time (0.9766 on some systems)"), false);
_misc_namedicon_delay.init( _("Pre-render named icons"), "/options/iconrender/named_nodelay", false);
@@ -1575,7 +1967,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter)
_page_list.expand_row(_path_tools, false);
if (desired_page >= PREFS_PAGE_TOOLS_SHAPES && desired_page <= PREFS_PAGE_TOOLS_SHAPES_SPIRAL)
_page_list.expand_row(_path_shapes, false);
- if (desired_page >= PREFS_PAGE_UI && desired_page <= PREFS_PAGE_UI_GRIDS)
+ if (desired_page >= PREFS_PAGE_UI && desired_page <= PREFS_PAGE_UI_KEYBOARD_SHORTCUTS)
_page_list.expand_row(_path_ui, false);
if (desired_page >= PREFS_PAGE_BEHAVIOR && desired_page <= PREFS_PAGE_BEHAVIOR_MASKS)
_page_list.expand_row(_path_behavior, false);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 6d13b9d20..eaf1ffc3d 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -18,15 +18,19 @@
#include <iostream>
#include <vector>
#include "ui/widget/preferences-widget.h"
+#include "ui/widget/button.h"
+#include <stddef.h>
#include <gtkmm/colorbutton.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/treestore.h>
#include <gtkmm/treeview.h>
#include <gtkmm/frame.h>
#include <gtkmm/notebook.h>
-#include <stddef.h>
#include <gtkmm/textview.h>
#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treemodel.h>
+#include <gtkmm/treemodelfilter.h>
#include "ui/widget/panel.h"
@@ -60,6 +64,7 @@ enum {
PREFS_PAGE_UI,
PREFS_PAGE_UI_WINDOWS,
PREFS_PAGE_UI_GRIDS,
+ PREFS_PAGE_UI_KEYBOARD_SHORTCUTS,
PREFS_PAGE_BEHAVIOR,
PREFS_PAGE_BEHAVIOR_SELECTING,
PREFS_PAGE_BEHAVIOR_TRANSFORMS,
@@ -68,6 +73,7 @@ enum {
PREFS_PAGE_BEHAVIOR_STEPS,
PREFS_PAGE_BEHAVIOR_CLONES,
PREFS_PAGE_BEHAVIOR_MASKS,
+ PREFS_PAGE_BEHAVIOR_MARKERS,
PREFS_PAGE_IO,
PREFS_PAGE_IO_MOUSE,
PREFS_PAGE_IO_SVGOUTPUT,
@@ -78,8 +84,17 @@ enum {
PREFS_PAGE_BITMAPS,
PREFS_PAGE_RENDERING,
PREFS_PAGE_SPELLCHECK
+
};
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
+}
+
namespace Inkscape {
namespace UI {
namespace Dialog {
@@ -151,6 +166,7 @@ protected:
UI::Widget::DialogPage _page_steps;
UI::Widget::DialogPage _page_clones;
UI::Widget::DialogPage _page_mask;
+ UI::Widget::DialogPage _page_markers;
UI::Widget::DialogPage _page_io;
UI::Widget::DialogPage _page_mouse;
@@ -164,6 +180,8 @@ protected:
UI::Widget::DialogPage _page_bitmaps;
UI::Widget::DialogPage _page_spellcheck;
+ UI::Widget::DialogPage _page_keyshortcuts;
+
UI::Widget::PrefSpinButton _mouse_sens;
UI::Widget::PrefSpinButton _mouse_thres;
UI::Widget::PrefSlider _mouse_grabsize;
@@ -178,7 +196,12 @@ protected:
UI::Widget::PrefCheckButton _scroll_space;
UI::Widget::PrefCheckButton _wheel_zoom;
+#if WITH_GTKMM_3_0
+ Gtk::Scale *_slider_snapping_delay;
+#else
Gtk::HScale *_slider_snapping_delay;
+#endif
+
UI::Widget::PrefCheckButton _snap_indicator;
UI::Widget::PrefCheckButton _snap_closest_only;
UI::Widget::PrefCheckButton _snap_mouse_pointer;
@@ -225,6 +248,7 @@ protected:
UI::Widget::PrefRadioButton _win_save_geom;
UI::Widget::PrefRadioButton _win_save_geom_prefs;
UI::Widget::PrefCheckButton _win_hide_task;
+ UI::Widget::PrefCheckButton _win_save_viewport;
UI::Widget::PrefCheckButton _win_zoom_resize;
UI::Widget::PrefCheckButton _win_show_close;
UI::Widget::PrefSpinButton _win_trans_focus; /**< The dialog transparency setting for when the dialog is focused. */
@@ -263,6 +287,8 @@ protected:
UI::Widget::PrefRadioButton _filter_quality_worse;
UI::Widget::PrefRadioButton _filter_quality_worst;
UI::Widget::PrefCheckButton _show_filters_info_box;
+ UI::Widget::PrefCombo _dockbar_style;
+ UI::Widget::PrefCombo _switcher_style;
UI::Widget::PrefSpinButton _rendering_cache_size;
UI::Widget::PrefSpinButton _filter_multi_threaded;
@@ -281,17 +307,24 @@ protected:
UI::Widget::PrefCheckButton _sel_layer_deselects;
UI::Widget::PrefCheckButton _sel_cycle;
+ UI::Widget::PrefCheckButton _markers_color_stock;
+ UI::Widget::PrefCheckButton _markers_color_custom;
+ UI::Widget::PrefCheckButton _markers_color_update;
+
UI::Widget::PrefSpinButton _importexport_export_res;
UI::Widget::PrefSpinButton _importexport_import_res;
+ UI::Widget::PrefCheckButton _importexport_import_res_override;
UI::Widget::PrefSlider _snap_delay;
UI::Widget::PrefSlider _snap_weight;
UI::Widget::PrefCheckButton _font_dialog;
UI::Widget::PrefCombo _font_unit_type;
+ UI::Widget::PrefCheckButton _font_output_px;
UI::Widget::PrefCheckButton _misc_comment;
UI::Widget::PrefCheckButton _misc_default_metadata;
UI::Widget::PrefCheckButton _misc_forkvectors;
UI::Widget::PrefCheckButton _misc_gradienteditor;
+ UI::Widget::PrefSpinButton _misc_gradientangle;
UI::Widget::PrefCheckButton _misc_scripts;
UI::Widget::PrefCheckButton _misc_namedicon_delay;
@@ -327,12 +360,16 @@ protected:
UI::Widget::PrefCheckButton _spell_ignorenumbers;
UI::Widget::PrefCheckButton _spell_ignoreallcaps;
+
UI::Widget::PrefCombo _misc_overs_bitmap;
UI::Widget::PrefEntryFileButtonHBox _misc_bitmap_editor;
UI::Widget::PrefCheckButton _misc_bitmap_autoreload;
UI::Widget::PrefSpinButton _bitmap_copy_res;
UI::Widget::PrefCombo _bitmap_import;
+ UI::Widget::PrefEntry _kb_search;
+ UI::Widget::PrefCombo _kb_filelist;
+
UI::Widget::PrefCheckButton _save_use_current_dir;
UI::Widget::PrefCheckButton _save_autosave_enable;
UI::Widget::PrefSpinButton _save_autosave_interval;
@@ -401,6 +438,37 @@ protected:
UI::Widget::PrefEntry _importexport_ocal_username;
UI::Widget::PrefEntry _importexport_ocal_password;
+ /*
+ * Keyboard shortcut members
+ */
+ class ModelColumns: public Gtk::TreeModel::ColumnRecord {
+ public:
+ ModelColumns() {
+ add(name);
+ add(id);
+ add(shortcut);
+ add(description);
+ add(shortcutid);
+ add(user_set);
+ }
+ virtual ~ModelColumns() {
+ }
+
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::ustring> id;
+ Gtk::TreeModelColumn<Glib::ustring> shortcut;
+ Gtk::TreeModelColumn<Glib::ustring> description;
+ Gtk::TreeModelColumn<unsigned int> shortcutid;
+ Gtk::TreeModelColumn<unsigned int> user_set;
+ };
+ ModelColumns _kb_columns;
+ static ModelColumns &onKBGetCols();
+ Glib::RefPtr<Gtk::TreeStore> _kb_store;
+ Gtk::TreeView _kb_tree;
+ Gtk::CellRendererAccel _kb_shortcut_renderer;
+ Glib::RefPtr<Gtk::TreeModelFilter> _kb_filter;
+ gboolean _kb_shortcuts_loaded;
+
int _max_dialog_width;
int _max_dialog_height;
int _sb_width;
@@ -431,9 +499,26 @@ protected:
void initPageBitmaps();
void initPageSystem();
void initPageI18n(); // Do we still need it?
+ void initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui);
void _presentPages();
+ /*
+ * Functions for the Keyboard shortcut editor panel
+ */
+ void onKBReset();
+ void onKBImport();
+ void onKBExport();
+ void onKBList();
+ void onKBRealize();
+ void onKBListKeyboardShortcuts();
+ void onKBTreeEdited (const Glib::ustring& path, guint accel_key, Gdk::ModifierType accel_mods, guint hardware_keycode);
+ void onKBTreeCleared(const Glib::ustring& path_string);
+ bool onKBSearchKeyEvent(GdkEventKey *event);
+ bool onKBSearchFilter(const Gtk::TreeModel::const_iterator& iter);
+ static void onKBShortcutRenderer(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter);
+
+
private:
InkscapePreferences();
InkscapePreferences(InkscapePreferences const &d);
diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp
index b3c1bddfd..82e65435d 100644
--- a/src/ui/dialog/input.cpp
+++ b/src/ui/dialog/input.cpp
@@ -17,7 +17,9 @@
#include <glib/gprintf.h>
#include <glibmm/i18n.h>
+
#include <gtkmm/alignment.h>
+#include <gtkmm/buttonbox.h>
#include <gtkmm/cellrenderercombo.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/comboboxtext.h>
@@ -31,7 +33,13 @@
#include <gtkmm/paned.h>
#include <gtkmm/progressbar.h>
#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/treemodel.h>
#include <gtkmm/treemodelcolumn.h>
#include <gtkmm/treestore.h>
@@ -357,6 +365,15 @@ static std::map<Gdk::InputMode, Glib::ustring> &getModeToString()
return mapping;
}
+static int getModeId(Gdk::InputMode im)
+{
+ if (im == Gdk::MODE_DISABLED) return 0;
+ if (im == Gdk::MODE_SCREEN) return 1;
+ if (im == Gdk::MODE_WINDOW) return 2;
+
+ return 0;
+}
+
static std::map<Glib::ustring, Gdk::InputMode> &getStringToMode()
{
static std::map<Glib::ustring, Gdk::InputMode> mapping;
@@ -400,15 +417,64 @@ private:
static void setCellStateToggle(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter);
void saveSettings();
+ void onTreeSelect();
void useExtToggled();
- Glib::RefPtr<Gtk::TreeStore> store;
- Gtk::TreeIter tabletIter;
- Gtk::TreeView tree;
- Gtk::ScrolledWindow treeScroller;
+ void onModeChange();
+ void setKeys(gint count);
+ void setAxis(gint count);
+
+ Glib::RefPtr<Gtk::TreeStore> confDeviceStore;
+ Gtk::TreeIter confDeviceIter;
+ Gtk::TreeView confDeviceTree;
+ Gtk::ScrolledWindow confDeviceScroller;
Blink watcher;
Gtk::CheckButton useExt;
Gtk::Button save;
+
+#if WITH_GTKMM_3_0
+ Gtk::Paned pane;
+#else
+ Gtk::HPaned pane;
+#endif
+
+ Gtk::VBox detailsBox;
+ Gtk::HBox titleFrame;
+ Gtk::Label titleLabel;
+ Inkscape::UI::Widget::Frame axisFrame;
+ Inkscape::UI::Widget::Frame keysFrame;
+ Gtk::VBox axisVBox;
+ Gtk::ComboBoxText modeCombo;
+ Gtk::Label modeLabel;
+ Gtk::HBox modeBox;
+
+ class KeysColumns : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ KeysColumns()
+ {
+ add(name);
+ add(value);
+ }
+ virtual ~KeysColumns() {}
+
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<Glib::ustring> value;
+ };
+
+ KeysColumns keysColumns;
+ KeysColumns axisColumns;
+
+ Glib::RefPtr<Gtk::ListStore> axisStore;
+ Gtk::TreeView axisTree;
+ Gtk::ScrolledWindow axisScroll;
+
+ Glib::RefPtr<Gtk::ListStore> keysStore;
+ Gtk::TreeView keysTree;
+ Gtk::ScrolledWindow keysScroll;
+ Gtk::CellRendererAccel _kb_shortcut_renderer;
+
+
};
static DeviceModelColumns &getCols();
@@ -425,35 +491,55 @@ private:
GdkInputSource lastSourceSeen;
Glib::ustring lastDevnameSeen;
- Glib::RefPtr<Gtk::TreeStore> store;
- Gtk::TreeIter tabletIter;
- Gtk::TreeView tree;
- Inkscape::UI::Widget::Frame detailFrame;
+ Glib::RefPtr<Gtk::TreeStore> deviceStore;
+ Gtk::TreeIter deviceIter;
+ Gtk::TreeView deviceTree;
Inkscape::UI::Widget::Frame testFrame;
+ Inkscape::UI::Widget::Frame axisFrame;
Gtk::ScrolledWindow treeScroller;
Gtk::ScrolledWindow detailScroller;
+
+#if WITH_GTKMM_3_0
+ Gtk::Paned splitter;
+ Gtk::Paned split2;
+#else
Gtk::HPaned splitter;
Gtk::VPaned split2;
+#endif
+
Gtk::Label devName;
Gtk::Label devKeyCount;
Gtk::Label devAxesCount;
Gtk::ComboBoxText axesCombo;
Gtk::ProgressBar axesValues[6];
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid axisTable;
+#else
+ Gtk::Table axisTable;
+#endif
+
Gtk::ComboBoxText buttonCombo;
Gtk::ComboBoxText linkCombo;
sigc::connection linkConnection;
Gtk::Label keyVal;
Gtk::Entry keyEntry;
- Gtk::Table devDetails;
Gtk::Notebook topHolder;
Gtk::Image testThumb;
Gtk::Image testButtons[24];
Gtk::Image testAxes[8];
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid imageTable;
+#else
Gtk::Table imageTable;
+#endif
+
Gtk::EventBox testDetector;
ConfPanel cfgPanel;
+
static void setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIter &tablet );
void setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo );
void updateTestButtons( Glib::ustring const& key, gint hotButton );
@@ -526,19 +612,28 @@ InputDialogImpl::InputDialogImpl() :
lastSourceSeen((GdkInputSource)-1),
lastDevnameSeen(""),
- store(Gtk::TreeStore::create(getCols())),
- tabletIter(),
- tree(store),
- detailFrame(),
+ deviceStore(Gtk::TreeStore::create(getCols())),
+ deviceIter(),
+ deviceTree(deviceStore),
testFrame(_("Test Area")),
+ axisFrame(_("Axis")),
treeScroller(),
detailScroller(),
splitter(),
+#if WITH_GTKMM_3_0
+ split2(Gtk::ORIENTATION_VERTICAL),
+ axisTable(),
+#else
split2(),
+ axisTable(11, 2),
+#endif
linkCombo(),
- devDetails(12, 2),
topHolder(),
+#if WITH_GTKMM_3_0
+ imageTable(),
+#else
imageTable(8, 7),
+#endif
testDetector(),
cfgPanel()
{
@@ -547,10 +642,12 @@ InputDialogImpl::InputDialogImpl() :
treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
treeScroller.set_shadow_type(Gtk::SHADOW_IN);
- treeScroller.add(tree);
+ treeScroller.add(deviceTree);
treeScroller.set_size_request(50, 0);
- split2.pack1(testFrame, false, false);
- split2.pack2(detailFrame, true, true);
+
+ split2.pack1(axisFrame, false, false);
+ split2.pack2(testFrame, true, true);
+
splitter.pack1(treeScroller);
splitter.pack2(split2);
@@ -558,13 +655,27 @@ InputDialogImpl::InputDialogImpl() :
testFrame.add(testDetector);
testThumb.set(getPix(PIX_TABLET));
testThumb.set_padding(24, 24);
+
+#if WITH_GTKMM_3_0
+ testThumb.set_hexpand();
+ testThumb.set_vexpand();
+ imageTable.attach(testThumb, 0, 0, 8, 1);
+#else
imageTable.attach(testThumb, 0, 8, 0, 1, ::Gtk::EXPAND, ::Gtk::EXPAND);
+#endif
+
{
guint col = 0;
guint row = 1;
for ( guint num = 0; num < G_N_ELEMENTS(testButtons); num++ ) {
testButtons[num].set(getPix(PIX_BUTTONS_NONE));
+
+#if WITH_GTKMM_3_0
+ imageTable.attach(testButtons[num], col, row, 1, 1);
+#else
imageTable.attach(testButtons[num], col, col + 1, row, row + 1, ::Gtk::FILL, ::Gtk::FILL);
+#endif
+
col++;
if (col > 7) {
col = 0;
@@ -575,7 +686,13 @@ InputDialogImpl::InputDialogImpl() :
col = 0;
for ( guint num = 0; num < G_N_ELEMENTS(testAxes); num++ ) {
testAxes[num].set(getPix(PIX_AXIS_NONE));
+
+#if WITH_GTKMM_3_0
+ imageTable.attach(testAxes[num], col * 2, row, 2, 1);
+#else
imageTable.attach(testAxes[num], col * 2, (col + 1) * 2, row, row + 1, ::Gtk::FILL, ::Gtk::FILL);
+#endif
+
col++;
if (col > 3) {
col = 0;
@@ -585,54 +702,76 @@ InputDialogImpl::InputDialogImpl() :
}
- topHolder.append_page(cfgPanel, _("Configuration"));
- topHolder.append_page(splitter, _("Hardware"));
- topHolder.show_all();
- topHolder.set_current_page(0);
+ // This is a hidden preference to enable the "hardware" details in a separate tab
+ // By default this is not available to users
+ if (Preferences::get()->getBool("/dialogs/inputdevices/test")) {
+ topHolder.append_page(cfgPanel, _("Configuration"));
+ topHolder.append_page(splitter, _("Hardware"));
+ topHolder.show_all();
+ topHolder.set_current_page(0);
+ contents->pack_start(topHolder);
+ } else {
+ contents->pack_start(cfgPanel);
+ }
- contents->pack_start(topHolder);
int rowNum = 0;
/* Gtk::Label* lbl = Gtk::manage(new Gtk::Label(_("Name:")));
- devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
+ axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
- devDetails.attach(devName, 1, 2, rowNum, rowNum + 1,
+ axisTable.attach(devName, 1, 2, rowNum, rowNum + 1,
::Gtk::SHRINK,
::Gtk::SHRINK);
rowNum++;*/
+ axisFrame.add(axisTable);
+
Gtk::Label *lbl = Gtk::manage(new Gtk::Label(_("Link:")));
- devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
+
+#if WITH_GTKMM_3_0
+ axisTable.attach(*lbl, 0, rowNum, 1, 1);
+#else
+ axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
+#endif
-#if WITH_GTKMM_2_24
linkCombo.append(_("None"));
-#else
- linkCombo.append_text(_("None"));
-#endif
linkCombo.set_active_text(_("None"));
linkCombo.set_sensitive(false);
linkConnection = linkCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::linkComboChanged));
- devDetails.attach(linkCombo, 1, 2, rowNum, rowNum + 1,
+#if WITH_GTKMM_3_0
+ axisTable.attach(linkCombo, 1, rowNum, 1, 1);
+#else
+ axisTable.attach(linkCombo, 1, 2, rowNum, rowNum + 1,
::Gtk::FILL,
::Gtk::SHRINK);
+#endif
+
rowNum++;
+
lbl = Gtk::manage(new Gtk::Label(_("Axes count:")));
- devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
+
+#if WITH_GTKMM_3_0
+ axisTable.attach(*lbl, 0, rowNum, 1, 1);
+ axisTable.attach(devAxesCount, 1, rowNum, 1, 1);
+#else
+ axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
- devDetails.attach(devAxesCount, 1, 2, rowNum, rowNum + 1,
+ axisTable.attach(devAxesCount, 1, 2, rowNum, rowNum + 1,
::Gtk::SHRINK,
::Gtk::SHRINK);
+#endif
rowNum++;
+
/*
lbl = Gtk::manage(new Gtk::Label(_("Actual axes count:")));
devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
@@ -647,24 +786,42 @@ InputDialogImpl::InputDialogImpl() :
for ( guint barNum = 0; barNum < static_cast<guint>(G_N_ELEMENTS(axesValues)); barNum++ ) {
lbl = Gtk::manage(new Gtk::Label(_("axis:")));
- devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
- ::Gtk::FILL,
+
+#if WITH_GTKMM_3_0
+ lbl->set_hexpand();
+ axisTable.attach(*lbl, 0, rowNum, 1, 1);
+
+ axesValues[barNum].set_hexpand();
+ axisTable.attach(axesValues[barNum], 1, rowNum, 1, 1);
+#else
+ axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
+ ::Gtk::EXPAND,
::Gtk::SHRINK);
- devDetails.attach(axesValues[barNum], 1, 2, rowNum, rowNum + 1,
+ axisTable.attach(axesValues[barNum], 1, 2, rowNum, rowNum + 1,
::Gtk::EXPAND,
::Gtk::SHRINK);
+#endif
+
axesValues[barNum].set_sensitive(false);
rowNum++;
+
+
}
lbl = Gtk::manage(new Gtk::Label(_("Button count:")));
- devDetails.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
+
+#if WITH_GTKMM_3_0
+ axisTable.attach(*lbl, 0, rowNum, 1, 1);
+ axisTable.attach(devKeyCount, 1, rowNum, 1, 1);
+#else
+ axisTable.attach(*lbl, 0, 1, rowNum, rowNum+ 1,
::Gtk::FILL,
::Gtk::SHRINK);
- devDetails.attach(devKeyCount, 1, 2, rowNum, rowNum + 1,
+ axisTable.attach(devKeyCount, 1, 2, rowNum, rowNum + 1,
::Gtk::SHRINK,
::Gtk::SHRINK);
+#endif
rowNum++;
@@ -680,9 +837,14 @@ InputDialogImpl::InputDialogImpl() :
rowNum++;
*/
- devDetails.attach(keyVal, 0, 2, rowNum, rowNum + 1,
+#if WITH_GTKMM_3_0
+ axisTable.attach(keyVal, 0, rowNum, 2, 1);
+#else
+ axisTable.attach(keyVal, 0, 2, rowNum, rowNum + 1,
::Gtk::FILL,
::Gtk::SHRINK);
+#endif
+
rowNum++;
@@ -700,19 +862,23 @@ InputDialogImpl::InputDialogImpl() :
#endif
testDetector.add_events(Gdk::POINTER_MOTION_MASK|Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK |Gdk::PROXIMITY_IN_MASK|Gdk::PROXIMITY_OUT_MASK|Gdk::SCROLL_MASK);
- devDetails.attach(keyEntry, 0, 2, rowNum, rowNum + 1,
+#if WITH_GTKMM_3_0
+ axisTable.attach(keyEntry, 0, rowNum, 2, 1);
+#else
+ axisTable.attach(keyEntry, 0, 2, rowNum, rowNum + 1,
::Gtk::FILL,
::Gtk::SHRINK);
+#endif
+
rowNum++;
- devDetails.set_sensitive(false);
- detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ axisTable.set_sensitive(false);
+
+/* detailScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
detailScroller.set_shadow_type(Gtk::SHADOW_NONE);
detailScroller.set_border_width (0);
- detailScroller.add(devDetails);
- detailFrame.add(detailScroller);
- detailFrame.set_size_request(0, 60);
+ detailScroller.add(devDetails);*/
//- 16x16/devices
// gnome-dev-mouse-optical
@@ -721,25 +887,24 @@ InputDialogImpl::InputDialogImpl() :
// mouse
-
//Add the TreeView's view columns:
- tree.append_column("I", getCols().thumbnail);
- tree.append_column("Bar", getCols().description);
+ deviceTree.append_column("I", getCols().thumbnail);
+ deviceTree.append_column("Bar", getCols().description);
- tree.set_enable_tree_lines();
- tree.set_headers_visible(false);
- tree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection));
+ deviceTree.set_enable_tree_lines();
+ deviceTree.set_headers_visible(false);
+ deviceTree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::resyncToSelection));
- setupTree( store, tabletIter );
+ setupTree( deviceStore, deviceIter );
Inkscape::DeviceManager::getManager().signalDeviceChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::handleDeviceChange));
Inkscape::DeviceManager::getManager().signalAxesChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceAxes));
Inkscape::DeviceManager::getManager().signalButtonsChanged().connect(sigc::mem_fun(*this, &InputDialogImpl::updateDeviceButtons));
- Glib::RefPtr<Gtk::TreeView> treePtr(&tree);
- Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr));
+ Glib::RefPtr<Gtk::TreeView> treePtr(&deviceTree);
+ Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), deviceIter, treePtr));
- tree.expand_all();
+ deviceTree.expand_all();
show_all_children();
}
@@ -781,12 +946,30 @@ static Glib::ustring getCommon( std::list<Glib::ustring> const &names )
return result;
}
+
+void InputDialogImpl::ConfPanel::onModeChange()
+{
+ Glib::ustring newText = modeCombo.get_active_text();
+
+ Glib::RefPtr<Gtk::TreeSelection> sel = confDeviceTree.get_selection();
+ Gtk::TreeModel::iterator iter = sel->get_selected();
+ if (iter) {
+ Glib::RefPtr<InputDevice const> dev = (*iter)[getCols().device];
+ if (dev && (getStringToMode().find(newText) != getStringToMode().end())) {
+ Gdk::InputMode mode = getStringToMode()[newText];
+ Inkscape::DeviceManager::getManager().setMode( dev->getId(), mode );
+ }
+ }
+
+}
+
+
void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIter &tablet )
{
std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices();
if ( !devList.empty() ) {
- Gtk::TreeModel::Row row = *(store->append());
- row[getCols().description] = _("Hardware");
+ //Gtk::TreeModel::Row row = *(store->append());
+ //row[getCols().description] = _("Hardware");
// Let's make some tablets!!!
std::list<TabletTmp> tablets;
@@ -811,7 +994,7 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt
// Phase 2 - build a UI for the present devices
for ( std::list<TabletTmp>::iterator it = tablets.begin(); it != tablets.end(); ++it ) {
- tablet = store->append(row.children());
+ tablet = store->prepend(/*row.children()*/);
Gtk::TreeModel::Row childrow = *tablet;
if ( it->name.empty() ) {
// Check to see if we can derive one
@@ -874,13 +1057,14 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt
for ( std::list<Glib::RefPtr<InputDevice const> >::iterator it = devList.begin(); it != devList.end(); ++it ) {
Glib::RefPtr<InputDevice const> dev = *it;
if ( dev && (consumed.find( dev->getId() ) == consumed.end()) ) {
- Gtk::TreeModel::Row deviceRow = *(store->append(row.children()));
+ Gtk::TreeModel::Row deviceRow = *(store->prepend(/*row.children()*/));
deviceRow[getCols().description] = dev->getName();
deviceRow[getCols().device] = dev;
deviceRow[getCols().mode] = dev->getMode();
deviceRow[getCols().thumbnail] = getPix(PIX_CORE);
}
}
+
} else {
g_warning("No devices found");
}
@@ -889,84 +1073,163 @@ void InputDialogImpl::setupTree( Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeIt
InputDialogImpl::ConfPanel::ConfPanel() :
Gtk::VBox(),
- store(Gtk::TreeStore::create(getCols())),
- tabletIter(),
- tree(store),
- treeScroller(),
+ confDeviceStore(Gtk::TreeStore::create(getCols())),
+ confDeviceIter(),
+ confDeviceTree(confDeviceStore),
+ confDeviceScroller(),
watcher(*this),
useExt(_("_Use pressure-sensitive tablet (requires restart)"), true),
- save(_("_Save"), true)
+ save(_("_Save"), true),
+ detailsBox(false, 4),
+ titleFrame(false, 4),
+ titleLabel(""),
+ axisFrame(_("Axes")),
+ keysFrame(_("Keys")),
+ modeLabel(_("Mode:")),
+ modeBox(false, 4)
+
{
- pack_start(treeScroller);
- treeScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
- treeScroller.add(tree);
- class Foo : public Gtk::TreeModel::ColumnRecord {
+ confDeviceScroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ confDeviceScroller.set_shadow_type(Gtk::SHADOW_IN);
+ confDeviceScroller.add(confDeviceTree);
+ confDeviceScroller.set_size_request(120, 0);
+
+ /* class Foo : public Gtk::TreeModel::ColumnRecord {
public :
Gtk::TreeModelColumn<Glib::ustring> one;
Foo() {add(one);}
};
static Foo foo;
- Glib::RefPtr<Gtk::ListStore> poppers = Gtk::ListStore::create(foo);
- poppers->reference();
-
- Gtk::TreeModel::Row row = *(poppers->append());
- row[foo.one] = getModeToString()[Gdk::MODE_DISABLED];
- row = *(poppers->append());
- row[foo.one] = getModeToString()[Gdk::MODE_SCREEN];
- row = *(poppers->append());
- row[foo.one] = getModeToString()[Gdk::MODE_WINDOW];
//Add the TreeView's view columns:
{
Gtk::CellRendererToggle *rendr = new Gtk::CellRendererToggle();
Gtk::TreeViewColumn *col = new Gtk::TreeViewColumn("xx", *rendr);
if (col) {
- tree.append_column(*col);
+ confDeviceTree.append_column(*col);
col->set_cell_data_func(*rendr, sigc::ptr_fun(setCellStateToggle));
- rendr->signal_toggled().connect(sigc::bind(sigc::ptr_fun(commitCellStateChange), store));
+ rendr->signal_toggled().connect(sigc::bind(sigc::ptr_fun(commitCellStateChange), confDeviceStore));
}
- }
+ }*/
- int expPos = tree.append_column("", getCols().expander);
+ //int expPos = confDeviceTree.append_column("", getCols().expander);
- tree.append_column("I", getCols().thumbnail);
- tree.append_column("Bar", getCols().description);
+ confDeviceTree.append_column("I", getCols().thumbnail);
+ confDeviceTree.append_column("Bar", getCols().description);
- {
- Gtk::CellRendererCombo *rendr = new Gtk::CellRendererCombo();
- rendr->property_model().set_value(poppers);
- rendr->property_text_column().set_value(0);
- rendr->property_has_entry() = false;
+ //confDeviceTree.get_column(0)->set_fixed_width(100);
+ //confDeviceTree.get_column(1)->set_expand();
+
+/* {
Gtk::TreeViewColumn *col = new Gtk::TreeViewColumn("X", *rendr);
if (col) {
- tree.append_column(*col);
+ confDeviceTree.append_column(*col);
col->set_cell_data_func(*rendr, sigc::ptr_fun(setModeCellString));
- rendr->signal_edited().connect(sigc::bind(sigc::ptr_fun(commitCellModeChange), store));
+ rendr->signal_edited().connect(sigc::bind(sigc::ptr_fun(commitCellModeChange), confDeviceStore));
rendr->property_editable() = true;
}
- }
+ }*/
+
+ //confDeviceTree.set_enable_tree_lines();
+ confDeviceTree.property_enable_tree_lines() = false;
+ confDeviceTree.property_enable_grid_lines() = false;
+ confDeviceTree.set_headers_visible(false);
+ //confDeviceTree.set_expander_column( *confDeviceTree.get_column(expPos - 1) );
- tree.set_enable_tree_lines();
- tree.set_headers_visible(false);
- tree.set_expander_column( *tree.get_column(expPos - 1) );
+ confDeviceTree.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::onTreeSelect));
- setupTree( store, tabletIter );
+ setupTree( confDeviceStore, confDeviceIter );
- Glib::RefPtr<Gtk::TreeView> treePtr(&tree);
- Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), tabletIter, treePtr));
+ Glib::RefPtr<Gtk::TreeView> treePtr(&confDeviceTree);
+ Inkscape::DeviceManager::getManager().signalLinkChanged().connect(sigc::bind(sigc::ptr_fun(&InputDialogImpl::updateDeviceLinks), confDeviceIter, treePtr));
- tree.expand_all();
+ confDeviceTree.expand_all();
useExt.set_active(Preferences::get()->getBool("/options/useextinput/value"));
useExt.signal_toggled().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::useExtToggled));
- pack_start(useExt, Gtk::PACK_SHRINK);
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *buttonBox = manage(new Gtk::ButtonBox);
+#else
+ Gtk::HButtonBox *buttonBox = manage (new Gtk::HButtonBox);
+#endif
+
+ buttonBox->set_layout (Gtk::BUTTONBOX_END);
+ //Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_START, 0, 0);
+ buttonBox->add(save);
save.signal_clicked().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::saveSettings));
- Gtk::Alignment *align = new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_START, 0, 0);
- align->add(save);
- pack_start(*Gtk::manage(align), Gtk::PACK_SHRINK);
+
+ titleFrame.pack_start(titleLabel, true, true);
+ //titleFrame.set_shadow_type(Gtk::SHADOW_IN);
+
+ modeCombo.append(getModeToString()[Gdk::MODE_DISABLED]);
+ modeCombo.append(getModeToString()[Gdk::MODE_SCREEN]);
+ modeCombo.append(getModeToString()[Gdk::MODE_WINDOW]);
+ modeCombo.set_tooltip_text(_("A device can be 'Disabled', its co-ordinates mapped to the whole 'Screen', or to a single (usually focused) 'Window'"));
+ modeCombo.signal_changed().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::onModeChange));
+
+ modeBox.pack_start(modeLabel, false, false);
+ modeBox.pack_start(modeCombo, true, true);
+
+ axisVBox.add(axisScroll);
+ axisFrame.add(axisVBox);
+
+ keysFrame.add(keysScroll);
+
+ /**
+ * Scrolled Window
+ */
+ keysScroll.add(keysTree);
+ keysScroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ keysScroll.set_shadow_type(Gtk::SHADOW_IN);
+ keysScroll.set_size_request(120, 80);
+
+ keysStore = Gtk::ListStore::create(keysColumns);
+
+ _kb_shortcut_renderer.property_editable() = true;
+
+ keysTree.set_model(keysStore);
+ keysTree.set_headers_visible(false);
+ keysTree.append_column("Name", keysColumns.name);
+ keysTree.append_column("Value", keysColumns.value);
+
+ //keysTree.append_column("Value", _kb_shortcut_renderer);
+ //keysTree.get_column(1)->add_attribute(_kb_shortcut_renderer.property_text(), keysColumns.value);
+ //_kb_shortcut_renderer.signal_accel_edited().connect( sigc::mem_fun(*this, &InputDialogImpl::onKBTreeEdited) );
+ //_kb_shortcut_renderer.signal_accel_cleared().connect( sigc::mem_fun(*this, &InputDialogImpl::onKBTreeCleared) );
+
+ axisStore = Gtk::ListStore::create(axisColumns);
+
+ axisTree.set_model(axisStore);
+ axisTree.set_headers_visible(false);
+ axisTree.append_column("Name", axisColumns.name);
+ axisTree.append_column("Value", axisColumns.value);
+
+ /**
+ * Scrolled Window
+ */
+ axisScroll.add(axisTree);
+ axisScroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ axisScroll.set_shadow_type(Gtk::SHADOW_IN);
+ axisScroll.set_size_request(0, 150);
+
+ pane.pack1(confDeviceScroller);
+ pane.pack2(detailsBox);
+
+ detailsBox.pack_start(titleFrame, false, false, 6);
+ detailsBox.pack_start(modeBox, false, false, 6);
+ detailsBox.pack_start(axisFrame, false, false);
+ detailsBox.pack_start(keysFrame, false, false);
+
+ pack_start(pane, true, true);
+ pack_start(useExt, Gtk::PACK_SHRINK);
+ pack_start(*buttonBox, false, false);
+
+ // Select the first device
+ confDeviceTree.get_selection()->select(confDeviceStore->get_iter("0"));
+
}
InputDialogImpl::ConfPanel::~ConfPanel()
@@ -999,6 +1262,8 @@ void InputDialogImpl::ConfPanel::commitCellModeChange(Glib::ustring const &path,
Inkscape::DeviceManager::getManager().setMode( dev->getId(), mode );
}
}
+
+
}
void InputDialogImpl::ConfPanel::setCellStateToggle(Gtk::CellRenderer *rndr, Gtk::TreeIter const &iter)
@@ -1033,6 +1298,25 @@ void InputDialogImpl::ConfPanel::commitCellStateChange(Glib::ustring const &path
}
}
+void InputDialogImpl::ConfPanel::onTreeSelect()
+{
+ Glib::RefPtr<Gtk::TreeSelection> treeSel = confDeviceTree.get_selection();
+ Gtk::TreeModel::iterator iter = treeSel->get_selected();
+ if (iter) {
+ Gtk::TreeModel::Row row = *iter;
+ Glib::ustring val = row[getCols().description];
+ Glib::RefPtr<InputDevice const> dev = row[getCols().device];
+ Gdk::InputMode mode = (*iter)[getCols().mode];
+ modeCombo.set_active(getModeId(mode));
+
+ titleLabel.set_markup("<b>" + row[getCols().description] + "</b>");
+
+ if (dev) {
+ setKeys(dev->getNumKeys());
+ setAxis(dev->getNumAxes());
+ }
+ }
+}
void InputDialogImpl::ConfPanel::saveSettings()
{
Inkscape::DeviceManager::getManager().saveConfig();
@@ -1074,8 +1358,8 @@ void InputDialogImpl::handleDeviceChange(Glib::RefPtr<InputDevice const> device)
{
// g_message("OUCH!!!! for %p hits %s", &device, device->getId().c_str());
std::vector<Glib::RefPtr<Gtk::TreeStore> > stores;
- stores.push_back(store);
- stores.push_back(cfgPanel.store);
+ stores.push_back(deviceStore);
+ stores.push_back(cfgPanel.confDeviceStore);
for (std::vector<Glib::RefPtr<Gtk::TreeStore> >::iterator it = stores.begin(); it != stores.end(); ++it) {
Gtk::TreeModel::iterator deviceIter;
@@ -1158,11 +1442,11 @@ bool InputDialogImpl::findDeviceByLink(const Gtk::TreeModel::iterator& iter,
void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device, Gtk::TreeIter tabletIter, Glib::RefPtr<Gtk::TreeView> tree)
{
- Glib::RefPtr<Gtk::TreeStore> store = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(tree->get_model());
+ Glib::RefPtr<Gtk::TreeStore> deviceStore = Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(tree->get_model());
// g_message("Links!!!! for %p hits [%s] with link of [%s]", &device, device->getId().c_str(), device->getLink().c_str());
Gtk::TreeModel::iterator deviceIter;
- store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
+ deviceStore->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
sigc::ptr_fun(&InputDialogImpl::findDevice),
device->getId(),
&deviceIter) );
@@ -1180,16 +1464,16 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
Glib::ustring descr = (*deviceIter)[getCols().description];
Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[getCols().thumbnail];
- Gtk::TreeModel::Row deviceRow = *store->append(tabletIter->children());
+ Gtk::TreeModel::Row deviceRow = *deviceStore->append(tabletIter->children());
deviceRow[getCols().description] = descr;
deviceRow[getCols().thumbnail] = thumb;
deviceRow[getCols().device] = dev;
deviceRow[getCols().mode] = dev->getMode();
Gtk::TreeModel::iterator oldParent = deviceIter->parent();
- store->erase(deviceIter);
+ deviceStore->erase(deviceIter);
if ( oldParent->children().empty() ) {
- store->erase(oldParent);
+ deviceStore->erase(oldParent);
}
}
} else {
@@ -1197,7 +1481,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
if ( deviceIter->parent() == tabletIter ) {
// Simple case. Not already linked
- Gtk::TreeIter newGroup = store->append(tabletIter->children());
+ Gtk::TreeIter newGroup = deviceStore->append(tabletIter->children());
(*newGroup)[getCols().description] = _("Pen");
(*newGroup)[getCols().thumbnail] = getPix(PIX_PEN);
@@ -1205,7 +1489,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
Glib::ustring descr = (*deviceIter)[getCols().description];
Glib::RefPtr<Gdk::Pixbuf> thumb = (*deviceIter)[getCols().thumbnail];
- Gtk::TreeModel::Row deviceRow = *store->append(newGroup->children());
+ Gtk::TreeModel::Row deviceRow = *deviceStore->append(newGroup->children());
deviceRow[getCols().description] = descr;
deviceRow[getCols().thumbnail] = thumb;
deviceRow[getCols().device] = dev;
@@ -1213,7 +1497,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
Gtk::TreeModel::iterator linkIter;
- store->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
+ deviceStore->foreach_iter( sigc::bind<Glib::ustring, Gtk::TreeModel::iterator*>(
sigc::ptr_fun(&InputDialogImpl::findDeviceByLink),
device->getId(),
&linkIter) );
@@ -1222,22 +1506,22 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
descr = (*linkIter)[getCols().description];
thumb = (*linkIter)[getCols().thumbnail];
- deviceRow = *store->append(newGroup->children());
+ deviceRow = *deviceStore->append(newGroup->children());
deviceRow[getCols().description] = descr;
deviceRow[getCols().thumbnail] = thumb;
deviceRow[getCols().device] = dev;
deviceRow[getCols().mode] = dev->getMode();
Gtk::TreeModel::iterator oldParent = linkIter->parent();
- store->erase(linkIter);
+ deviceStore->erase(linkIter);
if ( oldParent->children().empty() ) {
- store->erase(oldParent);
+ deviceStore->erase(oldParent);
}
}
Gtk::TreeModel::iterator oldParent = deviceIter->parent();
- store->erase(deviceIter);
+ deviceStore->erase(deviceIter);
if ( oldParent->children().empty() ) {
- store->erase(oldParent);
+ deviceStore->erase(oldParent);
}
tree->expand_row(Gtk::TreePath(newGroup), true);
}
@@ -1246,7 +1530,7 @@ void InputDialogImpl::updateDeviceLinks(Glib::RefPtr<InputDevice const> device,
}
void InputDialogImpl::linkComboChanged() {
- Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
+ Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection();
Gtk::TreeModel::iterator iter = treeSel->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
@@ -1272,34 +1556,26 @@ void InputDialogImpl::linkComboChanged() {
void InputDialogImpl::resyncToSelection() {
bool clear = true;
- Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
+ Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection();
Gtk::TreeModel::iterator iter = treeSel->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
Glib::ustring val = row[getCols().description];
Glib::RefPtr<InputDevice const> dev = row[getCols().device];
+
if ( dev ) {
- devDetails.set_sensitive(true);
+ axisTable.set_sensitive(true);
linkConnection.block();
-#if WITH_GTKMM_2_24
linkCombo.remove_all();
linkCombo.append(_("None"));
-#else
- linkCombo.clear_items();
- linkCombo.append_text(_("None"));
-#endif
linkCombo.set_active(0);
if ( dev->getSource() != Gdk::SOURCE_MOUSE ) {
Glib::ustring linked = dev->getLink();
std::list<Glib::RefPtr<InputDevice const> > devList = Inkscape::DeviceManager::getManager().getDevices();
for ( std::list<Glib::RefPtr<InputDevice const> >::const_iterator it = devList.begin(); it != devList.end(); ++it ) {
if ( ((*it)->getSource() != Gdk::SOURCE_MOUSE) && ((*it) != dev) ) {
-#if WITH_GTKMM_2_24
linkCombo.append((*it)->getName().c_str());
-#else
- linkCombo.append_text((*it)->getName().c_str());
-#endif
if ( (linked.length() > 0) && (linked == (*it)->getId()) ) {
linkCombo.set_active_text((*it)->getName().c_str());
}
@@ -1313,39 +1589,70 @@ void InputDialogImpl::resyncToSelection() {
clear = false;
devName.set_label(row[getCols().description]);
- detailFrame.set_label(row[getCols().description]);
+ axisFrame.set_label(row[getCols().description]);
setupValueAndCombo( dev->getNumAxes(), dev->getNumAxes(), devAxesCount, axesCombo);
setupValueAndCombo( dev->getNumKeys(), dev->getNumKeys(), devKeyCount, buttonCombo);
+
+
}
}
- devDetails.set_sensitive(!clear);
+ axisTable.set_sensitive(!clear);
if (clear) {
- detailFrame.set_label("");
+ axisFrame.set_label("");
devName.set_label("");
devAxesCount.set_label("");
devKeyCount.set_label("");
}
}
+void InputDialogImpl::ConfPanel::setAxis(gint count)
+{
+ /*
+ * TODO - Make each axis editable
+ */
+ axisStore->clear();
+
+ static Glib::ustring axesLabels[6] = {_("X"), _("Y"), _("Pressure"), _("X tilt"), _("Y tilt"), _("Wheel")};
+
+ for ( gint barNum = 0; barNum < static_cast<gint>(G_N_ELEMENTS(axesLabels)); barNum++ ) {
+
+ Gtk::TreeModel::Row row = *(axisStore->append());
+ row[axisColumns.name] = axesLabels[barNum];
+ if (barNum < count) {
+ row[axisColumns.value] = Glib::ustring::format(barNum+1);
+ } else {
+ row[axisColumns.value] = _("None");
+ }
+ }
+
+}
+void InputDialogImpl::ConfPanel::setKeys(gint count)
+{
+ /*
+ * TODO - Make each key assignable
+ */
+
+ keysStore->clear();
+
+ for (gint i = 0; i < count; i++) {
+ Gtk::TreeModel::Row row = *(keysStore->append());
+ row[keysColumns.name] = Glib::ustring::format(i+1);
+ row[keysColumns.value] = _("Disabled");
+ }
+
+
+}
void InputDialogImpl::setupValueAndCombo( gint reported, gint actual, Gtk::Label& label, Gtk::ComboBoxText& combo )
{
gchar *tmp = g_strdup_printf("%d", reported);
label.set_label(tmp);
g_free(tmp);
-#if WITH_GTKMM_2_24
combo.remove_all();
-#else
- combo.clear_items();
-#endif
for ( gint i = 1; i <= reported; ++i ) {
tmp = g_strdup_printf("%d", i);
-#if WITH_GTKMM_2_24
combo.append(tmp);
-#else
- combo.append_text(tmp);
-#endif
g_free(tmp);
}
@@ -1371,9 +1678,9 @@ void InputDialogImpl::updateTestButtons( Glib::ustring const& key, gint hotButto
void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev )
{
- static gdouble epsilon = 0.0001;
+ //static gdouble epsilon = 0.0001;
{
- Glib::RefPtr<Gtk::TreeSelection> treeSel = tree.get_selection();
+ Glib::RefPtr<Gtk::TreeSelection> treeSel = deviceTree.get_selection();
Gtk::TreeModel::iterator iter = treeSel->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
@@ -1385,7 +1692,6 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev )
}
}
-
for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(testAxes)); i++ ) {
if ( axesMap[key].find(i) != axesMap[key].end() ) {
switch ( axesMap[key][i].first ) {
@@ -1400,7 +1706,6 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev )
testAxes[i].set(getPix(PIX_AXIS_OFF));
axesValues[i].set_sensitive(true);
if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) {
-
// FIXME: Device axis ranges are inaccessible in GTK+ 3 and
// are deprecated in GTK+ 2. Progress-bar ranges are disabled
// until we find an alternative solution
diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp
index 465192aee..3feed2afe 100644
--- a/src/ui/dialog/layer-properties.cpp
+++ b/src/ui/dialog/layer-properties.cpp
@@ -28,7 +28,10 @@
#include "sp-item.h"
#include "verbs.h"
#include "selection.h"
-
+#include "selection-chemistry.h"
+#include "ui/icon-names.h"
+#include "ui/widget/imagetoggler.h"
+#include "event-context.h"
namespace Inkscape {
namespace UI {
@@ -37,21 +40,38 @@ namespace Dialogs {
LayerPropertiesDialog::LayerPropertiesDialog()
: _strategy(NULL), _desktop(NULL), _layer(NULL), _position_visible(false)
{
+#if WITH_GTKMM_3_0
+ Gtk::Box *mainVBox = get_content_area();
+ _layout_table.set_row_spacing(4);
+ _layout_table.set_column_spacing(4);
+#else
Gtk::Box *mainVBox = get_vbox();
-
_layout_table.set_spacings(4);
_layout_table.resize (1, 2);
+#endif
// Layer name widgets
_layer_name_entry.set_activates_default(true);
_layer_name_label.set_label(_("Layer name:"));
_layer_name_label.set_alignment(1.0, 0.5);
+#if WITH_GTKMM_3_0
+ _layer_name_label.set_halign(Gtk::ALIGN_FILL);
+ _layer_name_label.set_valign(Gtk::ALIGN_FILL);
+ _layout_table.attach(_layer_name_label, 0, 0, 1, 1);
+
+ _layer_name_entry.set_halign(Gtk::ALIGN_FILL);
+ _layer_name_entry.set_valign(Gtk::ALIGN_FILL);
+ _layer_name_entry.set_hexpand();
+ _layout_table.attach(_layer_name_entry, 1, 0, 1, 1);
+#else
_layout_table.attach(_layer_name_label,
0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
_layout_table.attach(_layer_name_entry,
1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
- mainVBox->pack_start(_layout_table, false, false, 4);
+#endif
+
+ mainVBox->pack_start(_layout_table, true, true, 4);
// Buttons
_close_button.set_use_stock(true);
@@ -82,6 +102,7 @@ LayerPropertiesDialog::LayerPropertiesDialog()
}
LayerPropertiesDialog::~LayerPropertiesDialog() {
+
_setDesktop(NULL);
_setLayer(NULL);
}
@@ -145,7 +166,9 @@ LayerPropertiesDialog::_setup_position_controls() {
_layer_position_combo.set_cell_data_func(_label_renderer,
sigc::mem_fun(*this, &LayerPropertiesDialog::_prepareLabelRenderer));
+#if !WITH_GTKMM_3_0
_layout_table.resize (2, 2);
+#endif
Gtk::ListStore::iterator row;
row = _dropdown_list->append();
@@ -159,15 +182,162 @@ LayerPropertiesDialog::_setup_position_controls() {
row->set_value(_dropdown_columns.position, LPOS_CHILD);
row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current")));
- _layout_table.attach(_layer_position_combo,
- 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
_layer_position_label.set_label(_("Position:"));
_layer_position_label.set_alignment(1.0, 0.5);
+
+#if WITH_GTKMM_3_0
+ _layer_position_combo.set_halign(Gtk::ALIGN_FILL);
+ _layer_position_combo.set_valign(Gtk::ALIGN_FILL);
+ _layer_position_combo.set_hexpand();
+ _layout_table.attach(_layer_position_combo, 1, 1, 1, 1);
+
+ _layer_position_label.set_halign(Gtk::ALIGN_FILL);
+ _layer_position_label.set_valign(Gtk::ALIGN_FILL);
+ _layout_table.attach(_layer_position_label, 0, 1, 1, 1);
+#else
+ _layout_table.attach(_layer_position_combo,
+ 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
_layout_table.attach(_layer_position_label,
0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
+#endif
+
+ show_all_children();
+}
+
+void
+LayerPropertiesDialog::_setup_layers_controls() {
+
+ ModelColumns *zoop = new ModelColumns();
+ _model = zoop;
+ _store = Gtk::TreeStore::create( *zoop );
+ _tree.set_model( _store );
+ _tree.set_headers_visible(false);
+
+ Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler(
+ INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) );
+ int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1;
+ Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum);
+ if ( col ) {
+ col->add_attribute( eyeRenderer->property_active(), _model->_colVisible );
+ }
+
+ Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler(
+ INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) );
+ int lockedColNum = _tree.append_column("lock", *renderer) - 1;
+ col = _tree.get_column(lockedColNum);
+ if ( col ) {
+ col->add_attribute( renderer->property_active(), _model->_colLocked );
+ }
+
+ Gtk::CellRendererText *_text_renderer = manage(new Gtk::CellRendererText());
+ int nameColNum = _tree.append_column("Name", *_text_renderer) - 1;
+ Gtk::TreeView::Column *_name_column = _tree.get_column(nameColNum);
+ _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel);
+
+ _tree.set_expander_column( *_tree.get_column(nameColNum) );
+ _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &LayerPropertiesDialog::_handleKeyEvent), false );
+ _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayerPropertiesDialog::_handleButtonEvent) );
+
+ _scroller.add( _tree );
+ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
+ _scroller.set_shadow_type(Gtk::SHADOW_IN);
+ _scroller.set_size_request(220, 180);
+
+ SPDocument* document = _desktop->doc();
+ SPRoot* root = document->getRoot();
+ if ( root ) {
+ SPObject* target = _desktop->currentLayer();
+ _store->clear();
+ _addLayer( document, SP_OBJECT(root), 0, target, 0 );
+ }
+
+ _layout_table.remove(_layer_name_entry);
+ _layout_table.remove(_layer_name_label);
+
+#if WITH_GTKMM_3_0
+ _scroller.set_halign(Gtk::ALIGN_FILL);
+ _scroller.set_valign(Gtk::ALIGN_FILL);
+ _scroller.set_hexpand();
+ _scroller.set_vexpand();
+ _layout_table.attach(_scroller, 0, 1, 2, 1);
+#else
+ _layout_table.attach(_scroller,
+ 0, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND);
+#endif
+
show_all_children();
}
+void LayerPropertiesDialog::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level )
+{
+ int _maxNestDepth = 20;
+ if ( _desktop && _desktop->layer_manager && layer && (level < _maxNestDepth) ) {
+ unsigned int counter = _desktop->layer_manager->childCount(layer);
+ for ( unsigned int i = 0; i < counter; i++ ) {
+ 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() );
+#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->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false;
+ row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false;
+
+ if ( target && child == target ) {
+ _tree.expand_to_path( _store->get_path(iter) );
+
+ Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
+ select->select(iter);
+
+ //_checkTreeSelection();
+ }
+
+ _addLayer( doc, child, &row, target, level + 1 );
+ }
+ }
+ }
+}
+
+SPObject* LayerPropertiesDialog::_selectedLayer()
+{
+ SPObject* obj = 0;
+
+ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
+ if ( iter ) {
+ Gtk::TreeModel::Row row = *iter;
+ obj = row[_model->_colObject];
+ }
+
+ return obj;
+}
+
+bool LayerPropertiesDialog::_handleKeyEvent(GdkEventKey *event)
+{
+
+ switch (get_group0_keyval(event)) {
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter: {
+ _strategy->perform(*this);
+ _close();
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+void LayerPropertiesDialog::_handleButtonEvent(GdkEventButton* event)
+{
+ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) {
+ _strategy->perform(*this);
+ _close();
+ }
+}
+
/** Formats the label for a given layer row
*/
void LayerPropertiesDialog::_prepareLabelRenderer(
@@ -202,8 +372,11 @@ void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) {
void LayerPropertiesDialog::Create::setup(LayerPropertiesDialog &dialog) {
dialog.set_title(_("Add Layer"));
- //TODO: find an unused layer number, forming name from _("Layer ") + "%d"
- dialog._layer_name_entry.set_text(_("Layer"));
+
+ // Set the initial name to the "next available" layer name
+ LayerManager *mgr = dialog._desktop->layer_manager;
+ Glib::ustring newName = mgr->getNextLayerName(NULL, dialog._desktop->currentLayer()->label());
+ dialog._layer_name_entry.set_text(newName.c_str());
dialog._apply_button.set_label(_("_Add"));
dialog._setup_position_controls();
}
@@ -231,6 +404,20 @@ void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) {
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created."));
}
+void LayerPropertiesDialog::Move::setup(LayerPropertiesDialog &dialog) {
+ dialog.set_title(_("Move to Layer"));
+ //TODO: find an unused layer number, forming name from _("Layer ") + "%d"
+ dialog._layer_name_entry.set_text(_("Layer"));
+ dialog._apply_button.set_label(_("_Move"));
+ dialog._setup_layers_controls();
+}
+
+void LayerPropertiesDialog::Move::perform(LayerPropertiesDialog &dialog) {
+
+ SPObject *moveto = dialog._selectedLayer();
+ sp_selection_to_layer(dialog._desktop, moveto, false);
+}
+
void LayerPropertiesDialog::_setDesktop(SPDesktop *desktop) {
if (desktop) {
Inkscape::GC::anchor (desktop);
diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h
index c7d7de130..0e2f8ed94 100644
--- a/src/ui/dialog/layer-properties.h
+++ b/src/ui/dialog/layer-properties.h
@@ -12,14 +12,28 @@
#ifndef INKSCAPE_DIALOG_LAYER_PROPERTIES_H
#define INKSCAPE_DIALOG_LAYER_PROPERTIES_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/dialog.h>
#include <gtkmm/entry.h>
#include <gtkmm/label.h>
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
#include <gtkmm/table.h>
+#endif
+
#include <gtkmm/combobox.h>
#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
#include "layer-fns.h"
+#include "ui/widget/layer-selector.h"
class SPDesktop;
@@ -40,6 +54,9 @@ class LayerPropertiesDialog : public Gtk::Dialog {
static void showCreate(SPDesktop *desktop, SPObject *layer) {
_showDialog(Create::instance(), desktop, layer);
}
+ static void showMove(SPDesktop *desktop, SPObject *layer) {
+ _showDialog(Move::instance(), desktop, layer);
+ }
protected:
struct Strategy {
@@ -57,9 +74,15 @@ protected:
void setup(LayerPropertiesDialog &dialog);
void perform(LayerPropertiesDialog &dialog);
};
+ struct Move : public Strategy {
+ static Move &instance() { static Move instance; return instance; }
+ void setup(LayerPropertiesDialog &dialog);
+ void perform(LayerPropertiesDialog &dialog);
+ };
- friend class Rename;
- friend class Create;
+ friend struct Rename;
+ friend struct Create;
+ friend struct Move;
Strategy *_strategy;
SPDesktop *_desktop;
@@ -79,9 +102,40 @@ protected:
Gtk::Entry _layer_name_entry;
Gtk::Label _layer_position_label;
Gtk::ComboBox _layer_position_combo;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _layout_table;
+#else
Gtk::Table _layout_table;
+#endif
+
bool _position_visible;
+ class ModelColumns : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+
+ ModelColumns()
+ {
+ add(_colObject);
+ add(_colVisible);
+ add(_colLocked);
+ add(_colLabel);
+ }
+ virtual ~ModelColumns() {}
+
+ Gtk::TreeModelColumn<SPObject*> _colObject;
+ Gtk::TreeModelColumn<Glib::ustring> _colLabel;
+ Gtk::TreeModelColumn<bool> _colVisible;
+ Gtk::TreeModelColumn<bool> _colLocked;
+ };
+
+ Gtk::TreeView _tree;
+ ModelColumns* _model;
+ Glib::RefPtr<Gtk::TreeStore> _store;
+ Gtk::ScrolledWindow _scroller;
+
+
PositionDropdownColumns _dropdown_columns;
Gtk::CellRendererText _label_renderer;
Glib::RefPtr<Gtk::ListStore> _dropdown_list;
@@ -104,8 +158,14 @@ protected:
void _close();
void _setup_position_controls();
+ void _setup_layers_controls();
void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
+ void _addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level );
+ SPObject* _selectedLayer();
+ bool _handleKeyEvent(GdkEventKey *event);
+ void _handleButtonEvent(GdkEventButton* event);
+
private:
LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy
LayerPropertiesDialog &operator=(LayerPropertiesDialog const &); // no assign
diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp
index 70cf7075c..dd147d00f 100644
--- a/src/ui/dialog/layers.cpp
+++ b/src/ui/dialog/layers.cpp
@@ -20,6 +20,7 @@
#include <gtkmm/separatormenuitem.h>
#include <glibmm/i18n.h>
+#include <glibmm/main.h>
#include "desktop.h"
#include "desktop-style.h"
@@ -69,6 +70,9 @@ enum {
BUTTON_SOLO,
BUTTON_SHOW_ALL,
BUTTON_HIDE_ALL,
+ BUTTON_LOCK_OTHERS,
+ BUTTON_LOCK_ALL,
+ BUTTON_UNLOCK_ALL,
DRAGNDROP
};
@@ -263,6 +267,21 @@ bool LayersPanel::_executeAction()
_fireAction( SP_VERB_LAYER_HIDE_ALL );
}
break;
+ case BUTTON_LOCK_OTHERS:
+ {
+ _fireAction( SP_VERB_LAYER_LOCK_OTHERS );
+ }
+ break;
+ case BUTTON_LOCK_ALL:
+ {
+ _fireAction( SP_VERB_LAYER_LOCK_ALL );
+ }
+ break;
+ case BUTTON_UNLOCK_ALL:
+ {
+ _fireAction( SP_VERB_LAYER_UNLOCK_ALL );
+ }
+ break;
case DRAGNDROP:
{
_doTreeMove( );
@@ -540,30 +559,76 @@ bool LayersPanel::_handleKeyEvent(GdkEventKey *event)
}
return false;
}
-void LayersPanel::_handleButtonEvent(GdkEventButton* event)
+
+bool LayersPanel::_handleButtonEvent(GdkEventButton* event)
{
static unsigned doubleclick = 0;
- // TODO - fix to a better is-popup function
if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) {
+ // TODO - fix to a better is-popup function
+ Gtk::TreeModel::Path path;
+ int x = static_cast<int>(event->x);
+ int y = static_cast<int>(event->y);
+ if ( _tree.get_path_at_pos( x, y, path ) ) {
+ _checkTreeSelection();
+ _popupMenu.popup(event->button, event->time);
+ }
+ }
- {
- Gtk::TreeModel::Path path;
- Gtk::TreeViewColumn* col = 0;
- int x = static_cast<int>(event->x);
- int y = static_cast<int>(event->y);
- int x2 = 0;
- int y2 = 0;
- if ( _tree.get_path_at_pos( x, y,
- path, col,
- x2, y2 ) ) {
- _checkTreeSelection();
- _popupMenu.popup(event->button, event->time);
+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)
+ && (event->state & GDK_MOD1_MASK)) {
+ // Alt left click on the visible/lock columns - eat this event to keep row selection
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn* col = 0;
+ int x = static_cast<int>(event->x);
+ int y = static_cast<int>(event->y);
+ int x2 = 0;
+ int y2 = 0;
+ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) {
+ if (col == _tree.get_column(COL_VISIBLE-1) ||
+ col == _tree.get_column(COL_LOCKED-1)) {
+ return true;
}
}
+ }
+ // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here.
+ if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)
+ && (event->state & (GDK_SHIFT_MASK | GDK_MOD1_MASK))) {
+
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn* col = 0;
+ int x = static_cast<int>(event->x);
+ int y = static_cast<int>(event->y);
+ int x2 = 0;
+ int y2 = 0;
+ if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) {
+ if (event->state & GDK_SHIFT_MASK) {
+ // Shift left click on the visible/lock columns toggles "solo" mode
+ if (col == _tree.get_column(COL_VISIBLE - 1)) {
+ _takeAction(BUTTON_SOLO);
+ } else if (col == _tree.get_column(COL_LOCKED - 1)) {
+ _takeAction(BUTTON_LOCK_OTHERS);
+ }
+ } else if (event->state & GDK_MOD1_MASK) {
+ // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection
+ Gtk::TreeModel::iterator iter = _store->get_iter(path);
+ if (_store->iter_is_valid(iter)) {
+ Gtk::TreeModel::Row row = *iter;
+ SPObject *obj = row[_model->_colObject];
+ if (col == _tree.get_column(COL_VISIBLE - 1)) {
+ _desktop->toggleLayerSolo( obj );
+ DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo"));
+ } else if (col == _tree.get_column(COL_LOCKED - 1)) {
+ _desktop->toggleLockOtherLayers( obj );
+ DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers"));
+ }
+ }
+ }
+ }
}
+
if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) {
doubleclick = 1;
}
@@ -584,13 +649,14 @@ void LayersPanel::_handleButtonEvent(GdkEventButton* event)
}
}
+ return false;
}
/*
* Drap and drop within the tree
* Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer
*/
-bool LayersPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time)
+bool LayersPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int x, int y, guint /*time*/)
{
int cell_x = 0, cell_y = 0;
Gtk::TreeModel::Path target_path;
@@ -678,7 +744,7 @@ void LayersPanel::_renameLayer(Gtk::TreeModel::Row row, const Glib::ustring& nam
if ( !name.empty() && (!oldLabel || name != oldLabel) ) {
_desktop->layer_manager->renameLayer( obj, name.c_str(), FALSE );
DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
- _("Renamed layer"));
+ _("Rename layer"));
}
}
@@ -780,8 +846,8 @@ LayersPanel::LayersPanel() :
_text_renderer->signal_edited().connect( sigc::mem_fun(*this, &LayersPanel::_handleEdited) );
_text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &LayersPanel::_handleEditingCancelled) );
- _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) );
- _tree.signal_button_release_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) );
+ _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent), false );
+ _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent), false );
_tree.signal_key_press_event().connect( sigc::mem_fun(*this, &LayersPanel::_handleKeyEvent), false );
_scroller.add( _tree );
@@ -810,43 +876,34 @@ LayersPanel::LayersPanel() :
SPDesktop* targetDesktop = getDesktop();
-#if !WITH_GTKMM_3_0
- // TODO: This has been removed from Gtkmm 3.0. Check that everything still
- // looks OK!
- _buttonsRow.set_child_min_width( 16 );
-#endif
-
- _buttonsRow.set_layout (Gtk::BUTTONBOX_END);
-
Gtk::Button* btn = manage( new Gtk::Button() );
_styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, C_("Layers", "New") );
btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) );
- _buttonsRow.add( *btn );
- _buttonsRow.set_child_secondary( *btn , true);
+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK);
btn = manage( new Gtk::Button() );
- _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, C_("Layers", "Top") );
- btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) );
- _watchingNonTop.push_back( btn );
- _buttonsRow.add( *btn );
-
- btn = manage( new Gtk::Button() );
- _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, C_("Layers", "Up") );
- btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) );
- _watchingNonTop.push_back( btn );
- _buttonsRow.add( *btn );
-
+ _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, C_("Layers", "Bot") );
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) );
+ _watchingNonBottom.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
btn = manage( new Gtk::Button() );
_styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, C_("Layers", "Dn") );
btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) );
_watchingNonBottom.push_back( btn );
- _buttonsRow.add( *btn );
-
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
btn = manage( new Gtk::Button() );
- _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, C_("Layers", "Bot") );
- btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) );
- _watchingNonBottom.push_back( btn );
- _buttonsRow.add( *btn );
+ _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, C_("Layers", "Up") );
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) );
+ _watchingNonTop.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ btn = manage( new Gtk::Button() );
+ _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, C_("Layers", "Top") );
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) );
+ _watchingNonTop.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
// btn = manage( new Gtk::Button("Dup") );
// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) );
@@ -856,9 +913,10 @@ LayersPanel::LayersPanel() :
_styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("X") );
btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) );
_watching.push_back( btn );
- _buttonsRow.add( *btn );
- _buttonsRow.set_child_secondary( *btn , true);
-
+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK);
+
+ _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET);
+ _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET);
@@ -876,6 +934,12 @@ LayersPanel::LayersPanel() :
_popupMenu.append(*manage(new Gtk::SeparatorMenuItem()));
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) );
+
+ _popupMenu.append(*manage(new Gtk::SeparatorMenuItem()));
+
_watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) );
_watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) );
diff --git a/src/ui/dialog/layers.h b/src/ui/dialog/layers.h
index 12e5f7986..e9fd9ebc6 100644
--- a/src/ui/dialog/layers.h
+++ b/src/ui/dialog/layers.h
@@ -13,7 +13,6 @@
#define SEEN_LAYERS_PANEL_H
#include <gtkmm/box.h>
-#include <gtkmm/buttonbox.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
#include <gtkmm/scrolledwindow.h>
@@ -65,7 +64,7 @@ private:
void _preToggle( GdkEvent const *event );
void _toggled( Glib::ustring const& str, int targetCol );
- void _handleButtonEvent(GdkEventButton *event);
+ bool _handleButtonEvent(GdkEventButton *event);
bool _handleKeyEvent(GdkEventKey *event);
bool _handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, guint time);
void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text);
@@ -122,9 +121,13 @@ private:
Gtk::CellRendererText *_text_renderer;
Gtk::TreeView::Column *_name_column;
#if WITH_GTKMM_3_0
- Gtk::ButtonBox _buttonsRow;
+ Gtk::Box _buttonsRow;
+ Gtk::Box _buttonsPrimary;
+ Gtk::Box _buttonsSecondary;
#else
- Gtk::HButtonBox _buttonsRow;
+ Gtk::HBox _buttonsRow;
+ Gtk::HBox _buttonsPrimary;
+ Gtk::HBox _buttonsSecondary;
#endif
Gtk::ScrolledWindow _scroller;
Gtk::Menu _popupMenu;
diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp
index c22aace37..b5f51d81d 100644
--- a/src/ui/dialog/livepatheffect-add.cpp
+++ b/src/ui/dialog/livepatheffect-add.cpp
@@ -48,6 +48,7 @@ LivePathEffectAdd::LivePathEffectAdd() :
effectlist_treeview.set_model(effectlist_store);
effectlist_treeview.set_headers_visible(false);
effectlist_treeview.append_column("Name", _columns.name);
+ //effectlist_treeview.set_activates_default(true);
/**
* Initialize Effect list
@@ -68,11 +69,16 @@ LivePathEffectAdd::LivePathEffectAdd() :
* Buttons
*/
close_button.set_use_stock(true);
- close_button.set_can_default();
+ //close_button.set_can_default();
add_button.set_use_underline(true);
add_button.set_can_default();
+#if WITH_GTKMM_3_0
+ Gtk::Box *mainVBox = get_content_area();
+#else
Gtk::Box *mainVBox = get_vbox();
+#endif
+
mainVBox->pack_start(scrolled_window, true, true);
add_action_widget(close_button, Gtk::RESPONSE_CLOSE);
add_action_widget(add_button, Gtk::RESPONSE_APPLY);
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 7ecb6d5cd..e6bb9b43d 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -48,8 +48,6 @@
#include "livepatheffect-add.h"
namespace Inkscape {
-class Application;
-
namespace UI {
namespace Dialog {
diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp
index f67c4db21..f5addc401 100644
--- a/src/ui/dialog/object-attributes.cpp
+++ b/src/ui/dialog/object-attributes.cpp
@@ -20,18 +20,18 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include <glibmm/i18n.h>
-
+#include "ui/dialog/dialog-manager.h"
#include "desktop-handles.h"
#include "macros.h"
#include "sp-anchor.h"
#include "sp-image.h"
#include "verbs.h"
#include "xml/repr.h"
-#include "ui/dialog/dialog-manager.h"
#include "ui/dialog/object-attributes.h"
+#include "widgets/sp-attribute-widget.h"
#include "inkscape.h"
#include "selection.h"
+#include <glibmm/i18n.h>
namespace Inkscape {
namespace UI {
@@ -81,14 +81,14 @@ ObjectAttributes::ObjectAttributes (void) :
UI::Widget::Panel ("", "/dialogs/objectattr/", SP_VERB_DIALOG_ATTR),
blocked (false),
CurrentItem(NULL),
- attrTable(),
+ attrTable(Gtk::manage(new SPAttributeTable())),
desktop(NULL),
deskTrack(),
selectChangedConn(),
subselChangedConn(),
selectModifiedConn()
{
- attrTable.show();
+ attrTable->show();
widget_setup();
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectAttributes::setTargetDesktop) );
@@ -123,7 +123,7 @@ void ObjectAttributes::widget_setup (void)
}
blocked = true;
- SPObject *obj = (SPObject*)item; //to get the selected item
+ SPObject *obj = SP_OBJECT(item); //to get the selected item
GObjectClass *klass = G_OBJECT_GET_CLASS(obj); //to deduce the object's type
GType type = G_TYPE_FROM_CLASS(klass);
const SPAttrDesc *desc;
@@ -163,12 +163,12 @@ void ObjectAttributes::widget_setup (void)
attrs.push_back (desc[len].attribute);
len += 1;
}
- attrTable.set_object(obj, labels, attrs, (GtkWidget*)gobj());
+ attrTable->set_object(obj, labels, attrs, (GtkWidget*)gobj());
CurrentItem = item;
}
else
{
- attrTable.change_object(obj);
+ attrTable->change_object(obj);
}
set_sensitive (true);
@@ -201,7 +201,7 @@ void ObjectAttributes::selectionModifiedCB( guint flags )
if (flags & ( SP_OBJECT_MODIFIED_FLAG |
SP_OBJECT_PARENT_MODIFIED_FLAG |
SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
- attrTable.reread_properties();
+ attrTable->reread_properties();
}
}
diff --git a/src/ui/dialog/object-attributes.h b/src/ui/dialog/object-attributes.h
index 81467dea6..b0d02a0af 100644
--- a/src/ui/dialog/object-attributes.h
+++ b/src/ui/dialog/object-attributes.h
@@ -28,7 +28,8 @@
#include "desktop.h"
#include "ui/dialog/desktop-tracker.h"
#include "ui/widget/panel.h"
-#include "widgets/sp-attribute-widget.h"
+
+class SPAttributeTable;
namespace Inkscape {
namespace UI {
@@ -72,7 +73,7 @@ private:
* in the SPAttrDesc arrays at the top of the cpp-file. This widgets also
* ensures object attribute modifications by the user are set.
*/
- SPAttributeTable attrTable;
+ SPAttributeTable *attrTable;
/**
* Stores the current desktop.
diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp
index 0aeb3816f..8a2b0299a 100644
--- a/src/ui/dialog/object-properties.cpp
+++ b/src/ui/dialog/object-properties.cpp
@@ -26,11 +26,8 @@
* Abhishek Sharma
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include "object-properties.h"
+#include "widgets/sp-attribute-widget.h"
#include "../../desktop-handles.h"
#include "../../document.h"
#include "../../document-undo.h"
@@ -41,6 +38,12 @@
#include "sp-item.h"
#include <glibmm/i18n.h>
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
namespace Inkscape {
namespace UI {
@@ -50,38 +53,60 @@ ObjectProperties::ObjectProperties (void) :
UI::Widget::Panel ("", "/dialogs/object/", SP_VERB_DIALOG_ITEM),
blocked (false),
CurrentItem(NULL),
- TopTable (3, 4, false),
+#if WITH_GTKMM_3_0
+ TopTable(Gtk::manage(new Gtk::Grid())),
+#else
+ TopTable(Gtk::manage(new Gtk::Table(3, 4))),
+#endif
LabelID(_("_ID:"), 1),
LabelLabel(_("_Label:"), 1),
LabelTitle(_("_Title:"),1),
- LabelDescription(_("_Description"),1),
+ LabelDescription(_("_Description:"),1),
FrameDescription("", FALSE),
HBoxCheck(FALSE, 0),
- CheckTable(1, 2, TRUE),
+#if WITH_GTKMM_3_0
+ CheckTable(Gtk::manage(new Gtk::Grid())),
+#else
+ CheckTable(Gtk::manage(new Gtk::Table(1, 2, true))),
+#endif
CBHide(_("_Hide"), 1),
CBLock(_("L_ock"), 1),
BSet (_("_Set"), 1),
LabelInteractivity(_("_Interactivity"), 1),
- attrTable(),
+ attrTable(Gtk::manage(new SPAttributeTable())),
desktop(NULL),
deskTrack(),
selectChangedConn(),
subselChangedConn()
{
//initialize labels for the table at the bottom of the dialog
- int_labels.push_back("onclick");
- int_labels.push_back("onmouseover");
- int_labels.push_back("onmouseout");
- int_labels.push_back("onmousedown");
- int_labels.push_back("onmouseup");
- int_labels.push_back("onmousemove");
- int_labels.push_back("onfocusin");
- int_labels.push_back("onfocusout");
- int_labels.push_back("onfocusout");
- int_labels.push_back("onload");
+ int_attrs.push_back("onclick");
+ int_attrs.push_back("onmouseover");
+ int_attrs.push_back("onmouseout");
+ int_attrs.push_back("onmousedown");
+ int_attrs.push_back("onmouseup");
+ int_attrs.push_back("onmousemove");
+ int_attrs.push_back("onfocusin");
+ int_attrs.push_back("onfocusout");
+ int_attrs.push_back("onload");
+
+ int_labels.push_back("onclick:");
+ int_labels.push_back("onmouseover:");
+ int_labels.push_back("onmouseout:");
+ int_labels.push_back("onmousedown:");
+ int_labels.push_back("onmouseup:");
+ int_labels.push_back("onmousemove:");
+ int_labels.push_back("onfocusin:");
+ int_labels.push_back("onfocusout:");
+ int_labels.push_back("onload:");
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectProperties::setTargetDesktop) );
deskTrack.connect(GTK_WIDGET(gobj()));
+
+#if WITH_GTKMM_3_0
+ CheckTable->set_row_homogeneous();
+ CheckTable->set_column_homogeneous(true);
+#endif
MakeWidget();
}
@@ -99,23 +124,44 @@ void ObjectProperties::MakeWidget(void)
Gtk::Box *contents = _getContents();
contents->set_spacing(0);
- TopTable.set_border_width(4);
- TopTable.set_row_spacings(4);
- TopTable.set_col_spacings(4);
- contents->pack_start (TopTable, true, true, 0);
+ TopTable->set_border_width(4);
+
+#if WITH_GTKMM_3_0
+ TopTable->set_row_spacing(4);
+ TopTable->set_column_spacing(0);
+#else
+ TopTable->set_row_spacings(4);
+ TopTable->set_col_spacings(0);
+#endif
+
+ contents->pack_start (*TopTable, false, false, 0);
/* Create the label for the object id */
+ LabelID.set_label (LabelID.get_label() + " ");
LabelID.set_alignment (1, 0.5);
- TopTable.attach (LabelID, 0, 1, 0, 1,
- Gtk::SHRINK | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ LabelID.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(LabelID, 0, 0, 1, 1);
+#else
+ TopTable->attach(LabelID, 0, 1, 0, 1,
+ Gtk::SHRINK | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
/* Create the entry box for the object id */
EntryID.set_tooltip_text (_("The id= attribute (only letters, digits, and the characters .-_: allowed)"));
EntryID.set_max_length (64);
- TopTable.attach (EntryID, 1, 2, 0, 1,
- Gtk::EXPAND | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ EntryID.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(EntryID, 1, 0, 1, 1);
+#else
+ TopTable->attach(EntryID, 1, 2, 0, 1,
+ Gtk::EXPAND | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
+
LabelID.set_mnemonic_widget (EntryID);
// pressing enter in the id field is the same as clicking Set:
@@ -124,43 +170,72 @@ void ObjectProperties::MakeWidget(void)
EntryID.grab_focus();
/* Create the label for the object label */
+ LabelLabel.set_label (LabelLabel.get_label() + " ");
LabelLabel.set_alignment (1, 0.5);
- TopTable.attach (LabelLabel, 0, 1, 1, 2,
- Gtk::SHRINK | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ LabelLabel.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(LabelLabel, 0, 1, 1, 1);
+#else
+ TopTable->attach(LabelLabel, 0, 1, 1, 2,
+ Gtk::SHRINK | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
/* Create the entry box for the object label */
EntryLabel.set_tooltip_text (_("A freeform label for the object"));
EntryLabel.set_max_length (256);
- TopTable.attach (EntryLabel, 1, 2, 1, 2,
- Gtk::EXPAND | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ EntryLabel.set_hexpand();
+ EntryLabel.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(EntryLabel, 1, 1, 1, 1);
+#else
+ TopTable->attach(EntryLabel, 1, 2, 1, 2,
+ Gtk::EXPAND | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
+
LabelLabel.set_mnemonic_widget (EntryLabel);
// pressing enter in the label field is the same as clicking Set:
EntryLabel.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed));
/* Create the label for the object title */
+ LabelTitle.set_label (LabelTitle.get_label() + " ");
LabelTitle.set_alignment (1, 0.5);
- TopTable.attach (LabelTitle, 0, 1, 2, 3,
- Gtk::SHRINK | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ LabelTitle.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(LabelTitle, 0, 2, 1, 1);
+#else
+ TopTable->attach(LabelTitle, 0, 1, 2, 3,
+ Gtk::SHRINK | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
/* Create the entry box for the object title */
EntryTitle.set_sensitive (FALSE);
EntryTitle.set_max_length (256);
- TopTable.attach (EntryTitle, 1, 3, 2, 3,
- Gtk::EXPAND | Gtk::FILL,
- Gtk::AttachOptions(), 0, 0 );
+
+#if WITH_GTKMM_3_0
+ EntryTitle.set_hexpand();
+ EntryTitle.set_valign(Gtk::ALIGN_CENTER);
+ TopTable->attach(EntryTitle, 1, 2, 1, 1);
+#else
+ TopTable->attach(EntryTitle, 1, 2, 2, 3,
+ Gtk::EXPAND | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
+
LabelTitle.set_mnemonic_widget (EntryTitle);
+ // pressing enter in the label field is the same as clicking Set:
+ EntryTitle.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed));
/* Create the frame for the object description */
FrameDescription.set_label_widget (LabelDescription);
- FrameDescription.set_padding (4,0,0,0);
-
- TopTable.attach (FrameDescription, 0, 3, 3, 4,
- Gtk::EXPAND | Gtk::FILL,
- Gtk::EXPAND | Gtk::FILL, 0, 0 );
+ FrameDescription.set_padding (0,0,0,0);
+ contents->pack_start (FrameDescription, true, true, 0);
/* Create the text view box for the object description */
FrameTextDescription.set_border_width(4);
@@ -175,27 +250,52 @@ void ObjectProperties::MakeWidget(void)
/* Check boxes */
contents->pack_start (HBoxCheck, FALSE, FALSE, 0);
- CheckTable.set_border_width(0);
- HBoxCheck.pack_start (CheckTable, TRUE, TRUE, 10);
+ CheckTable->set_border_width(4);
+ HBoxCheck.pack_start(*CheckTable, true, true, 0);
/* Hide */
CBHide.set_tooltip_text (_("Check to make the object invisible"));
- CheckTable.attach (CBHide, 0, 1, 0, 1,
+
+#if WITH_GTKMM_3_0
+ CBHide.set_hexpand();
+ CBHide.set_valign(Gtk::ALIGN_CENTER);
+ CheckTable->attach(CBHide, 0, 0, 1, 1);
+#else
+ CheckTable->attach(CBHide, 0, 1, 0, 1,
Gtk::EXPAND | Gtk::FILL,
Gtk::AttachOptions(), 0, 0 );
+#endif
+
CBHide.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::hidden_toggled));
/* Lock */
// TRANSLATORS: "Lock" is a verb here
CBLock.set_tooltip_text (_("Check to make the object insensitive (not selectable by mouse)"));
- CheckTable.attach (CBLock, 1, 2, 0, 1,
+
+#if WITH_GTKMM_3_0
+ CBLock.set_hexpand();
+ CBLock.set_valign(Gtk::ALIGN_CENTER);
+ CheckTable->attach(CBLock, 1, 0, 1, 1);
+#else
+ CheckTable->attach(CBLock, 1, 2, 0, 1,
Gtk::EXPAND | Gtk::FILL,
Gtk::AttachOptions(), 0, 0 );
+#endif
+
CBLock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::sensitivity_toggled));
/* Button for setting the object's id, label, title and description. */
- HBoxCheck.pack_start (BSet, TRUE, TRUE, 10);
+#if WITH_GTKMM_3_0
+ BSet.set_hexpand();
+ BSet.set_valign(Gtk::ALIGN_CENTER);
+ CheckTable->attach(BSet, 2, 0, 1, 1);
+#else
+ CheckTable->attach(BSet, 2, 3, 0, 1,
+ Gtk::EXPAND | Gtk::FILL,
+ Gtk::AttachOptions(), 0, 0 );
+#endif
+
BSet.signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::label_changed));
/* Create the frame for interactivity options */
@@ -224,7 +324,7 @@ void ObjectProperties::widget_setup(void)
CurrentItem = NULL;
//no selection anymore or multiple objects selected, means that we need
//to close the connections to the previously selected object
- attrTable.clear();
+ attrTable->clear();
return;
} else {
contents->set_sensitive (true);
@@ -288,13 +388,13 @@ void ObjectProperties::widget_setup(void)
if (CurrentItem == NULL)
{
- attrTable.set_object(obj, int_labels, int_labels, (GtkWidget*)EInteractivity.gobj());
+ attrTable->set_object(obj, int_labels, int_attrs, (GtkWidget*)EInteractivity.gobj());
}
else
{
- attrTable.change_object(obj);
+ attrTable->change_object(obj);
}
- attrTable.show_all();
+ attrTable->show_all();
}
CurrentItem = item;
blocked = false;
@@ -332,7 +432,6 @@ void ObjectProperties::label_changed(void)
/* Retrieve the label widget for the object's label */
Glib::ustring label = EntryLabel.get_text();
- g_assert(!label.empty());
/* Give feedback on success of setting the drawing object's label
* using the widget's label text
diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h
index 0bf622ce4..624a18246 100644
--- a/src/ui/dialog/object-properties.h
+++ b/src/ui/dialog/object-properties.h
@@ -29,19 +29,33 @@
#ifndef SEEN_DIALOGS_ITEM_PROPERTIES_H
#define SEEN_DIALOGS_ITEM_PROPERTIES_H
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include "ui/widget/panel.h"
#include "ui/widget/frame.h"
+
+#include <gtkmm/checkbutton.h>
#include <gtkmm/entry.h>
#include <gtkmm/expander.h>
#include <gtkmm/frame.h>
#include <gtkmm/textview.h>
#include "ui/dialog/desktop-tracker.h"
-#include "widgets/sp-attribute-widget.h"
+class SPAttributeTable;
class SPDesktop;
class SPItem;
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
+
namespace Inkscape {
namespace UI {
namespace Dialog {
@@ -67,9 +81,15 @@ public:
private:
bool blocked;
SPItem *CurrentItem; //to store the current item, for not wasting resources
+ std::vector<Glib::ustring> int_attrs;
std::vector<Glib::ustring> int_labels;
- Gtk::Table TopTable; //the table with the object properties
+#if WITH_GTKMM_3_0
+ Gtk::Grid *TopTable; //the table with the object properties
+#else
+ Gtk::Table *TopTable; //the table with the object properties
+#endif
+
Gtk::Label LabelID; //the label for the object ID
Gtk::Entry EntryID; //the entry for the object ID
Gtk::Label LabelLabel; //the label for the object label
@@ -83,14 +103,20 @@ private:
Gtk::TextView TextViewDescription; //the text view object showing the object description
Gtk::HBox HBoxCheck; // the HBox for the check boxes
- Gtk::Table CheckTable; //the table for the check boxes
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *CheckTable; //the table for the check boxes
+#else
+ Gtk::Table *CheckTable; //the table for the check boxes
+#endif
+
Gtk::CheckButton CBHide; //the check button hide
Gtk::CheckButton CBLock; //the check button lock
Gtk::Button BSet; //the button set
Gtk::Label LabelInteractivity; //the label for interactivity
Gtk::Expander EInteractivity; //the label for interactivity
- SPAttributeTable attrTable; //the widget for showing the on... names at the bottom
+ SPAttributeTable *attrTable; //the widget for showing the on... names at the bottom
SPDesktop *desktop;
DesktopTracker deskTrack;
diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp
index bb06e3e79..c597bc849 100644
--- a/src/ui/dialog/ocaldialogs.cpp
+++ b/src/ui/dialog/ocaldialogs.cpp
@@ -33,10 +33,16 @@
#include <gtkmm/notebook.h>
#include <gtkmm/spinner.h>
#include <gtkmm/stock.h>
-#include <glibmm/i18n.h>
#include <gdkmm/general.h>
#include <libxml/tree.h>
+#include <glibmm/convert.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/i18n.h>
+#include <glibmm/main.h>
+#include <glibmm/markup.h>
+#include <glibmm/miscutils.h>
+
namespace Inkscape
{
namespace UI
@@ -139,7 +145,7 @@ bool
ExportDialog::show()
{
set_modal (TRUE); //Window
- sp_transientize((GtkWidget *)gobj()); //Make transient
+ sp_transientize(GTK_WIDGET(gobj())); //Make transient
gint b = run(); //Dialog
hide();
@@ -244,7 +250,7 @@ bool
ExportPasswordDialog::show()
{
set_modal (TRUE); //Window
- sp_transientize((GtkWidget *)gobj()); //Make transient
+ sp_transientize(GTK_WIDGET(gobj())); //Make transient
gint b = run(); //Dialog
hide();
@@ -324,7 +330,11 @@ bool LoadingBox::_on_expose_event(GdkEventExpose* /*event*/)
}
#endif
-bool LoadingBox::_on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
+bool LoadingBox::_on_draw(const Cairo::RefPtr<Cairo::Context> &
+#if WITH_GTKMM_3_0
+cr
+#endif
+)
{
// Draw shadow
int x = get_allocation().get_x();
@@ -561,6 +571,7 @@ void StatusWidget::end_process()
clear();
}
+#if !GTK_CHECK_VERSION(3,6,0)
SearchEntry::SearchEntry() : Gtk::Entry()
{
signal_changed().connect(sigc::mem_fun(*this, &SearchEntry::_on_changed));
@@ -589,6 +600,8 @@ void SearchEntry::_on_changed()
set_icon_from_stock(Gtk::Stock::CLEAR, Gtk::ENTRY_ICON_SECONDARY);
}
}
+#endif
+
BaseBox::BaseBox() : Gtk::EventBox()
{
@@ -957,44 +970,40 @@ void SearchResultList::populate_from_xml(xmlNode * a_node)
for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next) {
// Get items information
- if (strcmp((const char*)cur_node->name, "rss")) // Avoid the root
+ if (strcmp(reinterpret_cast<const char*>(cur_node->name), "rss")) // Avoid the root
if (cur_node->type == XML_ELEMENT_NODE &&
- (cur_node->parent->name && !strcmp((const char*)cur_node->parent->name, "item")))
+ (cur_node->parent->name && !strcmp(reinterpret_cast<const char*>(cur_node->parent->name), "item")))
{
- if (!strcmp((const char*)cur_node->name, "title"))
+ if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "title"))
{
-#if WITH_GTKMM_2_24
row_num = append("");
-#else
- row_num = append_text("");
-#endif
xmlChar *xml_title = xmlNodeGetContent(cur_node);
- char* title = (char*) xml_title;
+ char* title = reinterpret_cast<char*>(xml_title);
set_text(row_num, RESULTS_COLUMN_TITLE, title);
xmlFree(title);
}
- else if (!strcmp((const char*)cur_node->name, "pubDate"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "pubDate"))
{
xmlChar *xml_date = xmlNodeGetContent(cur_node);
- char* date = (char*) xml_date;
+ char* date = reinterpret_cast<char*>(xml_date);
set_text(row_num, RESULTS_COLUMN_DATE, date);
xmlFree(xml_date);
}
- else if (!strcmp((const char*)cur_node->name, "creator"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "creator"))
{
xmlChar *xml_creator = xmlNodeGetContent(cur_node);
- char* creator = (char*) xml_creator;
+ char* creator = reinterpret_cast<char*>(xml_creator);
set_text(row_num, RESULTS_COLUMN_CREATOR, creator);
xmlFree(xml_creator);
}
- else if (!strcmp((const char*)cur_node->name, "description"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "description"))
{
xmlChar *xml_description = xmlNodeGetContent(cur_node);
//char* final_description;
- char* stripped_description = g_strstrip((char*) xml_description);
+ char* stripped_description = g_strstrip(reinterpret_cast<char*>(xml_description));
if (!strcmp(stripped_description, "")) {
stripped_description = _("No description");
@@ -1006,30 +1015,30 @@ void SearchResultList::populate_from_xml(xmlNode * a_node)
set_text(row_num, RESULTS_COLUMN_DESCRIPTION, stripped_description);
xmlFree(xml_description);
}
- else if (!strcmp((const char*)cur_node->name, "enclosure"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "enclosure"))
{
- xmlChar *xml_url = xmlGetProp(cur_node, (xmlChar*) "url");
- char* url = (char*) xml_url;
+ xmlChar *xml_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar*>(g_strdup("url")));
+ char* url = reinterpret_cast<char*>(xml_url);
char* filename = g_path_get_basename(url);
set_text(row_num, RESULTS_COLUMN_URL, url);
set_text(row_num, RESULTS_COLUMN_FILENAME, filename);
xmlFree(xml_url);
}
- else if (!strcmp((const char*)cur_node->name, "thumbnail"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "thumbnail"))
{
- xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, (xmlChar*) "url");
- char* thumbnail_url = (char*) xml_thumbnail_url;
+ xmlChar *xml_thumbnail_url = xmlGetProp(cur_node, reinterpret_cast<xmlChar*>(g_strdup("url")));
+ char* thumbnail_url = reinterpret_cast<char*>(xml_thumbnail_url);
char* thumbnail_filename = g_path_get_basename(thumbnail_url);
set_text(row_num, RESULTS_COLUMN_THUMBNAIL_URL, thumbnail_url);
set_text(row_num, RESULTS_COLUMN_THUMBNAIL_FILENAME, thumbnail_filename);
xmlFree(xml_thumbnail_url);
}
- else if (!strcmp((const char*)cur_node->name, "guid"))
+ else if (!strcmp(reinterpret_cast<const char*>(cur_node->name), "guid"))
{
xmlChar *xml_guid = xmlNodeGetContent(cur_node);
- char* guid_url = (char*) xml_guid;
+ char* guid_url = reinterpret_cast<char*>(xml_guid);
char* guid = g_path_get_basename(guid_url);
set_text(row_num, RESULTS_COLUMN_GUID, guid);
@@ -1116,8 +1125,14 @@ void ImportDialog::on_xml_file_read(const Glib::RefPtr<Gio::AsyncResult>& result
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
- doc = xmlReadMemory(data, (int) length, xml_uri.c_str(), NULL,
- XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR);
+ int parse_options = XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR; // do not use XML_PARSE_NOENT ! see bug lp:1025185
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool allowNetAccess = prefs->getBool("/options/externalresources/xml/allow_net_access", false);
+ if (!allowNetAccess) {
+ parse_options |= XML_PARSE_NONET;
+ }
+
+ doc = xmlReadMemory(data, (int) length, xml_uri.c_str(), NULL, parse_options);
if (doc == NULL) {
// If nothing is returned, no results could be found
@@ -1194,15 +1209,33 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, FileDialogType file_types
// Creation
Gtk::VBox *vbox = new Gtk::VBox(false, 0);
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *hbuttonbox_bottom = new Gtk::ButtonBox();
+#else
Gtk::HButtonBox *hbuttonbox_bottom = new Gtk::HButtonBox();
+#endif
+
Gtk::HBox *hbox_bottom = new Gtk::HBox(false, 12);
BaseBox *basebox_logo = new BaseBox();
BaseBox *basebox_no_search_results = new BaseBox();
label_not_found = new Gtk::Label();
label_description = new Gtk::Label();
+
+#if GTK_CHECK_VERSION(3,6,0)
+ entry_search = new Gtk::SearchEntry();
+#else
entry_search = new SearchEntry();
+#endif
+
button_search = new Gtk::Button(_("Search"));
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox* hbuttonbox_search = new Gtk::ButtonBox();
+#else
Gtk::HButtonBox* hbuttonbox_search = new Gtk::HButtonBox();
+#endif
+
Gtk::ScrolledWindow* scrolledwindow_preview = new Gtk::ScrolledWindow();
preview_files = new PreviewWidget();
/// Add the buttons in the bottom of the dialog
diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h
index 0dc61abb3..8cb247766 100644
--- a/src/ui/dialog/ocaldialogs.h
+++ b/src/ui/dialog/ocaldialogs.h
@@ -13,14 +13,19 @@
#ifndef __OCAL_DIALOG_H__
#define __OCAL_DIALOG_H__
-#include <cairomm/refptr.h>
-
//Gtk includes
#include <gtkmm/box.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/listviewtext.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/window.h>
+
+#include <cairomm/refptr.h>
+
+#if GTK_CHECK_VERSION(3,6,0)
+# include <gtkmm/searchentry.h>
+#endif
+
#include <giomm/file.h>
//Inkscape includes
@@ -64,7 +69,7 @@ public:
FileDialogBase(const Glib::ustring &title, Gtk::Window& /*parent*/) : Gtk::Window(Gtk::WINDOW_TOPLEVEL)
{
set_title(title);
- sp_transientize((GtkWidget*) gobj());
+ sp_transientize(GTK_WIDGET(gobj()));
// Allow shrinking of window so labels wrap correctly
set_resizable(true);
@@ -328,6 +333,7 @@ public:
Gtk::Label* label;
};
+#if !GTK_CHECK_VERSION(3,6,0)
/**
* A Gtk::Entry with search & clear icons
*/
@@ -340,6 +346,7 @@ private:
void _on_icon_pressed(Gtk::EntryIconPosition icon_position, const GdkEventButton* event);
void _on_changed();
};
+#endif
/**
* A box which paints an overlay of the OCAL logo
@@ -449,7 +456,13 @@ protected:
private:
Glib::ustring filename_image;
Glib::ustring filename_thumbnail;
+
+#if GTK_CHECK_VERSION(3,6,0)
+ Gtk::SearchEntry *entry_search;
+#else
SearchEntry *entry_search;
+#endif
+
LogoArea *drawingarea_logo;
SearchResultList *list_results;
PreviewWidget *preview_files;
diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp
index e940a3f55..2ab8cf121 100644
--- a/src/ui/dialog/print.cpp
+++ b/src/ui/dialog/print.cpp
@@ -138,7 +138,7 @@ static void draw_page(
#endif
bool ret = ctx->setSurfaceTarget (surface, true, &ctm);
if (ret) {
- ret = renderer.setupDocument (ctx, junk->_doc, TRUE, NULL);
+ ret = renderer.setupDocument (ctx, junk->_doc, TRUE, 0., NULL);
if (ret) {
renderer.renderItem(ctx, junk->_base);
ret = ctx->finish();
diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp
index 0da28061e..9cc18c02c 100644
--- a/src/ui/dialog/spellcheck.cpp
+++ b/src/ui/dialog/spellcheck.cpp
@@ -109,10 +109,6 @@ SpellCheck::SpellCheck (void) :
tree_view.append_column(_("Suggestions:"), tree_columns.suggestions);
{
-// Backward compatibility fix: The GtkComboBoxText API was introduced with
-// GTK+ 2.24. This check should eventually be dropped when we bump our
-// GTK dependency.
-#if GTK_CHECK_VERSION(2, 24, 0)
dictionary_combo = gtk_combo_box_text_new();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dictionary_combo), _lang.c_str());
if (_lang2 != "") {
@@ -121,16 +117,6 @@ SpellCheck::SpellCheck (void) :
if (_lang3 != "") {
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dictionary_combo), _lang3.c_str());
}
-#else
- dictionary_combo = gtk_combo_box_new_text();
- gtk_combo_box_append_text (GTK_COMBO_BOX (dictionary_combo), _lang.c_str());
- if (_lang2 != "") {
- gtk_combo_box_append_text (GTK_COMBO_BOX (dictionary_combo), _lang2.c_str());
- }
- if (_lang3 != "") {
- gtk_combo_box_append_text (GTK_COMBO_BOX (dictionary_combo), _lang3.c_str());
- }
-#endif
gtk_combo_box_set_active (GTK_COMBO_BOX (dictionary_combo), 0);
gtk_widget_show_all (dictionary_combo);
}
@@ -219,8 +205,8 @@ void SpellCheck::setTargetDesktop(SPDesktop *desktop)
void SpellCheck::clearRects()
{
for (GSList *it = _rects; it; it = it->next) {
- sp_canvas_item_hide((SPCanvasItem*) it->data);
- sp_canvas_item_destroy((SPCanvasItem*) it->data);
+ sp_canvas_item_hide(SP_CANVAS_ITEM(it->data));
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(it->data));
}
g_slist_free(_rects);
_rects = NULL;
@@ -330,8 +316,8 @@ SpellCheck::nextText()
_text = getText(_root);
if (_text) {
- _modified_connection = ((SPObject*) _text)->connectModified(sigc::mem_fun(*this, &SpellCheck::onObjModified));
- _release_connection = ((SPObject*) _text)->connectRelease(sigc::mem_fun(*this, &SpellCheck::onObjReleased));
+ _modified_connection = (SP_OBJECT(_text))->connectModified(sigc::mem_fun(*this, &SpellCheck::onObjModified));
+ _release_connection = (SP_OBJECT(_text))->connectRelease(sigc::mem_fun(*this, &SpellCheck::onObjReleased));
_layout = te_get_layout (_text);
_begin_w = _layout->begin();
diff --git a/src/ui/dialog/spellcheck.h b/src/ui/dialog/spellcheck.h
index 8eb240097..ab75809f3 100644
--- a/src/ui/dialog/spellcheck.h
+++ b/src/ui/dialog/spellcheck.h
@@ -240,10 +240,20 @@ private:
GtkWidget * dictionary_combo;
Gtk::HBox dictionary_hbox;
+#if WITH_GTKMM_3_0
+ Gtk::Separator action_sep;
+#else
Gtk::HSeparator action_sep;
+#endif
+
Gtk::Button stop_button;
Gtk::Button start_button;
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox actionbutton_hbox;
+#else
Gtk::HButtonBox actionbutton_hbox;
+#endif
SPDesktop * desktop;
DesktopTracker deskTrack;
diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp
index 16bb8222a..ab5f4c0e9 100644
--- a/src/ui/dialog/svg-fonts-dialog.cpp
+++ b/src/ui/dialog/svg-fonts-dialog.cpp
@@ -15,15 +15,13 @@
# include <config.h>
#endif
-#ifdef ENABLE_SVG_FONTS
-
#include "svg-fonts-dialog.h"
#include "document-private.h"
#include "document-undo.h"
#include <gtkmm/notebook.h>
#include <gtkmm/imagemenuitem.h>
+#include <gtkmm/scale.h>
#include <gtkmm/stock.h>
-#include <glibmm/i18n.h>
#include <message-stack.h>
#include "selection.h"
#include <string.h>
@@ -39,6 +37,9 @@
#include "sp-font.h"
#include "sp-glyph-kerning.h"
+#include <glibmm/i18n.h>
+#include <glibmm/stringutils.h>
+
SvgFontDrawingArea::SvgFontDrawingArea():
_x(0),
_y(0),
@@ -163,23 +164,14 @@ GlyphComboBox::GlyphComboBox(){
void GlyphComboBox::update(SPFont* spfont){
if (!spfont) return
-//TODO: figure out why do we need to append_text("") before clearing items properly...
+//TODO: figure out why do we need to append("") before clearing items properly...
-#if WITH_GTKMM_2_24
this->append(""); //Gtk is refusing to clear the combobox when I comment out this line
this->remove_all();
-#else
- this->append_text(""); //Gtk is refusing to clear the combobox when I comment out this line
- this->clear_items();
-#endif
for(SPObject* node = spfont->children; node; node=node->next){
if (SP_IS_GLYPH(node)){
-#if WITH_GTKMM_2_24
this->append((static_cast<SPGlyph*>(node))->unicode);
-#else
- this->append_text((static_cast<SPGlyph*>(node))->unicode);
-#endif
}
}
}
@@ -200,7 +192,7 @@ void SvgFontsDialog::on_kerning_value_changed(){
//slider values increase from right to left so that they match the kerning pair preview
//XML Tree being directly used here while it shouldn't be.
- this->kerning_pair->getRepr()->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider.get_value()).c_str());
+ this->kerning_pair->getRepr()->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider->get_value()).c_str());
DocumentUndo::maybeDone(document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS, _("Adjust kerning value"));
//populate_kerning_pairs_box();
@@ -278,7 +270,7 @@ void SvgFontsDialog::update_fonts()
_model->clear();
for(const GSList *l = fonts; l; l = l->next) {
Gtk::TreeModel::Row row = *_model->append();
- SPFont* f = (SPFont*)l->data;
+ SPFont* f = SP_FONT(l->data);
row[_columns.spfont] = f;
row[_columns.svgfont] = new SvgFont(f);
const gchar* lbl = f->label();
@@ -308,7 +300,7 @@ void SvgFontsDialog::on_kerning_pair_selection_changed(){
this->kerning_pair = kern;
//slider values increase from right to left so that they match the kerning pair preview
- kerning_slider.set_value(get_selected_spfont()->horiz_adv_x - kern->k);
+ kerning_slider->set_value(get_selected_spfont()->horiz_adv_x - kern->k);
}
void SvgFontsDialog::update_global_settings_tab(){
@@ -318,7 +310,7 @@ void SvgFontsDialog::update_global_settings_tab(){
SPObject* obj;
for (obj=font->children; obj; obj=obj->next){
if (SP_IS_FONTFACE(obj)){
- _familyname_entry->set_text(((SPFontFace*) obj)->font_family);
+ _familyname_entry->set_text((SP_FONTFACE(obj))->font_family);
}
}
}
@@ -337,9 +329,9 @@ void SvgFontsDialog::on_font_selection_changed(){
double set_width = spfont->horiz_adv_x;
setwidth_spin.set_value(set_width);
- kerning_slider.set_range(0, set_width);
- kerning_slider.set_draw_value(false);
- kerning_slider.set_value(0);
+ kerning_slider->set_range(0, set_width);
+ kerning_slider->set_draw_value(false);
+ kerning_slider->set_value(0);
update_global_settings_tab();
populate_glyphs_box();
@@ -788,7 +780,7 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){
add_kernpair_button.set_label(_("Add pair"));
add_kernpair_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_kerning_pair));
_KerningPairsList.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_pair_selection_changed));
- kerning_slider.signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_value_changed));
+ kerning_slider->signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_value_changed));
kerning_vbox.pack_start(*kerning_selector, false,false);
@@ -806,7 +798,7 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){
Gtk::HBox* kerning_amount_hbox = Gtk::manage(new Gtk::HBox());
kerning_vbox.pack_start(*kerning_amount_hbox, false,false);
kerning_amount_hbox->add(*Gtk::manage(new Gtk::Label(_("Kerning value:"))));
- kerning_amount_hbox->add(kerning_slider);
+ kerning_amount_hbox->add(*kerning_slider);
kerning_preview.set_size(300 + 20, 150 + 20);
_font_da.set_size(150 + 20, 50 + 20);
@@ -893,6 +885,12 @@ void SvgFontsDialog::add_font(){
SvgFontsDialog::SvgFontsDialog()
: UI::Widget::Panel("", "/dialogs/svgfonts", SP_VERB_DIALOG_SVG_FONTS), _add(Gtk::Stock::NEW)
{
+#if WITH_GTKMM_3_0
+ kerning_slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+#else
+ kerning_slider = Gtk::manage(new Gtk::HScale);
+#endif
+
_add.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_font));
Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox());
@@ -947,8 +945,6 @@ SvgFontsDialog::~SvgFontsDialog(){}
} // namespace UI
} // namespace Inkscape
-#endif //#ifdef ENABLE_SVG_FONTS
-
/*
Local Variables:
mode:c++
diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h
index 910f79d4c..01f70654a 100644
--- a/src/ui/dialog/svg-fonts-dialog.h
+++ b/src/ui/dialog/svg-fonts-dialog.h
@@ -20,15 +20,22 @@
#include <gtkmm/drawingarea.h>
#include <gtkmm/entry.h>
#include <gtkmm/liststore.h>
-#include <gtkmm/scale.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/treeview.h>
#include "attributes.h"
#include "xml/helper-observer.h"
-class SPGlyph;
-class SPGlyphKerning;
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
+}
+
+struct SPGlyph;
+struct SPGlyphKerning;
class SvgFont;
class SvgFontDrawingArea : Gtk::DrawingArea{
@@ -210,7 +217,12 @@ private:
GlyphComboBox first_glyph, second_glyph;
SPGlyphKerning* kerning_pair;
Inkscape::UI::Widget::SpinButton setwidth_spin;
- Gtk::HScale kerning_slider;
+
+#if WITH_GTKMM_3_0
+ Gtk::Scale* kerning_slider;
+#else
+ Gtk::HScale* kerning_slider;
+#endif
class EntryWidget : public Gtk::HBox
{
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
index 68bafe549..90cb1cdc9 100644
--- a/src/ui/dialog/swatches.cpp
+++ b/src/ui/dialog/swatches.cpp
@@ -23,6 +23,7 @@
#include <glibmm/i18n.h>
#include <glibmm/main.h>
+#include <glibmm/timer.h>
#include <gdkmm/pixbuf.h>
#include "color-item.h"
@@ -54,6 +55,8 @@
#include "dialog-manager.h"
#include "selection.h"
#include "verbs.h"
+#include "gradient-chemistry.h"
+#include "helper/action.h"
namespace Inkscape {
namespace UI {
@@ -62,10 +65,10 @@ namespace Dialogs {
#define VBLOCK 16
#define PREVIEW_PIXBUF_WIDTH 128
-void _loadPaletteFile( gchar const *filename );
+void _loadPaletteFile( gchar const *filename, gboolean user=FALSE );
-
-std::vector<SwatchPage*> possible;
+std::list<SwatchPage*> userSwatchPages;
+std::list<SwatchPage*> systemSwatchPages;
static std::map<SPDocument*, SwatchPage*> docPalettes;
static std::vector<DocTrack*> docTrackings;
static std::map<SwatchesPanel*, SPDocument*> docPerPanel;
@@ -142,8 +145,21 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr )
}
if (!shown) {
- GtkWidget *dialog = sp_gradient_vector_editor_new( gr );
- gtk_widget_show( dialog );
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) {
+ // Legacy gradient dialog
+ GtkWidget *dialog = sp_gradient_vector_editor_new( gr );
+ gtk_widget_show( dialog );
+ } else {
+ // 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);
+ if ( action ) {
+ sp_action_perform( action, NULL );
+ }
+ }
+ }
}
}
}
@@ -197,20 +213,7 @@ void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*us
if ( bounceTarget ) {
SwatchesPanel* swp = bouncePanel;
SPDesktop* desktop = swp ? swp->getDesktop() : 0;
- SPDocument *doc = desktop ? desktop->doc() : 0;
- if (doc) {
- std::string targetName(bounceTarget->def.descr);
- const GSList *gradients = doc->getResourceList("gradient");
- for (const GSList *item = gradients; item; item = item->next) {
- SPGradient* grad = SP_GRADIENT(item->data);
- if ( targetName == grad->getId() ) {
- grad->setSwatch(false);
- DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT,
- _("Delete"));
- break;
- }
- }
- }
+ sp_gradient_unset_swatch(desktop, bounceTarget->def.descr);
}
}
@@ -237,6 +240,9 @@ static void removeit( GtkWidget *widget, gpointer data )
gtk_container_remove( GTK_CONTAINER(data), widget );
}
+/* extern'ed from colot-item.cpp */
+gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data );
+
gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data )
{
gboolean handled = FALSE;
@@ -371,13 +377,13 @@ static char* trim( char* str ) {
return ret;
}
-void skipWhitespace( char*& str ) {
+static void skipWhitespace( char*& str ) {
while ( *str == ' ' || *str == '\t' ) {
str++;
}
}
-bool parseNum( char*& str, int& val ) {
+static bool parseNum( char*& str, int& val ) {
val = 0;
while ( '0' <= *str && *str <= '9' ) {
val = val * 10 + (*str - '0');
@@ -388,7 +394,7 @@ bool parseNum( char*& str, int& val ) {
}
-void _loadPaletteFile( gchar const *filename )
+void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ )
{
char block[1024];
FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" );
@@ -490,7 +496,10 @@ void _loadPaletteFile( gchar const *filename )
}
} while ( result && !hasErr );
if ( !hasErr ) {
- possible.push_back(onceMore);
+ if (user)
+ userSwatchPages.push_back(onceMore);
+ else
+ systemSwatchPages.push_back(onceMore);
#if ENABLE_MAGIC_COLORS
ColorItem::_wireMagicColors( onceMore );
#endif // ENABLE_MAGIC_COLORS
@@ -504,9 +513,16 @@ void _loadPaletteFile( gchar const *filename )
}
}
+static bool
+compare_swatch_names(SwatchPage const *a, SwatchPage const *b) {
+
+ return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0;
+}
+
static void loadEmUp()
{
static bool beenHere = false;
+ gboolean userPalete = true;
if ( !beenHere ) {
beenHere = true;
@@ -518,7 +534,6 @@ static void loadEmUp()
// Use this loop to iterate through a list of possible document locations.
while (!sources.empty()) {
gchar *dirname = sources.front();
-
if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS )
&& Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) {
GError *err = 0;
@@ -532,11 +547,13 @@ static void loadEmUp()
while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
gchar* lower = g_ascii_strdown( filename, -1 );
// if ( g_str_has_suffix(lower, ".gpl") ) {
+ if ( !g_str_has_suffix(lower, "~") ) {
gchar* full = g_build_filename(dirname, filename, NULL);
if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) {
- _loadPaletteFile(full);
+ _loadPaletteFile(full, userPalete);
}
g_free(full);
+ }
// }
g_free(lower);
}
@@ -547,15 +564,15 @@ static void loadEmUp()
// toss the dirname
g_free(dirname);
sources.pop_front();
+ userPalete = false;
}
}
-}
-
-
-
-
+ // Sort the list of swatches by name, grouped by user/system
+ userSwatchPages.sort(compare_swatch_names);
+ systemSwatchPages.sort(compare_swatch_names);
+}
@@ -589,7 +606,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
}
loadEmUp();
- if ( !possible.empty() ) {
+ if ( !systemSwatchPages.empty() ) {
SwatchPage* first = 0;
int index = 0;
Glib::ustring targetName;
@@ -600,8 +617,9 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
if (targetName == "Auto") {
first = docPalettes[0];
} else {
- index++;
- for ( std::vector<SwatchPage*>::iterator iter = possible.begin(); iter != possible.end(); ++iter ) {
+ //index++;
+ std::vector<SwatchPage*> pages = _getSwatchSets();
+ for ( std::vector<SwatchPage*>::iterator iter = pages.begin(); iter != pages.end(); ++iter ) {
if ( (*iter)->_name == targetName ) {
first = *iter;
break;
@@ -632,6 +650,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
hotItem = single;
}
_regItem( single, 3, i );
+
i++;
}
}
@@ -1024,6 +1043,7 @@ void SwatchesPanel::handleDefsModified(SPDocument *document)
}
}
+
std::vector<SwatchPage*> SwatchesPanel::_getSwatchSets() const
{
std::vector<SwatchPage*> tmp;
@@ -1031,7 +1051,8 @@ std::vector<SwatchPage*> SwatchesPanel::_getSwatchSets() const
tmp.push_back(docPalettes[_currentDocument]);
}
- tmp.insert(tmp.end(), possible.begin(), possible.end());
+ tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end());
+ tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end());
return tmp;
}
@@ -1158,9 +1179,6 @@ void SwatchesPanel::_rebuild()
_holder->thawUpdates();
}
-
-
-
} //namespace Dialogs
} //namespace UI
} //namespace Inkscape
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
new file mode 100644
index 000000000..dfc92774c
--- /dev/null
+++ b/src/ui/dialog/symbols.cpp
@@ -0,0 +1,762 @@
+/**
+ * @file
+ * Symbols dialog.
+ */
+/* Authors:
+ * Copyright (C) 2012 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <iostream>
+#include <algorithm>
+#include <locale>
+#include <functional>
+#include <sstream>
+
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/label.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/iconview.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treemodelcolumn.h>
+#include <gtkmm/clipboard.h>
+
+#include <glibmm/i18n.h>
+#include "path-prefix.h"
+#include "io/sys.h"
+
+#include "ui/cache/svg_preview_cache.h"
+#include "ui/clipboard.h"
+
+#include "symbols.h"
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "document.h"
+#include "inkscape.h"
+#include "sp-root.h"
+#include "sp-use.h"
+#include "sp-symbol.h"
+
+#ifdef WITH_LIBVISIO
+#include <libvisio/libvisio.h>
+#include <libwpd-stream/libwpd-stream.h>
+#endif
+
+#include "verbs.h"
+#include "xml/repr.h"
+
+namespace Inkscape {
+namespace UI {
+
+static Cache::SvgPreview svg_preview_cache;
+
+namespace Dialog {
+
+ // See: http://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeModelColumnRecord.html
+class SymbolColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+
+ Gtk::TreeModelColumn<Glib::ustring> symbol_id;
+ Gtk::TreeModelColumn<Glib::ustring> symbol_title;
+ Gtk::TreeModelColumn< Glib::RefPtr<Gdk::Pixbuf> > symbol_image;
+
+ SymbolColumns() {
+ add(symbol_id);
+ add(symbol_title);
+ add(symbol_image);
+ }
+};
+
+SymbolColumns* SymbolsDialog::getColumns()
+{
+ SymbolColumns* columns = new SymbolColumns();
+ return columns;
+}
+
+/**
+ * Constructor
+ */
+SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
+ UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SYMBOLS),
+ store(Gtk::ListStore::create(*getColumns())),
+ iconView(0),
+ previewScale(0),
+ previewSize(0),
+ currentDesktop(0),
+ deskTrack(),
+ currentDocument(0),
+ previewDocument(0),
+ instanceConns()
+{
+
+ /******************** Table *************************/
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = new Gtk::Grid();
+#else
+ Gtk::Table *table = new Gtk::Table(2, 4, false);
+#endif
+
+ // panel is a cloked Gtk::VBox
+ _getContents()->pack_start(*Gtk::manage(table), Gtk::PACK_EXPAND_WIDGET);
+ guint row = 0;
+
+ /******************** Symbol Sets *************************/
+ Gtk::Label* labelSet = new Gtk::Label(_("Symbol set: "));
+
+#if WITH_GTKMM_3_0
+ table->attach(*Gtk::manage(labelSet),0,row,1,1);
+#else
+ table->attach(*Gtk::manage(labelSet),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
+#endif
+
+ symbolSet = new Gtk::ComboBoxText(); // Fill in later
+ symbolSet->append(_("Current Document"));
+ symbolSet->set_active_text(_("Current Document"));
+
+#if WITH_GTKMM_3_0
+ symbolSet->set_hexpand();
+ table->attach(*Gtk::manage(symbolSet),1,row,1,1);
+#else
+ table->attach(*Gtk::manage(symbolSet),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
+#endif
+
+ sigc::connection connSet =
+ symbolSet->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
+ instanceConns.push_back(connSet);
+
+ ++row;
+
+ /********************* Icon View **************************/
+ SymbolColumns* columns = getColumns();
+
+ iconView = new Gtk::IconView(static_cast<Glib::RefPtr<Gtk::TreeModel> >(store));
+ //iconView->set_text_column( columns->symbol_id );
+ iconView->set_tooltip_column( 1 );
+ iconView->set_pixbuf_column( columns->symbol_image );
+
+ std::vector< Gtk::TargetEntry > targets;
+ targets.push_back(Gtk::TargetEntry( "application/x-inkscape-paste"));
+
+ iconView->enable_model_drag_source (targets, Gdk::BUTTON1_MASK, Gdk::ACTION_COPY);
+ iconView->signal_drag_data_get().connect(sigc::mem_fun(*this, &SymbolsDialog::iconDragDataGet));
+
+ sigc::connection connIconChanged;
+ connIconChanged =
+ iconView->signal_selection_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::iconChanged));
+ instanceConns.push_back(connIconChanged);
+
+ Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow();
+ scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
+ scroller->add(*Gtk::manage(iconView));
+
+#if WITH_GTKMM_3_0
+ scroller->set_hexpand();
+ scroller->set_vexpand();
+ table->attach(*Gtk::manage(scroller),0,row,2,1);
+#else
+ table->attach(*Gtk::manage(scroller),0,2,row,row+1,Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL);
+#endif
+
+ ++row;
+
+ /******************** Preview Scale ***********************/
+ Gtk::Label* labelScale = new Gtk::Label(_("Preview scale: "));
+
+#if WITH_GTKMM_3_0
+ table->attach(*Gtk::manage(labelScale),0,row,1,1);
+#else
+ table->attach(*Gtk::manage(labelScale),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
+#endif
+
+ previewScale = new Gtk::ComboBoxText();
+ const gchar *scales[] =
+ {_("Fit"), _("Fit to width"), _("Fit to height"), "0.1", "0.2", "0.5", "1.0", "2.0", "5.0", NULL};
+ for( int i = 0; scales[i]; ++i ) {
+ previewScale->append(scales[i]);
+ }
+ previewScale->set_active_text(scales[0]);
+
+#if WITH_GTKMM_3_0
+ previewScale->set_hexpand();
+ table->attach(*Gtk::manage(previewScale),1,row,1,1);
+#else
+ table->attach(*Gtk::manage(previewScale),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
+#endif
+
+ sigc::connection connScale =
+ previewScale->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
+ instanceConns.push_back(connScale);
+
+ ++row;
+
+ /******************** Preview Size ************************/
+ Gtk::Label* labelSize = new Gtk::Label(_("Preview size: "));
+
+#if WITH_GTKMM_3_0
+ table->attach(*Gtk::manage(labelSize),0,row,1,1);
+#else
+ table->attach(*Gtk::manage(labelSize),0,1,row,row+1,Gtk::SHRINK,Gtk::SHRINK);
+#endif
+
+ previewSize = new Gtk::ComboBoxText();
+ const gchar *sizes[] = {"16", "24", "32", "48", "64", NULL};
+ for( int i = 0; sizes[i]; ++i ) {
+ previewSize->append(sizes[i]);
+ }
+ previewSize->set_active_text(sizes[2]);
+
+#if WITH_GTKMM_3_0
+ previewSize->set_hexpand();
+ table->attach(*Gtk::manage(previewSize),1,row,1,1);
+#else
+ table->attach(*Gtk::manage(previewSize),1,2,row,row+1,Gtk::FILL|Gtk::EXPAND,Gtk::SHRINK);
+#endif
+
+ sigc::connection connSize =
+ previewSize->signal_changed().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
+ instanceConns.push_back(connSize);
+
+ ++row;
+
+ /**********************************************************/
+ currentDesktop = inkscape_active_desktop();
+ currentDocument = sp_desktop_document(currentDesktop);
+
+ previewDocument = symbols_preview_doc(); /* Template to render symbols in */
+ previewDocument->ensureUpToDate(); /* Necessary? */
+
+ key = SPItem::display_key_new(1);
+ renderDrawing.setRoot(previewDocument->getRoot()->invoke_show(renderDrawing, key, SP_ITEM_SHOW_DISPLAY ));
+
+ get_symbols();
+ draw_symbols( currentDocument ); /* Defaults to current document */
+
+ desktopChangeConn =
+ deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &SymbolsDialog::setTargetDesktop) );
+ instanceConns.push_back( desktopChangeConn );
+ deskTrack.connect(GTK_WIDGET(gobj()));
+}
+
+SymbolsDialog::~SymbolsDialog()
+{
+ for (std::vector<sigc::connection>::iterator it = instanceConns.begin(); it != instanceConns.end(); ++it) {
+ it->disconnect();
+ }
+ instanceConns.clear();
+ deskTrack.disconnect();
+}
+
+SymbolsDialog& SymbolsDialog::getInstance()
+{
+ return *new SymbolsDialog();
+}
+
+void SymbolsDialog::rebuild() {
+
+ store->clear();
+ Glib::ustring symbolSetString = symbolSet->get_active_text();
+
+ SPDocument* symbolDocument = symbolSets[symbolSetString];
+ if( !symbolDocument ) {
+ // Symbol must be from Current Document (this method of
+ // checking should be language independent).
+ symbolDocument = currentDocument;
+ }
+ draw_symbols( symbolDocument );
+}
+
+void SymbolsDialog::iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& /*context*/, Gtk::SelectionData& data, guint /*info*/, guint /*time*/)
+{
+#if WITH_GTKMM_3_0
+ std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items();
+#else
+ Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items();
+#endif
+
+ if( iconArray.empty() ) {
+ //std::cout << " iconArray empty: huh? " << std::endl;
+ } else {
+ Gtk::TreeModel::Path const & path = *iconArray.begin();
+ Gtk::ListStore::iterator row = store->get_iter(path);
+ Glib::ustring symbol_id = (*row)[getColumns()->symbol_id];
+
+ GdkAtom dataAtom = gdk_atom_intern( "application/x-inkscape-paste", FALSE );
+ gtk_selection_data_set( data.gobj(), dataAtom, 9, (guchar*)symbol_id.c_str(), symbol_id.length() );
+ }
+
+}
+
+void SymbolsDialog::iconChanged() {
+#if WITH_GTKMM_3_0
+ std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items();
+#else
+ Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items();
+#endif
+
+ if( iconArray.empty() ) {
+ //std::cout << " iconArray empty: huh? " << std::endl;
+ } else {
+ Gtk::TreeModel::Path const & path = *iconArray.begin();
+ Gtk::ListStore::iterator row = store->get_iter(path);
+ Glib::ustring symbol_id = (*row)[getColumns()->symbol_id];
+
+ /* OK, we know symbol name... now we need to copy it to clipboard, bon chance! */
+ Glib::ustring symbolSetString = symbolSet->get_active_text();
+
+ SPDocument* symbolDocument = symbolSets[symbolSetString];
+ if( !symbolDocument ) {
+ // Symbol must be from Current Document (this method of
+ // checking should be language independent).
+ symbolDocument = currentDocument;
+ }
+
+ SPObject* symbol = symbolDocument->getObjectById(symbol_id);
+ if( symbol ) {
+
+ // Find style for use in <use>
+ // First look for default style stored in <symbol>
+ gchar const* style = symbol->getAttribute("inkscape:symbol-style");
+ if( !style ) {
+ // If no default style in <symbol>, look in documents.
+ if( symbolDocument == currentDocument ) {
+ style = style_from_use( symbol_id.c_str(), currentDocument );
+ } else {
+ style = symbolDocument->getReprRoot()->attribute("style");
+ }
+ }
+
+ ClipboardManager *cm = ClipboardManager::get();
+ cm->copySymbol(symbol->getRepr(), style);
+ }
+ }
+}
+
+#ifdef WITH_LIBVISIO
+// Read Visio stencil files
+SPDocument* read_vss( gchar* fullname, gchar* filename ) {
+
+ WPXFileStream input(fullname);
+
+ if (!libvisio::VisioDocument::isSupported(&input)) {
+ return NULL;
+ }
+
+ libvisio::VSDStringVector output;
+ if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) {
+ return NULL;
+ }
+
+ if (output.empty()) {
+ return NULL;
+ }
+
+ Glib::ustring tmpSVGOutput;
+ tmpSVGOutput += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
+ tmpSVGOutput += "<svg\n";
+ tmpSVGOutput += " xmlns=\"http://www.w3.org/2000/svg\"\n";
+ tmpSVGOutput += " xmlns:svg=\"http://www.w3.org/2000/svg\"\n";
+ tmpSVGOutput += " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n";
+ tmpSVGOutput += " version=\"1.1\"\n";
+ tmpSVGOutput += " style=\"fill:none;stroke:#000000;stroke-width:2\">\n";
+ tmpSVGOutput += " <title>";
+ tmpSVGOutput += filename;
+ tmpSVGOutput += "</title>\n";
+ tmpSVGOutput += " <defs>\n";
+
+ // Create a string we can use for the symbol id (libvisio doesn't give us a name)
+ std::string sanitized( filename );
+ sanitized.erase( sanitized.find_last_of(".vss")-3 );
+ sanitized.erase( std::remove_if( sanitized.begin(), sanitized.end(), ispunct ), sanitized.end() );
+ std::replace( sanitized.begin(), sanitized.end(), ' ', '_' );
+ // std::cout << filename << " |" << sanitized << "|" << std::endl;
+
+ // Each "symbol" is in it's own SVG file, we wrap with <symbol> and merge into one file.
+ for (unsigned i=0; i<output.size(); ++i) {
+
+ std::stringstream ss;
+ ss << i;
+
+ tmpSVGOutput += " <symbol id=\"";
+ tmpSVGOutput += sanitized;
+ tmpSVGOutput += "_";
+ tmpSVGOutput += ss.str();
+ tmpSVGOutput += "\">\n";
+
+ std::istringstream iss( output[i].cstr() );
+ std::string line;
+ while( std::getline( iss, line ) ) {
+ // std::cout << line << std::endl;
+ if( line.find( "svg:svg" ) == std::string::npos ) {
+ tmpSVGOutput += line;
+ tmpSVGOutput += "\n";
+ }
+ }
+
+ tmpSVGOutput += " </symbol>\n";
+ }
+
+ tmpSVGOutput += " </defs>\n";
+ tmpSVGOutput += "</svg>\n";
+
+ return SPDocument::createNewDocFromMem( tmpSVGOutput.c_str(), strlen( tmpSVGOutput.c_str()), 0 );
+
+}
+#endif
+
+/* Hunts preference directories for symbol files */
+void SymbolsDialog::get_symbols() {
+
+ std::list<Glib::ustring> directories;
+
+ if( Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_EXISTS ) &&
+ Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) {
+ directories.push_back( INKSCAPE_SYMBOLSDIR );
+ }
+ if( Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_EXISTS ) &&
+ Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) {
+ directories.push_back( profile_path("symbols") );
+ }
+
+ std::list<Glib::ustring>::iterator it;
+ for( it = directories.begin(); it != directories.end(); ++it ) {
+
+ GError *err = 0;
+ GDir *dir = g_dir_open( (*it).c_str(), 0, &err );
+ if( dir ) {
+
+ gchar *filename = 0;
+ while( (filename = (gchar *)g_dir_read_name( dir ) ) != NULL) {
+
+ gchar *fullname = g_build_filename((*it).c_str(), filename, NULL);
+
+ if ( !Inkscape::IO::file_test( fullname, G_FILE_TEST_IS_DIR ) ) {
+
+ Glib::ustring fn( filename );
+ Glib::ustring tag = fn.substr( fn.find_last_of(".") + 1 );
+
+ SPDocument* symbol_doc = NULL;
+
+#ifdef WITH_LIBVISIO
+ if( tag.compare( "vss" ) == 0 ) {
+
+ symbol_doc = read_vss( fullname, filename );
+ if( symbol_doc ) {
+ symbolSets[Glib::ustring(filename)]= symbol_doc;
+ symbolSet->append(filename);
+ }
+ }
+#endif
+ // Try to read all remaining files as SVG
+ if( !symbol_doc ) {
+
+ symbol_doc = SPDocument::createNewDoc( fullname, FALSE );
+ if( symbol_doc ) {
+ symbolSets[Glib::ustring(filename)]= symbol_doc;
+ symbolSet->append(filename);
+ }
+ }
+
+ }
+ g_free( fullname );
+ }
+ g_dir_close( dir );
+ }
+ }
+}
+
+GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l)
+{
+ if (!r) {
+ return l;
+ }
+
+ // Stop multiple counting of same symbol
+ if( SP_IS_USE(r) ) {
+ return l;
+ }
+
+ if( SP_IS_SYMBOL(r) ) {
+ l = g_slist_prepend (l, r);
+ }
+
+ for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
+ l = symbols_in_doc_recursive( child, l );
+ }
+
+ return l;
+}
+
+GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) {
+
+ GSList *l = NULL;
+ l = symbols_in_doc_recursive (symbolDocument->getRoot(), l );
+ return l;
+}
+
+GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l)
+{
+
+ if( SP_IS_USE(r) ) {
+ l = g_slist_prepend (l, r);
+ }
+
+ for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
+ l = use_in_doc_recursive( child, l );
+ }
+
+ return l;
+}
+
+GSList* SymbolsDialog::use_in_doc( SPDocument* useDocument ) {
+
+ GSList *l = NULL;
+ l = use_in_doc_recursive (useDocument->getRoot(), l );
+ return l;
+}
+
+// Returns style from first <use> element found that references id.
+// This is a last ditch effort to find a style.
+gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* document) {
+
+ gchar const* style = 0;
+ GSList* l = use_in_doc( document );
+ for( ; l != NULL; l = l->next ) {
+ SPObject* use = SP_OBJECT(l->data);
+ if( SP_IS_USE( use ) ) {
+ gchar const *href = use->getRepr()->attribute("xlink:href");
+ if( href ) {
+ Glib::ustring href2(href);
+ Glib::ustring id2(id);
+ id2 = "#" + id2;
+ if( !href2.compare(id2) ) {
+ style = use->getRepr()->attribute("style");
+ break;
+ }
+ }
+ }
+ }
+ return style;
+}
+
+void SymbolsDialog::draw_symbols( SPDocument* symbolDocument ) {
+
+
+ SymbolColumns* columns = getColumns();
+
+ GSList* l = symbols_in_doc( symbolDocument );
+ for( ; l != NULL; l = l->next ) {
+
+ SPObject* symbol = SP_OBJECT(l->data);
+ if (!SP_IS_SYMBOL(symbol)) {
+ //std::cout << " Error: not symbol" << std::endl;
+ continue;
+ }
+
+ gchar const *id = symbol->getRepr()->attribute("id");
+ gchar const *title = symbol->title(); // From title element
+ if( !title ) {
+ title = id;
+ }
+
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf = create_symbol_image(id, symbolDocument, &renderDrawing, key );
+ if( pixbuf ) {
+
+ Gtk::ListStore::iterator row = store->append();
+ (*row)[columns->symbol_id] = Glib::ustring( id );
+ (*row)[columns->symbol_title] = Glib::ustring( title );
+ (*row)[columns->symbol_image] = pixbuf;
+ }
+ }
+
+ delete columns;
+}
+
+/*
+ * Returns image of symbol.
+ *
+ * Symbols normally are not visible. They must be referenced by a
+ * <use> element. A temporary document is created with a dummy
+ * <symbol> element and a <use> element that references the symbol
+ * element. Each real symbol is swapped in for the dummy symbol and
+ * the temporary document is rendered.
+ */
+Glib::RefPtr<Gdk::Pixbuf>
+SymbolsDialog::create_symbol_image(gchar const *symbol_id,
+ SPDocument *source,
+ Inkscape::Drawing* drawing,
+ unsigned /*visionkey*/)
+{
+ // Retrieve the symbol named 'symbol_id' from the source SVG document
+ SPObject const* symbol = source->getObjectById(symbol_id);
+ if (symbol == NULL) {
+ //std::cout << " Failed to find symbol: " << symbol_id << std::endl;
+ //return 0;
+ }
+
+ // Create a copy repr of the symbol with id="the_symbol"
+ Inkscape::XML::Document *xml_doc = previewDocument->getReprDoc();
+ Inkscape::XML::Node *repr = symbol->getRepr()->duplicate(xml_doc);
+ repr->setAttribute("id", "the_symbol");
+
+ // Replace old "the_symbol" in previewDocument by new.
+ Inkscape::XML::Node *root = previewDocument->getReprRoot();
+ SPObject *symbol_old = previewDocument->getObjectById("the_symbol");
+ if (symbol_old) {
+ symbol_old->deleteObject(false);
+ }
+
+ // First look for default style stored in <symbol>
+ gchar const* style = repr->attribute("inkscape:symbol-style");
+ if( !style ) {
+ // If no default style in <symbol>, look in documents.
+ if( source == currentDocument ) {
+ style = style_from_use( symbol_id, source );
+ } else {
+ style = source->getReprRoot()->attribute("style");
+ }
+ }
+ // Last ditch effort to provide some default styling
+ if( !style ) style = "fill:#bbbbbb;stroke:#808080";
+
+ // This is for display in Symbols dialog only
+ if( style ) {
+ repr->setAttribute( "style", style );
+ }
+
+ // BUG: Symbols don't work if defined outside of <defs>. Causes Inkscape
+ // crash when trying to read in such a file.
+ root->appendChild(repr);
+ //defsrepr->appendChild(repr);
+ Inkscape::GC::release(repr);
+
+ // Uncomment this to get the previewDocument documents saved (useful for debugging)
+ // FILE *fp = fopen (g_strconcat(symbol_id, ".svg", NULL), "w");
+ // sp_repr_save_stream(previewDocument->getReprDoc(), fp);
+ // fclose (fp);
+
+ // Make sure previewDocument is up-to-date.
+ previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ previewDocument->ensureUpToDate();
+
+ // Make sure we have symbol in previewDocument
+ SPObject *object_temp = previewDocument->getObjectById( "the_use" );
+ previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+ previewDocument->ensureUpToDate();
+
+ // if( object_temp == NULL || !SP_IS_ITEM(object_temp) ) {
+ // //std::cout << " previewDocument broken?" << std::endl;
+ // //return 0;
+ // }
+
+ SPItem *item = SP_ITEM(object_temp);
+
+ Glib::ustring previewSizeString = previewSize->get_active_text();
+ unsigned psize = atol( previewSizeString.c_str() );
+
+ Glib::ustring previewScaleString = previewScale->get_active_text();
+ int previewScaleRow = previewScale->get_active_row_number();
+
+ /* Update to renderable state */
+ Glib::ustring key = svg_preview_cache.cache_key(previewDocument->getURI(), symbol_id, psize);
+ //std::cout << " Key: " << key << std::endl;
+ // FIX ME
+ //Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key));
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::RefPtr<Gdk::Pixbuf>(0);
+
+ // Find object's bbox in document.
+ // Note symbols can have own viewport... ignore for now.
+ //Geom::OptRect dbox = item->geometricBounds();
+ Geom::OptRect dbox = item->documentVisualBounds();
+ if (!dbox) {
+ //std::cout << " No dbox" << std::endl;
+ return pixbuf;
+ }
+
+ if (!pixbuf) {
+
+ /* Scale symbols to fit */
+ double scale = 1.0;
+ double width = dbox->width();
+ double height = dbox->height();
+ if( width == 0.0 ) {
+ width = 1.0;
+ }
+ if( height == 0.0 ) {
+ height = 1.0;
+ }
+
+ switch (previewScaleRow) {
+ case 0:
+ /* Fit */
+ scale = psize/std::max(width,height);
+ break;
+ case 1:
+ /* Fit width */
+ scale = psize/width;
+ break;
+ case 2:
+ /* Fit height */
+ scale = psize/height;
+ break;
+ default:
+ scale = atof( previewScaleString.c_str() );
+ }
+
+ pixbuf = Glib::wrap(render_pixbuf(*drawing, scale, *dbox, psize));
+ svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj());
+ }
+
+ return pixbuf;
+}
+
+/*
+ * Return empty doc to render symbols in.
+ * Symbols are by default not rendered so a <use> element is
+ * provided.
+ */
+SPDocument* SymbolsDialog::symbols_preview_doc()
+{
+ // BUG: <symbol> must be inside <defs>
+ gchar const *buffer =
+"<svg xmlns=\"http://www.w3.org/2000/svg\""
+" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""
+" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""
+" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
+" <defs id=\"defs\">"
+" <symbol id=\"the_symbol\"/>"
+" </defs>"
+" <use id=\"the_use\" xlink:href=\"#the_symbol\"/>"
+"</svg>";
+
+ return SPDocument::createNewDocFromMem( buffer, strlen(buffer), FALSE );
+}
+
+void SymbolsDialog::setTargetDesktop(SPDesktop *desktop)
+{
+ if (this->currentDesktop != desktop) {
+ this->currentDesktop = desktop;
+ if( !symbolSets[symbolSet->get_active_text()] ) {
+ // Symbol set is from Current document, update
+ rebuild();
+ }
+ }
+}
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h
new file mode 100644
index 000000000..5486ff546
--- /dev/null
+++ b/src/ui/dialog/symbols.h
@@ -0,0 +1,115 @@
+/** @file
+ * @brief Symbols dialog
+ */
+/* Authors:
+ * Tavmjong Bah
+ *
+ * Copyright (C) 2012 Tavmjong Bah
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_UI_DIALOG_SYMBOLS_H
+#define INKSCAPE_UI_DIALOG_SYMBOLS_H
+
+#include "ui/widget/panel.h"
+#include "ui/widget/button.h"
+
+#include "ui/dialog/desktop-tracker.h"
+
+#include "display/drawing.h"
+
+#include <glib.h>
+#include <gtkmm/treemodel.h>
+
+#include <vector>
+
+class SPObject;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+class SymbolColumns; // For Gtk::ListStore
+
+/**
+ * A dialog that displays selectable symbols.
+ */
+class SymbolsDialog : public UI::Widget::Panel {
+
+public:
+ SymbolsDialog( gchar const* prefsPath = "/dialogs/symbols" );
+ virtual ~SymbolsDialog();
+
+ static SymbolsDialog& getInstance();
+
+protected:
+
+
+private:
+ SymbolsDialog(SymbolsDialog const &); // no copy
+ SymbolsDialog &operator=(SymbolsDialog const &); // no assign
+
+ static SymbolColumns *getColumns();
+
+ void rebuild();
+ void iconChanged();
+ void iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time);
+
+ void get_symbols();
+ void draw_symbols( SPDocument* symbol_document );
+ SPDocument* symbols_preview_doc();
+
+ GSList* symbols_in_doc_recursive(SPObject *r, GSList *l);
+ GSList* symbols_in_doc( SPDocument* document );
+ GSList* use_in_doc_recursive(SPObject *r, GSList *l);
+ GSList* use_in_doc( SPDocument* document );
+ gchar const* style_from_use( gchar const* id, SPDocument* document);
+
+ Glib::RefPtr<Gdk::Pixbuf>
+ create_symbol_image(gchar const *symbol_name,
+ SPDocument *source, Inkscape::Drawing* drawing,
+ unsigned /*visionkey*/);
+
+ /* Keep track of all symbol template documents */
+ std::map<Glib::ustring, SPDocument*> symbolSets;
+
+
+ Glib::RefPtr<Gtk::ListStore> store;
+ Gtk::ComboBoxText* symbolSet;
+ Gtk::IconView* iconView;
+ Gtk::ComboBoxText* previewScale;
+ Gtk::ComboBoxText* previewSize;
+
+ void setTargetDesktop(SPDesktop *desktop);
+ SPDesktop* currentDesktop;
+ DesktopTracker deskTrack;
+ SPDocument* currentDocument;
+ SPDocument* previewDocument; /* Document to render single symbol */
+
+ /* For rendering the template drawing */
+ unsigned key;
+ Inkscape::Drawing renderDrawing;
+
+ std::vector<sigc::connection> instanceConns;
+ sigc::connection desktopChangeConn;
+
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+#endif // INKSCAPE_UI_DIALOG_SYMBOLS_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/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 5a983fc1a..c87e94fc6 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -8,8 +8,9 @@
* Johan Engelen <goejendaagh@zonnet.nl>
* Abhishek Sharma
* John Smith
+ * Tavmjong Bah
*
- * Copyright (C) 1999-2012 Authors
+ * Copyright (C) 1999-2013 Authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -32,6 +33,7 @@ extern "C" {
#include <gtkmm/stock.h>
#include <libnrtype/font-instance.h>
#include <libnrtype/font-style-to-pos.h>
+#include <libnrtype/font-lister.h>
#include <xml/repr.h>
#include "macros.h"
@@ -55,6 +57,8 @@ extern "C" {
#include "widgets/icon.h"
#include "widgets/font-selector.h"
#include <glibmm/i18n.h>
+#include <glibmm/markup.h>
+#include "unit-constants.h"
namespace Inkscape {
@@ -94,41 +98,33 @@ TextEdit::TextEdit()
styleButton(&align_center, _("Align center"), GTK_STOCK_JUSTIFY_CENTER, &align_left);
styleButton(&align_right, _("Align right"), GTK_STOCK_JUSTIFY_RIGHT, &align_left);
styleButton(&align_justify, _("Justify (only flowed text)"), GTK_STOCK_JUSTIFY_FILL, &align_left);
+
+#if WITH_GTKMM_3_0
+ align_sep.set_orientation(Gtk::ORIENTATION_VERTICAL);
+#endif
+
layout_hbox.pack_start(align_sep, false, false, 10);
/* Direction buttons */
styleButton(&text_horizontal, _("Horizontal text"), INKSCAPE_ICON("format-text-direction-horizontal"), NULL);
styleButton(&text_vertical, _("Vertical text"), INKSCAPE_ICON("format-text-direction-vertical"), &text_horizontal);
+
+#if WITH_GTKMM_3_0
+ text_sep.set_orientation(Gtk::ORIENTATION_VERTICAL);
+#endif
+
layout_hbox.pack_start(text_sep, false, false, 10);
/* Line Spacing */
GtkWidget *px = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("text_line_spacing") );
layout_hbox.pack_start(*Gtk::manage(Glib::wrap(px)), false, false);
-/*
-This would introduce dependency on gtk version 2.24 which is currently not available in
-Trisquel GNU/Linux 4.5.1 (released on May 25th, 2011)
-This conditional and its #else block can be deleted in the future.
-*/
-#if GTK_CHECK_VERSION(2, 24,0)
spacing_combo = gtk_combo_box_text_new_with_entry ();
-#else
- spacing_combo = gtk_combo_box_entry_new_text ();
-#endif
gtk_widget_set_size_request (spacing_combo, 90, -1);
const gchar *spacings[] = {"50%", "80%", "90%", "100%", "110%", "120%", "130%", "140%", "150%", "200%", "300%", NULL};
for (int i = 0; spacings[i]; i++) {
-/*
-This would introduce dependency on gtk version 2.24 which is currently not available in
-Trisquel GNU/Linux 4.5.1 (released on May 25th, 2011)
-This conditional and its #else block can be deleted in the future.
-*/
-#if GTK_CHECK_VERSION(2, 24,0)
gtk_combo_box_text_append_text((GtkComboBoxText *) spacing_combo, spacings[i]);
-#else
- gtk_combo_box_append_text((GtkComboBox *) spacing_combo, spacings[i]);
-#endif
}
gtk_widget_set_tooltip_text (px, _("Spacing between lines (percent of font size)"));
@@ -312,18 +308,20 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
// FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists
- // Get a font_instance using the font-specification attribute stored in SPStyle if available
- font_instance *font = font_factory::Default()->FaceFromStyle(query);
+ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
- if (font) {
+ // This is done for us by text-toolbar. No need to do it twice.
+ // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP ));
+ // fontlister->selection_update();
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- sp_font_selector_set_font (fsel, font, sp_style_get_css_font_size_units(query->font_size.computed, unit) );
- setPreviewText(font, phrase);
- font->Unref();
- font=NULL;
- }
+ Glib::ustring fontspec = fontlister->get_fontspec();
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
+ double size = sp_style_css_size_px_to_units(query->font_size.computed, unit);
+ sp_font_selector_set_fontspec(fsel, fontspec, size );
+
+ setPreviewText (fontspec, phrase);
if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) {
if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) {
@@ -358,31 +356,31 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
blocked = false;
}
-void TextEdit::setPreviewText (font_instance *font, Glib::ustring phrase)
+
+void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
{
- if (!font) {
+ if (font_spec.empty()) {
return;
}
- char *desc = pango_font_description_to_string(font->descr);
- double unit_size = sp_font_selector_get_size(fsel);
+ Glib::ustring phrase_escaped = Glib::Markup::escape_text( phrase );
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- double px_size = unit_size * (unit_size / sp_style_get_css_font_size_units(unit_size, unit));
-
- gchar *const phrase_escaped = g_markup_escape_text(phrase.c_str(), -1);
+ double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * PT_PER_PX;
- gchar *markup = g_strdup_printf("<span font=\"%s\" size=\"%d\">%s</span>",
- desc, (int) (px_size * PANGO_SCALE), phrase_escaped);
+ // Pango font size is in 1024ths of a point
+ // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE );
+ std::ostringstream size_st;
+ size_st << pt_size * PANGO_SCALE;
- preview_label.set_markup(markup);
+ Glib::ustring markup = "<span font=\"" + font_spec +
+ "\" size=\"" + size_st.str() + "\">" + phrase_escaped + "</span>";
- g_free(desc);
- g_free(phrase_escaped);
- g_free(markup);
+ preview_label.set_markup(markup.c_str());
}
+
SPItem *TextEdit::getSelectedTextItem (void)
{
if (!SP_ACTIVE_DESKTOP)
@@ -426,54 +424,38 @@ void TextEdit::onSelectionChange()
void TextEdit::updateObjectText ( SPItem *text )
{
GtkTextIter start, end;
- gchar *str;
// write text
if (gtk_text_buffer_get_modified (text_buffer)) {
gtk_text_buffer_get_bounds (text_buffer, &start, &end);
- str = gtk_text_buffer_get_text (text_buffer, &start, &end, TRUE);
+ gchar *str = gtk_text_buffer_get_text (text_buffer, &start, &end, TRUE);
sp_te_set_repr_text_multiline (text, str);
g_free (str);
gtk_text_buffer_set_modified (text_buffer, FALSE);
}
}
-SPCSSAttr *TextEdit::getTextStyle ()
+SPCSSAttr *TextEdit::fillTextStyle ()
{
SPCSSAttr *css = sp_repr_css_attr_new ();
- // font
- font_instance *font = sp_font_selector_get_font (fsel);
-
- if ( font ) {
- Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font);
- sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str());
-
- gchar c[256];
-
- font->Family(c, 256);
- sp_repr_css_set_property (css, "font-family", c);
-
- font->Attribute( "weight", c, 256);
- sp_repr_css_set_property (css, "font-weight", c);
-
- font->Attribute("style", c, 256);
- sp_repr_css_set_property (css, "font-style", c);
+ Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
- font->Attribute("stretch", c, 256);
- sp_repr_css_set_property (css, "font-stretch", c);
+ if( !fontspec.empty() ) {
- font->Attribute("variant", c, 256);
- sp_repr_css_set_property (css, "font-variant", c);
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->fill_css( css, fontspec );
+ // TODO, possibly move this to FontLister::set_css to be shared.
Inkscape::CSSOStringStream os;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit);
+ if (prefs->getBool("/options/font/textOutputPx", true)) {
+ os << sp_style_css_size_units_to_px(sp_font_selector_get_size (fsel), unit) << sp_style_get_css_unit_string(SP_CSS_UNIT_PX);
+ } else {
+ os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit);
+ }
sp_repr_css_set_property (css, "font-size", os.str().c_str());
-
- font->Unref();
- font=NULL;
}
// Layout
@@ -501,16 +483,7 @@ SPCSSAttr *TextEdit::getTextStyle ()
// Note that CSS 1.1 does not support line-height; we set it for consistency, but also set
// sodipodi:linespacing for backwards compatibility; in 1.2 we use line-height for flowtext
-/*
-This would introduce dependency on gtk version 2.24 which is currently not available in
-Trisquel GNU/Linux 4.5.1 (released on May 25th, 2011)
-This conditional and its #else block can be deleted in the future.
-*/
-#if GTK_CHECK_VERSION(2, 24,0)
const gchar *sstr = gtk_combo_box_text_get_active_text ((GtkComboBoxText *) spacing_combo);
-#else
- const gchar *sstr = gtk_entry_get_text ((GtkEntry *) (gtk_bin_get_child (GTK_BIN (spacing_combo))));
-#endif
sp_repr_css_set_property (css, "line-height", sstr);
return css;
@@ -518,7 +491,7 @@ This conditional and its #else block can be deleted in the future.
void TextEdit::onSetDefault()
{
- SPCSSAttr *css = getTextStyle ();
+ SPCSSAttr *css = fillTextStyle ();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
blocked = true;
@@ -538,7 +511,7 @@ void TextEdit::onApply()
unsigned items = 0;
const GSList *item_list = sp_desktop_selection(desktop)->itemList();
- SPCSSAttr *css = getTextStyle ();
+ SPCSSAttr *css = fillTextStyle ();
sp_desktop_set_style(desktop, css, true);
for (; item_list != NULL; item_list = item_list->next) {
@@ -569,6 +542,13 @@ void TextEdit::onApply()
}
}
+ // Update FontLister
+ Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
+ if( !fontspec.empty() ) {
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->set_fontspec( fontspec, false );
+ }
+
// complete the transaction
DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT,
_("Set text style"));
@@ -590,11 +570,11 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self)
GtkTextIter end;
gtk_text_buffer_get_bounds (text_buffer, &start, &end);
gchar *str = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE);
- font_instance *font = sp_font_selector_get_font(self->fsel);
+ Glib::ustring fontspec = sp_font_selector_get_fontspec(self->fsel);
- if (font) {
+ if( !fontspec.empty() ) {
const gchar *phrase = str && *str ? str : self->samplephrase.c_str();
- self->setPreviewText(font, phrase);
+ self->setPreviewText(fontspec, phrase);
} else {
self->preview_label.set_markup("");
}
@@ -607,7 +587,7 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self)
self->setasdefault_button.set_sensitive ( true);
}
-void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, TextEdit *self)
+void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextEdit *self)
{
GtkTextIter start, end;
gchar *str;
@@ -620,9 +600,9 @@ void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font,
gtk_text_buffer_get_bounds (self->text_buffer, &start, &end);
str = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE);
- if (font) {
+ if (fontspec) {
const gchar *phrase = str && *str ? str : self->samplephrase.c_str();
- self->setPreviewText(font, phrase);
+ self->setPreviewText(fontspec, phrase);
} else {
self->preview_label.set_markup("");
}
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index 9fd9baa30..f27fdfc87 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -7,8 +7,9 @@
* Johan Engelen <goejendaagh@zonnet.nl>
* John Smith
* Kris De Gussem <Kris.DeGussem@gmail.com>
+ * Tavmjong Bah
*
- * Copyright (C) 1999-2012 Authors
+ * Copyright (C) 1999-2013 Authors
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -29,7 +30,7 @@
#include "ui/dialog/desktop-tracker.h"
class SPItem;
-class SPFontSelector;
+struct SPFontSelector;
class font_instance;
class SPCSSAttr;
@@ -100,10 +101,10 @@ protected:
* onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label.
*
* @param fontsel pointer to SPFontSelector (currently not used).
- * @param font pointer to the font instance for the text to be previewed
+ * @param fontspec for the text to be previewed.
* @param self pointer to the current instance of the dialog.
*/
- static void onFontChange (SPFontSelector *fontsel, font_instance *font, TextEdit *self);
+ static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self);
/**
* Get the selected text off the main canvas.
@@ -118,15 +119,15 @@ protected:
unsigned getSelectedTextCount (void);
/**
- * Helper function to create markup from a font definition and display in the preview label.
+ * Helper function to create markup from a fontspec and display in the preview label.
*
- * @param font pointer to the font instance for the text to be previewed
+ * @param fontspec for the text to be previewed
* @param phrase text to be shown
*/
- void setPreviewText (font_instance *font, Glib::ustring phrase);
+ void setPreviewText (Glib::ustring font_spec, Glib::ustring phrase);
void updateObjectText ( SPItem *text );
- SPCSSAttr *getTextStyle ();
+ SPCSSAttr *fillTextStyle ();
/**
* Helper function to style radio buttons with icons, tooltips.
@@ -172,10 +173,22 @@ private:
Gtk::RadioButton align_center;
Gtk::RadioButton align_right;
Gtk::RadioButton align_justify;
+
+#if WITH_GTKMM_3_0
+ Gtk::Separator align_sep;
+#else
Gtk::VSeparator align_sep;
+#endif
+
Gtk::RadioButton text_vertical;
Gtk::RadioButton text_horizontal;
+
+#if WITH_GTKMM_3_0
+ Gtk::Separator text_sep;
+#else
Gtk::VSeparator text_sep;
+#endif
+
GtkWidget *spacing_combo;
Gtk::Label preview_label;
diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp
index 77dae056f..c35d3b554 100644
--- a/src/ui/dialog/tile.cpp
+++ b/src/ui/dialog/tile.cpp
@@ -14,14 +14,17 @@
*/
//#define DEBUG_GRID_ARRANGE 1
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "tile.h"
#include <gtk/gtk.h> //for GTK_RESPONSE* types
#include <glibmm/i18n.h>
#include <gtkmm/stock.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <2geom/transforms.h>
#include "verbs.h"
@@ -42,7 +45,7 @@
* 0 *elem1 == *elem2
* >0 *elem1 goes after *elem2
*/
-int sp_compare_x_position(SPItem *first, SPItem *second)
+static int sp_compare_x_position(SPItem *first, SPItem *second)
{
using Geom::X;
using Geom::Y;
@@ -84,7 +87,7 @@ int sp_compare_x_position(SPItem *first, SPItem *second)
/*
* Sort items by their y co-ordinates.
*/
-int
+static int
sp_compare_y_position(SPItem *first, SPItem *second)
{
Geom::OptRect a = first->documentVisualBounds();
@@ -124,7 +127,7 @@ void TileDialog::Grid_Arrange ()
{
int cnt,row_cnt,col_cnt,a,row,col;
- double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy;
+ double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y;
double total_col_width,total_row_height;
col_width = 0;
row_height = 0;
@@ -175,9 +178,6 @@ void TileDialog::Grid_Arrange ()
width = b->dimensions()[Geom::X];
height = b->dimensions()[Geom::Y];
- cx = b->midpoint()[Geom::X];
- cy = b->midpoint()[Geom::Y];
-
if (b->min()[Geom::X] < grid_left) {
grid_left = b->min()[Geom::X];
}
@@ -197,7 +197,7 @@ void TileDialog::Grid_Arrange ()
g_return_if_fail(selection);
const GSList *items2 = selection->itemList();
- GSList *rev = g_slist_copy((GSList *) items2);
+ GSList *rev = g_slist_copy(const_cast<GSList *>(items2));
GSList *sorted = NULL;
rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position);
sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position);
@@ -615,8 +615,13 @@ static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscap
*/
TileDialog::TileDialog()
: UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE),
- XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns"),
- YPadding(_("Y:"), _("Vertical spacing between rows."), XPadding, "", "object-rows")
+ XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns", &PaddingUnitMenu),
+ YPadding(_("Y:"), _("Vertical spacing between rows."), UNIT_TYPE_LINEAR, "", "object-rows", &PaddingUnitMenu),
+#if WITH_GTKMM_3_0
+ PaddingTable(Gtk::manage(new Gtk::Grid()))
+#else
+ PaddingTable(Gtk::manage(new Gtk::Table(2, 2, false)))
+#endif
{
// bool used by spin button callbacks to stop loops where they change each other.
updating = false;
@@ -669,7 +674,7 @@ TileDialog::TileDialog()
NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed));
NoOfRowsSpinner.set_tooltip_text(_("Number of rows"));
NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN);
- gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj());
+ gtk_size_group_add_widget(_col1, GTK_WIDGET(NoOfRowsBox.gobj()));
RowHeightButton.set_label(_("Equal _height"));
RowHeightButton.set_use_underline(true);
@@ -726,7 +731,7 @@ TileDialog::TileDialog()
XByYLabel.set_markup(" &#215; ");
XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN);
SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN);
- gtk_size_group_add_widget(_col2, (GtkWidget *) XByYLabelVBox.gobj());
+ gtk_size_group_add_widget(_col2, GTK_WIDGET(XByYLabelVBox.gobj()));
/*#### Number of columns ####*/
@@ -741,7 +746,7 @@ TileDialog::TileDialog()
NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed));
NoOfColsSpinner.set_tooltip_text(_("Number of columns"));
NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN);
- gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj());
+ gtk_size_group_add_widget(_col3, GTK_WIDGET(NoOfColsBox.gobj()));
ColumnWidthButton.set_label(_("Equal _width"));
ColumnWidthButton.set_use_underline(true);
@@ -817,6 +822,8 @@ TileDialog::TileDialog()
{
/*#### Padding ####*/
+ PaddingUnitMenu.setUnitType(UNIT_TYPE_LINEAR);
+ PaddingUnitMenu.setUnit("px");
YPadding.setDigits(5);
YPadding.setIncrements(0.2, 0);
@@ -833,8 +840,24 @@ TileDialog::TileDialog()
XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed));
}
- TileBox.pack_start(XPadding, false, false, MARGIN);
- TileBox.pack_start(YPadding, false, false, MARGIN);
+
+ PaddingTable->set_border_width(MARGIN);
+
+#if WITH_GTKMM_3_0
+ PaddingTable->set_row_spacing(MARGIN);
+ PaddingTable->set_column_spacing(MARGIN);
+ PaddingTable->attach(XPadding, 0, 0, 1, 1);
+ PaddingTable->attach(PaddingUnitMenu, 1, 0, 1, 1);
+ PaddingTable->attach(YPadding, 0, 1, 1, 1);
+#else
+ PaddingTable->set_row_spacings(MARGIN);
+ PaddingTable->set_col_spacings(MARGIN);
+ PaddingTable->attach(XPadding, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+ PaddingTable->attach(PaddingUnitMenu, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+ PaddingTable->attach(YPadding, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
+ TileBox.pack_start(*PaddingTable, false, false, MARGIN);
contents->pack_start(TileBox);
diff --git a/src/ui/dialog/tile.h b/src/ui/dialog/tile.h
index f9e9d9842..86dbd25a9 100644
--- a/src/ui/dialog/tile.h
+++ b/src/ui/dialog/tile.h
@@ -15,6 +15,10 @@
#ifndef SEEN_UI_DIALOG_TILE_H
#define SEEN_UI_DIALOG_TILE_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/notebook.h>
#include <gtkmm/checkbutton.h>
@@ -26,6 +30,12 @@
namespace Gtk {
class Button;
+
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
}
namespace Inkscape {
@@ -129,9 +139,16 @@ private:
Gtk::RadioButton HorizRightRadioButton;
double HorizAlign;
+ Inkscape::UI::Widget::UnitMenu PaddingUnitMenu;
Inkscape::UI::Widget::ScalarUnit XPadding;
Inkscape::UI::Widget::ScalarUnit YPadding;
+#if WITH_GTKMM_3_0
+ Gtk::Grid *PaddingTable;
+#else
+ Gtk::Table *PaddingTable;
+#endif
+
// BBox or manual spacing
Gtk::VBox SpacingVBox;
Gtk::RadioButtonGroup SpacingGroup;
diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp
index a6495c205..bd467555e 100644
--- a/src/ui/dialog/tracedialog.cpp
+++ b/src/ui/dialog/tracedialog.cpp
@@ -20,12 +20,15 @@
#include <gtkmm/frame.h>
#include "ui/widget/spinbutton.h"
#include "ui/widget/frame.h"
+#include <gtkmm/radiobutton.h>
#include <gtkmm/stock.h>
#include <gtk/gtk.h> //for GTK_RESPONSE* types
#include <glibmm/i18n.h>
#include "desktop.h"
+#include "desktop-tracker.h"
+#include "selection.h"
#include "trace/potrace/inkscape-potrace.h"
#include "inkscape.h"
@@ -83,6 +86,13 @@ class TraceDialogImpl : public TraceDialog
void abort();
void previewCallback();
+ void previewLiveCallback();
+ void onSettingsChange();
+ void onSelectionModified( guint flags );
+ void onSetDefaults();
+
+ void setDesktop(SPDesktop *desktop);
+ void setTargetDesktop(SPDesktop *desktop);
//############ General items
@@ -90,6 +100,7 @@ class TraceDialogImpl : public TraceDialog
Gtk::Button *mainOkButton;
Gtk::Button *mainCancelButton;
+ Gtk::Button *mainResetButton;
//######## Left pannel
@@ -194,11 +205,40 @@ class TraceDialogImpl : public TraceDialog
UI::Widget::Frame previewFrame;
Gtk::VBox previewVBox;
Gtk::Button previewButton;
+ Gtk::CheckButton previewLiveButton;
+ gboolean previewLive;
Gtk::Image previewImage;
+ SPDesktop *desktop;
+ DesktopTracker deskTrack;
+ sigc::connection desktopChangeConn;
+ sigc::connection selectChangedConn;
+ sigc::connection selectModifiedConn;
+
};
+void TraceDialogImpl::setDesktop(SPDesktop *desktop)
+{
+ Panel::setDesktop(desktop);
+ deskTrack.setBase(desktop);
+}
+void TraceDialogImpl::setTargetDesktop(SPDesktop *desktop)
+{
+ if (this->desktop != desktop) {
+ if (this->desktop) {
+ selectChangedConn.disconnect();
+ selectModifiedConn.disconnect();
+ }
+ this->desktop = desktop;
+ if (desktop && desktop->selection) {
+ selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange)));
+ selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &TraceDialogImpl::onSelectionModified)));
+
+ }
+ onSettingsChange();
+ }
+}
//#########################################################################
//## E V E N T S
@@ -294,8 +334,9 @@ void TraceDialogImpl::potraceProcess(bool do_i_trace)
{
int width = preview->get_width();
int height = preview->get_height();
- double scaleFX = 200.0 / (double)width;
- double scaleFY = 200.0 / (double)height;
+ const Gtk::Allocation& vboxAlloc = previewImage.get_allocation();
+ double scaleFX = vboxAlloc.get_width() / (double)width;
+ double scaleFY = vboxAlloc.get_height() / (double)height;
double scaleFactor = scaleFX > scaleFY ? scaleFY : scaleFX;
int newWidth = (int) (((double)width) * scaleFactor);
int newHeight = (int) (((double)height) * scaleFactor);
@@ -351,6 +392,58 @@ void TraceDialogImpl::abort()
//#########################################################################
/**
+ * Callback for when any setting changes
+ */
+void TraceDialogImpl::onSettingsChange()
+{
+ if (previewLive) {
+ previewCallback();
+ }
+}
+
+void TraceDialogImpl::onSelectionModified( guint flags )
+{
+ if (flags & ( SP_OBJECT_MODIFIED_FLAG |
+ SP_OBJECT_PARENT_MODIFIED_FLAG |
+ SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
+ onSettingsChange();
+ }
+}
+
+/**
+ * Callback for when users resets defaults
+ */
+void TraceDialogImpl::onSetDefaults()
+{
+
+ // temporarily disable live update
+ gboolean wasLive = previewLive;
+ previewLive = false;
+
+ modeBrightnessRadioButton.set_active(true);
+ modeBrightnessSpinner.set_value(0.45);
+ modeCannyHiSpinner.set_value(0.65);
+ modeMultiScanNrColorSpinner.set_value(8.0);
+ modeMultiScanNrColorSpinner.set_value(8.0);
+ optionsSpecklesSizeSpinner.set_value(2);
+ optionsCornersThresholdSpinner.set_value(1.0);
+ optionsOptimToleranceSpinner.set_value(0.2);
+
+ modeInvertButton.set_active(false);
+ modeMultiScanSmoothButton.set_active(true);
+ modeMultiScanStackButton.set_active(true);
+ modeMultiScanBackgroundButton.set_active(false);
+ optionsSpecklesButton.set_active(true);
+ optionsCornersButton.set_active(true);
+ optionsOptimButton.set_active(true);
+ sioxButton.set_active(false);
+
+ previewLive = wasLive;
+ onSettingsChange();
+
+}
+
+/**
* Callback from the Preview button. Can be called from elsewhere.
*/
void TraceDialogImpl::previewCallback()
@@ -359,24 +452,31 @@ void TraceDialogImpl::previewCallback()
}
/**
+ * Callback from the Preview Live button.
+ */
+void TraceDialogImpl::previewLiveCallback()
+{
+ previewLive = previewLiveButton.get_active();
+ previewButton.set_sensitive(!previewLive);
+ onSettingsChange();
+}
+
+/**
* Default response from the dialog. Let's intercept it
*/
void TraceDialogImpl::responseCallback(int response_id)
{
- if (response_id == GTK_RESPONSE_OK)
- {
- // for now, we assume potrace, as it's the only one we have
- potraceProcess(true);
- }
- else if (response_id == GTK_RESPONSE_CANCEL)
- {
+ if (response_id == GTK_RESPONSE_OK) {
+ // for now, we assume potrace, as it's the only one we have
+ potraceProcess(true);
+ } else if (response_id == GTK_RESPONSE_CANCEL) {
abort();
- }
- else
- {
+ } else if (response_id == GTK_RESPONSE_HELP) {
+ onSetDefaults();
+ } else {
hide();
return;
- }
+ }
}
@@ -417,6 +517,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeBrightnessSpinner.set_value(0.45);
modeBrightnessBox.pack_end(modeBrightnessSpinner, false, false, MARGIN);
modeBrightnessSpinner.set_tooltip_text(_("Brightness cutoff for black/white"));
+ modeBrightnessSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeBrightnessSpinnerLabel.set_label(_("_Threshold:"));
modeBrightnessSpinnerLabel.set_use_underline(true);
@@ -435,6 +536,8 @@ TraceDialogImpl::TraceDialogImpl() :
modeCannyRadioButton.set_use_underline(true);
modeCannyBox.pack_start(modeCannyRadioButton, false, false, MARGIN);
modeCannyRadioButton.set_tooltip_text(_("Trace with optimal edge detection by J. Canny's algorithm"));
+ modeCannyRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
+
/*
modeCannyBox.pack_start(modeCannySeparator);
modeCannyLoSpinnerLabel.set_label(_("Low"));
@@ -451,6 +554,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeCannyHiSpinner.set_value(0.65);
modeCannyBox.pack_end(modeCannyHiSpinner, false, false, MARGIN);
modeCannyHiSpinner.set_tooltip_text(_("Brightness cutoff for adjacent pixels (determines edge thickness)"));
+ modeCannyHiSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeCannyHiSpinnerLabel.set_label(_("T_hreshold:"));
modeCannyHiSpinnerLabel.set_use_underline(true);
@@ -469,6 +573,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeQuantRadioButton.set_use_underline(true);
modeQuantBox.pack_start(modeQuantRadioButton, false, false, MARGIN);
modeQuantRadioButton.set_tooltip_text(_("Trace along the boundaries of reduced colors"));
+ modeQuantRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeQuantNrColorSpinner.set_digits(0);
modeQuantNrColorSpinner.set_increments(1.0, 0);
@@ -476,6 +581,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeQuantNrColorSpinner.set_value(8.0);
modeQuantBox.pack_end(modeQuantNrColorSpinner, false, false, MARGIN);
modeQuantNrColorSpinner.set_tooltip_text(_("The number of reduced colors"));
+ modeQuantNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeQuantNrColorLabel.set_label(_("_Colors:"));
modeQuantNrColorLabel.set_mnemonic_widget(modeQuantNrColorSpinner);
@@ -491,6 +597,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeInvertBox.pack_start(modeInvertButton, false, false, MARGIN);
modeBrightnessVBox.pack_start(modeInvertBox, false, false, MARGIN);
modeInvertButton.set_tooltip_text(_("Invert black and white regions"));
+ modeInvertButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeBrightnessFrame.add(modeBrightnessVBox);
modePageBox.pack_start(modeBrightnessFrame, false, false, 0);
@@ -504,6 +611,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanBrightnessRadioButton.set_use_underline(true);
modeMultiScanHBox1.pack_start(modeMultiScanBrightnessRadioButton, false, false, MARGIN);
modeMultiScanBrightnessRadioButton.set_tooltip_text(_("Trace the given number of brightness levels"));
+ modeMultiScanBrightnessRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanNrColorSpinner.set_digits(0);
modeMultiScanNrColorSpinner.set_increments(1.0, 0);
@@ -515,6 +623,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanNrColorLabel.set_mnemonic_widget(modeMultiScanNrColorSpinner);
modeMultiScanHBox1.pack_end(modeMultiScanNrColorLabel, false, false, MARGIN);
modeMultiScanNrColorSpinner.set_tooltip_text(_("The desired number of scans"));
+ modeMultiScanNrColorSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanVBox.pack_start(modeMultiScanHBox1, false, false, MARGIN);
@@ -523,6 +632,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanColorRadioButton.set_use_underline(true);
modeMultiScanHBox2.pack_start(modeMultiScanColorRadioButton, false, false, MARGIN);
modeMultiScanColorRadioButton.set_tooltip_text(_("Trace the given number of reduced colors"));
+ modeMultiScanColorRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanVBox.pack_start(modeMultiScanHBox2, false, false, MARGIN);
@@ -531,6 +641,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanMonoRadioButton.set_use_underline(true);
modeMultiScanHBox3.pack_start(modeMultiScanMonoRadioButton, false, false, MARGIN);
modeMultiScanMonoRadioButton.set_tooltip_text(_("Same as Colors, but the result is converted to grayscale"));
+ modeMultiScanMonoRadioButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanVBox.pack_start(modeMultiScanHBox3, false, false, MARGIN);
@@ -540,6 +651,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanSmoothButton.set_active(true);
modeMultiScanHBox4.pack_start(modeMultiScanSmoothButton, false, false, MARGIN);
modeMultiScanSmoothButton.set_tooltip_text(_("Apply Gaussian blur to the bitmap before tracing"));
+ modeMultiScanSmoothButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
// TRANSLATORS: "Stack" is a verb here
modeMultiScanStackButton.set_label(_("Stac_k scans"));
@@ -547,6 +659,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanStackButton.set_active(true);
modeMultiScanHBox4.pack_start(modeMultiScanStackButton, false, false, MARGIN);
modeMultiScanStackButton.set_tooltip_text(_("Stack scans on top of one another (no gaps) instead of tiling (usually with gaps)"));
+ modeMultiScanStackButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanBackgroundButton.set_label(_("Remo_ve background"));
@@ -555,6 +668,7 @@ TraceDialogImpl::TraceDialogImpl() :
modeMultiScanHBox4.pack_start(modeMultiScanBackgroundButton, false, false, MARGIN);
// TRANSLATORS: "Layer" refers to one of the stacked paths in the multiscan
modeMultiScanBackgroundButton.set_tooltip_text(_("Remove bottom (background) layer when done"));
+ modeMultiScanBackgroundButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
modeMultiScanVBox.pack_start(modeMultiScanHBox4, false, false, MARGIN);
@@ -577,12 +691,14 @@ TraceDialogImpl::TraceDialogImpl() :
optionsSpecklesButton.set_use_underline(true);
optionsSpecklesButton.set_tooltip_text(_("Ignore small spots (speckles) in the bitmap"));
optionsSpecklesButton.set_active(true);
+ optionsSpecklesButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsSpecklesBox.pack_start(optionsSpecklesButton, false, false, MARGIN);
optionsSpecklesSizeSpinner.set_digits(0);
optionsSpecklesSizeSpinner.set_increments(1, 0);
optionsSpecklesSizeSpinner.set_range(0, 1000);
optionsSpecklesSizeSpinner.set_value(2);
optionsSpecklesSizeSpinner.set_tooltip_text(_("Speckles of up to this many pixels will be suppressed"));
+ optionsSpecklesSizeSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsSpecklesBox.pack_end(optionsSpecklesSizeSpinner, false, false, MARGIN);
optionsSpecklesSizeLabel.set_label(_("S_ize:"));
optionsSpecklesSizeLabel.set_use_underline(true);
@@ -593,6 +709,7 @@ TraceDialogImpl::TraceDialogImpl() :
optionsCornersButton.set_use_underline(true);
optionsCornersButton.set_tooltip_text(_("Smooth out sharp corners of the trace"));
optionsCornersButton.set_active(true);
+ optionsCornersButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsCornersBox.pack_start(optionsCornersButton, false, false, MARGIN);
optionsCornersThresholdSpinner.set_digits(2);
optionsCornersThresholdSpinner.set_increments(0.01, 0);
@@ -600,6 +717,7 @@ TraceDialogImpl::TraceDialogImpl() :
optionsCornersThresholdSpinner.set_value(1.0);
optionsCornersBox.pack_end(optionsCornersThresholdSpinner, false, false, MARGIN);
optionsCornersThresholdSpinner.set_tooltip_text(_("Increase this to smooth corners more"));
+ optionsCornersThresholdSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsCornersThresholdLabel.set_label(_("_Threshold:"));
optionsCornersThresholdLabel.set_use_underline(true);
optionsCornersThresholdLabel.set_mnemonic_widget(optionsCornersThresholdSpinner);
@@ -609,6 +727,7 @@ TraceDialogImpl::TraceDialogImpl() :
optionsOptimButton.set_use_underline(true);
optionsOptimButton.set_active(true);
optionsOptimButton.set_tooltip_text(_("Try to optimize paths by joining adjacent Bezier curve segments"));
+ optionsOptimButton.signal_clicked().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsOptimBox.pack_start(optionsOptimButton, false, false, MARGIN);
optionsOptimToleranceSpinner.set_digits(2);
optionsOptimToleranceSpinner.set_increments(0.05, 0);
@@ -616,6 +735,7 @@ TraceDialogImpl::TraceDialogImpl() :
optionsOptimToleranceSpinner.set_value(0.2);
optionsOptimBox.pack_end(optionsOptimToleranceSpinner, false, false, MARGIN);
optionsOptimToleranceSpinner.set_tooltip_text(_("Increase this to reduce the number of nodes in the trace by more aggressive optimization"));
+ optionsOptimToleranceSpinner.get_adjustment()->signal_value_changed().connect( sigc::mem_fun(*this, &TraceDialogImpl::onSettingsChange) );
optionsOptimToleranceLabel.set_label(_("To_lerance:"));
optionsOptimToleranceLabel.set_use_underline(true);
optionsOptimToleranceLabel.set_mnemonic_widget(optionsOptimToleranceSpinner);
@@ -645,7 +765,7 @@ TraceDialogImpl::TraceDialogImpl() :
//#### end left panel
- mainHBox.pack_start(leftVBox);
+ mainHBox.pack_start(leftVBox, false, false, 0);
//#### begin right panel
@@ -658,12 +778,20 @@ TraceDialogImpl::TraceDialogImpl() :
rightVBox.pack_start(sioxBox, false, false, 0);
//## preview
+ Gtk::HBox *previewButtonHBox = manage(new Gtk::HBox(false, MARGIN ));
+ previewLiveButton.set_label(_("Live Preview"));
+ previewLiveButton.set_use_underline(true);
+ previewLiveCallback();
+ previewLiveButton.signal_clicked().connect(
+ sigc::mem_fun(*this, &TraceDialogImpl::previewLiveCallback) );
previewButton.set_label(_("_Update"));
previewButton.set_use_underline(true);
previewButton.signal_clicked().connect(
sigc::mem_fun(*this, &TraceDialogImpl::previewCallback) );
- previewVBox.pack_end(previewButton, false, false, 0);
+ previewButtonHBox->pack_start(previewLiveButton, false, false, 0);
+ previewButtonHBox->pack_end(previewButton, true, true, 0);
+ previewVBox.pack_end(*previewButtonHBox, false, false, 0);
// I guess it's correct to call the "intermediate bitmap" a preview of the trace
previewButton.set_tooltip_text(_("Preview the intermediate bitmap with the current settings, without actual tracing"));
previewImage.set_size_request(200,200);
@@ -677,11 +805,13 @@ TraceDialogImpl::TraceDialogImpl() :
//#### end right panel
- mainHBox.pack_start(rightVBox);
+ mainHBox.pack_start(rightVBox, true, true, 0);
//#### Global stuff
contents->pack_start(mainHBox);
+ mainResetButton = addResponseButton(_("Reset"), GTK_RESPONSE_HELP, true);
+ mainResetButton ->set_tooltip_text(_("Reset all settings to defaults"));
//## The OK button
mainCancelButton = addResponseButton(Gtk::Stock::STOP, GTK_RESPONSE_CANCEL);
@@ -694,6 +824,9 @@ TraceDialogImpl::TraceDialogImpl() :
show_all_children();
+ desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TraceDialogImpl::setTargetDesktop) );
+ deskTrack.connect(GTK_WIDGET(gobj()));
+
//## Connect the signal
signalResponse().connect(
sigc::mem_fun(*this, &TraceDialogImpl::responseCallback));
@@ -714,6 +847,9 @@ TraceDialog &TraceDialog::getInstance()
*/
TraceDialogImpl::~TraceDialogImpl()
{
+ selectChangedConn.disconnect();
+ selectModifiedConn.disconnect();
+ desktopChangeConn.disconnect();
}
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 15ad41d02..c071fcf95 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -42,16 +42,16 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
+static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
{
int page = daad->getCurrentPage();
daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection);
}
-void on_selection_modified( Inkscape::Application */*inkscape*/,
- Inkscape::Selection *selection,
- guint /*flags*/,
- Transformation *daad )
+static void on_selection_modified( Inkscape::Application */*inkscape*/,
+ Inkscape::Selection *selection,
+ guint /*flags*/,
+ Transformation *daad )
{
int page = daad->getCurrentPage();
daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection);
@@ -157,14 +157,25 @@ Transformation::Transformation()
g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this);
g_signal_connect (G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (on_selection_modified), this);
+ _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Transformation::setDesktop) );
+ _deskTrack.connect(GTK_WIDGET(gobj()));
+
show_all_children();
}
Transformation::~Transformation()
{
sp_signal_disconnect_by_data (G_OBJECT (INKSCAPE), this);
+ _desktopChangeConn.disconnect();
+ _deskTrack.disconnect();
}
+void Transformation::setTargetDesktop(SPDesktop *desktop)
+{
+ if (_desktop != desktop) {
+ _desktop = desktop;
+ }
+}
/*########################################################################
# U T I L I T Y
@@ -205,25 +216,40 @@ void Transformation::layoutPageMove()
_scalar_move_vertical.setIncrements(0.1, 1.0);
//_scalar_move_vertical.set_label_image( INKSCAPE_STOCK_ARROWS_HOR );
+
+#if WITH_GTKMM_3_0
+ _page_move.table().attach(_scalar_move_horizontal, 0, 0, 2, 1);
+ _page_move.table().attach(_units_move, 2, 0, 1, 1);
+#else
_page_move.table()
.attach(_scalar_move_horizontal, 0, 2, 0, 1, Gtk::FILL, Gtk::SHRINK);
_page_move.table()
.attach(_units_move, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+#endif
_scalar_move_horizontal.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onMoveValueChanged));
//_scalar_move_vertical.set_label_image( INKSCAPE_STOCK_ARROWS_VER );
+#if WITH_GTKMM_3_0
+ _page_move.table().attach(_scalar_move_vertical, 0, 1, 2, 1);
+#else
_page_move.table()
.attach(_scalar_move_vertical, 0, 2, 1, 2, Gtk::FILL, Gtk::SHRINK);
+#endif
_scalar_move_vertical.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onMoveValueChanged));
// Relative moves
+#if WITH_GTKMM_3_0
+ _page_move.table().attach(_check_move_relative, 0, 2, 2, 1);
+#else
_page_move.table()
.attach(_check_move_relative, 0, 2, 2, 3, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_check_move_relative.set_active(true);
_check_move_relative.signal_toggled()
.connect(sigc::mem_fun(*this, &Transformation::onMoveRelativeToggled));
@@ -248,21 +274,37 @@ void Transformation::layoutPageScale()
_scalar_scale_vertical.setAbsoluteIsIncrement(true);
_scalar_scale_vertical.setPercentageIsIncrement(true);
+#if WITH_GTKMM_3_0
+ _page_scale.table().attach(_scalar_scale_horizontal, 0, 0, 2, 1);
+#else
_page_scale.table()
.attach(_scalar_scale_horizontal, 0, 2, 0, 1, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_scalar_scale_horizontal.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onScaleXValueChanged));
+#if WITH_GTKMM_3_0
+ _page_scale.table().attach(_units_scale, 2, 0, 1, 1);
+ _page_scale.table().attach(_scalar_scale_vertical, 0, 1, 2, 1);
+#else
_page_scale.table()
.attach(_units_scale, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
_page_scale.table()
.attach(_scalar_scale_vertical, 0, 2, 1, 2, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_scalar_scale_vertical.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onScaleYValueChanged));
+#if WITH_GTKMM_3_0
+ _page_scale.table().attach(_check_scale_proportional, 0, 2, 2, 1);
+#else
_page_scale.table()
.attach(_check_scale_proportional, 0, 2, 2, 3, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_check_scale_proportional.set_active(false);
_check_scale_proportional.signal_toggled()
.connect(sigc::mem_fun(*this, &Transformation::onScaleProportionalToggled));
@@ -293,6 +335,12 @@ void Transformation::layoutPageRotate()
Gtk::RadioButton::Group group = _counterclockwise_rotate.get_group();
_clockwise_rotate.set_group(group);
+#if WITH_GTKMM_3_0
+ _page_rotate.table().attach(_scalar_rotate, 0, 0, 2, 1);
+ _page_rotate.table().attach(_units_rotate, 2, 0, 1, 1);
+ _page_rotate.table().attach(_counterclockwise_rotate, 3, 0, 1, 1);
+ _page_rotate.table().attach(_clockwise_rotate, 4, 0, 1, 1);
+#else
_page_rotate.table()
.attach(_scalar_rotate, 0, 2, 0, 1, Gtk::FILL, Gtk::SHRINK);
@@ -304,6 +352,7 @@ void Transformation::layoutPageRotate()
_page_rotate.table()
.attach(_clockwise_rotate, 4, 5, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+#endif
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/dialogs/transformation/rotateCounterClockwise", TRUE)) {
@@ -337,16 +386,27 @@ void Transformation::layoutPageSkew()
_scalar_skew_vertical.setDigits(3);
_scalar_skew_vertical.setIncrements(0.1, 1.0);
+#if WITH_GTKMM_3_0
+ _page_skew.table().attach(_scalar_skew_horizontal, 0, 0, 2, 1);
+#else
_page_skew.table()
.attach(_scalar_skew_horizontal, 0, 2, 0, 1, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_scalar_skew_horizontal.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onSkewValueChanged));
+#if WITH_GTKMM_3_0
+ _page_skew.table().attach(_units_skew, 2, 0, 1, 1);
+ _page_skew.table().attach(_scalar_skew_vertical, 0, 1, 2, 1);
+#else
_page_skew.table()
.attach(_units_skew, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
_page_skew.table()
.attach(_scalar_skew_vertical, 0, 2, 1, 2, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_scalar_skew_vertical.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onSkewValueChanged));
@@ -362,30 +422,46 @@ void Transformation::layoutPageTransform()
_scalar_transform_a.setDigits(3);
_scalar_transform_a.setIncrements(0.1, 1.0);
_scalar_transform_a.setValue(1.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_a, 0, 0, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_a, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_a.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
-
_scalar_transform_b.setWidgetSizeRequest(65, -1);
_scalar_transform_b.setRange(-1e10, 1e10);
_scalar_transform_b.setDigits(3);
_scalar_transform_b.setIncrements(0.1, 1.0);
_scalar_transform_b.setValue(0.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_b, 0, 1, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_b, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_b.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
-
_scalar_transform_c.setWidgetSizeRequest(65, -1);
_scalar_transform_c.setRange(-1e10, 1e10);
_scalar_transform_c.setDigits(3);
_scalar_transform_c.setIncrements(0.1, 1.0);
_scalar_transform_c.setValue(0.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_c, 1, 0, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_c, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_c.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
@@ -395,8 +471,14 @@ void Transformation::layoutPageTransform()
_scalar_transform_d.setDigits(3);
_scalar_transform_d.setIncrements(0.1, 1.0);
_scalar_transform_d.setValue(1.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_d, 1, 1, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_d, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_d.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
@@ -406,8 +488,14 @@ void Transformation::layoutPageTransform()
_scalar_transform_e.setDigits(3);
_scalar_transform_e.setIncrements(0.1, 1.0);
_scalar_transform_e.setValue(0.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_e, 2, 0, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_e, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_e.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
@@ -417,14 +505,25 @@ void Transformation::layoutPageTransform()
_scalar_transform_f.setDigits(3);
_scalar_transform_f.setIncrements(0.1, 1.0);
_scalar_transform_f.setValue(0.0);
+
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_scalar_transform_f, 2, 1, 1, 1);
+#else
_page_transform.table()
.attach(_scalar_transform_f, 2, 3, 1, 2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
_scalar_transform_f.signal_value_changed()
.connect(sigc::mem_fun(*this, &Transformation::onTransformValueChanged));
// Edit existing matrix
+#if WITH_GTKMM_3_0
+ _page_transform.table().attach(_check_replace_matrix, 0, 2, 2, 1);
+#else
_page_transform.table()
.attach(_check_replace_matrix, 0, 2, 2, 3, Gtk::FILL, Gtk::SHRINK);
+#endif
+
_check_replace_matrix.set_active(false);
_check_replace_matrix.signal_toggled()
.connect(sigc::mem_fun(*this, &Transformation::onReplaceMatrixToggled));
diff --git a/src/ui/dialog/transformation.h b/src/ui/dialog/transformation.h
index 68c6a1e8e..1d24a0c94 100644
--- a/src/ui/dialog/transformation.h
+++ b/src/ui/dialog/transformation.h
@@ -12,19 +12,15 @@
#define INKSCAPE_UI_DIALOG_TRANSFORMATION_H
-
#include <gtkmm/notebook.h>
#include <glibmm/i18n.h>
-
-
#include "ui/widget/panel.h"
#include "ui/widget/notebook-page.h"
#include "ui/widget/scalar-unit.h"
#include "ui/widget/imageicon.h"
#include "ui/widget/button.h"
-
-
+#include "ui/dialog/desktop-tracker.h"
namespace Inkscape {
@@ -32,8 +28,6 @@ namespace UI {
namespace Dialog {
-
-
/**
* Transformation dialog.
*
@@ -159,6 +153,10 @@ protected:
UI::Widget::CheckButton _check_apply_separately;
UI::Widget::CheckButton _check_replace_matrix;
+ SPDesktop *_desktop;
+ DesktopTracker _deskTrack;
+ sigc::connection _desktopChangeConn;
+
/**
* Layout the GUI components, and prepare for use
*/
@@ -217,6 +215,8 @@ protected:
void applyPageSkew(Inkscape::Selection *);
void applyPageTransform(Inkscape::Selection *);
+ void setTargetDesktop(SPDesktop* desktop);
+
private:
/**
diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp
index 52d160124..a487eb930 100644
--- a/src/ui/dialog/undo-history.cpp
+++ b/src/ui/dialog/undo-history.cpp
@@ -14,11 +14,11 @@
# include <config.h>
#endif
+#include "undo-history.h"
#include <glibmm/i18n.h>
#include <stddef.h>
#include <sigc++/sigc++.h>
-#include "undo-history.h"
#include "document.h"
#include "document-undo.h"
#include "inkscape.h"
@@ -159,11 +159,15 @@ UndoHistory::UndoHistory()
_document (sp_desktop_document(getDesktop())),
_event_log (getDesktop() ? getDesktop()->event_log : NULL),
_columns (_event_log ? &_event_log->getColumns() : NULL),
- _event_list_selection (_event_list_view.get_selection())
+ _event_list_selection (_event_list_view.get_selection()),
+ _desktop(NULL),
+ _deskTrack(),
+ _desktopChangeConn()
+
{
if ( !_document || !_event_log || !_columns ) return;
- set_size_request(300, 95);
+ set_size_request(-1, 95);
_getContents()->pack_start(_scrolled_window);
_scrolled_window.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
@@ -176,31 +180,35 @@ UndoHistory::UndoHistory()
_event_list_view.set_headers_visible(false);
CellRendererSPIcon* icon_renderer = Gtk::manage(new CellRendererSPIcon());
- icon_renderer->property_xpad() = 8;
- icon_renderer->property_width() = 36;
+ icon_renderer->property_xpad() = 2;
+ icon_renderer->property_width() = 24;
int cols_count = _event_list_view.append_column("Icon", *icon_renderer);
Gtk::TreeView::Column* icon_column = _event_list_view.get_column(cols_count-1);
icon_column->add_attribute(icon_renderer->property_event_type(), _columns->type);
+ CellRendererInt* children_renderer = Gtk::manage(new CellRendererInt(greater_than_1));
+ children_renderer->property_weight() = 600; // =Pango::WEIGHT_SEMIBOLD (not defined in old versions of pangomm)
+ children_renderer->property_xalign() = 1.0;
+ children_renderer->property_xpad() = 2;
+ children_renderer->property_width() = 24;
+
+ cols_count = _event_list_view.append_column("Children", *children_renderer);
+ Gtk::TreeView::Column* children_column = _event_list_view.get_column(cols_count-1);
+ children_column->add_attribute(children_renderer->property_number(), _columns->child_count);
+
Gtk::CellRendererText* description_renderer = Gtk::manage(new Gtk::CellRendererText());
+ description_renderer->property_ellipsize() = Pango::ELLIPSIZE_END;
cols_count = _event_list_view.append_column("Description", *description_renderer);
Gtk::TreeView::Column* description_column = _event_list_view.get_column(cols_count-1);
description_column->add_attribute(description_renderer->property_text(), _columns->description);
description_column->set_resizable();
+ description_column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+ description_column->set_min_width (150);
_event_list_view.set_expander_column( *_event_list_view.get_column(cols_count-1) );
- CellRendererInt* children_renderer = Gtk::manage(new CellRendererInt(greater_than_1));
- children_renderer->property_weight() = 600; // =Pango::WEIGHT_SEMIBOLD (not defined in old versions of pangomm)
- children_renderer->property_xalign() = 1.0;
- children_renderer->property_xpad() = 20;
-
- cols_count = _event_list_view.append_column("Children", *children_renderer);
- Gtk::TreeView::Column* children_column = _event_list_view.get_column(cols_count-1);
- children_column->add_attribute(children_renderer->property_number(), _columns->child_count);
-
_scrolled_window.add(_event_list_view);
// connect EventLog callbacks
@@ -216,6 +224,9 @@ UndoHistory::UndoHistory()
// connect with the EventLog
_event_log->connectWithDialog(&_event_list_view, &_callback_connections);
+ _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &UndoHistory::setDesktop) );
+ _deskTrack.connect(GTK_WIDGET(gobj()));
+
show_all_children();
// scroll to the selected row
@@ -224,8 +235,10 @@ UndoHistory::UndoHistory()
UndoHistory::~UndoHistory()
{
+ _desktopChangeConn.disconnect();
}
+
void
UndoHistory::_onListSelectionChange()
{
diff --git a/src/ui/dialog/undo-history.h b/src/ui/dialog/undo-history.h
index f6bca30b7..adf4f1936 100644
--- a/src/ui/dialog/undo-history.h
+++ b/src/ui/dialog/undo-history.h
@@ -24,6 +24,7 @@
#include "event-log.h"
#include "widgets/icon.h"
+#include "ui/dialog/desktop-tracker.h"
class SPDesktop;
@@ -67,6 +68,7 @@ private:
Glib::Property<Glib::RefPtr<Gdk::Pixbuf> > _property_icon;
Glib::Property<unsigned int> _property_event_type;
std::map<const unsigned int, Glib::RefPtr<Gdk::Pixbuf> > _icon_cache;
+
};
@@ -135,6 +137,7 @@ protected:
SPDocument *_document;
EventLog *_event_log;
+
const EventLog::EventModelColumns *_columns;
Gtk::ScrolledWindow _scrolled_window;
@@ -143,6 +146,10 @@ protected:
Gtk::TreeView _event_list_view;
Glib::RefPtr<Gtk::TreeSelection> _event_list_selection;
+ SPDesktop *_desktop;
+ DesktopTracker _deskTrack;
+ sigc::connection _desktopChangeConn;
+
EventLog::CallbackMap _callback_connections;
void _onListSelectionChange();
diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp
index accf03586..29dbc4b93 100644
--- a/src/ui/dialog/xml-tree.cpp
+++ b/src/ui/dialog/xml-tree.cpp
@@ -79,7 +79,11 @@ XmlTree::XmlTree (void) :
xml_attribute_delete_button (_("Delete attribute")),
text_container (),
attr_container (),
- attr_subpaned_container (),
+#if WITH_GTKMM_3_0
+ attr_subpaned_container(Gtk::ORIENTATION_VERTICAL),
+#else
+ attr_subpaned_container(),
+#endif
set_attr (_("Set")),
new_window(NULL)
{
@@ -842,6 +846,10 @@ gboolean XmlTree::quit_on_esc (GtkWidget *w, GdkEventKey *event, GObject */*tbl*
case GDK_KEY_Escape: // defocus
gtk_widget_destroy(w);
return TRUE;
+ case GDK_KEY_Return: // create
+ case GDK_KEY_KP_Enter:
+ gtk_widget_destroy(w);
+ return TRUE;
}
return FALSE;
}
diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h
index ee1dadc14..58ef3aef8 100644
--- a/src/ui/dialog/xml-tree.h
+++ b/src/ui/dialog/xml-tree.h
@@ -13,6 +13,10 @@
#ifndef SEEN_DIALOGS_XML_TREE_H
#define SEEN_DIALOGS_XML_TREE_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "ui/widget/panel.h"
#include <gtkmm/entry.h>
#include <gtkmm/textview.h>
@@ -24,8 +28,8 @@
#include "ui/dialog/desktop-tracker.h"
#include "message.h"
-struct SPDesktop;
-struct SPObject;
+class SPDesktop;
+class SPObject;
struct SPXMLViewAttrList;
struct SPXMLViewContent;
struct SPXMLViewTree;
@@ -215,7 +219,12 @@ private:
Gtk::Button *create_button;
Gtk::Entry *name_entry;
+#if WITH_GTKMM_3_0
+ Gtk::Paned paned;
+#else
Gtk::HPaned paned;
+#endif
+
Gtk::VBox left_box;
Gtk::VBox right_box;
Gtk::HBox status_box;
@@ -239,7 +248,13 @@ private:
Gtk::ScrolledWindow text_container;
Gtk::HBox attr_hbox;
Gtk::VBox attr_container;
+
+#if WITH_GTKMM_3_0
+ Gtk::Paned attr_subpaned_container;
+#else
Gtk::VPaned attr_subpaned_container;
+#endif
+
Gtk::Button set_attr;
GtkWidget *new_window;
diff --git a/src/ui/previewable.h b/src/ui/previewable.h
index 9a086a9a2..377e109fb 100644
--- a/src/ui/previewable.h
+++ b/src/ui/previewable.h
@@ -35,12 +35,13 @@ typedef enum {
VIEW_TYPE_GRID
} ViewType;
+
class Previewable
{
public:
// TODO need to add some nice parameters
virtual ~Previewable() {}
- virtual Gtk::Widget* getPreview( PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio ) = 0;
+ virtual Gtk::Widget* getPreview( PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) = 0;
};
diff --git a/src/ui/previewfillable.h b/src/ui/previewfillable.h
index d5f609a0b..044357503 100644
--- a/src/ui/previewfillable.h
+++ b/src/ui/previewfillable.h
@@ -28,11 +28,12 @@ public:
virtual void addPreview( Previewable* preview ) = 0;
virtual void freezeUpdates() = 0;
virtual void thawUpdates() = 0;
- virtual void setStyle( ::PreviewSize size, ViewType type, guint ratio) = 0;
+ virtual void setStyle( ::PreviewSize size, ViewType type, guint ratio, ::BorderStyle border ) = 0;
virtual void setOrientation(SPAnchorType how) = 0;
virtual ::PreviewSize getPreviewSize() const = 0;
virtual ViewType getPreviewType() const = 0;
virtual guint getPreviewRatio() const = 0;
+ virtual ::BorderStyle getPreviewBorder() const = 0;
virtual void setWrap( bool b ) = 0;
virtual bool getWrap() const = 0;
};
diff --git a/src/ui/previewholder.cpp b/src/ui/previewholder.cpp
index e1c2c718a..b5a1a29a8 100644
--- a/src/ui/previewholder.cpp
+++ b/src/ui/previewholder.cpp
@@ -12,10 +12,18 @@
#include "previewholder.h"
+#include "preferences.h"
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/sizegroup.h>
#include <gtkmm/scrollbar.h>
+#include <gtkmm/adjustment.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
#define COLUMNS_FOR_SMALL 16
#define COLUMNS_FOR_LARGE 8
@@ -38,25 +46,65 @@ PreviewHolder::PreviewHolder() :
_baseSize(PREVIEW_SIZE_SMALL),
_ratio(100),
_view(VIEW_TYPE_LIST),
- _wrap(false)
+ _wrap(false),
+ _border(BORDER_NONE)
{
_scroller = manage(new Gtk::ScrolledWindow());
+
+#if WITH_GTKMM_3_0
+ _insides = manage(new Gtk::Grid());
+ _insides->set_column_spacing(8);
+
+ // Add a container with the scroller and a spacer
+ Gtk::Grid* spaceHolder = manage(new Gtk::Grid());
+
+ _scroller->set_hexpand();
+ _scroller->set_vexpand();
+#else
_insides = manage(new Gtk::Table( 1, 2 ));
_insides->set_col_spacings( 8 );
-
+
// Add a container with the scroller and a spacer
Gtk::Table* spaceHolder = manage( new Gtk::Table(1, 2) );
+#endif
+
_scroller->add( *_insides );
+
+#if WITH_GTKMM_3_0
+ spaceHolder->attach( *_scroller, 0, 0, 1, 1);
+#else
spaceHolder->attach( *_scroller, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+#endif
pack_start(*spaceHolder, Gtk::PACK_EXPAND_WIDGET);
}
PreviewHolder::~PreviewHolder()
{
+
}
+bool PreviewHolder::on_scroll_event(GdkEventScroll *event)
+{
+ // Scroll horizontally by page on mouse wheel
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> adj = dynamic_cast<Gtk::ScrolledWindow*>(_scroller)->get_hadjustment();
+#else
+ Gtk::Adjustment *adj = dynamic_cast<Gtk::ScrolledWindow*>(_scroller)->get_hadjustment();
+#endif
+
+ if (!adj) {
+ return FALSE;
+ }
+ int move = (event->direction == GDK_SCROLL_DOWN) ? adj->get_page_size() : -adj->get_page_size();
+
+ double value = std::min(adj->get_upper() - move, adj->get_value() + move );
+
+ adj->set_value(value);
+
+ return FALSE;
+}
void PreviewHolder::clear()
{
@@ -69,6 +117,11 @@ void PreviewHolder::clear()
rebuildUI();
}
+/**
+ * Add a Previewable item to the PreviewHolder
+ *
+ * \param[in] preview The Previewable item to add
+ */
void PreviewHolder::addPreview( Previewable* preview )
{
items.push_back(preview);
@@ -76,41 +129,78 @@ void PreviewHolder::addPreview( Previewable* preview )
{
int i = items.size() - 1;
- if ( _view == VIEW_TYPE_LIST ) {
- Gtk::Widget* label = manage(preview->getPreview(PREVIEW_STYLE_BLURB, VIEW_TYPE_LIST, _baseSize, _ratio));
- Gtk::Widget* thing = manage(preview->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_LIST, _baseSize, _ratio));
+ switch(_view) {
+ case VIEW_TYPE_LIST:
+ {
+ Gtk::Widget* label = manage(preview->getPreview(PREVIEW_STYLE_BLURB, VIEW_TYPE_LIST, _baseSize, _ratio, _border));
+ Gtk::Widget* thing = manage(preview->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_LIST, _baseSize, _ratio, _border));
- _insides->attach( *thing, 0, 1, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
- _insides->attach( *label, 1, 2, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK );
- } else {
- Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_GRID, _baseSize, _ratio));
-
- int width = 1;
- int height = 1;
- calcGridSize( thing, items.size(), width, height );
- int col = i % width;
- int row = i / width;
-
- if ( _insides && width > (int)_insides->property_n_columns() ) {
- std::vector<Gtk::Widget*>kids = _insides->get_children();
- int oldWidth = (int)_insides->property_n_columns();
- int childCount = (int)kids.size();
-// g_message(" %3d resize from %d to %d (r:%d, c:%d) with %d children", i, oldWidth, width, row, col, childCount );
- _insides->resize( height, width );
-
- for ( int j = oldWidth; j < childCount; j++ ) {
- Gtk::Widget* target = kids[childCount - (j + 1)];
- int col2 = j % width;
- int row2 = j / width;
- Glib::RefPtr<Gtk::Widget> handle(target);
- _insides->remove( *target );
- _insides->attach( *target, col2, col2+1, row2, row2+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+#if WITH_GTKMM_3_0
+ thing->set_hexpand();
+ thing->set_vexpand();
+ _insides->attach(*thing, 0, i, 1, 1);
+
+ label->set_hexpand();
+ label->set_valign(Gtk::ALIGN_CENTER);
+ _insides->attach(*label, 1, i, 1, 1);
+#else
+ _insides->attach( *thing, 0, 1, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+ _insides->attach( *label, 1, 2, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK );
+#endif
+ }
+
+ break;
+ case VIEW_TYPE_GRID:
+ {
+ Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_GRID, _baseSize, _ratio, _border));
+
+ int width = 1;
+ int height = 1;
+ calcGridSize( thing, items.size(), width, height );
+
+ // Column and row for the new widget
+ int col = i % width;
+ int row = i / width;
+
+#if !WITH_GTKMM_3_0
+ // If the existing grid isn't wide enough, we need to resize
+ // it and re-pack the existing widgets
+ if ( _insides && width > (int)_insides->property_n_columns() ) {
+ _insides->resize( height, width );
+#endif
+ std::vector<Gtk::Widget*>kids = _insides->get_children();
+ int childCount = (int)kids.size();
+ // g_message(" %3d resize from %d to %d (r:%d, c:%d) with %d children", i, oldWidth, width, row, col, childCount );
+
+ // Loop through the existing widgets and move them to new location
+ for ( int j = 1; j < childCount; j++ ) {
+ Gtk::Widget* target = kids[childCount - (j + 1)];
+ int col2 = j % width;
+ int row2 = j / width;
+ Glib::RefPtr<Gtk::Widget> handle(target);
+ _insides->remove( *target );
+
+#if WITH_GTKMM_3_0
+ target->set_hexpand();
+ target->set_vexpand();
+ _insides->attach( *target, col2, row2, 1, 1);
+#else
+ _insides->attach( *target, col2, col2+1, row2, row2+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+#endif
+ }
+#if WITH_GTKMM_3_0
+ thing->set_hexpand();
+ thing->set_vexpand();
+ _insides->attach(*thing, col, row, 1, 1);
+#else
+ } else if ( col == 0 ) {
+ // we just started a new row
+ _insides->resize( row + 1, width );
+ }
+
+ _insides->attach( *thing, col, col+1, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+#endif
}
- } else if ( col == 0 ) {
- // we just started a new row
- _insides->resize( row + 1, width );
- }
- _insides->attach( *thing, col, col+1, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
}
_scroller->show_all_children();
@@ -129,12 +219,13 @@ void PreviewHolder::thawUpdates()
rebuildUI();
}
-void PreviewHolder::setStyle( ::PreviewSize size, ViewType view, guint ratio )
+void PreviewHolder::setStyle( ::PreviewSize size, ViewType view, guint ratio, ::BorderStyle border )
{
- if ( size != _baseSize || view != _view || ratio != _ratio ) {
+ if ( size != _baseSize || view != _view || ratio != _ratio || border != _border ) {
_baseSize = size;
_view = view;
_ratio = ratio;
+ _border = border;
// Kludge to restore scrollbars
if ( !_wrap && (_view != VIEW_TYPE_LIST) && (_anchor == SP_ANCHOR_NORTH || _anchor == SP_ANCHOR_SOUTH) ) {
dynamic_cast<Gtk::ScrolledWindow*>(_scroller)->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_NEVER );
@@ -233,8 +324,17 @@ void PreviewHolder::on_size_allocate( Gtk::Allocation& allocation )
// g_message(" items:%d", (int)items.size());
//}
+/**
+ * Calculate the grid side of a preview holder
+ *
+ * \param[in] thing
+ * \param[in] itemCount The number of items to pack into the grid
+ * \param[out] width The width of the grid
+ * \param[out] height The height of the grid
+ */
void PreviewHolder::calcGridSize( const Gtk::Widget* thing, int itemCount, int& width, int& height )
{
+ // Initially set all items in a horizontal row
width = itemCount;
height = 1;
@@ -301,45 +401,104 @@ void PreviewHolder::rebuildUI()
_scroller->remove();
_insides = 0; // remove() call should have deleted the Gtk::Table.
- if ( _view == VIEW_TYPE_LIST ) {
- _insides = manage(new Gtk::Table( 1, 2 ));
- _insides->set_col_spacings( 8 );
+ switch(_view) {
+ case VIEW_TYPE_LIST:
+ {
- for ( unsigned int i = 0; i < items.size(); i++ ) {
- Gtk::Widget* label = manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio));
- //label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+#if WITH_GTKMM_3_0
+ _insides = manage(new Gtk::Grid());
+ _insides->set_column_spacing(8);
+#else
+ _insides = manage(new Gtk::Table( 1, 2 ));
+ _insides->set_col_spacings( 8 );
+#endif
- Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio));
+ if (_border == BORDER_WIDE) {
+#if WITH_GTKMM_3_0
+ _insides->set_row_spacing(1);
+#else
+ _insides->set_row_spacings( 1 );
+#endif
+ }
- _insides->attach( *thing, 0, 1, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
- _insides->attach( *label, 1, 2, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK );
- }
- _scroller->add( *_insides );
- } else {
- int col = 0;
- int row = 0;
- int width = 2;
- int height = 1;
+ for ( unsigned int i = 0; i < items.size(); i++ ) {
+ Gtk::Widget* label = manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio, _border));
+ //label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
- for ( unsigned int i = 0; i < items.size(); i++ ) {
- Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio));
+ Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, _border));
- if ( !_insides ) {
- calcGridSize( thing, items.size(), width, height );
- _insides = manage(new Gtk::Table( height, width ));
- }
+#if WITH_GTKMM_3_0
+ thing->set_hexpand();
+ thing->set_vexpand();
+ _insides->attach(*thing, 0, i, 1, 1);
- _insides->attach( *thing, col, col+1, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
- if ( ++col >= width ) {
- col = 0;
- row++;
+ label->set_hexpand();
+ label->set_valign(Gtk::ALIGN_CENTER);
+ _insides->attach(*label, 1, i, 1, 1);
+#else
+ _insides->attach( *thing, 0, 1, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+ _insides->attach( *label, 1, 2, i, i+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK );
+#endif
+ }
+
+ _scroller->add( *_insides );
}
- }
- if ( !_insides ) {
- _insides = manage(new Gtk::Table( 1, 2 ));
- }
+ break;
- _scroller->add( *_insides );
+ case VIEW_TYPE_GRID:
+ {
+ int col = 0;
+ int row = 0;
+ int width = 2;
+ int height = 1;
+
+ for ( unsigned int i = 0; i < items.size(); i++ ) {
+
+ // If this is the last row, flag so the previews can draw a bottom
+ ::BorderStyle border = ((row == height -1) && (_border == BORDER_SOLID)) ? BORDER_SOLID_LAST_ROW : _border;
+ Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, border));
+
+ if ( !_insides ) {
+ calcGridSize( thing, items.size(), width, height );
+
+#if WITH_GTKMM_3_0
+ _insides = manage(new Gtk::Grid());
+ if (_border == BORDER_WIDE) {
+ _insides->set_column_spacing(1);
+ _insides->set_row_spacing(1);
+ }
+#else
+ _insides = manage(new Gtk::Table( height, width ));
+ if (_border == BORDER_WIDE) {
+ _insides->set_col_spacings( 1 );
+ _insides->set_row_spacings( 1 );
+ }
+#endif
+ }
+
+#if WITH_GTKMM_3_0
+ thing->set_hexpand();
+ thing->set_vexpand();
+ _insides->attach( *thing, col, row, 1, 1);
+#else
+ _insides->attach( *thing, col, col+1, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND );
+#endif
+
+ if ( ++col >= width ) {
+ col = 0;
+ row++;
+ }
+ }
+ if ( !_insides ) {
+#if WITH_GTKMM_3_0
+ _insides = manage(new Gtk::Grid());
+#else
+ _insides = manage(new Gtk::Table( 1, 2 ));
+#endif
+ }
+
+ _scroller->add( *_insides );
+ }
}
_scroller->show_all_children();
diff --git a/src/ui/previewholder.h b/src/ui/previewholder.h
index b7073024e..f6d1985cc 100644
--- a/src/ui/previewholder.h
+++ b/src/ui/previewholder.h
@@ -12,10 +12,21 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
#include <gtkmm/box.h>
#include <gtkmm/bin.h>
-#include <gtkmm/table.h>
+
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
+
#include "previewfillable.h"
#include "../widgets/eek-preview.h"
#include "enums.h"
@@ -33,18 +44,20 @@ public:
virtual void addPreview( Previewable* preview );
virtual void freezeUpdates();
virtual void thawUpdates();
- virtual void setStyle( ::PreviewSize size, ViewType view, guint ratio );
+ virtual void setStyle( ::PreviewSize size, ViewType view, guint ratio, ::BorderStyle border );
virtual void setOrientation(SPAnchorType how);
virtual int getColumnPref() const { return _prefCols; }
virtual void setColumnPref( int cols );
virtual ::PreviewSize getPreviewSize() const { return _baseSize; }
virtual ViewType getPreviewType() const { return _view; }
virtual guint getPreviewRatio() const { return _ratio; }
+ virtual ::BorderStyle getPreviewBorder() const { return _border; }
virtual void setWrap( bool b );
virtual bool getWrap() const { return _wrap; }
protected:
virtual void on_size_allocate( Gtk::Allocation& allocation );
+ virtual bool on_scroll_event(GdkEventScroll*);
// virtual void on_size_request( Gtk::Requisition* requisition );
@@ -54,7 +67,13 @@ private:
std::vector<Previewable*> items;
Gtk::Bin *_scroller;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *_insides;
+#else
Gtk::Table *_insides;
+#endif
+
int _prefCols;
bool _updatesFrozen;
SPAnchorType _anchor;
@@ -62,6 +81,7 @@ private:
guint _ratio;
ViewType _view;
bool _wrap;
+ ::BorderStyle _border;
};
} //namespace UI
diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp
index 8c4924f26..069dcc67b 100644
--- a/src/ui/tool/control-point.cpp
+++ b/src/ui/tool/control-point.cpp
@@ -7,8 +7,8 @@
*/
#include <iostream>
+#include <gdk/gdkkeysyms.h>
#include <gdkmm.h>
-#include <gtkmm.h>
#include <2geom/point.h>
#include "desktop.h"
#include "desktop-handles.h"
diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h
index 30efe8a27..27a0f8074 100644
--- a/src/ui/tool/control-point.h
+++ b/src/ui/tool/control-point.h
@@ -23,7 +23,7 @@
#include "enums.h"
class SPDesktop;
-class SPEventContext;
+struct SPEventContext;
namespace Inkscape {
namespace UI {
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index eca90f40f..70bd0e859 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -11,9 +11,8 @@
*/
#include <boost/shared_ptr.hpp>
-#include <glib.h>
-#include <glibmm/i18n.h>
#include "node.h"
+#include <glibmm/i18n.h>
#include "desktop.h"
#include "desktop-handles.h"
#include "document.h"
@@ -65,7 +64,6 @@ typedef std::pair<double, IterPair> DistanceMapItem;
void find_join_iterators(ControlPointSelection &sel, IterPairList &pairs)
{
IterSet join_iters;
- DistanceMap dists;
// find all endnodes in selection
for (ControlPointSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
@@ -672,6 +670,9 @@ bool MultiPathManipulator::event(SPEventContext *event_context, GdkEvent *event)
// b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed
// Hence xor
deleteNodes(del_preserves_shape ^ held_control(event->key));
+
+ // Delete any selected gradient nodes as well
+ event_context->deleteSelectedDrag(held_control(event->key));
}
return true;
case GDK_KEY_c:
diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp
index 71c0d3b26..e743e0efc 100644
--- a/src/ui/tool/node-tool.cpp
+++ b/src/ui/tool/node-tool.cpp
@@ -41,6 +41,7 @@
#include "pixmaps/cursor-node.xpm"
#include "pixmaps/cursor-node-d.xpm"
+#include "selection-chemistry.h"
#include <gdk/gdkkeysyms.h>
@@ -106,8 +107,6 @@ using Inkscape::ControlManager;
namespace {
SPCanvasGroup *create_control_group(SPDesktop *d);
-void ink_node_tool_class_init(InkNodeToolClass *klass);
-void ink_node_tool_init(InkNodeTool *node_context);
void ink_node_tool_dispose(GObject *object);
void ink_node_tool_setup(SPEventContext *ec);
@@ -125,39 +124,10 @@ void handleControlUiStyleChange(InkNodeTool *nt);
} // anonymous namespace
-GType ink_node_tool_get_type()
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo info = {
- sizeof(InkNodeToolClass),
- NULL, NULL,
- (GClassInitFunc) ink_node_tool_class_init,
- NULL, NULL,
- sizeof(InkNodeTool),
- 4,
- (GInstanceInitFunc) ink_node_tool_init,
- NULL, /* value_table */
- };
- type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "InkNodeTool", &info, (GTypeFlags)0);
- }
- return type;
-}
-
-namespace {
+G_DEFINE_TYPE(InkNodeTool, ink_node_tool, SP_TYPE_EVENT_CONTEXT);
-SPCanvasGroup *create_control_group(SPDesktop *d)
-{
- return reinterpret_cast<SPCanvasGroup*>(sp_canvas_item_new(
- sp_desktop_controls(d), SP_TYPE_CANVAS_GROUP, NULL));
-}
-
-void destroy_group(SPCanvasGroup *g)
-{
- sp_canvas_item_destroy(SP_CANVAS_ITEM(g));
-}
-
-void ink_node_tool_class_init(InkNodeToolClass *klass)
+static void
+ink_node_tool_class_init(InkNodeToolClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
SPEventContextClass *event_context_class = (SPEventContextClass *) klass;
@@ -170,7 +140,8 @@ void ink_node_tool_class_init(InkNodeToolClass *klass)
event_context_class->item_handler = ink_node_tool_item_handler;
}
-void ink_node_tool_init(InkNodeTool *nt)
+static void
+ink_node_tool_init(InkNodeTool *nt)
{
SPEventContext *event_context = SP_EVENT_CONTEXT(nt);
@@ -190,12 +161,29 @@ void ink_node_tool_init(InkNodeTool *nt)
new (&nt->_shape_editors) ShapeEditors();
}
+namespace {
+
+SPCanvasGroup *create_control_group(SPDesktop *d)
+{
+ return reinterpret_cast<SPCanvasGroup*>(sp_canvas_item_new(
+ sp_desktop_controls(d), SP_TYPE_CANVAS_GROUP, NULL));
+}
+
+void destroy_group(SPCanvasGroup *g)
+{
+ sp_canvas_item_destroy(SP_CANVAS_ITEM(g));
+}
+
void ink_node_tool_dispose(GObject *object)
{
InkNodeTool *nt = INK_NODE_TOOL(object);
nt->enableGrDrag(false);
+ if (nt->flash_tempitem) {
+ nt->desktop->remove_temporary_canvasitem(nt->flash_tempitem);
+ }
+
nt->_selection_changed_connection.disconnect();
nt->_selection_modified_connection.disconnect();
nt->_mouseover_changed_connection.disconnect();
@@ -223,15 +211,15 @@ void ink_node_tool_dispose(GObject *object)
delete nt->_node_message_context;
}
- G_OBJECT_CLASS(g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL)))->dispose(object);
+ G_OBJECT_CLASS(ink_node_tool_parent_class)->dispose(object);
}
void ink_node_tool_setup(SPEventContext *ec)
{
InkNodeTool *nt = INK_NODE_TOOL(ec);
- SPEventContextClass *parent = (SPEventContextClass *) g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL));
- if (parent->setup) parent->setup(ec);
+ if (SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->setup)
+ SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->setup(ec);
nt->_node_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack());
@@ -367,10 +355,8 @@ void ink_node_tool_set(SPEventContext *ec, Inkscape::Preferences::Entry *value)
nt->edit_masks = value->getBool();
ink_node_tool_selection_changed(nt, nt->desktop->selection);
} else {
- SPEventContextClass *parent_class =
- (SPEventContextClass *) g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL));
- if (parent_class->set)
- parent_class->set(ec, value);
+ if (SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->set)
+ SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->set(ec, value);
}
}
@@ -517,7 +503,7 @@ gint ink_node_tool_root_handler(SPEventContext *event_context, GdkEvent *event)
{
case GDK_KEY_Escape: // deselect everything
if (nt->_selected_nodes->empty()) {
- selection->clear();
+ Inkscape::SelectionHelper::selectNone(desktop);
} else {
nt->_selected_nodes->clear();
}
@@ -551,9 +537,9 @@ gint ink_node_tool_root_handler(SPEventContext *event_context, GdkEvent *event)
default: break;
}
- SPEventContextClass *parent_class = (SPEventContextClass *) g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL));
- if (parent_class->root_handler)
- return parent_class->root_handler(event_context, event);
+ if (SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->root_handler)
+ return SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->root_handler(event_context, event);
+
return FALSE;
}
@@ -617,10 +603,9 @@ void ink_node_tool_update_tip(InkNodeTool *nt, GdkEvent *event)
gint ink_node_tool_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event)
{
- SPEventContextClass *parent_class =
- (SPEventContextClass *) g_type_class_peek(g_type_parent(INK_TYPE_NODE_TOOL));
- if (parent_class->item_handler)
- return parent_class->item_handler(event_context, item, event);
+ if (SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->item_handler)
+ return SP_EVENT_CONTEXT_CLASS(ink_node_tool_parent_class)->item_handler(event_context, item, event);
+
return FALSE;
}
diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h
index 49b1496d4..bc5267bb2 100644
--- a/src/ui/tool/node-tool.h
+++ b/src/ui/tool/node-tool.h
@@ -25,9 +25,6 @@
#define INK_IS_NODE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_TYPE_NODE_TOOL))
#define INK_IS_NODE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INK_TYPE_NODE_TOOL))
-class InkNodeTool;
-class InkNodeToolClass;
-
namespace Inkscape {
namespace Display {
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index bda410856..dc6e0fbae 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -293,7 +293,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
Geom::Point parent_pos = _parent->position();
Geom::Point origin = _last_drag_origin();
SnapManager &sm = _desktop->namedview->snap_manager;
- bool snap = sm.someSnapperMightSnap();
+ bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap();
boost::optional<Inkscape::Snapper::SnapConstraint> ctrl_constraint;
// with Alt, preserve length
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index 35eb23f42..ac023beaa 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -19,7 +19,6 @@
#include <2geom/bezier-curve.h>
#include <2geom/bezier-utils.h>
#include <2geom/svg-path.h>
-#include <glibmm.h>
#include <glibmm/i18n.h>
#include "ui/tool/path-manipulator.h"
#include "desktop.h"
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index a51b8c410..1444272e8 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -21,8 +21,8 @@
#include "ui/tool/manipulator.h"
struct SPCanvasItem;
-struct SPCurve;
-struct SPPath;
+class SPCurve;
+class SPPath;
namespace Inkscape {
namespace XML { class Node; }
diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h
index 412c7ff8c..26e47abbb 100644
--- a/src/ui/view/edit-widget-interface.h
+++ b/src/ui/view/edit-widget-interface.h
@@ -101,9 +101,6 @@ struct EditWidgetInterface
/// Update the "inactive desktop" indicator
virtual void deactivateDesktop() = 0;
- /// Set rulers to position
- virtual void viewSetPosition (Geom::Point p) = 0;
-
/// Update rulers from current values
virtual void updateRulers() = 0;
diff --git a/src/ui/view/view-widget.h b/src/ui/view/view-widget.h
index 668f9d19a..295e7932b 100644
--- a/src/ui/view/view-widget.h
+++ b/src/ui/view/view-widget.h
@@ -23,7 +23,7 @@ class View;
} // namespace Inkscape
class SPViewWidget;
-class SPNamedView;
+struct SPNamedView;
#define SP_TYPE_VIEW_WIDGET (sp_view_widget_get_type ())
#define SP_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_VIEW_WIDGET, SPViewWidget))
diff --git a/src/ui/view/view.cpp b/src/ui/view/view.cpp
index e13976cc4..72548e213 100644
--- a/src/ui/view/view.cpp
+++ b/src/ui/view/view.cpp
@@ -27,12 +27,6 @@ namespace UI {
namespace View {
static void
-_onPositionSet (double x, double y, View* v)
-{
- v->onPositionSet (x,y);
-}
-
-static void
_onResized (double x, double y, View* v)
{
v->onResized (x,y);
@@ -69,7 +63,6 @@ View::View()
_message_stack = GC::release(new Inkscape::MessageStack());
_tips_message_context = new Inkscape::MessageContext(_message_stack);
- _position_set_connection = _position_set_signal.connect (sigc::bind (sigc::ptr_fun (&_onPositionSet), this));
_resized_connection = _resized_signal.connect (sigc::bind (sigc::ptr_fun (&_onResized), this));
_redraw_requested_connection = _redraw_requested_signal.connect (sigc::bind (sigc::ptr_fun (&_onRedrawRequested), this));
@@ -102,16 +95,6 @@ void View::_close() {
Inkscape::Verb::delete_all_view (this);
}
-void View::setPosition (double x, double y)
-{
- _position_set_signal.emit (x,y);
-}
-
-void View::setPosition(Geom::Point const &p)
-{
- setPosition (double(p[Geom::X]), double(p[Geom::Y]));
-}
-
void View::emitResized (double width, double height)
{
_resized_signal.emit (width, height);
diff --git a/src/ui/view/view.h b/src/ui/view/view.h
index 6ed9f476c..48f4d2549 100644
--- a/src/ui/view/view.h
+++ b/src/ui/view/view.h
@@ -90,8 +90,6 @@ public:
Inkscape::MessageContext *tipsMessageContext() const
{ return _tips_message_context; }
- void setPosition(gdouble x, gdouble y);
- void setPosition(Geom::Point const &p);
void emitResized(gdouble width, gdouble height);
void requestRedraw();
@@ -101,7 +99,6 @@ public:
virtual void mouseover() = 0;
virtual void mouseout() = 0;
- virtual void onPositionSet (double, double) = 0;
virtual void onResized (double, double) = 0;
virtual void onRedrawRequested() = 0;
virtual void onStatusMessage (Inkscape::MessageType type, gchar const *message) = 0;
@@ -126,13 +123,11 @@ protected:
*/
virtual void setDocument(SPDocument *doc);
- sigc::signal<void,double,double> _position_set_signal;
sigc::signal<void,double,double> _resized_signal;
sigc::signal<void,gchar const*> _document_uri_set_signal;
sigc::signal<void> _redraw_requested_signal;
private:
- sigc::connection _position_set_connection;
sigc::connection _resized_connection;
sigc::connection _redraw_requested_connection;
sigc::connection _message_changed_connection; // foreign
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert
index 8589f16b0..2de954674 100644
--- a/src/ui/widget/Makefile_insert
+++ b/src/ui/widget/Makefile_insert
@@ -19,6 +19,10 @@ ink_common_sources += \
ui/widget/entry.h \
ui/widget/filter-effect-chooser.h \
ui/widget/filter-effect-chooser.cpp \
+ ui/widget/gimpspinscale.c \
+ ui/widget/gimpspinscale.h \
+ ui/widget/gimpcolorwheel.c \
+ ui/widget/gimpcolorwheel.h \
ui/widget/frame.cpp \
ui/widget/frame.h \
ui/widget/imageicon.cpp \
@@ -62,6 +66,8 @@ ink_common_sources += \
ui/widget/selected-style.cpp \
ui/widget/spinbutton.h \
ui/widget/spinbutton.cpp \
+ ui/widget/spin-scale.h \
+ ui/widget/spin-scale.cpp \
ui/widget/spin-slider.h \
ui/widget/spin-slider.cpp \
ui/widget/style-subject.h \
diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp
index e5c542a7c..5585f2db4 100644
--- a/src/ui/widget/color-picker.cpp
+++ b/src/ui/widget/color-picker.cpp
@@ -55,9 +55,15 @@ void ColorPicker::setupDialog(const Glib::ustring &title)
_colorSelectorDialog.hide();
_colorSelectorDialog.set_title (title);
_colorSelectorDialog.set_border_width (4);
- _colorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK);
+ _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
+
+#if WITH_GTKMM_3_0
+ _colorSelectorDialog.get_content_area()->pack_start (
+ *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+#else
_colorSelectorDialog.get_vbox()->pack_start (
*Glib::wrap(&_colorSelector->vbox), true, true, 0);
+#endif
g_signal_connect(G_OBJECT(_colorSelector), "dragged",
G_CALLBACK(sp_color_picker_color_mod), (void *)this);
diff --git a/src/ui/widget/color-preview.cpp b/src/ui/widget/color-preview.cpp
index 3ebb282ec..4b4a7b738 100644
--- a/src/ui/widget/color-preview.cpp
+++ b/src/ui/widget/color-preview.cpp
@@ -26,13 +26,6 @@ ColorPreview::ColorPreview (guint32 rgba)
}
void
-ColorPreview::on_size_request (Gtk::Requisition *req)
-{
- req->width = SPCP_DEFAULT_WIDTH;
- req->height = SPCP_DEFAULT_HEIGHT;
-}
-
-void
ColorPreview::on_size_allocate (Gtk::Allocation &all)
{
set_allocation (all);
@@ -40,14 +33,55 @@ ColorPreview::on_size_allocate (Gtk::Allocation &all)
queue_draw();
}
+#if WITH_GTKMM_3_0
+void
+ColorPreview::get_preferred_height_vfunc(int& minimum_height, int& natural_height) const
+{
+ minimum_height = natural_height = SPCP_DEFAULT_HEIGHT;
+}
+
+void
+ColorPreview::get_preferred_height_for_width_vfunc(int /* width */, int& minimum_height, int& natural_height) const
+{
+ minimum_height = natural_height = SPCP_DEFAULT_HEIGHT;
+}
+
+void
+ColorPreview::get_preferred_width_vfunc(int& minimum_width, int& natural_width) const
+{
+ minimum_width = natural_width = SPCP_DEFAULT_WIDTH;
+}
+
+void
+ColorPreview::get_preferred_width_for_height_vfunc(int /* height */, int& minimum_width, int& natural_width) const
+{
+ minimum_width = natural_width = SPCP_DEFAULT_WIDTH;
+}
+#else
+void
+ColorPreview::on_size_request (Gtk::Requisition *req)
+{
+ req->width = SPCP_DEFAULT_WIDTH;
+ req->height = SPCP_DEFAULT_HEIGHT;
+}
+
bool
ColorPreview::on_expose_event (GdkEventExpose *event)
{
+ bool result = true;
+
if (get_is_drawable())
- paint (&event->area);
+ {
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
+ cr->rectangle(event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cr->clip();
+ result = on_draw(cr);
+ }
- return true;
+ return result;
}
+#endif
void
ColorPreview::setRgba32 (guint32 rgba)
@@ -58,11 +92,10 @@ ColorPreview::setRgba32 (guint32 rgba)
queue_draw();
}
-void
-ColorPreview::paint (GdkRectangle *area)
+bool
+ColorPreview::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
GdkRectangle warea, carea;
- GdkRectangle wpaint, cpaint;
gint w2;
const Gtk::Allocation& allocation = get_allocation();
@@ -71,12 +104,6 @@ ColorPreview::paint (GdkRectangle *area)
warea.width = allocation.get_width();
warea.height = allocation.get_height();
- if (!gdk_rectangle_intersect (area, &warea, &wpaint))
- return;
-
- GtkWidget *widget = GTK_WIDGET(this->gobj());
- cairo_t *ct = gdk_cairo_create(gtk_widget_get_window(widget));
-
/* Transparent area */
w2 = warea.width / 2;
@@ -86,17 +113,15 @@ ColorPreview::paint (GdkRectangle *area)
carea.width = w2;
carea.height = warea.height;
- if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
- cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard();
+ cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard();
- cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height);
- cairo_set_source(ct, checkers);
- cairo_fill_preserve(ct);
- ink_cairo_set_source_rgba32(ct, _rgba);
- cairo_fill(ct);
+ cr->rectangle(carea.x, carea.y, carea.width, carea.height);
+ cairo_set_source(cr->cobj(), checkers);
+ cr->fill_preserve();
+ ink_cairo_set_source_rgba32(cr->cobj(), _rgba);
+ cr->fill();
- cairo_pattern_destroy(checkers);
- }
+ cairo_pattern_destroy(checkers);
/* Solid area */
@@ -105,13 +130,11 @@ ColorPreview::paint (GdkRectangle *area)
carea.width = warea.width - w2;
carea.height = warea.height;
- if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
- cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height);
- ink_cairo_set_source_rgba32(ct, _rgba | 0xff);
- cairo_fill(ct);
- }
+ cr->rectangle(carea.x, carea.y, carea.width, carea.height);
+ ink_cairo_set_source_rgba32(cr->cobj(), _rgba | 0xff);
+ cr->fill();
- cairo_destroy(ct);
+ return true;
}
GdkPixbuf*
@@ -173,3 +196,4 @@ ColorPreview::toPixbuf (int width, int height)
fill-column:99
End:
*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/color-preview.h b/src/ui/widget/color-preview.h
index d6d3da01c..caddfb9a2 100644
--- a/src/ui/widget/color-preview.h
+++ b/src/ui/widget/color-preview.h
@@ -11,6 +11,10 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/widget.h>
namespace Inkscape {
@@ -27,10 +31,19 @@ public:
GdkPixbuf* toPixbuf (int width, int height);
protected:
- virtual void on_size_request (Gtk::Requisition *req);
virtual void on_size_allocate (Gtk::Allocation &all);
- virtual bool on_expose_event (GdkEventExpose *event);
- void paint (GdkRectangle *area);
+
+#if WITH_GTKMM_3_0
+ virtual void get_preferred_height_vfunc(int& minimum_height, int& natural_height) const;
+ virtual void get_preferred_height_for_width_vfunc(int width, int& minimum_height, int& natural_height) const;
+ virtual void get_preferred_width_vfunc(int& minimum_width, int& natural_width) const;
+ virtual void get_preferred_width_for_height_vfunc(int height, int& minimum_width, int& natural_width) const;
+#else
+ virtual void on_size_request (Gtk::Requisition *req);
+ virtual bool on_expose_event(GdkEventExpose *event);
+#endif
+
+ virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
guint32 _rgba;
};
diff --git a/src/ui/widget/dock-item.cpp b/src/ui/widget/dock-item.cpp
index b9cc50845..8d960ddc3 100644
--- a/src/ui/widget/dock-item.cpp
+++ b/src/ui/widget/dock-item.cpp
@@ -18,6 +18,7 @@
#include <gtkmm/icontheme.h>
#include <gtkmm/stockitem.h>
+#include <glibmm/exceptionhandler.h>
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp
index a7dabef1c..2bfc7e0df 100644
--- a/src/ui/widget/dock.cpp
+++ b/src/ui/widget/dock.cpp
@@ -54,6 +54,17 @@ Dock::Dock(Gtk::Orientation orientation)
{
gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation));
+#if WITH_GTKMM_3_0
+ switch(orientation) {
+ case Gtk::ORIENTATION_VERTICAL:
+ _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
+ break;
+ case Gtk::ORIENTATION_HORIZONTAL:
+ _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ }
+
+ _paned = Gtk::manage(new Gtk::Paned(orientation));
+#else
switch (orientation) {
case Gtk::ORIENTATION_VERTICAL:
_dock_box = Gtk::manage(new Gtk::HBox());
@@ -63,6 +74,7 @@ Dock::Dock(Gtk::Orientation orientation)
_dock_box = Gtk::manage(new Gtk::VBox());
_paned = Gtk::manage(new Gtk::HPaned());
}
+#endif
_scrolled_window->add(*_dock_box);
_scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
@@ -81,9 +93,15 @@ Dock::Dock(Gtk::Orientation orientation)
static_cast<GdlSwitcherStyle>(prefs->getIntLimited("/options/dock/switcherstyle",
GDL_SWITCHER_STYLE_BOTH, 0, 4));
- g_object_set (GDL_DOCK_OBJECT(_gdl_dock)->master,
- "switcher-style", gdl_switcher_style,
- NULL);
+ GdlDockMaster* master = NULL;
+
+ g_object_get(GDL_DOCK_OBJECT(_gdl_dock),
+ "master", &master,
+ NULL);
+
+ g_object_set(master,
+ "switcher-style", gdl_switcher_style,
+ NULL);
GdlDockBarStyle gdl_dock_bar_style =
static_cast<GdlDockBarStyle>(prefs->getIntLimited("/options/dock/dockbarstyle",
diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp
index 173e014d9..64d28119a 100644
--- a/src/ui/widget/entry.cpp
+++ b/src/ui/widget/entry.cpp
@@ -13,6 +13,8 @@
#include "entry.h"
+#include <gtkmm/entry.h>
+
namespace Inkscape {
namespace UI {
namespace Widget {
diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h
index 53b848fc9..de5cceadd 100644
--- a/src/ui/widget/entry.h
+++ b/src/ui/widget/entry.h
@@ -11,10 +11,10 @@
#define INKSCAPE_UI_WIDGET_ENTRY__H
#include "labelled.h"
-#include <gtkmm.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/comboboxtext.h>
+namespace Gtk {
+class Entry;
+}
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp
index 8d6bcf60f..65706a9dc 100644
--- a/src/ui/widget/filter-effect-chooser.cpp
+++ b/src/ui/widget/filter-effect-chooser.cpp
@@ -22,12 +22,9 @@ namespace UI {
namespace Widget {
SimpleFilterModifier::SimpleFilterModifier(int flags)
- : _hb_blur(false, 0),
- _lb_blend(_("Blend mode:")),
- _lb_blur(_("_Blur:")),
- _lb_blur_unit(_("%")),
+ : _lb_blend(_("Blend mode:")),
_blend(BlendModeConverter, SP_ATTR_INVALID, false),
- _blur(0, 0, 100, 1, 0.01, 1)
+ _blur(_("Blur (%)"), 0, 0, 100, 1, 0.01, 1)
{
_flags = flags;
@@ -37,11 +34,7 @@ SimpleFilterModifier::SimpleFilterModifier(int flags)
_hb_blend.pack_start(_blend);
}
if (flags & BLUR) {
- add(_hb_blur);
- _lb_blur.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
- _hb_blur.pack_start(_lb_blur, false, false, 0);
- _hb_blur.pack_start(_blur, true, true, 0);
- _hb_blur.pack_start(_lb_blur_unit, false, false, 3);
+ add(_blur);
}
show_all_children();
@@ -49,8 +42,6 @@ SimpleFilterModifier::SimpleFilterModifier(int flags)
_hb_blend.set_spacing(12);
_lb_blend.set_use_underline();
_lb_blend.set_mnemonic_widget(_blend);
- _lb_blur.set_use_underline();
- _lb_blur.set_mnemonic_widget(_blur.get_scale());
_blend.signal_changed().connect(signal_blend_blur_changed());
_blur.signal_value_changed().connect(signal_blend_blur_changed());
}
diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h
index 6afb6c180..ae3ec07c4 100644
--- a/src/ui/widget/filter-effect-chooser.h
+++ b/src/ui/widget/filter-effect-chooser.h
@@ -18,6 +18,7 @@
#include "combo-enums.h"
#include "filter-enums.h"
#include "spin-slider.h"
+#include "spin-scale.h"
namespace Inkscape {
namespace UI {
@@ -45,17 +46,14 @@ public:
double get_blur_value() const;
void set_blur_value(const double);
void set_blur_sensitive(const bool);
- Gtk::Label *get_blur_label() { return &_lb_blur; };
-
private:
int _flags;
Gtk::HBox _hb_blend;
- Gtk::HBox _hb_blur;
- Gtk::Label _lb_blend, _lb_blur, _lb_blur_unit;
+ Gtk::Label _lb_blend;
ComboBoxEnum<Inkscape::Filters::FilterBlendMode> _blend;
- SpinSlider _blur;
+ SpinScale _blur;
sigc::signal<void> _signal_blend_blur_changed;
};
diff --git a/src/ui/widget/frame.cpp b/src/ui/widget/frame.cpp
index b2968f806..eaa4336bb 100644
--- a/src/ui/widget/frame.cpp
+++ b/src/ui/widget/frame.cpp
@@ -56,9 +56,7 @@ Frame::set_label(const Glib::ustring &label_text, gboolean label_bold /*= TRUE*/
void
Frame::set_padding (guint padding_top, guint padding_bottom, guint padding_left, guint padding_right)
{
-#if WITH_GTKMM_2_24
_alignment.set_padding(padding_top, padding_bottom, padding_left, padding_right);
-#endif
}
Gtk::Label const *
diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h
index cf736d8a1..a04666651 100644
--- a/src/ui/widget/frame.h
+++ b/src/ui/widget/frame.h
@@ -10,11 +10,9 @@
#ifndef INKSCAPE_UI_WIDGET_FRAME_H
#define INKSCAPE_UI_WIDGET_FRAME_H
-#include <gtkmm.h>
-
-namespace Gtk {
-class Frame;
-}
+#include <gtkmm/alignment.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/label.h>
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/gimpcolorwheel.c b/src/ui/widget/gimpcolorwheel.c
new file mode 100644
index 000000000..f632331d8
--- /dev/null
+++ b/src/ui/widget/gimpcolorwheel.c
@@ -0,0 +1,1598 @@
+/* HSV color selector for GTK+
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
+ * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
+ * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
+ * Michael Natterer <mitch@gimp.org> (ported back to GIMP)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * This widget was adopted by Inkscape by Alex Valavanis <valavanisalex@gmail.com>
+ * on 2013-01-08. Last merges with GIMP code were applied using the following
+ * commits from the GIMP git repository at
+ * http://git.gnome.org/browse/gimp/tree/modules/gimpcolorwheel.c
+ *
+ * Gtk+ 2 code merge: commit 632c5 (2013-01-06)
+ * Gtk+ 3 code merge: commit bcfc6, gtk3-port branch (2013-01-06)
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gimpcolorwheel.h"
+#include <math.h>
+
+
+/* Default ring fraction */
+#define DEFAULT_FRACTION 0.1
+
+/* Default width/height */
+#define DEFAULT_SIZE 100
+
+/* Default ring width */
+#define DEFAULT_RING_WIDTH 10
+
+
+/* Dragging modes */
+typedef enum
+{
+ DRAG_NONE,
+ DRAG_H,
+ DRAG_SV
+} DragMode;
+
+/* Private part of the GimpColorWheel structure */
+typedef struct
+{
+ /* Color value */
+ gdouble h;
+ gdouble s;
+ gdouble v;
+
+ /* ring_width is this fraction of size */
+ gdouble ring_fraction;
+
+ /* Size and ring width */
+ gint size;
+ gint ring_width;
+
+ /* Window for capturing events */
+ GdkWindow *window;
+
+ /* Dragging mode */
+ DragMode mode;
+
+ guint focus_on_ring : 1;
+} GimpColorWheelPrivate;
+
+enum
+{
+ CHANGED,
+ MOVE,
+ LAST_SIGNAL
+};
+
+static void gimp_color_wheel_map (GtkWidget *widget);
+static void gimp_color_wheel_unmap (GtkWidget *widget);
+static void gimp_color_wheel_realize (GtkWidget *widget);
+static void gimp_color_wheel_unrealize (GtkWidget *widget);
+static void gimp_color_wheel_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean gimp_color_wheel_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_color_wheel_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_color_wheel_motion (GtkWidget *widget,
+ GdkEventMotion *event);
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean gimp_color_wheel_draw (GtkWidget *widget,
+ cairo_t *cr);
+static void gimp_color_wheel_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width);
+static void gimp_color_wheel_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height);
+#else
+static gboolean gimp_color_wheel_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gimp_color_wheel_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+#endif
+
+static gboolean gimp_color_wheel_grab_broken (GtkWidget *widget,
+ GdkEventGrabBroken *event);
+static gboolean gimp_color_wheel_focus (GtkWidget *widget,
+ GtkDirectionType direction);
+static void gimp_color_wheel_move (GimpColorWheel *wheel,
+ GtkDirectionType dir);
+
+
+static guint wheel_signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (GimpColorWheel, gimp_color_wheel, GTK_TYPE_WIDGET)
+
+#define parent_class gimp_color_wheel_parent_class
+
+
+static void
+gimp_color_wheel_class_init (GimpColorWheelClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GimpColorWheelClass *wheel_class = GIMP_COLOR_WHEEL_CLASS (class);
+ GtkBindingSet *binding_set;
+
+ widget_class->map = gimp_color_wheel_map;
+ widget_class->unmap = gimp_color_wheel_unmap;
+ widget_class->realize = gimp_color_wheel_realize;
+ widget_class->unrealize = gimp_color_wheel_unrealize;
+ widget_class->size_allocate = gimp_color_wheel_size_allocate;
+ widget_class->button_press_event = gimp_color_wheel_button_press;
+ widget_class->button_release_event = gimp_color_wheel_button_release;
+ widget_class->motion_notify_event = gimp_color_wheel_motion;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ widget_class->get_preferred_width = gimp_color_wheel_get_preferred_width;
+ widget_class->get_preferred_height = gimp_color_wheel_get_preferred_height;
+ widget_class->draw = gimp_color_wheel_draw;
+#else
+ widget_class->size_request = gimp_color_wheel_size_request;
+ widget_class->expose_event = gimp_color_wheel_expose;
+#endif
+
+ widget_class->focus = gimp_color_wheel_focus;
+ widget_class->grab_broken_event = gimp_color_wheel_grab_broken;
+
+ wheel_class->move = gimp_color_wheel_move;
+
+ wheel_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpColorWheelClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ wheel_signals[MOVE] =
+ g_signal_new ("move",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GimpColorWheelClass, move),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_DIRECTION_TYPE);
+
+ binding_set = gtk_binding_set_by_class (class);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_UP);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Up, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_UP);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_DOWN);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Down, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_DOWN);
+
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_RIGHT);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_RIGHT);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_LEFT);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_LEFT);
+
+ g_type_class_add_private (object_class, sizeof (GimpColorWheelPrivate));
+}
+
+static void
+gimp_color_wheel_init (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (wheel, GIMP_TYPE_COLOR_WHEEL,
+ GimpColorWheelPrivate);
+
+ wheel->priv = priv;
+
+ gtk_widget_set_has_window (GTK_WIDGET (wheel), FALSE);
+ gtk_widget_set_can_focus (GTK_WIDGET (wheel), TRUE);
+
+ priv->ring_fraction = DEFAULT_FRACTION;
+ priv->size = DEFAULT_SIZE;
+ priv->ring_width = DEFAULT_RING_WIDTH;
+}
+
+static void
+gimp_color_wheel_map (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+ gdk_window_show (priv->window);
+}
+
+static void
+gimp_color_wheel_unmap (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ gdk_window_hide (priv->window);
+
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static void
+gimp_color_wheel_realize (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ GdkWindowAttr attr;
+ gint attr_mask;
+ GdkWindow *parent_window;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ gtk_widget_set_realized (widget, TRUE);
+
+ attr.window_type = GDK_WINDOW_CHILD;
+ attr.x = allocation.x;
+ attr.y = allocation.y;
+ attr.width = allocation.width;
+ attr.height = allocation.height;
+ attr.wclass = GDK_INPUT_ONLY;
+ attr.event_mask = (gtk_widget_get_events (widget) |
+ GDK_KEY_PRESS_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK);
+
+ attr_mask = GDK_WA_X | GDK_WA_Y;
+
+ parent_window = gtk_widget_get_parent_window (widget);
+
+ gtk_widget_set_window (widget, parent_window);
+ g_object_ref (parent_window);
+
+ priv->window = gdk_window_new (parent_window, &attr, attr_mask);
+ gdk_window_set_user_data (priv->window, wheel);
+
+ gtk_widget_style_attach (widget);
+}
+
+static void
+gimp_color_wheel_unrealize (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ gdk_window_set_user_data (priv->window, NULL);
+ gdk_window_destroy (priv->window);
+ priv->window = NULL;
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gimp_color_wheel_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ *minimum_width = *natural_width = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+
+static void
+gimp_color_wheel_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ *minimum_height = *natural_height = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+#else
+static void
+gimp_color_wheel_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ requisition->width = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+ requisition->height = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+#endif
+
+static void
+gimp_color_wheel_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ priv->size = MIN (allocation->width - 2 * (focus_width + focus_pad),
+ allocation->height - 2 * (focus_width + focus_pad));
+
+ priv->ring_width = priv->size * priv->ring_fraction;
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (priv->window,
+ allocation->x,
+ allocation->y,
+ allocation->width,
+ allocation->height);
+}
+
+
+/* Utility functions */
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+/* Converts from HSV to RGB */
+static void
+hsv_to_rgb (gdouble *h,
+ gdouble *s,
+ gdouble *v)
+{
+ gdouble hue, saturation, value;
+ gdouble f, p, q, t;
+
+ if (*s == 0.0)
+ {
+ *h = *v;
+ *s = *v;
+ *v = *v; /* heh */
+ }
+ else
+ {
+ hue = *h * 6.0;
+ saturation = *s;
+ value = *v;
+
+ if (hue == 6.0)
+ hue = 0.0;
+
+ f = hue - (int) hue;
+ p = value * (1.0 - saturation);
+ q = value * (1.0 - saturation * f);
+ t = value * (1.0 - saturation * (1.0 - f));
+
+ switch ((int) hue)
+ {
+ case 0:
+ *h = value;
+ *s = t;
+ *v = p;
+ break;
+
+ case 1:
+ *h = q;
+ *s = value;
+ *v = p;
+ break;
+
+ case 2:
+ *h = p;
+ *s = value;
+ *v = t;
+ break;
+
+ case 3:
+ *h = p;
+ *s = q;
+ *v = value;
+ break;
+
+ case 4:
+ *h = t;
+ *s = p;
+ *v = value;
+ break;
+
+ case 5:
+ *h = value;
+ *s = p;
+ *v = q;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+}
+
+/* Computes the vertices of the saturation/value triangle */
+static void
+compute_triangle (GimpColorWheel *wheel,
+ gint *hx,
+ gint *hy,
+ gint *sx,
+ gint *sy,
+ gint *vx,
+ gint *vy)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+ gdouble angle;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+ angle = priv->h * 2.0 * G_PI;
+
+ *hx = floor (center_x + cos (angle) * inner + 0.5);
+ *hy = floor (center_y - sin (angle) * inner + 0.5);
+ *sx = floor (center_x + cos (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *sy = floor (center_y - sin (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *vx = floor (center_x + cos (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+ *vy = floor (center_y - sin (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+}
+
+/* Computes whether a point is inside the hue ring */
+static gboolean
+is_in_ring (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ gdouble dx, dy, dist;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+
+ dx = x - center_x;
+ dy = center_y - y;
+ dist = dx * dx + dy * dy;
+
+ return (dist >= inner * inner && dist <= outer * outer);
+}
+
+/* Computes a saturation/value pair based on the mouse coordinates */
+static void
+compute_sv (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y,
+ gdouble *s,
+ gdouble *v)
+{
+ GtkAllocation allocation;
+ gint ihx, ihy, isx, isy, ivx, ivy;
+ gdouble hx, hy, sx, sy, vx, vy;
+ gdouble center_x;
+ gdouble center_y;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ compute_triangle (wheel, &ihx, &ihy, &isx, &isy, &ivx, &ivy);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ hx = ihx - center_x;
+ hy = center_y - ihy;
+ sx = isx - center_x;
+ sy = center_y - isy;
+ vx = ivx - center_x;
+ vy = center_y - ivy;
+ x -= center_x;
+ y = center_y - y;
+
+ if (vx * (x - sx) + vy * (y - sy) < 0.0)
+ {
+ *s = 1.0;
+ *v = (((x - sx) * (hx - sx) + (y - sy) * (hy-sy))
+ / ((hx - sx) * (hx - sx) + (hy - sy) * (hy - sy)));
+
+ if (*v < 0.0)
+ *v = 0.0;
+ else if (*v > 1.0)
+ *v = 1.0;
+ }
+ else if (hx * (x - sx) + hy * (y - sy) < 0.0)
+ {
+ *s = 0.0;
+ *v = (((x - sx) * (vx - sx) + (y - sy) * (vy - sy))
+ / ((vx - sx) * (vx - sx) + (vy - sy) * (vy - sy)));
+
+ if (*v < 0.0)
+ *v = 0.0;
+ else if (*v > 1.0)
+ *v = 1.0;
+ }
+ else if (sx * (x - hx) + sy * (y - hy) < 0.0)
+ {
+ *v = 1.0;
+ *s = (((x - vx) * (hx - vx) + (y - vy) * (hy - vy)) /
+ ((hx - vx) * (hx - vx) + (hy - vy) * (hy - vy)));
+
+ if (*s < 0.0)
+ *s = 0.0;
+ else if (*s > 1.0)
+ *s = 1.0;
+ }
+ else
+ {
+ *v = (((x - sx) * (hy - vy) - (y - sy) * (hx - vx))
+ / ((vx - sx) * (hy - vy) - (vy - sy) * (hx - vx)));
+
+ if (*v<= 0.0)
+ {
+ *v = 0.0;
+ *s = 0.0;
+ }
+ else
+ {
+ if (*v > 1.0)
+ *v = 1.0;
+
+ if (fabs (hy - vy) < fabs (hx - vx))
+ *s = (x - sx - *v * (vx - sx)) / (*v * (hx - vx));
+ else
+ *s = (y - sy - *v * (vy - sy)) / (*v * (hy - vy));
+
+ if (*s < 0.0)
+ *s = 0.0;
+ else if (*s > 1.0)
+ *s = 1.0;
+ }
+ }
+}
+
+/* Computes whether a point is inside the saturation/value triangle */
+static gboolean
+is_in_triangle (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ gint hx, hy, sx, sy, vx, vy;
+ gdouble det, s, v;
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ det = (vx - sx) * (hy - sy) - (vy - sy) * (hx - sx);
+
+ s = ((x - sx) * (hy - sy) - (y - sy) * (hx - sx)) / det;
+ v = ((vx - sx) * (y - sy) - (vy - sy) * (x - sx)) / det;
+
+ return (s >= 0.0 && v >= 0.0 && s + v <= 1.0);
+}
+
+/* Computes a value based on the mouse coordinates */
+static double
+compute_v (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ GtkAllocation allocation;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble dx, dy;
+ gdouble angle;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ dx = x - center_x;
+ dy = center_y - y;
+
+ angle = atan2 (dy, dx);
+ if (angle < 0.0)
+ angle += 2.0 * G_PI;
+
+ return angle / (2.0 * G_PI);
+}
+
+static void
+set_cross_grab (GimpColorWheel *wheel,
+ guint32 time)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GdkCursor *cursor;
+
+ cursor =
+ gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (wheel)),
+ GDK_CROSSHAIR);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_device_grab (gtk_get_current_event_device(),
+ priv->window,
+ GDK_OWNERSHIP_NONE,
+ FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ cursor, time);
+ g_object_unref (cursor);
+#else
+ gdk_pointer_grab (priv->window, FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL, cursor, time);
+ gdk_cursor_unref (cursor);
+#endif
+}
+
+static gboolean gimp_color_wheel_grab_broken(GtkWidget *widget, GdkEventGrabBroken *event)
+{
+ (void)event;
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ priv->mode = DRAG_NONE;
+
+ return TRUE;
+}
+
+static gboolean
+gimp_color_wheel_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble x, y;
+
+ if (priv->mode != DRAG_NONE || event->button != 1)
+ return FALSE;
+
+ x = event->x;
+ y = event->y;
+
+ if (is_in_ring (wheel, x, y))
+ {
+ priv->mode = DRAG_H;
+ set_cross_grab (wheel, event->time);
+
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y),
+ priv->s,
+ priv->v);
+
+ gtk_widget_grab_focus (widget);
+ priv->focus_on_ring = TRUE;
+
+ return TRUE;
+ }
+
+ if (is_in_triangle (wheel, x, y))
+ {
+ gdouble s, v;
+
+ priv->mode = DRAG_SV;
+ set_cross_grab (wheel, event->time);
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+
+ gtk_widget_grab_focus (widget);
+ priv->focus_on_ring = FALSE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_color_wheel_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ DragMode mode;
+ gdouble x, y;
+
+ if (priv->mode == DRAG_NONE || event->button != 1)
+ return FALSE;
+
+ /* Set the drag mode to DRAG_NONE so that signal handlers for "catched"
+ * can see that this is the final color state.
+ */
+
+ mode = priv->mode;
+ priv->mode = DRAG_NONE;
+
+ x = event->x;
+ y = event->y;
+
+ if (mode == DRAG_H)
+ {
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y), priv->s, priv->v);
+ }
+ else if (mode == DRAG_SV)
+ {
+ gdouble s, v;
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+ }
+ else
+ g_assert_not_reached ();
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_device_ungrab (gtk_get_current_event_device(),
+ event->time);
+#else
+ gdk_display_pointer_ungrab (gdk_window_get_display (event->window),
+ event->time);
+#endif
+
+ return TRUE;
+}
+
+static gboolean
+gimp_color_wheel_motion (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble x, y;
+
+ if (priv->mode == DRAG_NONE)
+ return FALSE;
+
+ gdk_event_request_motions (event);
+ x = event->x;
+ y = event->y;
+
+ if (priv->mode == DRAG_H)
+ {
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y), priv->s, priv->v);
+ return TRUE;
+ }
+ else if (priv->mode == DRAG_SV)
+ {
+ gdouble s, v;
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+ return TRUE;
+ }
+
+ g_assert_not_reached ();
+
+ return FALSE;
+}
+
+
+/* Redrawing */
+
+/* Paints the hue ring */
+static void
+paint_ring (GimpColorWheel *wheel,
+ cairo_t *cr)
+{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *widget = GTK_WIDGET (wheel);
+#else
+ GtkAllocation allocation;
+#endif
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint width, height;
+ gint xx, yy;
+ gdouble dx, dy, dist;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+ guint32 *buf, *p;
+ gdouble angle;
+ gdouble hue;
+ gdouble r, g, b;
+ cairo_surface_t *source;
+ cairo_t *source_cr;
+ gint stride;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+#else
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+ width = allocation.width;
+ height = allocation.height;
+#endif
+
+ center_x = width / 2.0;
+ center_y = height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+
+ /* Create an image initialized with the ring colors */
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
+
+ for (yy = 0; yy < height; yy++)
+ {
+ p = buf + yy * width;
+ dy = -(yy - center_y);
+
+ for (xx = 0; xx < width; xx++)
+ {
+ dx = xx - center_x;
+
+ dist = dx * dx + dy * dy;
+ if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1)))
+ {
+ *p++ = 0;
+ continue;
+ }
+
+ angle = atan2 (dy, dx);
+ if (angle < 0.0)
+ angle += 2.0 * G_PI;
+
+ hue = angle / (2.0 * G_PI);
+
+ r = hue;
+ g = 1.0;
+ b = 1.0;
+ hsv_to_rgb (&r, &g, &b);
+
+ *p++ = (((int)floor (r * 255 + 0.5) << 16) |
+ ((int)floor (g * 255 + 0.5) << 8) |
+ (int)floor (b * 255 + 0.5));
+ }
+ }
+
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
+ CAIRO_FORMAT_RGB24,
+ width, height, stride);
+
+ /* Now draw the value marker onto the source image, so that it
+ * will get properly clipped at the edges of the ring
+ */
+ source_cr = cairo_create (source);
+
+ r = priv->h;
+ g = 1.0;
+ b = 1.0;
+ hsv_to_rgb (&r, &g, &b);
+
+ if (INTENSITY (r, g, b) > 0.5)
+ cairo_set_source_rgb (source_cr, 0.0, 0.0, 0.0);
+ else
+ cairo_set_source_rgb (source_cr, 1.0, 1.0, 1.0);
+
+ cairo_move_to (source_cr, center_x, center_y);
+ cairo_line_to (source_cr,
+ center_x + cos (priv->h * 2.0 * G_PI) * priv->size / 2,
+ center_y - sin (priv->h * 2.0 * G_PI) * priv->size / 2);
+ cairo_stroke (source_cr);
+ cairo_destroy (source_cr);
+
+ /* Draw the ring using the source image */
+
+ cairo_save (cr);
+
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_set_line_width (cr, priv->ring_width);
+ cairo_new_path (cr);
+ cairo_arc (cr,
+ center_x, center_y,
+ priv->size / 2.0 - priv->ring_width / 2.0,
+ 0, 2 * G_PI);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ g_free (buf);
+}
+
+/* Converts an HSV triplet to an integer RGB triplet */
+static void
+get_color (gdouble h,
+ gdouble s,
+ gdouble v,
+ gint *r,
+ gint *g,
+ gint *b)
+{
+ hsv_to_rgb (&h, &s, &v);
+
+ *r = floor (h * 255 + 0.5);
+ *g = floor (s * 255 + 0.5);
+ *b = floor (v * 255 + 0.5);
+}
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+#define LERP(a, b, v1, v2, i) (((v2) - (v1) != 0) \
+ ? ((a) + ((b) - (a)) * ((i) - (v1)) / ((v2) - (v1))) \
+ : (a))
+
+/* Number of pixels we extend out from the edges when creating
+ * color source to avoid artifacts
+ */
+#define PAD 3
+
+/* Paints the HSV triangle */
+static void
+paint_triangle (GimpColorWheel *wheel,
+ cairo_t *cr,
+ gboolean draw_focus)
+{
+ GtkWidget *widget = GTK_WIDGET (wheel);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint hx, hy, sx, sy, vx, vy; /* HSV vertices */
+ gint x1, y1, r1, g1, b1; /* First vertex in scanline order */
+ gint x2, y2, r2, g2, b2; /* Second vertex */
+ gint x3, y3, r3, g3, b3; /* Third vertex */
+ gint t;
+ guint32 *buf, *p, c;
+ gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */
+ gint xx, yy;
+ gint x_interp, y_interp;
+ gint x_start, x_end;
+ cairo_surface_t *source;
+ gdouble r, g, b;
+ gint stride;
+ gint width, height;
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *context;
+
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+#else
+ gchar *detail;
+
+ GtkAllocation allocation;
+ gtk_widget_get_allocation (widget, &allocation);
+ width = allocation.width;
+ height = allocation.height;
+#endif
+
+ /* Compute triangle's vertices */
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ x1 = hx;
+ y1 = hy;
+ get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1);
+
+ x2 = sx;
+ y2 = sy;
+ get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2);
+
+ x3 = vx;
+ y3 = vy;
+ get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3);
+
+ if (y2 > y3)
+ {
+ SWAP (x2, x3, t);
+ SWAP (y2, y3, t);
+ SWAP (r2, r3, t);
+ SWAP (g2, g3, t);
+ SWAP (b2, b3, t);
+ }
+
+ if (y1 > y3)
+ {
+ SWAP (x1, x3, t);
+ SWAP (y1, y3, t);
+ SWAP (r1, r3, t);
+ SWAP (g1, g3, t);
+ SWAP (b1, b3, t);
+ }
+
+ if (y1 > y2)
+ {
+ SWAP (x1, x2, t);
+ SWAP (y1, y2, t);
+ SWAP (r1, r2, t);
+ SWAP (g1, g2, t);
+ SWAP (b1, b2, t);
+ }
+
+ /* Shade the triangle */
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
+
+ for (yy = 0; yy < height; yy++)
+ {
+ p = buf + yy * width;
+
+ if (yy >= y1 - PAD && yy < y3 + PAD)
+ {
+ y_interp = CLAMP (yy, y1, y3);
+
+ if (y_interp < y2)
+ {
+ xl = LERP (x1, x2, y1, y2, y_interp);
+
+ rl = LERP (r1, r2, y1, y2, y_interp);
+ gl = LERP (g1, g2, y1, y2, y_interp);
+ bl = LERP (b1, b2, y1, y2, y_interp);
+ }
+ else
+ {
+ xl = LERP (x2, x3, y2, y3, y_interp);
+
+ rl = LERP (r2, r3, y2, y3, y_interp);
+ gl = LERP (g2, g3, y2, y3, y_interp);
+ bl = LERP (b2, b3, y2, y3, y_interp);
+ }
+
+ xr = LERP (x1, x3, y1, y3, y_interp);
+
+ rr = LERP (r1, r3, y1, y3, y_interp);
+ gr = LERP (g1, g3, y1, y3, y_interp);
+ br = LERP (b1, b3, y1, y3, y_interp);
+
+ if (xl > xr)
+ {
+ SWAP (xl, xr, t);
+ SWAP (rl, rr, t);
+ SWAP (gl, gr, t);
+ SWAP (bl, br, t);
+ }
+
+ x_start = MAX (xl - PAD, 0);
+ x_end = MIN (xr + PAD, width);
+ x_start = MIN (x_start, x_end);
+
+ c = (rl << 16) | (gl << 8) | bl;
+
+ for (xx = 0; xx < x_start; xx++)
+ *p++ = c;
+
+ for (; xx < x_end; xx++)
+ {
+ x_interp = CLAMP (xx, xl, xr);
+
+ *p++ = ((LERP (rl, rr, xl, xr, x_interp) << 16) |
+ (LERP (gl, gr, xl, xr, x_interp) << 8) |
+ LERP (bl, br, xl, xr, x_interp));
+ }
+
+ c = (rr << 16) | (gr << 8) | br;
+
+ for (; xx < width; xx++)
+ *p++ = c;
+ }
+ }
+
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
+ CAIRO_FORMAT_RGB24,
+ width, height, stride);
+
+ /* Draw a triangle with the image as a source */
+
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x3, y3);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ g_free (buf);
+
+ /* Draw value marker */
+
+ xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5);
+ yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5);
+
+ r = priv->h;
+ g = priv->s;
+ b = priv->v;
+ hsv_to_rgb (&r, &g, &b);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ context = gtk_widget_get_style_context (widget);
+
+ gtk_style_context_save (context);
+#endif
+
+ if (INTENSITY (r, g, b) > 0.5)
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_add_class (context, "light-area-focus");
+#else
+ detail = "colorwheel_light";
+#endif
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ }
+ else
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_add_class (context, "dark-area-focus");
+#else
+ detail = "colorwheel_dark";
+#endif
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ }
+
+#define RADIUS 4
+#define FOCUS_RADIUS 6
+
+ cairo_new_path (cr);
+ cairo_arc (cr, xx, yy, RADIUS, 0, 2 * G_PI);
+ cairo_stroke (cr);
+
+ /* Draw focus outline */
+
+ if (draw_focus && ! priv->focus_on_ring)
+ {
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_render_focus (context, cr,
+ xx - FOCUS_RADIUS - focus_width - focus_pad,
+ yy - FOCUS_RADIUS - focus_width - focus_pad,
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad),
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad));
+#else
+ gtk_widget_get_allocation (widget, &allocation);
+ gtk_paint_focus (gtk_widget_get_style (widget),
+ gtk_widget_get_window (widget),
+ gtk_widget_get_state (widget),
+ NULL, widget, detail,
+ allocation.x + xx - FOCUS_RADIUS - focus_width - focus_pad,
+ allocation.y + yy - FOCUS_RADIUS - focus_width - focus_pad,
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad),
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad));
+#endif
+ }
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_restore (context);
+#endif
+}
+
+#if GTK_CHECK_VERSION(3,2,0)
+static gboolean
+gimp_color_wheel_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gboolean draw_focus;
+
+ draw_focus = gtk_widget_has_visible_focus (widget);
+
+ paint_ring (wheel, cr);
+ paint_triangle (wheel, cr, draw_focus);
+
+ if (draw_focus && priv->focus_on_ring)
+ {
+ GtkStyleContext *context = gtk_widget_get_style_context (widget);
+
+ gtk_render_focus (context, cr, 0, 0,
+ gtk_widget_get_allocated_width (widget),
+ gtk_widget_get_allocated_height (widget));
+ }
+
+ return FALSE;
+}
+#else
+static gint
+gimp_color_wheel_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gboolean draw_focus;
+ GtkAllocation allocation;
+
+ if (! (event->window == gtk_widget_get_window (widget) &&
+ gtk_widget_is_drawable (widget)))
+ return FALSE;
+
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ cairo_translate (cr, allocation.x, allocation.y);
+
+ draw_focus = gtk_widget_has_focus (widget);
+
+ paint_ring (wheel, cr);
+ paint_triangle (wheel, cr, draw_focus);
+
+ cairo_destroy (cr);
+
+ if (draw_focus && priv->focus_on_ring)
+ gtk_paint_focus (gtk_widget_get_style (widget),
+ gtk_widget_get_window (widget),
+ gtk_widget_get_state (widget),
+ &event->area, widget, NULL,
+ allocation.x,
+ allocation.y,
+ allocation.width,
+ allocation.height);
+
+ return FALSE;
+}
+#endif
+
+static gboolean
+gimp_color_wheel_focus (GtkWidget *widget,
+ GtkDirectionType dir)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ if (!gtk_widget_has_focus (widget))
+ {
+ if (dir == GTK_DIR_TAB_BACKWARD)
+ priv->focus_on_ring = FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+
+ gtk_widget_grab_focus (widget);
+ return TRUE;
+ }
+
+ switch (dir)
+ {
+ case GTK_DIR_UP:
+ if (priv->focus_on_ring)
+ return FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+ break;
+
+ case GTK_DIR_DOWN:
+ if (priv->focus_on_ring)
+ priv->focus_on_ring = FALSE;
+ else
+ return FALSE;
+ break;
+
+ case GTK_DIR_LEFT:
+ case GTK_DIR_TAB_BACKWARD:
+ if (priv->focus_on_ring)
+ return FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+ break;
+
+ case GTK_DIR_RIGHT:
+ case GTK_DIR_TAB_FORWARD:
+ if (priv->focus_on_ring)
+ priv->focus_on_ring = FALSE;
+ else
+ return FALSE;
+ break;
+ }
+
+ gtk_widget_queue_draw (widget);
+
+ return TRUE;
+}
+
+/**
+ * gimp_color_wheel_new:
+ *
+ * Creates a new HSV color selector.
+ *
+ * Return value: A newly-created HSV color selector.
+ *
+ * Since: 2.14
+ */
+GtkWidget*
+gimp_color_wheel_new (void)
+{
+ return g_object_new (GIMP_TYPE_COLOR_WHEEL, NULL);
+}
+
+/**
+ * gimp_color_wheel_set_color:
+ * @hsv: An HSV color selector
+ * @h: Hue
+ * @s: Saturation
+ * @v: Value
+ *
+ * Sets the current color in an HSV color selector.
+ * Color component values must be in the [0.0, 1.0] range.
+ *
+ * Since: 2.14
+ */
+void
+gimp_color_wheel_set_color (GimpColorWheel *wheel,
+ gdouble h,
+ gdouble s,
+ gdouble v)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel));
+ g_return_if_fail (h >= 0.0 && h <= 1.0);
+ g_return_if_fail (s >= 0.0 && s <= 1.0);
+ g_return_if_fail (v >= 0.0 && v <= 1.0);
+
+ priv = wheel->priv;
+
+ priv->h = h;
+ priv->s = s;
+ priv->v = v;
+
+ g_signal_emit (wheel, wheel_signals[CHANGED], 0);
+
+ gtk_widget_queue_draw (GTK_WIDGET (wheel));
+}
+
+/**
+ * gimp_color_wheel_get_color:
+ * @hsv: An HSV color selector
+ * @h: (out): Return value for the hue
+ * @s: (out): Return value for the saturation
+ * @v: (out): Return value for the value
+ *
+ * Queries the current color in an HSV color selector.
+ * Returned values will be in the [0.0, 1.0] range.
+ *
+ * Since: 2.14
+ */
+void
+gimp_color_wheel_get_color (GimpColorWheel *wheel,
+ gdouble *h,
+ gdouble *s,
+ gdouble *v)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel));
+
+ priv = wheel->priv;
+
+ if (h) *h = priv->h;
+ if (s) *s = priv->s;
+ if (v) *v = priv->v;
+}
+
+/**
+ * gimp_color_wheel_set_ring_fraction:
+ * @ring: A wheel color selector
+ * @fraction: Ring fraction
+ *
+ * Sets the ring fraction of a wheel color selector.
+ *
+ * Since: GIMP 2.10
+ */
+void
+gimp_color_wheel_set_ring_fraction (GimpColorWheel *hsv,
+ gdouble fraction)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (hsv));
+
+ priv = hsv->priv;
+
+ priv->ring_fraction = CLAMP (fraction, 0.01, 0.99);
+
+ gtk_widget_queue_draw (GTK_WIDGET (hsv));
+}
+
+/**
+ * gimp_color_wheel_get_ring_fraction:
+ * @ring: A wheel color selector
+ *
+ * Returns value: The ring fraction of the wheel color selector.
+ *
+ * Since: GIMP 2.10
+ */
+gdouble
+gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), DEFAULT_FRACTION);
+
+ priv = wheel->priv;
+
+ return priv->ring_fraction;
+}
+
+/**
+ * gimp_color_wheel_is_adjusting:
+ * @hsv: A #GimpColorWheel
+ *
+ * An HSV color selector can be said to be adjusting if multiple rapid
+ * changes are being made to its value, for example, when the user is
+ * adjusting the value with the mouse. This function queries whether
+ * the HSV color selector is being adjusted or not.
+ *
+ * Return value: %TRUE if clients can ignore changes to the color value,
+ * since they may be transitory, or %FALSE if they should consider
+ * the color value status to be final.
+ *
+ * Since: 2.14
+ */
+gboolean
+gimp_color_wheel_is_adjusting (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), FALSE);
+
+ priv = wheel->priv;
+
+ return priv->mode != DRAG_NONE;
+}
+
+static void
+gimp_color_wheel_move (GimpColorWheel *wheel,
+ GtkDirectionType dir)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble hue, sat, val;
+ gint hx, hy, sx, sy, vx, vy; /* HSV vertices */
+ gint x, y; /* position in triangle */
+
+ hue = priv->h;
+ sat = priv->s;
+ val = priv->v;
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ x = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5);
+ y = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5);
+
+#define HUE_DELTA 0.002
+ switch (dir)
+ {
+ case GTK_DIR_UP:
+ if (priv->focus_on_ring)
+ hue += HUE_DELTA;
+ else
+ {
+ y -= 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_DOWN:
+ if (priv->focus_on_ring)
+ hue -= HUE_DELTA;
+ else
+ {
+ y += 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_LEFT:
+ if (priv->focus_on_ring)
+ hue += HUE_DELTA;
+ else
+ {
+ x -= 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_RIGHT:
+ if (priv->focus_on_ring)
+ hue -= HUE_DELTA
+ ;
+ else
+ {
+ x += 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ default:
+ /* we don't care about the tab directions */
+ break;
+ }
+
+ /* Wrap */
+ if (hue < 0.0)
+ hue = 1.0;
+ else if (hue > 1.0)
+ hue = 0.0;
+
+ gimp_color_wheel_set_color (wheel, hue, sat, val);
+}
diff --git a/src/ui/widget/gimpcolorwheel.h b/src/ui/widget/gimpcolorwheel.h
new file mode 100644
index 000000000..016fb593f
--- /dev/null
+++ b/src/ui/widget/gimpcolorwheel.h
@@ -0,0 +1,95 @@
+/* HSV color selector for GTK+
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
+ * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
+ * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GIMP_COLOR_WHEEL_H__
+#define __GIMP_COLOR_WHEEL_H__
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_COLOR_WHEEL (gimp_color_wheel_get_type ())
+#define GIMP_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheel))
+#define GIMP_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass))
+#define GIMP_IS_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_COLOR_WHEEL))
+#define GIMP_IS_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_WHEEL))
+#define GIMP_COLOR_WHEEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass))
+
+
+typedef struct _GimpColorWheel GimpColorWheel;
+typedef struct _GimpColorWheelClass GimpColorWheelClass;
+
+struct _GimpColorWheel
+{
+ GtkWidget parent_instance;
+
+ /* Private data */
+ gpointer priv;
+};
+
+struct _GimpColorWheelClass
+{
+ GtkWidgetClass parent_class;
+
+ /* Notification signals */
+ void (* changed) (GimpColorWheel *wheel);
+
+ /* Keybindings */
+ void (* move) (GimpColorWheel *wheel,
+ GtkDirectionType type);
+
+ /* Padding for future expansion */
+ void (*_gimp_reserved1) (void);
+ void (*_gimp_reserved2) (void);
+ void (*_gimp_reserved3) (void);
+ void (*_gimp_reserved4) (void);
+};
+
+
+GType gimp_color_wheel_get_type (void) G_GNUC_CONST;
+GtkWidget * gimp_color_wheel_new (void);
+
+void gimp_color_wheel_set_color (GimpColorWheel *wheel,
+ double h,
+ double s,
+ double v);
+void gimp_color_wheel_get_color (GimpColorWheel *wheel,
+ gdouble *h,
+ gdouble *s,
+ gdouble *v);
+
+void gimp_color_wheel_set_ring_fraction (GimpColorWheel *wheel,
+ gdouble fraction);
+gdouble gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel);
+
+gboolean gimp_color_wheel_is_adjusting (GimpColorWheel *wheel);
+
+G_END_DECLS
+
+#endif /* __GIMP_COLOR_WHEEL_H__ */
diff --git a/src/ui/widget/gimpspinscale.c b/src/ui/widget/gimpspinscale.c
new file mode 100644
index 000000000..f9f9a3807
--- /dev/null
+++ b/src/ui/widget/gimpspinscale.c
@@ -0,0 +1,1092 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpspinscale.c
+ * Copyright (C) 2010 Michael Natterer <mitch@gimp.org>
+ * 2012 Øyvind Kolås <pippin@gimp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <math.h>
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gimpspinscale.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_LABEL,
+ PROP_FOCUS_WIDGET
+};
+
+typedef enum
+{
+ TARGET_NUMBER,
+ TARGET_UPPER,
+ TARGET_LOWER
+#if WITH_GTKMM_3_0
+ ,TARGET_NONE
+#endif
+} SpinScaleTarget;
+
+typedef enum
+{
+ APPEARANCE_FULL = 1, /* Full size suitable for tablets */
+ APPEARANCE_COMPACT, /* Compact, suitable for desktops with mouse control */
+} SpinScaleAppearance;
+
+typedef struct _GimpSpinScalePrivate GimpSpinScalePrivate;
+
+struct _GimpSpinScalePrivate
+{
+ gchar *label;
+
+ gboolean scale_limits_set;
+ gdouble scale_lower;
+ gdouble scale_upper;
+ gdouble gamma;
+
+ PangoLayout *layout;
+ gboolean changing_value;
+ gboolean relative_change;
+ gdouble start_x;
+ gdouble start_value;
+
+ GtkWidget* focusWidget;
+ gboolean transferFocus;
+ SpinScaleAppearance appearanceMode;
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ GIMP_TYPE_SPIN_SCALE, \
+ GimpSpinScalePrivate))
+
+
+static void gimp_spin_scale_dispose (GObject *object);
+static void gimp_spin_scale_finalize (GObject *object);
+static void gimp_spin_scale_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_spin_scale_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_spin_scale_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+
+#if WITH_GTKMM_3_0
+static void gimp_spin_scale_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width);
+static void gimp_spin_scale_get_preferred_height (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width);
+static gboolean gimp_spin_scale_draw (GtkWidget *widget,
+ cairo_t *cr);
+#else
+static void gimp_spin_scale_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+
+static gboolean gimp_spin_scale_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+#endif
+
+static gboolean gimp_spin_scale_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_spin_scale_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_spin_scale_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event);
+static gboolean gimp_spin_scale_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event);
+static gboolean gimp_spin_scale_keypress( GtkWidget *widget,
+ GdkEventKey *event);
+
+static void gimp_spin_scale_defocus( GtkSpinButton *spin_button );
+
+static void gimp_spin_scale_value_changed (GtkSpinButton *spin_button);
+
+
+G_DEFINE_TYPE (GimpSpinScale, gimp_spin_scale, GTK_TYPE_SPIN_BUTTON);
+
+#define parent_class gimp_spin_scale_parent_class
+
+
+static void
+gimp_spin_scale_class_init (GimpSpinScaleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkSpinButtonClass *spin_button_class = GTK_SPIN_BUTTON_CLASS (klass);
+
+ object_class->dispose = gimp_spin_scale_dispose;
+ object_class->finalize = gimp_spin_scale_finalize;
+ object_class->set_property = gimp_spin_scale_set_property;
+ object_class->get_property = gimp_spin_scale_get_property;
+
+ widget_class->style_set = gimp_spin_scale_style_set;
+#if WITH_GTKMM_3_0
+ widget_class->get_preferred_width = gimp_spin_scale_get_preferred_width;
+ widget_class->get_preferred_height = gimp_spin_scale_get_preferred_height;
+ widget_class->draw = gimp_spin_scale_draw;
+#else
+ widget_class->size_request = gimp_spin_scale_size_request;
+ widget_class->expose_event = gimp_spin_scale_expose;
+#endif
+ widget_class->button_press_event = gimp_spin_scale_button_press;
+ widget_class->button_release_event = gimp_spin_scale_button_release;
+ widget_class->motion_notify_event = gimp_spin_scale_motion_notify;
+ widget_class->leave_notify_event = gimp_spin_scale_leave_notify;
+ widget_class->key_press_event = gimp_spin_scale_keypress;
+
+ spin_button_class->value_changed = gimp_spin_scale_value_changed;
+
+ g_object_class_install_property (object_class, PROP_LABEL,
+ g_param_spec_string ("label", NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (GimpSpinScalePrivate));
+}
+
+static void
+gimp_spin_scale_init (GimpSpinScale *scale)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (scale);
+
+ gtk_entry_set_alignment (GTK_ENTRY (scale), 1.0);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scale), TRUE);
+
+ private->gamma = 1.0;
+ private->focusWidget = NULL;
+ private->transferFocus = FALSE;
+ private->appearanceMode = APPEARANCE_COMPACT;
+}
+
+static void
+gimp_spin_scale_dispose (GObject *object)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (object);
+
+ if (private->layout)
+ {
+ g_object_unref (private->layout);
+ private->layout = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gimp_spin_scale_finalize (GObject *object)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (object);
+
+ if (private->label)
+ {
+ g_free (private->label);
+ private->label = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_spin_scale_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ g_free (private->label);
+ private->label = g_value_dup_string (value);
+ if (private->layout)
+ {
+ g_object_unref (private->layout);
+ private->layout = NULL;
+ }
+ gtk_widget_queue_resize (GTK_WIDGET (object));
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ {
+ /* TODO unhook prior */
+ private->focusWidget = (GtkWidget*)g_value_get_pointer( value );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_spin_scale_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ g_value_set_string (value, private->label);
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ g_value_set_pointer( value, private->focusWidget );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+void
+gimp_spin_scale_set_focuswidget( GtkWidget *scale, GtkWidget* widget )
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (scale);
+
+ /* TODO unhook prior */
+
+ private->focusWidget = widget;
+}
+
+void
+gimp_spin_scale_set_appearance( GtkWidget *widget, const gchar *appearance)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+
+ if ( strcmp("full", appearance) == 0 ) {
+ private->appearanceMode = APPEARANCE_FULL;
+ } else if ( strcmp("compact", appearance) == 0 ) {
+ private->appearanceMode = APPEARANCE_COMPACT;
+ }
+}
+
+static void
+#if WITH_GTKMM_3_0
+gimp_spin_scale_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+#else
+gimp_spin_scale_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+#endif
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+ GtkStyle *style = gtk_widget_get_style (widget);
+ PangoContext *context = gtk_widget_get_pango_context (widget);
+ PangoFontMetrics *metrics;
+
+#if WITH_GTKMM_3_0
+ GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget,
+ minimum_width,
+ natural_width);
+#else
+ gint height;
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
+#endif
+
+ metrics = pango_context_get_metrics (context, style->font_desc,
+ pango_context_get_language (context));
+
+#if WITH_GTKMM_3_0
+#else
+ height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+ pango_font_metrics_get_descent (metrics));
+
+ if (private->appearanceMode == APPEARANCE_COMPACT) {
+ requisition->height += 1;
+ } else {
+ requisition->height += height;
+ }
+
+#endif
+
+
+ if (private->label)
+ {
+ gint char_width;
+ gint digit_width;
+ gint char_pixels;
+
+ char_width = pango_font_metrics_get_approximate_char_width (metrics);
+ digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
+ char_pixels = PANGO_PIXELS (MAX (char_width, digit_width));
+
+#if WITH_GTKMM_3_0
+ *minimum_width += char_pixels * 3;
+ *natural_width += char_pixels * 3;
+#else
+ /* ~3 chars for the ellipses */
+ requisition->width += char_pixels * 3;
+#endif
+
+ }
+
+ pango_font_metrics_unref (metrics);
+}
+
+#if WITH_GTKMM_3_0
+static void
+gimp_spin_scale_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkStyle *style = gtk_widget_get_style (widget);
+ PangoContext *context = gtk_widget_get_pango_context (widget);
+ PangoFontMetrics *metrics;
+ //gint height;
+
+ GTK_WIDGET_CLASS (parent_class)->get_preferred_height (widget,
+ minimum_height,
+ natural_height);
+
+ metrics = pango_context_get_metrics (context, style->font_desc,
+ pango_context_get_language (context));
+
+ //height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+ // pango_font_metrics_get_descent (metrics));
+
+ *minimum_height += 1;
+ *natural_height += 1;
+
+ pango_font_metrics_unref (metrics);
+}
+#endif
+
+static void
+gimp_spin_scale_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
+
+ if (private->layout)
+ {
+ g_object_unref (private->layout);
+ private->layout = NULL;
+ }
+}
+
+
+static gboolean
+
+#if WITH_GTKMM_3_0
+ gimp_spin_scale_draw (GtkWidget *widget, cairo_t *cr)
+#else
+ gimp_spin_scale_expose (GtkWidget *widget, GdkEventExpose *event)
+#endif
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+
+#if WITH_GTKMM_3_0
+ GtkStyleContext *style = gtk_widget_get_style_context(widget);
+ GtkAllocation allocation;
+ GdkRGBA color;
+
+ cairo_save (cr);
+ GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
+ cairo_restore (cr);
+
+ gtk_widget_get_allocation (widget, &allocation);
+#else
+ GtkStyle *style = gtk_widget_get_style (widget);
+ cairo_t *cr;
+ gint w;
+
+ GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
+
+ cr = gdk_cairo_create (event->window);
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ w = gdk_window_get_width (event->window);
+#endif
+
+ cairo_set_line_width (cr, 1.0);
+
+
+#if WITH_GTKMM_3_0
+ if (private->label)
+ {
+ GdkRectangle text_area;
+ gint minimum_width;
+ gint natural_width;
+#else
+ if (private->label &&
+ gtk_widget_is_drawable (widget) &&
+ event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)))
+ {
+ GtkRequisition requisition;
+ GtkAllocation allocation;
+#endif
+
+ PangoRectangle logical;
+ gint layout_offset_x;
+ gint layout_offset_y;
+
+#if WITH_GTKMM_3_0
+ gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area);
+
+ GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget,
+ &minimum_width,
+ &natural_width);
+#else
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, &requisition);
+ gtk_widget_get_allocation (widget, &allocation);
+#endif
+
+ if (! private->layout)
+ {
+ private->layout = gtk_widget_create_pango_layout (widget,
+ private->label);
+ pango_layout_set_ellipsize (private->layout, PANGO_ELLIPSIZE_END);
+ }
+
+ pango_layout_set_width (private->layout,
+ PANGO_SCALE *
+#if WITH_GTKMM_3_0
+ (allocation.width - minimum_width + 10));
+#else
+ (allocation.width - requisition.width + 10));
+#endif
+ pango_layout_get_pixel_extents (private->layout, NULL, &logical);
+
+ gtk_entry_get_layout_offsets (GTK_ENTRY (widget), NULL, &layout_offset_y);
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+#if WITH_GTKMM_3_0
+ layout_offset_x = text_area.x + text_area.width - logical.width - 4;
+#else
+ layout_offset_x = w - logical.width - 4;
+#endif
+ else
+ layout_offset_x = 4;
+
+ layout_offset_x -= logical.x;
+
+#if WITH_GTKMM_3_0
+ cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3);
+
+ gtk_style_context_get_color (style, gtk_widget_get_state_flags (widget),
+ &color);
+
+ gdk_cairo_set_source_rgba (cr, &color);
+#else
+ cairo_move_to (cr, layout_offset_x, layout_offset_y-3);
+
+ gdk_cairo_set_source_color (cr,
+ &style->text[gtk_widget_get_state (widget)]);
+#endif
+
+ pango_cairo_show_layout (cr, private->layout);
+ }
+
+#if WITH_GTKMM_3_0
+#else
+ cairo_destroy (cr);
+#endif
+
+ return FALSE;
+}
+
+#if WITH_GTKMM_3_0
+/* Returns TRUE if a translation should be done */
+static gboolean
+gtk_widget_get_translation_to_window (GtkWidget *widget,
+ GdkWindow *window,
+ int *x,
+ int *y)
+{
+ GdkWindow *w, *widget_window;
+
+ if (!gtk_widget_get_has_window (widget))
+ {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ *x = -allocation.x;
+ *y = -allocation.y;
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ }
+
+ widget_window = gtk_widget_get_window (widget);
+
+ for (w = window; w && w != widget_window; w = gdk_window_get_parent (w))
+ {
+ int wx, wy;
+ gdk_window_get_position (w, &wx, &wy);
+ *x += wx;
+ *y += wy;
+ }
+
+ if (w == NULL)
+ {
+ *x = 0;
+ *y = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+gimp_spin_scale_event_to_widget_coords (GtkWidget *widget,
+ GdkWindow *window,
+ gdouble event_x,
+ gdouble event_y,
+ gint *widget_x,
+ gint *widget_y)
+{
+ gint tx, ty;
+
+ if (gtk_widget_get_translation_to_window (widget, window, &tx, &ty))
+ {
+ event_x += tx;
+ event_y += ty;
+ }
+
+ *widget_x = event_x;
+ *widget_y = event_y;
+}
+#endif
+
+static SpinScaleTarget
+gimp_spin_scale_get_target (GtkWidget *widget,
+ gdouble x,
+ gdouble y)
+{
+ GtkAllocation allocation;
+ PangoRectangle logical;
+ gint layout_x;
+ gint layout_y;
+
+ gtk_widget_get_allocation (widget, &allocation);
+ gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &layout_x, &layout_y);
+ pango_layout_get_pixel_extents (gtk_entry_get_layout (GTK_ENTRY (widget)),
+ NULL, &logical);
+
+#if WITH_GTKMM_3_0
+ GdkRectangle text_area;
+ gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area);
+
+ if (x >= text_area.x && x < text_area.width &&
+ y >= text_area.y && y < text_area.height)
+ {
+ x -= text_area.x;
+ y -= text_area.y;
+
+ if (x > layout_x && x < layout_x + logical.width &&
+ y > layout_y && y < layout_y + logical.height)
+ {
+ return TARGET_NUMBER;
+ }
+ else if (y > text_area.height / 2)
+ {
+ return TARGET_LOWER;
+ }
+
+ return TARGET_UPPER;
+ }
+
+ return TARGET_NONE;
+#else
+ if (x > layout_x && x < layout_x + logical.width &&
+ y > layout_y && y < layout_y + logical.height)
+ {
+ return TARGET_NUMBER;
+ }
+
+ else if (y > allocation.height / 2)
+ {
+ return TARGET_LOWER;
+ }
+ return TARGET_UPPER;
+#endif
+}
+
+static void
+gimp_spin_scale_get_limits (GimpSpinScale *scale,
+ gdouble *lower,
+ gdouble *upper)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (scale);
+
+ if (private->scale_limits_set)
+ {
+ *lower = private->scale_lower;
+ *upper = private->scale_upper;
+ }
+ else
+ {
+ GtkSpinButton *spin_button = GTK_SPIN_BUTTON (scale);
+ GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button);
+
+ *lower = gtk_adjustment_get_lower (adjustment);
+ *upper = gtk_adjustment_get_upper (adjustment);
+ }
+}
+
+static void
+gimp_spin_scale_change_value (GtkWidget *widget,
+ gdouble x)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+ GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget);
+ GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button);
+ gdouble lower;
+ gdouble upper;
+ gdouble value;
+#if WITH_GTKMM_3_0
+#else
+#endif
+#if WITH_GTKMM_3_0
+ GdkRectangle text_area;
+ gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area);
+ gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (widget), &lower, &upper);
+#else
+ GdkWindow *text_window = gtk_entry_get_text_window (GTK_ENTRY (widget));
+ gint width;
+
+ gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (widget), &lower, &upper);
+
+ width = gdk_window_get_width (text_window);
+#endif
+
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+#if WITH_GTKMM_3_0
+ x = text_area.width - x;
+#else
+ x = width - x;
+#endif
+
+
+ if (private->relative_change)
+ {
+ gdouble diff;
+ gdouble step;
+
+
+#if WITH_GTKMM_3_0
+ step = (upper - lower) / text_area.width / 10.0;
+#else
+ step = (upper - lower) / width / 10.0;
+#endif
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+
+#if WITH_GTKMM_3_0
+ diff = x - (text_area.width - private->start_x);
+#else
+ diff = x - (width - private->start_x);
+#endif
+ else
+ diff = x - private->start_x;
+
+ value = (private->start_value + diff * step);
+ }
+ else
+ {
+ gdouble fraction;
+
+
+#if WITH_GTKMM_3_0
+ fraction = x / (gdouble) text_area.width;
+#else
+ fraction = x / (gdouble) width;
+#endif
+ if (fraction > 0.0)
+ fraction = pow (fraction, private->gamma);
+
+ value = fraction * (upper - lower) + lower;
+ }
+
+ gtk_adjustment_set_value (adjustment, value);
+}
+
+static gboolean
+gimp_spin_scale_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+
+ private->changing_value = FALSE;
+ private->relative_change = FALSE;
+
+#if WITH_GTKMM_3_0
+ gint x, y;
+ gimp_spin_scale_event_to_widget_coords (widget, event->window,
+ event->x, event->y,
+ &x, &y);
+ switch (gimp_spin_scale_get_target (widget, x, y))
+ {
+ case TARGET_UPPER:
+ private->changing_value = TRUE;
+
+ gtk_widget_grab_focus (widget);
+
+ gimp_spin_scale_change_value (widget, x);
+
+ return TRUE;
+
+ case TARGET_LOWER:
+ private->changing_value = TRUE;
+
+ gtk_widget_grab_focus (widget);
+
+ private->relative_change = TRUE;
+ private->start_x = x;
+ private->start_value = gtk_adjustment_get_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)));
+
+ return TRUE;
+
+ default:
+ break;
+ }
+#else
+ if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)))
+ {
+ switch (gimp_spin_scale_get_target (widget, event->x, event->y))
+ {
+ case TARGET_UPPER:
+ private->changing_value = TRUE;
+
+ gtk_widget_grab_focus (widget);
+
+ gimp_spin_scale_change_value (widget, event->x);
+
+ return TRUE;
+
+ case TARGET_LOWER:
+ private->changing_value = TRUE;
+
+ gtk_widget_grab_focus (widget);
+
+ private->relative_change = TRUE;
+ private->start_x = event->x;
+ private->start_value = gtk_adjustment_get_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)));
+
+ return TRUE;
+
+ default:
+ break;
+ }
+ }
+#endif
+
+ return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
+}
+
+static gboolean
+gimp_spin_scale_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+#if WITH_GTKMM_3_0
+ gint x, y;
+
+ gimp_spin_scale_event_to_widget_coords (widget, event->window,
+ event->x, event->y,
+ &x, &y);
+#endif
+
+ if (private->changing_value)
+ {
+ private->changing_value = FALSE;
+#if WITH_GTKMM_3_0
+ gimp_spin_scale_change_value (widget, x);
+#else
+ gimp_spin_scale_change_value (widget, event->x);
+#endif
+ return TRUE;
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
+}
+
+static gboolean
+gimp_spin_scale_motion_notify (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+#if WITH_GTKMM_3_0
+ gint x, y;
+
+ gimp_spin_scale_event_to_widget_coords (widget, event->window,
+ event->x, event->y,
+ &x, &y);
+#endif
+
+ if (private->changing_value)
+ {
+#if WITH_GTKMM_3_0
+ gimp_spin_scale_change_value (widget, x);
+#else
+ gimp_spin_scale_change_value (widget, event->x);
+#endif
+
+ return TRUE;
+ }
+
+ GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
+
+ if (! (event->state &
+ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))
+#if WITH_GTKMM_3_0
+#else
+ && event->window == gtk_entry_get_text_window (GTK_ENTRY (widget))
+#endif
+ )
+ {
+ GdkDisplay *display = gtk_widget_get_display (widget);
+ GdkCursor *cursor = NULL;
+
+#if WITH_GTKMM_3_0
+ switch (gimp_spin_scale_get_target (widget, x, y))
+#else
+ switch (gimp_spin_scale_get_target (widget, event->x, event->y))
+#endif
+ {
+ case TARGET_NUMBER:
+ cursor = gdk_cursor_new_for_display (display, GDK_XTERM);
+ break;
+
+ case TARGET_UPPER:
+ cursor = gdk_cursor_new_for_display (display, GDK_SB_UP_ARROW);
+ break;
+
+ case TARGET_LOWER:
+ cursor = gdk_cursor_new_for_display (display, GDK_SB_H_DOUBLE_ARROW);
+ break;
+
+ default:
+ break;
+ }
+
+
+#if WITH_GTKMM_3_0
+ if (cursor)
+ {
+ gdk_window_set_cursor (event->window, cursor);
+ g_object_unref (cursor);
+ }
+#else
+ gdk_window_set_cursor (event->window, cursor);
+ gdk_cursor_unref (cursor);
+#endif
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_spin_scale_leave_notify (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ gdk_window_set_cursor (event->window, NULL);
+
+ return GTK_WIDGET_CLASS (parent_class)->leave_notify_event (widget, event);
+}
+
+gboolean gimp_spin_scale_keypress( GtkWidget *widget, GdkEventKey *event)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+ guint key = 0;
+ gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ),
+ event->hardware_keycode, (GdkModifierType)event->state,
+ 0, &key, 0, 0, 0 );
+
+ switch ( key ) {
+
+ case GDK_KEY_Escape:
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ {
+ private->transferFocus = TRUE;
+ gimp_spin_scale_defocus( GTK_SPIN_BUTTON(widget) );
+ }
+ break;
+
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+}
+
+static void
+gimp_spin_scale_defocus( GtkSpinButton *spin_button )
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (spin_button);
+
+ if ( private->transferFocus ) {
+ if ( private->focusWidget ) {
+ gtk_widget_grab_focus( private->focusWidget );
+ }
+ }
+}
+
+static void
+gimp_spin_scale_value_changed (GtkSpinButton *spin_button)
+{
+ GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button);
+ GimpSpinScalePrivate *private = GET_PRIVATE (spin_button);
+ gdouble lower;
+ gdouble upper;
+ gdouble value;
+
+ gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (spin_button), &lower, &upper);
+
+ value = CLAMP (gtk_adjustment_get_value (adjustment), lower, upper);
+
+
+ gtk_entry_set_progress_fraction (GTK_ENTRY (spin_button),
+ pow ((value - lower) / (upper - lower),
+ 1.0 / private->gamma));
+
+ // TODO - Allow scrollwheel to change value then return focus,
+ // but clicks/keypress should keep focus in the control
+ //if ( gtk_widget_has_focus( GTK_WIDGET(spin_button) ) ) {
+ // gimp_spin_scale_defocus( spin_button );
+ //}
+}
+
+
+/* public functions */
+
+GtkWidget *
+gimp_spin_scale_new (GtkAdjustment *adjustment,
+ const gchar *label,
+ gint digits)
+{
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
+
+ return g_object_new (GIMP_TYPE_SPIN_SCALE,
+ "adjustment", adjustment,
+ "label", label,
+ "digits", digits,
+ NULL);
+}
+
+void
+gimp_spin_scale_set_scale_limits (GimpSpinScale *scale,
+ gdouble lower,
+ gdouble upper)
+{
+ GimpSpinScalePrivate *private;
+ GtkSpinButton *spin_button;
+ GtkAdjustment *adjustment;
+
+ g_return_if_fail (GIMP_IS_SPIN_SCALE (scale));
+
+ private = GET_PRIVATE (scale);
+ spin_button = GTK_SPIN_BUTTON (scale);
+ adjustment = gtk_spin_button_get_adjustment (spin_button);
+
+ g_return_if_fail (lower >= gtk_adjustment_get_lower (adjustment));
+ g_return_if_fail (upper <= gtk_adjustment_get_upper (adjustment));
+
+ private->scale_limits_set = TRUE;
+ private->scale_lower = lower;
+ private->scale_upper = upper;
+ private->gamma = 1.0;
+
+ gimp_spin_scale_value_changed (spin_button);
+}
+
+void
+gimp_spin_scale_set_gamma (GimpSpinScale *scale,
+ gdouble gamma)
+{
+ GimpSpinScalePrivate *private;
+
+ g_return_if_fail (GIMP_IS_SPIN_SCALE (scale));
+
+ private = GET_PRIVATE (scale);
+
+ private->gamma = gamma;
+
+ gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale));
+}
+
+gdouble
+gimp_spin_scale_get_gamma (GimpSpinScale *scale)
+{
+ GimpSpinScalePrivate *private;
+
+ g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), 1.0);
+
+ private = GET_PRIVATE (scale);
+
+ return private->gamma;
+}
+
+void
+gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale)
+{
+ GimpSpinScalePrivate *private;
+
+ g_return_if_fail (GIMP_IS_SPIN_SCALE (scale));
+
+ private = GET_PRIVATE (scale);
+
+ private->scale_limits_set = FALSE;
+ private->scale_lower = 0.0;
+ private->scale_upper = 0.0;
+
+ gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale));
+}
+
+gboolean
+gimp_spin_scale_get_scale_limits (GimpSpinScale *scale,
+ gdouble *lower,
+ gdouble *upper)
+{
+ GimpSpinScalePrivate *private;
+
+ g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), FALSE);
+
+ private = GET_PRIVATE (scale);
+
+ if (lower)
+ *lower = private->scale_lower;
+
+ if (upper)
+ *upper = private->scale_upper;
+
+ return private->scale_limits_set;
+}
diff --git a/src/ui/widget/gimpspinscale.h b/src/ui/widget/gimpspinscale.h
new file mode 100644
index 000000000..ad63625ac
--- /dev/null
+++ b/src/ui/widget/gimpspinscale.h
@@ -0,0 +1,76 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpspinscale.h
+ * Copyright (C) 2010 Michael Natterer <mitch@gimp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_SPIN_SCALE_H__
+#define __GIMP_SPIN_SCALE_H__
+
+#ifndef WITH_GIMP
+#include <gtk/gtk.h>
+#endif
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_SPIN_SCALE (gimp_spin_scale_get_type ())
+#define GIMP_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScale))
+#define GIMP_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass))
+#define GIMP_IS_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SPIN_SCALE))
+#define GIMP_IS_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SPIN_SCALE))
+#define GIMP_SPIN_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass))
+
+
+typedef struct _GimpSpinScale GimpSpinScale;
+typedef struct _GimpSpinScaleClass GimpSpinScaleClass;
+
+struct _GimpSpinScale
+{
+ GtkSpinButton parent_instance;
+};
+
+struct _GimpSpinScaleClass
+{
+ GtkSpinButtonClass parent_class;
+};
+
+
+GType gimp_spin_scale_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gimp_spin_scale_new (GtkAdjustment *adjustment,
+ const gchar *label,
+ gint digits);
+
+void gimp_spin_scale_set_scale_limits (GimpSpinScale *scale,
+ gdouble lower,
+ gdouble upper);
+void gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale);
+gboolean gimp_spin_scale_get_scale_limits (GimpSpinScale *scale,
+ gdouble *lower,
+ gdouble *upper);
+
+void gimp_spin_scale_set_gamma (GimpSpinScale *scale,
+ gdouble gamma);
+gdouble gimp_spin_scale_get_gamma (GimpSpinScale *scale);
+
+void gimp_spin_scale_set_focuswidget( GtkWidget *scale, GtkWidget* widget );
+
+void gimp_spin_scale_set_appearance( GtkWidget *scale, const gchar *appearance);
+
+G_END_DECLS
+
+#endif /* __GIMP_SPIN_SCALE_H__ */
diff --git a/src/ui/widget/imageicon.cpp b/src/ui/widget/imageicon.cpp
index 567608ef8..1c36dc36e 100644
--- a/src/ui/widget/imageicon.cpp
+++ b/src/ui/widget/imageicon.cpp
@@ -117,7 +117,7 @@ bool ImageIcon::showSvgDocument(const SPDocument *docArg)
viewerGtkmm->show();
pack_start(*viewerGtkmm, TRUE, TRUE, 0);
- //GtkWidget *vbox = (GtkWidget *)gobj();
+ //GtkWidget *vbox = GTK_WIDGET(gobj());
//gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0);
return true;
@@ -306,7 +306,7 @@ void ImageIcon::showBrokenImage(const Glib::ustring &errorMessage)
"</svg>";
//Fill in the template
- char *cErrorMessage = (char *)errorMessage.c_str();
+ char *cErrorMessage = const_cast<char *>(errorMessage.c_str());
gchar *xmlBuffer = g_strdup_printf(xformat, cErrorMessage);
//g_message("%s\n", xmlBuffer);
@@ -375,7 +375,7 @@ bool ImageIcon::show(const Glib::ustring &fileName)
if (!Glib::file_test(fileName, Glib::FILE_TEST_EXISTS))
return false;
- gchar *fName = (gchar *)fileName.c_str();
+ gchar *fName = const_cast<gchar *>(fileName.c_str());
//g_message("fname:%s\n", fName);
diff --git a/src/ui/widget/imageicon.h b/src/ui/widget/imageicon.h
index 803b2f53f..2ea8b8533 100644
--- a/src/ui/widget/imageicon.h
+++ b/src/ui/widget/imageicon.h
@@ -12,9 +12,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <glibmm/ustring.h>
#include <gtkmm/box.h>
-
+#include <glibmm/ustring.h>
class SPDocument;
diff --git a/src/ui/widget/imagetoggler.h b/src/ui/widget/imagetoggler.h
index ca1bfd69d..7b02fa4dc 100644
--- a/src/ui/widget/imagetoggler.h
+++ b/src/ui/widget/imagetoggler.h
@@ -14,9 +14,9 @@
#include "config.h"
#endif
-#include <glibmm/property.h>
#include <gtkmm/cellrendererpixbuf.h>
#include <gtkmm/widget.h>
+#include <glibmm/property.h>
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/labelled.cpp b/src/ui/widget/labelled.cpp
index 2dda941f2..6e3652830 100644
--- a/src/ui/widget/labelled.cpp
+++ b/src/ui/widget/labelled.cpp
@@ -78,6 +78,11 @@ Labelled::setTooltipText(const Glib::ustring &tooltip)
_widget->set_tooltip_text(tooltip);
}
+bool Labelled::on_mnemonic_activate ( bool group_cycling )
+{
+ return _widget->mnemonic_activate ( group_cycling );
+}
+
} // namespace Widget
} // namespace UI
} // namespace Inkscape
diff --git a/src/ui/widget/labelled.h b/src/ui/widget/labelled.h
index 030fd0d93..88eb3ce19 100644
--- a/src/ui/widget/labelled.h
+++ b/src/ui/widget/labelled.h
@@ -56,7 +56,11 @@ public:
void setLabelText(const Glib::ustring &str);
void setTooltipText(const Glib::ustring &tooltip);
+private:
+ virtual bool on_mnemonic_activate( bool group_cycling );
+
protected:
+
Gtk::Widget *_widget;
Gtk::Label *_label;
Gtk::Label *_suffix;
diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp
index c6622627b..7b1a8dbfb 100644
--- a/src/ui/widget/layer-selector.cpp
+++ b/src/ui/widget/layer-selector.cpp
@@ -34,6 +34,7 @@
#include "widgets/icon.h"
#include "widgets/shrink-wrap-button.h"
#include "xml/node-event-vector.h"
+#include "widgets/gradient-vector.h"
namespace Inkscape {
namespace Widgets {
@@ -162,17 +163,6 @@ LayerSelector::~LayerSelector() {
_selection_changed_connection.disconnect();
}
-namespace {
-
-/** Helper function - detaches desktop from selector
- */
-bool detach(LayerSelector *selector) {
- selector->setDesktop(NULL);
- return FALSE;
-}
-
-}
-
/** Sets the desktop for the widget. First disconnects signals
* for the current desktop, then stores the pointer to the
* given \a desktop, and attaches its signals to this one.
@@ -185,7 +175,10 @@ void LayerSelector::setDesktop(SPDesktop *desktop) {
if (_desktop) {
// _desktop_shutdown_connection.disconnect();
- _layer_changed_connection.disconnect();
+ if (_current_layer_changed_connection)
+ _current_layer_changed_connection.disconnect();
+ if (_layers_changed_connection)
+ _layers_changed_connection.disconnect();
// g_signal_handlers_disconnect_by_func(_desktop, (gpointer)&detach, this);
}
_desktop = desktop;
@@ -195,9 +188,13 @@ void LayerSelector::setDesktop(SPDesktop *desktop) {
// sigc::bind (sigc::ptr_fun (detach), this));
// g_signal_connect_after(_desktop, "shutdown", GCallback(detach), this);
- _layer_changed_connection = _desktop->connectCurrentLayerChanged(
- sigc::mem_fun(*this, &LayerSelector::_selectLayer)
- );
+ LayerManager *mgr = _desktop->layer_manager;
+ if ( mgr ) {
+ _current_layer_changed_connection = mgr->connectCurrentLayerChanged( sigc::mem_fun(*this, &LayerSelector::_selectLayer) );
+ //_layerUpdatedConnection = mgr->connectLayerDetailsChanged( sigc::mem_fun(*this, &LayerSelector::_updateLayer) );
+ _layers_changed_connection = mgr->connectChanged( sigc::mem_fun(*this, &LayerSelector::_layersChanged) );
+ }
+
_selectLayer(_desktop->currentLayer());
}
}
@@ -230,6 +227,17 @@ private:
}
+void LayerSelector::_layersChanged()
+{
+ if (_desktop) {
+ /*
+ * This code fixes #166691 but causes issues #1066543 and #1080378.
+ * Comment out until solution found.
+ */
+ //_selectLayer(_desktop->currentLayer());
+ }
+}
+
/** Selects the given layer in the dropdown selector.
*/
void LayerSelector::_selectLayer(SPObject *layer) {
@@ -300,11 +308,13 @@ void LayerSelector::_setDesktopLayer() {
Gtk::ListStore::iterator selected(_selector.get_active());
SPObject *layer=_selector.get_active()->get_value(_model_columns.object);
if ( _desktop && layer ) {
- _layer_changed_connection.block();
+ _current_layer_changed_connection.block();
+ _layers_changed_connection.block();
_desktop->layer_manager->setCurrentLayer(layer);
- _layer_changed_connection.unblock();
+ _current_layer_changed_connection.unblock();
+ _layers_changed_connection.unblock();
_selectLayer(_desktop->currentLayer());
}
@@ -565,7 +575,7 @@ void LayerSelector::_prepareLabelRenderer(
gchar const *label;
if ( object != root ) {
label = object->label();
- if (!label) {
+ if (!object->label()) {
label = object->defaultLabel();
label_defaulted = true;
}
@@ -573,7 +583,7 @@ void LayerSelector::_prepareLabelRenderer(
label = _("(root)");
}
- gchar *text = g_markup_printf_escaped(format, label);
+ gchar *text = g_markup_printf_escaped(format, gr_ellipsize_text (label, 50).c_str());
_label_renderer.property_markup() = text;
g_free(text);
g_free(format);
@@ -585,6 +595,7 @@ void LayerSelector::_prepareLabelRenderer(
_label_renderer.property_style() = ( label_defaulted ?
Pango::STYLE_ITALIC :
Pango::STYLE_NORMAL );
+
}
void LayerSelector::_lockLayer(bool lock) {
diff --git a/src/ui/widget/layer-selector.h b/src/ui/widget/layer-selector.h
index 6fbdc9857..ff9e4ddfc 100644
--- a/src/ui/widget/layer-selector.h
+++ b/src/ui/widget/layer-selector.h
@@ -68,7 +68,8 @@ private:
Glib::RefPtr<Gtk::ListStore> _layer_model;
// sigc::connection _desktop_shutdown_connection;
- sigc::connection _layer_changed_connection;
+ sigc::connection _layers_changed_connection;
+ sigc::connection _current_layer_changed_connection;
sigc::connection _selection_changed_connection;
sigc::connection _visibility_toggled_connection;
sigc::connection _lock_toggled_connection;
@@ -76,6 +77,8 @@ private:
SPObject *_layer;
void _selectLayer(SPObject *layer);
+ void _layersChanged();
+
void _setDesktopLayer();
void _buildEntry(unsigned depth, SPObject &object);
diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp
index 7fff7d87f..c729354cb 100644
--- a/src/ui/widget/licensor.cpp
+++ b/src/ui/widget/licensor.cpp
@@ -44,7 +44,7 @@ const struct rdf_license_t _other_license =
class LicenseItem : public Gtk::RadioButton {
public:
- LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr);
+ LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group);
protected:
void on_toggled();
struct rdf_license_t const *_lic;
@@ -52,13 +52,12 @@ protected:
Registry &_wr;
};
-LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr)
+LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group)
: Gtk::RadioButton(_(license->name)), _lic(license), _eep(entity), _wr(wr)
{
- static Gtk::RadioButtonGroup group = get_group();
- static bool first = true;
- if (first) first = false;
- else set_group (group);
+ if (group) {
+ set_group (*group);
+ }
}
/// \pre it is assumed that the license URI entry is a Gtk::Entry
@@ -80,7 +79,8 @@ void LicenseItem::on_toggled()
//---------------------------------------------------
Licensor::Licensor()
-: Gtk::VBox(false,4)
+: Gtk::VBox(false,4),
+ _eentry (NULL)
{
}
@@ -97,18 +97,19 @@ void Licensor::init (Registry& wr)
LicenseItem *i;
wr.setUpdating (true);
- i = manage (new LicenseItem (&_proprietary_license, _eentry, wr));
+ i = manage (new LicenseItem (&_proprietary_license, _eentry, wr, NULL));
+ Gtk::RadioButtonGroup group = i->get_group();
add (*i);
LicenseItem *pd = i;
for (struct rdf_license_t * license = rdf_licenses;
license && license->name;
license++) {
- i = manage (new LicenseItem (license, _eentry, wr));
+ i = manage (new LicenseItem (license, _eentry, wr, &group));
add(*i);
}
// add Other at the end before the URI field for the confused ppl.
- LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr));
+ LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr, &group));
add (*io);
pd->set_active();
diff --git a/src/ui/widget/notebook-page.cpp b/src/ui/widget/notebook-page.cpp
index 92bcb6937..6653499b8 100644
--- a/src/ui/widget/notebook-page.cpp
+++ b/src/ui/widget/notebook-page.cpp
@@ -9,22 +9,35 @@
* Released under GNU GPL. Read the file 'COPYING' for more information
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "notebook-page.h"
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
namespace Inkscape {
namespace UI {
namespace Widget {
NotebookPage::NotebookPage(int n_rows, int n_columns, bool expand, bool fill, guint padding)
- :_table(n_rows, n_columns)
+#if WITH_GTKMM_3_0
+ :_table(Gtk::manage(new Gtk::Grid()))
+#else
+ :_table(Gtk::manage(new Gtk::Table(n_rows, n_columns)))
+#endif
{
set_border_width(2);
- _table.set_spacings(2);
- pack_start(_table, expand, fill, padding);
+
+#if WITH_GTKMM_3_0
+ _table->set_row_spacing(2);
+ _table->set_column_spacing(2);
+#else
+ _table->set_spacings(2);
+#endif
+
+ pack_start(*_table, expand, fill, padding);
}
} // namespace Widget
diff --git a/src/ui/widget/notebook-page.h b/src/ui/widget/notebook-page.h
index 140b7cb33..d8b8fb0c4 100644
--- a/src/ui/widget/notebook-page.h
+++ b/src/ui/widget/notebook-page.h
@@ -10,8 +10,19 @@
#ifndef INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H
#define INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
+
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
namespace Inkscape {
namespace UI {
@@ -31,10 +42,19 @@ public:
*/
NotebookPage(int n_rows, int n_columns, bool expand=false, bool fill=false, guint padding=0);
- Gtk::Table& table() { return _table; }
+#if WITH_GTKMM_3_0
+ Gtk::Grid& table() { return *_table; }
+#else
+ Gtk::Table& table() { return *_table; }
+#endif
protected:
- Gtk::Table _table;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *_table;
+#else
+ Gtk::Table *_table;
+#endif
};
} // namespace Widget
diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp
index 1cb384501..537db0fdd 100644
--- a/src/ui/widget/object-composite-settings.cpp
+++ b/src/ui/widget/object-composite-settings.cpp
@@ -16,6 +16,7 @@
#include <glibmm/i18n.h>
+#include "desktop.h"
#include "desktop-handles.h"
#include "desktop-style.h"
#include "document.h"
@@ -32,6 +33,7 @@
#include "ui/icon-names.h"
#include "display/sp-canvas.h"
#include "ui/widget/style-subject.h"
+#include "ui/widget/gimpspinscale.h"
namespace Inkscape {
namespace UI {
@@ -62,50 +64,34 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co
_blur_tag(Glib::ustring(history_prefix) + ":blur"),
_opacity_tag(Glib::ustring(history_prefix) + ":opacity"),
_opacity_vbox(false, 0),
- _opacity_label(_("Opacity:")),
- _opacity_label_unit(_("%")),
-#if WITH_GTKMM_3_0
- _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)),
-#else
- _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0),
-#endif
- _opacity_hscale(_opacity_adjustment),
- _opacity_spin_button(_opacity_adjustment, 0.01, 1),
+ _opacity_scale(_("Opacity (%)"), 100.0, 0.0, 100.0, 1.0, 1.0, 1),
_fe_cb(flags),
_fe_vbox(false, 0),
- _fe_alignment(1, 1, 1, 1),
_blocked(false)
{
// Filter Effects
pack_start(_fe_vbox, false, false, 2);
- _fe_alignment.set_padding(0, 0, 4, 0);
- _fe_alignment.add(_fe_cb);
- _fe_vbox.pack_start(_fe_alignment, false, false, 0);
+ _fe_vbox.pack_start(_fe_cb, false, false, 0);
_fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_blendBlurValueChanged));
// Opacity
pack_start(_opacity_vbox, false, false, 2);
- _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
- _opacity_hbox.pack_start(_opacity_label, false, false, 3);
- //_opacity_vbox.pack_start(_opacity_label_box, false, false, 0);
- _opacity_vbox.pack_start(_opacity_hbox, false, false, 0);
- _opacity_hbox.pack_start(_opacity_hscale, true, true, 0);
- _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0);
- _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3);
- _opacity_hscale.set_draw_value(false);
-#if WITH_GTKMM_3_0
- _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged));
- _opacity_label.set_mnemonic_widget(_opacity_hscale);
-#else
- _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged));
- _opacity_label.set_mnemonic_widget(_opacity_hscale);
-#endif
+ _opacity_vbox.pack_start(_opacity_scale);
+
+ _opacity_scale.set_appearance("compact");
+
+ _opacity_scale.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged));
+
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ _opacity_scale.set_focuswidget(GTK_WIDGET(desktop->canvas));
/* SizeGroup keeps the blur and opacity labels aligned in Fill & Stroke dlg */
+/*
GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
- gtk_size_group_add_widget(labels, (GtkWidget *) _opacity_label.gobj());
- gtk_size_group_add_widget(labels, (GtkWidget *) _fe_cb.get_blur_label()->gobj());
+ gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj()));
+ gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj()));
+*/
show_all_children();
@@ -223,11 +209,7 @@ ObjectCompositeSettings::_opacityValueChanged()
SPCSSAttr *css = sp_repr_css_attr_new ();
Inkscape::CSSOStringStream os;
-#if WITH_GTKMM_3_0
- os << CLAMP (_opacity_adjustment->get_value() / 100, 0.0, 1.0);
-#else
- os << CLAMP (_opacity_adjustment.get_value() / 100, 0.0, 1.0);
-#endif
+ os << CLAMP (_opacity_scale.get_adjustment()->get_value() / 100, 0.0, 1.0);
sp_repr_css_set_property (css, "opacity", os.str().c_str());
_subject->setCSS(css);
@@ -263,18 +245,14 @@ ObjectCompositeSettings::_subjectChanged() {
switch (result) {
case QUERY_STYLE_NOTHING:
- _opacity_hbox.set_sensitive(false);
+ _opacity_vbox.set_sensitive(false);
// gtk_widget_set_sensitive (opa, FALSE);
break;
case QUERY_STYLE_SINGLE:
case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently
case QUERY_STYLE_MULTIPLE_SAME:
- _opacity_hbox.set_sensitive(true);
-#if WITH_GTKMM_3_0
- _opacity_adjustment->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value));
-#else
- _opacity_adjustment.set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value));
-#endif
+ _opacity_vbox.set_sensitive(true);
+ _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value));
break;
}
diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h
index 32da626d6..bee9f09b9 100644
--- a/src/ui/widget/object-composite-settings.h
+++ b/src/ui/widget/object-composite-settings.h
@@ -21,8 +21,10 @@
#include "ui/widget/filter-effect-chooser.h"
#include "ui/widget/spinbutton.h"
+class SPDesktop;
+
namespace Inkscape {
-class Application;
+struct Application;
namespace UI {
namespace Widget {
@@ -45,22 +47,12 @@ private:
Glib::ustring _opacity_tag;
Gtk::VBox _opacity_vbox;
- Gtk::HBox _opacity_hbox;
- Gtk::Label _opacity_label;
- Gtk::Label _opacity_label_unit;
-#if WITH_GTKMM_3_0
- Glib::RefPtr<Gtk::Adjustment> _opacity_adjustment;
-#else
- Gtk::Adjustment _opacity_adjustment;
-#endif
- Gtk::HScale _opacity_hscale;
- Inkscape::UI::Widget::SpinButton _opacity_spin_button;
+ Inkscape::UI::Widget::SpinScale _opacity_scale;
StyleSubject *_subject;
SimpleFilterModifier _fe_cb;
Gtk::VBox _fe_vbox;
- Gtk::Alignment _fe_alignment;
bool _blocked;
gulong _desktop_activated;
diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index 90eb6a3fd..fa3f8e3a1 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -245,12 +245,14 @@ PageSizer::PageSizer(Registry & _wr)
_widgetRegistry(&_wr)
{
// set precision of scalar entry boxes
+ _wr.setUpdating (true);
_dimensionWidth.setDigits(5);
_dimensionHeight.setDigits(5);
_marginTop.setDigits(5);
_marginLeft.setDigits(5);
_marginRight.setDigits(5);
_marginBottom.setDigits(5);
+ _wr.setUpdating (false);
//# Set up the Paper Size combo box
_paperSizeListStore = Gtk::ListStore::create(_paperSizeListColumns);
@@ -315,25 +317,49 @@ PageSizer::PageSizer(Registry & _wr)
// Setting default custom unit to document unit
SPDesktop *dt = SP_ACTIVE_DESKTOP;
SPNamedView *nv = sp_desktop_namedview(dt);
+ _wr.setUpdating (true);
if (nv->units) {
_dimensionUnits.setUnit(nv->units);
} else if (nv->doc_units) {
_dimensionUnits.setUnit(nv->doc_units);
}
+ _wr.setUpdating (false);
//## Set up custom size frame
_customFrame.set_label(_("Custom size"));
pack_start (_customFrame, false, false, 0);
_customFrame.add(_customDimTable);
- _customDimTable.resize(3, 2);
_customDimTable.set_border_width(4);
+
+#if WITH_GTKMM_3_0
+ _customDimTable.set_row_spacing(4);
+ _customDimTable.set_column_spacing(4);
+
+ _dimensionWidth.set_hexpand();
+ _dimensionWidth.set_vexpand();
+ _customDimTable.attach(_dimensionWidth, 0, 0, 1, 1);
+
+ _dimensionUnits.set_hexpand();
+ _dimensionUnits.set_vexpand();
+ _customDimTable.attach(_dimensionUnits, 1, 0, 1, 1);
+
+ _dimensionHeight.set_hexpand();
+ _dimensionHeight.set_vexpand();
+ _customDimTable.attach(_dimensionHeight, 0, 1, 1, 1);
+
+ _fitPageMarginExpander.set_hexpand();
+ _fitPageMarginExpander.set_vexpand();
+ _customDimTable.attach(_fitPageMarginExpander, 0, 2, 2, 1);
+#else
+ _customDimTable.resize(3, 2);
_customDimTable.set_row_spacings(4);
_customDimTable.set_col_spacings(4);
_customDimTable.attach(_dimensionWidth, 0,1, 0,1);
_customDimTable.attach(_dimensionUnits, 1,2, 0,1);
_customDimTable.attach(_dimensionHeight, 0,1, 1,2);
_customDimTable.attach(_fitPageMarginExpander, 0,2, 2,3);
+#endif
_dimTabOrderGList = NULL;
_dimTabOrderGList = g_list_append(_dimTabOrderGList, _dimensionWidth.gobj());
@@ -349,7 +375,32 @@ PageSizer::PageSizer(Registry & _wr)
_fitPageMarginExpander.add(_marginTable);
//## Set up margin settings
- _marginTable.resize(4, 2);
+ _marginTable.set_border_width(4);
+
+#if WITH_GTKMM_3_0
+ _marginTable.set_row_spacing(4);
+ _marginTable.set_column_spacing(4);
+
+ _marginTopAlign.set_hexpand();
+ _marginTopAlign.set_vexpand();
+ _marginTable.attach(_marginTopAlign, 0, 0, 2, 1);
+
+ _marginLeftAlign.set_hexpand();
+ _marginLeftAlign.set_vexpand();
+ _marginTable.attach(_marginLeftAlign, 0, 1, 1, 1);
+
+ _marginRightAlign.set_hexpand();
+ _marginRightAlign.set_vexpand();
+ _marginTable.attach(_marginRightAlign, 1, 1, 1, 1);
+
+ _marginBottomAlign.set_hexpand();
+ _marginBottomAlign.set_vexpand();
+ _marginTable.attach(_marginBottomAlign, 0, 2, 2, 1);
+
+ _fitPageButtonAlign.set_hexpand();
+ _fitPageButtonAlign.set_vexpand();
+ _marginTable.attach(_fitPageButtonAlign, 0, 3, 2, 1);
+#else
_marginTable.set_border_width(4);
_marginTable.set_row_spacings(4);
_marginTable.set_col_spacings(4);
@@ -358,6 +409,7 @@ PageSizer::PageSizer(Registry & _wr)
_marginTable.attach(_marginRightAlign, 1,2, 1,2);
_marginTable.attach(_marginBottomAlign, 0,2, 2,3);
_marginTable.attach(_fitPageButtonAlign, 0,2, 3,4);
+#endif
_marginTopAlign.set(0.5, 0.5, 0.0, 1.0);
_marginTopAlign.add(_marginTop);
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index 17fd7b1ea..d1fbb56e0 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -10,6 +10,10 @@
#ifndef INKSCAPE_UI_WIDGET_PAGE_SIZER_H
#define INKSCAPE_UI_WIDGET_PAGE_SIZER_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <stddef.h>
#include "ui/widget/registered-widget.h"
#include <sigc++/sigc++.h>
@@ -21,7 +25,13 @@
#include <gtkmm/frame.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/radiobutton.h>
namespace Inkscape {
@@ -207,7 +217,13 @@ protected:
//### Custom size frame
Gtk::Frame _customFrame;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _customDimTable;
+#else
Gtk::Table _customDimTable;
+#endif
+
RegisteredUnitMenu _dimensionUnits;
RegisteredScalarUnit _dimensionWidth;
RegisteredScalarUnit _dimensionHeight;
@@ -215,7 +231,13 @@ protected:
//### Fit Page options
Gtk::Expander _fitPageMarginExpander;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _marginTable;
+#else
Gtk::Table _marginTable;
+#endif
+
Gtk::Alignment _marginTopAlign;
Gtk::Alignment _marginLeftAlign;
Gtk::Alignment _marginRightAlign;
diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp
index a1ae6a36d..7eb114d0a 100644
--- a/src/ui/widget/panel.cpp
+++ b/src/ui/widget/panel.cpp
@@ -15,8 +15,6 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
-
#include <gtkmm/dialog.h> // for Gtk::RESPONSE_*
#include <gtkmm/menu.h>
#include <gtkmm/stock.h>
@@ -24,6 +22,8 @@
#include <gtkmm/radiomenuitem.h>
#include <gtkmm/separatormenuitem.h>
+#include <glibmm/i18n.h>
+
#include <gtk/gtk.h>
#include "panel.h"
@@ -42,7 +42,8 @@ static const int PANEL_SETTING_SIZE = 0;
static const int PANEL_SETTING_MODE = 1;
static const int PANEL_SETTING_SHAPE = 2;
static const int PANEL_SETTING_WRAP = 3;
-static const int PANEL_SETTING_NEXTFREE = 4;
+static const int PANEL_SETTING_BORDER = 4;
+static const int PANEL_SETTING_NEXTFREE = 5;
void Panel::prep() {
@@ -93,7 +94,7 @@ void Panel::_init()
Glib::ustring tmp("<");
_anchor = SP_ANCHOR_CENTER;
- guint panel_size = 0, panel_mode = 0, panel_ratio = 100;
+ guint panel_size = 0, panel_mode = 0, panel_ratio = 100, panel_border = 0;
bool panel_wrap = 0;
if (!_prefs_path.empty()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -101,6 +102,7 @@ void Panel::_init()
panel_size = prefs->getIntLimited(_prefs_path + "/panel_size", 1, 0, PREVIEW_SIZE_HUGE);
panel_mode = prefs->getIntLimited(_prefs_path + "/panel_mode", 1, 0, 10);
panel_ratio = prefs->getIntLimited(_prefs_path + "/panel_ratio", 100, 0, 500 );
+ panel_border = prefs->getIntLimited(_prefs_path + "/panel_border", BORDER_NONE, 0, 2 );
}
_menu = new Gtk::Menu();
@@ -198,6 +200,42 @@ void Panel::_init()
}
{
+ Glib::ustring widthItemLabel(C_("Swatches", "Border"));
+
+ //TRANSLATORS: Indicates border of colour swatches
+ const gchar *widthLabels[] = {
+ NC_("Swatches border", "None"),
+ NC_("Swatches border", "Solid"),
+ NC_("Swatches border", "Wide"),
+ };
+
+ Gtk::MenuItem *item = manage( new Gtk::MenuItem(widthItemLabel));
+ Gtk::Menu *type_menu = manage(new Gtk::Menu());
+ item->set_submenu(*type_menu);
+ _menu->append(*item);
+
+ Gtk::RadioMenuItem::Group widthGroup;
+
+ guint values[] = {0, 1, 2};
+ guint hot_index = 0;
+ for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) {
+ // Assume all values are in increasing order
+ if ( values[i] <= panel_border ) {
+ hot_index = i;
+ }
+ }
+ for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) {
+ Glib::ustring _label(g_dpgettext2(NULL, "Swatches border", widthLabels[i]));
+ Gtk::RadioMenuItem *_item = manage(new Gtk::RadioMenuItem(widthGroup, _label));
+ type_menu->append(*_item);
+ if ( i <= hot_index ) {
+ _item->set_active(true);
+ }
+ _item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_BORDER, values[i]));
+ }
+ }
+
+ {
//TRANSLATORS: "Wrap" indicates how colour swatches are displayed
Glib::ustring wrap_label(C_("Swatches","Wrap"));
Gtk::CheckMenuItem *check = manage(new Gtk::CheckMenuItem(wrap_label));
@@ -259,6 +297,7 @@ void Panel::_init()
_bounceCall(PANEL_SETTING_MODE, panel_mode);
_bounceCall(PANEL_SETTING_SHAPE, panel_ratio);
_bounceCall(PANEL_SETTING_WRAP, panel_wrap);
+ _bounceCall(PANEL_SETTING_BORDER, panel_border);
}
void Panel::setLabel(Glib::ustring const &label)
@@ -323,7 +362,7 @@ void Panel::present()
void Panel::restorePanelPrefs()
{
- guint panel_size = 0, panel_mode = 0, panel_ratio = 100;
+ guint panel_size = 0, panel_mode = 0, panel_ratio = 100, panel_border = 0;
bool panel_wrap = 0;
if (!_prefs_path.empty()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -331,11 +370,13 @@ void Panel::restorePanelPrefs()
panel_size = prefs->getIntLimited(_prefs_path + "/panel_size", 1, 0, PREVIEW_SIZE_HUGE);
panel_mode = prefs->getIntLimited(_prefs_path + "/panel_mode", 1, 0, 10);
panel_ratio = prefs->getIntLimited(_prefs_path + "/panel_ratio", 000, 0, 500 );
+ panel_border = prefs->getIntLimited(_prefs_path + "/panel_border", BORDER_NONE, 0, 2 );
}
_bounceCall(PANEL_SETTING_SIZE, panel_size);
_bounceCall(PANEL_SETTING_MODE, panel_mode);
_bounceCall(PANEL_SETTING_SHAPE, panel_ratio);
_bounceCall(PANEL_SETTING_WRAP, panel_wrap);
+ _bounceCall(PANEL_SETTING_BORDER, panel_border);
}
sigc::signal<void, int> &Panel::signalResponse()
@@ -360,30 +401,32 @@ void Panel::_bounceCall(int i, int j)
if (_fillable) {
ViewType curr_type = _fillable->getPreviewType();
guint curr_ratio = _fillable->getPreviewRatio();
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
+
switch (j) {
case 0:
{
- _fillable->setStyle(::PREVIEW_SIZE_TINY, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_TINY, curr_type, curr_ratio, curr_border);
}
break;
case 1:
{
- _fillable->setStyle(::PREVIEW_SIZE_SMALL, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_SMALL, curr_type, curr_ratio, curr_border);
}
break;
case 2:
{
- _fillable->setStyle(::PREVIEW_SIZE_MEDIUM, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_MEDIUM, curr_type, curr_ratio, curr_border);
}
break;
case 3:
{
- _fillable->setStyle(::PREVIEW_SIZE_BIG, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_BIG, curr_type, curr_ratio, curr_border);
}
break;
case 4:
{
- _fillable->setStyle(::PREVIEW_SIZE_HUGE, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_HUGE, curr_type, curr_ratio, curr_border);
}
break;
default:
@@ -399,15 +442,16 @@ void Panel::_bounceCall(int i, int j)
if (_fillable) {
::PreviewSize curr_size = _fillable->getPreviewSize();
guint curr_ratio = _fillable->getPreviewRatio();
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
switch (j) {
case 0:
{
- _fillable->setStyle(curr_size, VIEW_TYPE_LIST, curr_ratio);
+ _fillable->setStyle(curr_size, VIEW_TYPE_LIST, curr_ratio, curr_border);
}
break;
case 1:
{
- _fillable->setStyle(curr_size, VIEW_TYPE_GRID, curr_ratio);
+ _fillable->setStyle(curr_size, VIEW_TYPE_GRID, curr_ratio, curr_border);
}
break;
default:
@@ -423,7 +467,40 @@ void Panel::_bounceCall(int i, int j)
if ( _fillable ) {
ViewType curr_type = _fillable->getPreviewType();
::PreviewSize curr_size = _fillable->getPreviewSize();
- _fillable->setStyle(curr_size, curr_type, j);
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
+
+ _fillable->setStyle(curr_size, curr_type, j, curr_border);
+ }
+ break;
+ case PANEL_SETTING_BORDER:
+ if (!_prefs_path.empty()) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt(_prefs_path + "/panel_border", j);
+ }
+ if ( _fillable ) {
+ ::PreviewSize curr_size = _fillable->getPreviewSize();
+ ViewType curr_type = _fillable->getPreviewType();
+ guint curr_ratio = _fillable->getPreviewRatio();
+
+ switch (j) {
+ case 0:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_NONE);
+ }
+ break;
+ case 1:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_SOLID);
+ }
+ break;
+ case 2:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_WIDE);
+ }
+ break;
+ default:
+ break;
+ }
}
break;
case PANEL_SETTING_WRAP:
@@ -483,6 +560,7 @@ void Panel::_regItem(Gtk::MenuItem* item, int group, int id)
_menu->append(*item);
item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), group + PANEL_SETTING_NEXTFREE, id));
item->show();
+
}
void Panel::_handleAction(int /*set_id*/, int /*item_id*/)
@@ -495,31 +573,41 @@ void Panel::_apply()
g_warning("Apply button clicked for panel [Panel::_apply()]");
}
-Gtk::Button *Panel::addResponseButton(const Glib::ustring &button_text, int response_id)
+Gtk::Button *Panel::addResponseButton(const Glib::ustring &button_text, int response_id, bool pack_start)
{
Gtk::Button *button = new Gtk::Button(button_text);
- _addResponseButton(button, response_id);
+ _addResponseButton(button, response_id, pack_start);
return button;
}
-Gtk::Button *Panel::addResponseButton(const Gtk::StockID &stock_id, int response_id)
+Gtk::Button *Panel::addResponseButton(const Gtk::StockID &stock_id, int response_id, bool pack_start)
{
Gtk::Button *button = new Gtk::Button(stock_id);
- _addResponseButton(button, response_id);
+ _addResponseButton(button, response_id, pack_start);
return button;
}
-void Panel::_addResponseButton(Gtk::Button *button, int response_id)
+void Panel::_addResponseButton(Gtk::Button *button, int response_id, bool pack_start)
{
// Create a button box for the response buttons if it's the first button to be added
if (!_action_area) {
+#if WITH_GTKMM_3_0
+ _action_area = new Gtk::ButtonBox();
+ _action_area->set_layout(Gtk::BUTTONBOX_END);
+ _action_area->set_spacing(6);
+#else
_action_area = new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 6);
+#endif
_action_area->set_border_width(4);
pack_end(*_action_area, Gtk::PACK_SHRINK, 0);
}
_action_area->pack_end(*button);
+ if (pack_start) {
+ _action_area->set_child_secondary( *button , true);
+ }
+
if (response_id != 0) {
// Re-emit clicked signals as response signals
button->signal_clicked().connect(sigc::bind(_signal_response.make_slot(), response_id));
diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h
index 2d92d65c9..5bb054577 100644
--- a/src/ui/widget/panel.h
+++ b/src/ui/widget/panel.h
@@ -13,6 +13,10 @@
#ifndef SEEN_INKSCAPE_UI_WIDGET_PANEL_H
#define SEEN_INKSCAPE_UI_WIDGET_PANEL_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/arrow.h>
#include <gtkmm/button.h>
@@ -27,7 +31,13 @@ class SPDocument;
namespace Gtk {
class CheckMenuItem;
+
+#if WITH_GTKMM_3_0
+ class ButtonBox;
+#else
class HButtonBox;
+#endif
+
class MenuItem;
}
@@ -96,8 +106,8 @@ public:
/* Methods providing a Gtk::Dialog like interface for adding buttons that emit Gtk::RESPONSE
* signals on click. */
- Gtk::Button* addResponseButton (const Glib::ustring &button_text, int response_id);
- Gtk::Button* addResponseButton (const Gtk::StockID &stock_id, int response_id);
+ Gtk::Button* addResponseButton (const Glib::ustring &button_text, int response_id, bool pack_start=false);
+ Gtk::Button* addResponseButton (const Gtk::StockID &stock_id, int response_id, bool pack_start=false);
void setDefaultResponse(int response_id);
void setResponseSensitive(int response_id, bool setting);
@@ -119,7 +129,7 @@ protected:
virtual void _handleResponse(int response_id);
/* Helper methods */
- void _addResponseButton(Gtk::Button *button, int response_id);
+ void _addResponseButton(Gtk::Button *button, int response_id, bool pack_start=false);
Inkscape::Selection *_getSelection();
/**
@@ -157,7 +167,13 @@ private:
Gtk::EventBox _menu_popper;
Gtk::Button _close_button;
Gtk::Menu *_menu;
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *_action_area; //< stores response buttons
+#else
Gtk::HButtonBox *_action_area; //< stores response buttons
+#endif
+
std::vector<Gtk::Widget *> _non_horizontal;
std::vector<Gtk::Widget *> _non_vertical;
PreviewFillable *_fillable;
diff --git a/src/ui/widget/point.h b/src/ui/widget/point.h
index 15f1a80fb..17078df8f 100644
--- a/src/ui/widget/point.h
+++ b/src/ui/widget/point.h
@@ -13,8 +13,8 @@
#ifndef INKSCAPE_UI_WIDGET_POINT_H
#define INKSCAPE_UI_WIDGET_POINT_H
-#include <2geom/point.h>
#include "ui/widget/labelled.h"
+#include <2geom/point.h>
#include "ui/widget/scalar.h"
namespace Gtk {
diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp
index 8ce7c63db..d32de6871 100644
--- a/src/ui/widget/preferences-widget.cpp
+++ b/src/ui/widget/preferences-widget.cpp
@@ -21,7 +21,9 @@
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
#include <gtkmm/alignment.h>
+#include <gtkmm/scale.h>
#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
#include "preferences.h"
#include "ui/widget/preferences-widget.h"
@@ -39,6 +41,8 @@
#include "selection-chemistry.h"
#include "ui/dialog/filedialog.h"
#include "xml/repr.h"
+
+#include <glibmm/convert.h>
#include <glibmm/i18n.h>
using namespace Inkscape::UI::Widget;
@@ -49,86 +53,139 @@ namespace Widget {
DialogPage::DialogPage()
{
- this->set_border_width(12);
- this->set_col_spacings(12);
- this->set_row_spacings(6);
+ set_border_width(12);
+
+#if WITH_GTKMM_3_0
+ set_orientation(Gtk::ORIENTATION_VERTICAL);
+ set_column_spacing(12);
+ set_row_spacing(6);
+#else
+ set_col_spacings(12);
+ set_row_spacings(6);
+#endif
}
-void DialogPage::add_line(bool indent, Glib::ustring const &label, Gtk::Widget &widget, Glib::ustring const &suffix, const Glib::ustring &tip, bool expand_widget)
+/**
+ * Add a widget to the bottom row of the dialog page
+ *
+ * \param[in] indent Whether the widget should be indented by one column
+ * \param[in] label The label text for the widget
+ * \param[in] widget The widget to add to the page
+ * \param[in] suffix Text for an optional label at the right of the widget
+ * \param[in] tip Tooltip text for the widget
+ * \param[in] expand_widget Whether to expand the widget horizontally
+ * \param[in] other_widget An optional additional widget to display at the right of the first one
+ */
+void DialogPage::add_line(bool indent,
+ Glib::ustring const &label,
+ Gtk::Widget &widget,
+ Glib::ustring const &suffix,
+ const Glib::ustring &tip,
+ bool expand_widget,
+ Gtk::Widget *other_widget)
{
- int start_col;
- int row = this->property_n_rows();
- Gtk::Widget* w;
- if (expand_widget)
- {
- w = &widget;
- }
- else
- {
- Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
- hb->set_spacing(12);
- hb->pack_start(widget,false,false);
- w = (Gtk::Widget*) hb;
- }
+ if (tip != "")
+ widget.set_tooltip_text (tip);
+
+ Gtk::Alignment* label_alignment = Gtk::manage(new Gtk::Alignment());
+
+ Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
+ hb->set_spacing(12);
+ hb->pack_start(widget, expand_widget, expand_widget);
+
+ // Pack an additional widget into a box with the widget if desired
+ if (other_widget)
+ hb->pack_start(*other_widget, expand_widget, expand_widget);
+
+ // Pack the widget into an alignment container so that it can
+ // be indented if desired
+ Gtk::Alignment* w_alignment = Gtk::manage(new Gtk::Alignment());
+ w_alignment->add(*hb);
+
+#if WITH_GTKMM_3_0
+ w_alignment->set_valign(Gtk::ALIGN_CENTER);
+#else
+ guint row = property_n_rows();
+#endif
+
+ // Add a label in the first column if provided
if (label != "")
{
- Gtk::Label* label_widget;
- label_widget = Gtk::manage(new Gtk::Label(label , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
+ Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START,
+ Gtk::ALIGN_CENTER, true));
label_widget->set_mnemonic_widget(widget);
+
+ // Pack the label into an alignment container so that we can indent it
+ // if necessary
+ label_alignment->add(*label_widget);
+
if (indent)
- {
- Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
- alignment->set_padding(0, 0, 12, 0);
- alignment->add(*label_widget);
- this->attach(*alignment , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- }
- else
- this->attach(*label_widget , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- start_col = 1;
- }
- else
- start_col = 0;
+ label_alignment->set_padding(0, 0, 12, 0);
- if (start_col == 0 && indent) //indent this widget
- {
- Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
- alignment->set_padding(0, 0, 12, 0);
- alignment->add(*w);
- this->attach(*alignment, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
+#if WITH_GTKMM_3_0
+ label_alignment->set_valign(Gtk::ALIGN_CENTER);
+ add(*label_alignment);
+ attach_next_to(*w_alignment, *label_alignment, Gtk::POS_RIGHT, 1, 1);
+#else
+ attach(*label_alignment, 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
+#endif
}
- else
+
+ // Now add the widget to the bottom of the dialog
+#if WITH_GTKMM_3_0
+ if (label == "")
{
- this->attach(*w, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
+ if (indent)
+ w_alignment->set_padding(0, 0, 12, 0);
+
+ add(*w_alignment);
+
+ GValue width = G_VALUE_INIT;
+ g_value_init(&width, G_TYPE_INT);
+ g_value_set_int(&width, 2);
+ gtk_container_child_set_property(GTK_CONTAINER(gobj()), GTK_WIDGET(w_alignment->gobj()), "width", &width);
}
+#else
+ // The widget should span two columns if there is no label
+ int w_col_span = 1;
+ if (label == "")
+ w_col_span = 2;
+
+ attach(*w_alignment, 2 - w_col_span, 2, row, row + 1,
+ Gtk::FILL | Gtk::EXPAND,
+ Gtk::AttachOptions(),
+ 0, 0);
+#endif
+ // Add a label on the right of the widget if desired
if (suffix != "")
{
Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
- if (expand_widget)
- this->attach(*suffix_widget, 2, 3, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- else
- ((Gtk::HBox*)w)->pack_start(*suffix_widget,false,false);
- }
-
- if (tip != "")
- {
- widget.set_tooltip_text (tip);
+ hb->pack_start(*suffix_widget,false,false);
}
}
void DialogPage::add_group_header(Glib::ustring name)
{
- int row = this->property_n_rows();
if (name != "")
{
Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(Glib::ustring(/*"<span size='large'>*/"<b>") + name +
Glib::ustring("</b>"/*</span>"*/) , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
label_widget->set_use_markup(true);
- this->attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_widget->set_valign(Gtk::ALIGN_CENTER);
+ add(*label_widget);
+// if (row != 1)
+ // set_row_spacing(row - 1, 18);
+#else
+ int row = property_n_rows();
+ attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
if (row != 1)
- this->set_row_spacing(row - 1, 18);
+ set_row_spacing(row - 1, 18);
+#endif
}
}
@@ -369,17 +426,29 @@ ZoomCorrRuler::draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int maj
}
}
-void
-ZoomCorrRuler::redraw() {
+#if !WITH_GTKMM_3_0
+bool
+ZoomCorrRuler::on_expose_event(GdkEventExpose *event) {
+ bool result = false;
+
+ if(get_is_drawable())
+ {
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
+ cr->rectangle(event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cr->clip();
+ result = on_draw(cr);
+ }
+
+ return result;
+}
+#endif
+
+bool
+ZoomCorrRuler::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
Glib::RefPtr<Gdk::Window> window = get_window();
- Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
-#if WITH_GTKMM_2_24
int w = window->get_width();
-#else
- int w, h;
- window->get_size(w, h);
-#endif
_drawing_width = w - _border * 2;
cr->set_source_rgb(1.0, 1.0, 1.0);
@@ -416,14 +485,11 @@ ZoomCorrRuler::redraw() {
draw_marks(cr, 1, 1);
}
cr->stroke();
-}
-bool
-ZoomCorrRuler::on_expose_event(GdkEventExpose */*event*/) {
- this->redraw();
return true;
}
+
void
ZoomCorrRulerSlider::on_slider_value_changed()
{
@@ -431,9 +497,9 @@ ZoomCorrRulerSlider::on_slider_value_changed()
{
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setDouble("/options/zoomcorrection/value", _slider.get_value() / 100.0);
- _sb.set_value(_slider.get_value());
- _ruler.redraw();
+ prefs->setDouble("/options/zoomcorrection/value", _slider->get_value() / 100.0);
+ _sb.set_value(_slider->get_value());
+ _ruler.queue_draw();
freeze = false;
}
}
@@ -446,8 +512,8 @@ ZoomCorrRulerSlider::on_spinbutton_value_changed()
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble("/options/zoomcorrection/value", _sb.get_value() / 100.0);
- _slider.set_value(_sb.get_value());
- _ruler.redraw();
+ _slider->set_value(_sb.get_value());
+ _ruler.queue_draw();
freeze = false;
}
}
@@ -464,10 +530,16 @@ ZoomCorrRulerSlider::on_unit_changed() {
double conv = _unit.getConversion(_unit.getUnitAbbr(), "px");
_ruler.set_unit_conversion(conv);
if (_ruler.get_visible()) {
- _ruler.redraw();
+ _ruler.queue_draw();
}
}
+bool ZoomCorrRulerSlider::on_mnemonic_activate ( bool group_cycling )
+{
+ return _sb.mnemonic_activate ( group_cycling );
+}
+
+
void
ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, double upper,
double step_increment, double page_increment, double default_value)
@@ -479,13 +551,19 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl
_ruler.set_size(ruler_width, ruler_height);
- _slider.set_size_request(_ruler.width(), -1);
- _slider.set_range (lower, upper);
- _slider.set_increments (step_increment, page_increment);
- _slider.set_value (value);
- _slider.set_digits(2);
+#if WITH_GTKMM_3_0
+ _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+#else
+ _slider = Gtk::manage(new Gtk::HScale());
+#endif
+
+ _slider->set_size_request(_ruler.width(), -1);
+ _slider->set_range (lower, upper);
+ _slider->set_increments (step_increment, page_increment);
+ _slider->set_value (value);
+ _slider->set_digits(2);
- _slider.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed));
+ _slider->signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed));
_sb.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_spinbutton_value_changed));
_unit.signal_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_unit_changed));
@@ -499,18 +577,28 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl
_unit.set_data("sensitive", GINT_TO_POINTER(1));
_unit.setUnit(prefs->getString("/options/zoomcorrection/unit"));
- Gtk::Table *table = Gtk::manage(new Gtk::Table());
Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
alignment1->add(_sb);
alignment2->add(_unit);
- table->attach(_slider, 0, 1, 0, 1);
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = Gtk::manage(new Gtk::Grid());
+ table->attach(*_slider, 0, 0, 1, 1);
+ alignment1->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment1, 1, 0, 1, 1);
+ table->attach(_ruler, 0, 1, 1, 1);
+ alignment2->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment2, 1, 1, 1, 1);
+#else
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ table->attach(*_slider, 0, 1, 0, 1);
table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
table->attach(_ruler, 0, 1, 1, 2);
table->attach(*alignment2, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0));
+#endif
- this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
+ pack_start(*table, Gtk::PACK_SHRINK);
}
void
@@ -520,8 +608,8 @@ PrefSlider::on_slider_value_changed()
{
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setDouble(_prefs_path, _slider.get_value());
- _sb.set_value(_slider.get_value());
+ prefs->setDouble(_prefs_path, _slider->get_value());
+ _sb.set_value(_slider->get_value());
freeze = false;
}
}
@@ -534,11 +622,16 @@ PrefSlider::on_spinbutton_value_changed()
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble(_prefs_path, _sb.get_value());
- _slider.set_value(_sb.get_value());
+ _slider->set_value(_sb.get_value());
freeze = false;
}
}
+bool PrefSlider::on_mnemonic_activate ( bool group_cycling )
+{
+ return _sb.mnemonic_activate ( group_cycling );
+}
+
void
PrefSlider::init(Glib::ustring const &prefs_path,
double lower, double upper, double step_increment, double page_increment, double default_value, int digits)
@@ -550,11 +643,17 @@ PrefSlider::init(Glib::ustring const &prefs_path,
freeze = false;
- _slider.set_range (lower, upper);
- _slider.set_increments (step_increment, page_increment);
- _slider.set_value (value);
- _slider.set_digits(digits);
- _slider.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed));
+#if WITH_GTKMM_3_0
+ _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+#else
+ _slider = Gtk::manage(new Gtk::HScale());
+#endif
+
+ _slider->set_range (lower, upper);
+ _slider->set_increments (step_increment, page_increment);
+ _slider->set_value (value);
+ _slider->set_digits(digits);
+ _slider->signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed));
_sb.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_spinbutton_value_changed));
_sb.set_range (lower, upper);
@@ -562,12 +661,20 @@ PrefSlider::init(Glib::ustring const &prefs_path,
_sb.set_value (value);
_sb.set_digits(digits);
- Gtk::Table *table = Gtk::manage(new Gtk::Table());
Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
alignment1->add(_sb);
- table->attach(_slider, 0, 1, 0, 1);
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = Gtk::manage(new Gtk::Grid());
+ _slider->set_hexpand();
+ table->attach(*_slider, 0, 0, 1, 1);
+ alignment1->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment1, 1, 0, 1, 1);
+#else
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ table->attach(*_slider, 0, 1, 0, 1);
table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
+#endif
this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
}
@@ -582,11 +689,7 @@ void PrefCombo::init(Glib::ustring const &prefs_path,
for (int i = 0 ; i < num_items; ++i)
{
-#if WITH_GTKMM_2_24
this->append(labels[i]);
-#else
- this->append_text(labels[i]);
-#endif
_values.push_back(values[i]);
if (value == values[i])
row = i;
@@ -608,11 +711,7 @@ void PrefCombo::init(Glib::ustring const &prefs_path,
for (int i = 0 ; i < num_items; ++i)
{
-#if WITH_GTKMM_2_24
this->append(labels[i]);
-#else
- this->append_text(labels[i]);
-#endif
_ustr_values.push_back(values[i]);
if (value == values[i])
row = i;
@@ -625,7 +724,7 @@ void PrefCombo::on_changed()
if (this->get_visible()) //only take action if user changed value
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if(_values.size() > 0)
+ if(!_values.empty())
{
prefs->setInt(_prefs_path, _values[this->get_active_row_number()]);
}
@@ -674,6 +773,11 @@ void PrefEntryButtonHBox::onRelatedButtonClickedCallback()
}
}
+bool PrefEntryButtonHBox::on_mnemonic_activate ( bool group_cycling )
+{
+ return relatedEntry->mnemonic_activate ( group_cycling );
+}
+
void PrefEntryFileButtonHBox::init(Glib::ustring const &prefs_path,
bool visibility)
{
@@ -806,6 +910,11 @@ void PrefEntryFileButtonHBox::onRelatedButtonClickedCallback()
}
}
+bool PrefEntryFileButtonHBox::on_mnemonic_activate ( bool group_cycling )
+{
+ return relatedEntry->mnemonic_activate ( group_cycling );
+}
+
void PrefFileButton::init(Glib::ustring const &prefs_path)
{
_prefs_path = prefs_path;
diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h
index 874e0958a..e3968045d 100644
--- a/src/ui/widget/preferences-widget.h
+++ b/src/ui/widget/preferences-widget.h
@@ -25,14 +25,26 @@
#include <gtkmm/radiobutton.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/drawingarea.h>
-#include <gtkmm/scale.h>
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
#include <gtkmm/table.h>
+#endif
#include "ui/widget/color-picker.h"
#include "ui/widget/unit-menu.h"
#include "ui/widget/spinbutton.h"
#include "ui/widget/scalar-unit.h"
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
+}
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -101,8 +113,6 @@ public:
ZoomCorrRuler(int width = 100, int height = 20);
void set_size(int x, int y);
void set_unit_conversion(double conv) { _unitconv = conv; }
- void set_cairo_context(Cairo::RefPtr<Cairo::Context> cr);
- void redraw();
int width() { return _min_width + _border*2; }
@@ -110,7 +120,12 @@ public:
static const double textpadding;
private:
+#if !WITH_GTKMM_3_0
bool on_expose_event(GdkEventExpose *event);
+#endif
+
+ bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
+
void draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int major_interval);
double _unitconv;
@@ -130,10 +145,15 @@ private:
void on_slider_value_changed();
void on_spinbutton_value_changed();
void on_unit_changed();
+ virtual bool on_mnemonic_activate( bool group_cycling );
Inkscape::UI::Widget::SpinButton _sb;
UnitMenu _unit;
- Gtk::HScale _slider;
+#if WITH_GTKMM_3_0
+ Gtk::Scale* _slider;
+#else
+ Gtk::HScale* _slider;
+#endif
ZoomCorrRuler _ruler;
bool freeze; // used to block recursive updates of slider and spinbutton
};
@@ -147,10 +167,17 @@ public:
private:
void on_slider_value_changed();
void on_spinbutton_value_changed();
-
+ virtual bool on_mnemonic_activate( bool group_cycling );
+
Glib::ustring _prefs_path;
Inkscape::UI::Widget::SpinButton _sb;
- Gtk::HScale _slider;
+
+#if WITH_GTKMM_3_0
+ Gtk::Scale* _slider;
+#else
+ Gtk::HScale* _slider;
+#endif
+
bool freeze; // used to block recursive updates of slider and spinbutton
};
@@ -188,6 +215,7 @@ class PrefEntryButtonHBox : public Gtk::HBox
public:
void init(Glib::ustring const &prefs_path,
bool mask, Glib::ustring const &default_string);
+
protected:
Glib::ustring _prefs_path;
Glib::ustring _default_string;
@@ -195,6 +223,7 @@ protected:
Gtk::Entry *relatedEntry;
void onRelatedEntryChangedCallback();
void onRelatedButtonClickedCallback();
+ virtual bool on_mnemonic_activate( bool group_cycling );
};
class PrefEntryFileButtonHBox : public Gtk::HBox
@@ -208,6 +237,7 @@ protected:
Gtk::Entry *relatedEntry;
void onRelatedEntryChangedCallback();
void onRelatedButtonClickedCallback();
+ virtual bool on_mnemonic_activate( bool group_cycling );
};
class PrefFileButton : public Gtk::FileChooserButton
@@ -243,11 +273,15 @@ protected:
void on_changed();
};
+#if WITH_GTKMM_3_0
+class DialogPage : public Gtk::Grid
+#else
class DialogPage : public Gtk::Table
+#endif
{
public:
DialogPage();
- void add_line(bool indent, Glib::ustring const &label, Gtk::Widget& widget, Glib::ustring const &suffix, Glib::ustring const &tip, bool expand = true);
+ void add_line(bool indent, Glib::ustring const &label, Gtk::Widget& widget, Glib::ustring const &suffix, Glib::ustring const &tip, bool expand = true, Gtk::Widget *other_widget = NULL);
void add_group_header(Glib::ustring name);
void set_tip(Gtk::Widget &widget, Glib::ustring const &tip);
};
diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h
index 2a7843a51..fa35b815e 100644
--- a/src/ui/widget/registered-widget.h
+++ b/src/ui/widget/registered-widget.h
@@ -32,7 +32,7 @@
#include <gtkmm/checkbutton.h>
-class SPUnit;
+struct SPUnit;
class SPDocument;
namespace Gtk {
diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp
index 7655f25e3..f26e71553 100644
--- a/src/ui/widget/rendering-options.cpp
+++ b/src/ui/widget/rendering-options.cpp
@@ -12,10 +12,9 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
-
-#include "unit-constants.h"
#include "rendering-options.h"
+#include "unit-constants.h"
+#include <glibmm/i18n.h>
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp
index 7be666843..1d91515e5 100644
--- a/src/ui/widget/rotateable.cpp
+++ b/src/ui/widget/rotateable.cpp
@@ -24,12 +24,15 @@ Rotateable::Rotateable():
{
dragging = false;
working = false;
+ scrolling = false;
modifier = 0;
current_axis = axis;
signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click));
signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion));
signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release));
+ signal_scroll_event().connect(sigc::mem_fun(*this, &Rotateable::on_scroll));
+
}
bool Rotateable::on_click(GdkEventButton *event) {
@@ -124,6 +127,34 @@ bool Rotateable::on_release(GdkEventButton *event) {
return false;
}
+bool Rotateable::on_scroll(GdkEventScroll* event)
+{
+ double change = 0.0;
+
+ if (event->direction == GDK_SCROLL_UP) {
+ change = 1.0;
+ } else if (event->direction == GDK_SCROLL_DOWN) {
+ change = -1.0;
+ } else {
+ return FALSE;
+ }
+
+ drag_started_x = event->x;
+ drag_started_y = event->y;
+ modifier = get_single_modifier(modifier, event->state);
+ dragging = false;
+ working = false;
+ scrolling = true;
+ current_axis = axis;
+
+ do_scroll(change, modifier);
+
+ dragging = false;
+ working = false;
+ scrolling = false;
+
+ return TRUE;
+}
Rotateable::~Rotateable() {
}
diff --git a/src/ui/widget/rotateable.h b/src/ui/widget/rotateable.h
index 15e0bf71c..52fb5306c 100644
--- a/src/ui/widget/rotateable.h
+++ b/src/ui/widget/rotateable.h
@@ -31,10 +31,12 @@ public:
bool on_click(GdkEventButton *event);
bool on_motion(GdkEventMotion *event);
bool on_release(GdkEventButton *event);
+ bool on_scroll(GdkEventScroll* event);
double axis;
double current_axis;
double maxdecl;
+ bool scrolling;
private:
double drag_started_x;
@@ -47,6 +49,7 @@ private:
virtual void do_motion (double /*by*/, guint /*state*/) {}
virtual void do_release (double /*by*/, guint /*state*/) {}
+ virtual void do_scroll (double /*by*/, guint /*state*/) {}
};
} // namespace Widget
diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp
index 9bbcc80f9..fca8a7974 100644
--- a/src/ui/widget/scalar.cpp
+++ b/src/ui/widget/scalar.cpp
@@ -142,7 +142,7 @@ void Scalar::update()
void Scalar::addSlider()
{
#if WITH_GTKMM_3_0
- Gtk::HScale *scale = new Gtk::HScale(static_cast<SpinButton*>(_widget)->get_adjustment());
+ Gtk::Scale *scale = new Gtk::Scale(static_cast<SpinButton*>(_widget)->get_adjustment());
#else
Gtk::HScale *scale = new Gtk::HScale( * static_cast<SpinButton*>(_widget)->get_adjustment() );
#endif
diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
index a37f36eea..18dbb984b 100644
--- a/src/ui/widget/selected-style.cpp
+++ b/src/ui/widget/selected-style.cpp
@@ -23,6 +23,7 @@
#include "desktop-handles.h"
#include "style.h"
#include "desktop-style.h"
+#include "sp-namedview.h"
#include "sp-linear-gradient-fns.h"
#include "sp-radial-gradient-fns.h"
#include "sp-pattern.h"
@@ -38,7 +39,6 @@
#include "sp-gradient.h"
#include "svg/svg-color.h"
#include "svg/css-ostringstream.h"
-#include "helper/units.h"
#include "event-context.h"
#include "message-context.h"
#include "verbs.h"
@@ -47,7 +47,9 @@
#include "pixmaps/cursor-adj-h.xpm"
#include "pixmaps/cursor-adj-s.xpm"
#include "pixmaps/cursor-adj-l.xpm"
+#include "pixmaps/cursor-adj-a.xpm"
#include "sp-cursor.h"
+#include "gradient-chemistry.h"
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"};
@@ -117,8 +119,11 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
current_stroke_width(0),
_desktop (NULL),
-
+#if WITH_GTKMM_3_0
+ _table(),
+#else
_table(2, 6),
+#endif
_fill_label (_("Fill:")),
_stroke_label (_("Stroke:")),
_opacity_label (_("O:")),
@@ -143,10 +148,7 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_blocked (false),
- _popup_px(_sw_group),
- _popup_pt(_sw_group),
- _popup_mm(_sw_group),
-
+ _unit_mis(NULL),
_sw_unit(NULL)
{
_drop[0] = _drop[1] = 0;
@@ -159,8 +161,13 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_label.set_alignment(0.0, 0.5);
_opacity_label.set_padding(0, 0);
+#if WITH_GTKMM_3_0
+ _table.set_column_spacing(2);
+ _table.set_row_spacing(0);
+#else
_table.set_col_spacings (2);
_table.set_row_spacings (0);
+#endif
for (int i = SS_FILL; i <= SS_STROKE; i++) {
@@ -297,34 +304,39 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
}
{
- _popup_px.add(*(new Gtk::Label(_("px"), 0.0, 0.5)));
- _popup_px.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_px));
- _popup_sw.attach(_popup_px, 0,1, 0,1);
-
- _popup_pt.add(*(new Gtk::Label(_("pt"), 0.0, 0.5)));
- _popup_pt.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_pt));
- _popup_sw.attach(_popup_pt, 0,1, 1,2);
-
- _popup_mm.add(*(new Gtk::Label(_("mm"), 0.0, 0.5)));
- _popup_mm.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_mm));
- _popup_sw.attach(_popup_mm, 0,1, 2,3);
+ 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);
+ Gtk::RadioMenuItem *mi = Gtk::manage(new Gtk::RadioMenuItem(_sw_group));
+ mi->add(*(new Gtk::Label(u->abbr, 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));
+ _popup_sw.attach(*mi, 0,1, row, row+1);
+ row++;
+ }
- _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, 3,4);
+ _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, row, row+1);
+ row++;
for (guint i = 0; i < G_N_ELEMENTS(_sw_presets_str); ++i) {
Gtk::MenuItem *mi = Gtk::manage(new Gtk::MenuItem());
mi->add(*(new Gtk::Label(_sw_presets_str[i], 0.0, 0.5)));
mi->signal_activate().connect(sigc::bind<int>(sigc::mem_fun(*this, &SelectedStyle::on_popup_preset), i));
- _popup_sw.attach(*mi, 0,1, 4+i, 5+i);
+ _popup_sw.attach(*mi, 0,1, row, row+1);
+ row++;
}
- guint i = G_N_ELEMENTS(_sw_presets_str) + 5;
-
- _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, i,i+1);
+ _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, row, row+1);
+ row++;
_popup_sw_remove.add(*(new Gtk::Label(_("Remove"), 0.0, 0.5)));
_popup_sw_remove.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_remove));
- _popup_sw.attach(_popup_sw_remove, 0,1, i+1,i+2);
+ _popup_sw.attach(_popup_sw_remove, 0,1, row, row+1);
+ row++;
+
+ sp_set_font_size_smaller (GTK_WIDGET(_popup_sw.gobj()));
_popup_sw.show_all();
}
@@ -335,6 +347,7 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
_stroke_width_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
+
_opacity_sb.signal_populate_popup().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_menu));
_opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed));
// Connect to key-press to ensure focus is consistent with other spin buttons when using the keys vs mouse-click
@@ -356,6 +369,16 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_sb.set_size_request (SELECTED_STYLE_SB_WIDTH, -1);
_opacity_sb.set_sensitive (false);
+#if WITH_GTKMM_3_0
+ _table.attach(_fill_label, 0, 0, 1, 1);
+ _table.attach(_stroke_label, 0, 1, 1, 1);
+
+ _table.attach(_fill_flag_place, 1, 0, 1, 1);
+ _table.attach(_stroke_flag_place, 1, 1, 1, 1);
+
+ _table.attach(_fill_place, 2, 0, 1, 1);
+ _table.attach(_stroke, 2, 1, 1, 1);
+#else
_table.attach(_fill_label, 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
_table.attach(_stroke_label, 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
@@ -364,10 +387,17 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_table.attach(_fill_place, 2,3, 0,1);
_table.attach(_stroke, 2,3, 1,2);
+#endif
_opacity_place.add(_opacity_label);
+
+#if WITH_GTKMM_3_0
+ _table.attach(_opacity_place, 4, 0, 1, 2);
+ _table.attach(_opacity_sb, 5, 0, 1, 2);
+#else
_table.attach(_opacity_place, 4,5, 0,2, Gtk::SHRINK, Gtk::SHRINK);
_table.attach(_opacity_sb, 5,6, 0,2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
pack_start(_table, true, true, 2);
@@ -446,7 +476,17 @@ SelectedStyle::setDesktop(SPDesktop *desktop)
this )
));
- //_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units;
+ _sw_unit = const_cast<SPUnit*>(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)) {
+ mi->set_active();
+ break;
+ }
+ }
}
void SelectedStyle::dragDataReceived( GtkWidget */*widget*/,
@@ -598,6 +638,12 @@ void SelectedStyle::on_fill_invert() {
SPCSSAttr *css = sp_repr_css_attr_new ();
guint32 color = _thisselected[SS_FILL];
gchar c[64];
+ if (_mode[SS_FILL] == SS_LGRADIENT || _mode[SS_FILL] == SS_RGRADIENT) {
+ sp_gradient_invert_selected_gradients(_desktop, Inkscape::FOR_FILL);
+ return;
+
+ }
+
if (_mode[SS_FILL] != SS_COLOR) return;
sp_svg_write_color (c, sizeof(c),
SP_RGBA32_U_COMPOSE(
@@ -618,6 +664,10 @@ void SelectedStyle::on_stroke_invert() {
SPCSSAttr *css = sp_repr_css_attr_new ();
guint32 color = _thisselected[SS_STROKE];
gchar c[64];
+ if (_mode[SS_STROKE] == SS_LGRADIENT || _mode[SS_STROKE] == SS_RGRADIENT) {
+ sp_gradient_invert_selected_gradients(_desktop, Inkscape::FOR_STROKE);
+ return;
+ }
if (_mode[SS_STROKE] != SS_COLOR) return;
sp_svg_write_color (c, sizeof(c),
SP_RGBA32_U_COMPOSE(
@@ -876,16 +926,8 @@ SelectedStyle::on_opacity_click(GdkEventButton *event)
return false;
}
-void SelectedStyle::on_popup_px() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PX));
- update();
-}
-void SelectedStyle::on_popup_pt() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PT));
- update();
-}
-void SelectedStyle::on_popup_mm() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_MM));
+void SelectedStyle::on_popup_units(SPUnitId id) {
+ _sw_unit = (SPUnit *) &(sp_unit_get_by_id(id));
update();
}
@@ -971,13 +1013,13 @@ SelectedStyle::update()
if (SP_IS_LINEARGRADIENT (server)) {
SPGradient *vector = SP_GRADIENT(server)->getVector();
- sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_l[i], vector);
+ sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_l[i]), vector);
place->add(_gradient_box_l[i]);
place->set_tooltip_text(__lgradient[i]);
_mode[i] = SS_LGRADIENT;
} else if (SP_IS_RADIALGRADIENT (server)) {
SPGradient *vector = SP_GRADIENT(server)->getVector();
- sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_r[i], vector);
+ sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_r[i]), vector);
place->add(_gradient_box_r[i]);
place->set_tooltip_text(__rgradient[i]);
_mode[i] = SS_RGRADIENT;
@@ -993,7 +1035,7 @@ SelectedStyle::update()
guint32 color = paint->value.color.toRGBA32(
SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value));
_lastselected[i] = _thisselected[i];
- _thisselected[i] = color | 0xff; // only color, opacity === 1
+ _thisselected[i] = color; // include opacity
((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color);
_color_preview[i]->show_all();
place->add(*_color_preview[i]);
@@ -1196,39 +1238,43 @@ RotateableSwatch::~RotateableSwatch() {
}
double
-RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier)
+RotateableSwatch::color_adjust(float *hsla, double by, guint32 cc, guint modifier)
{
- sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc));
-
+ sp_color_rgb_to_hsl_floatv (hsla, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc));
+ hsla[3] = SP_RGBA32_A_F(cc);
double diff = 0;
if (modifier == 2) { // saturation
- double old = hsl[1];
+ double old = hsla[1];
if (by > 0) {
- hsl[1] += by * (1 - hsl[1]);
+ hsla[1] += by * (1 - hsla[1]);
} else {
- hsl[1] += by * (hsl[1]);
+ hsla[1] += by * (hsla[1]);
}
- diff = hsl[1] - old;
+ diff = hsla[1] - old;
} else if (modifier == 1) { // lightness
- double old = hsl[2];
+ double old = hsla[2];
if (by > 0) {
- hsl[2] += by * (1 - hsl[2]);
+ hsla[2] += by * (1 - hsla[2]);
} else {
- hsl[2] += by * (hsl[2]);
+ hsla[2] += by * (hsla[2]);
}
- diff = hsl[2] - old;
+ diff = hsla[2] - old;
+ } else if (modifier == 3) { // alpha
+ double old = hsla[3];
+ hsla[3] += by/2;
+ diff = hsla[3] - old;
} else { // hue
- double old = hsl[0];
- hsl[0] += by/2;
- while (hsl[0] < 0)
- hsl[0] += 1;
- while (hsl[0] > 1)
- hsl[0] -= 1;
- diff = hsl[0] - old;
+ double old = hsla[0];
+ hsla[0] += by/2;
+ while (hsla[0] < 0)
+ hsla[0] += 1;
+ while (hsla[0] > 1)
+ hsla[0] -= 1;
+ diff = hsla[0] - old;
}
float rgb[3];
- sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]);
+ sp_color_hsl_to_rgb_floatv (rgb, hsla[0], hsla[1], hsla[2]);
gchar c[64];
sp_svg_write_color (c, sizeof(c),
@@ -1241,10 +1287,14 @@ RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier
);
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (fillstroke == SS_FILL)
- sp_repr_css_set_property (css, "fill", c);
- else
- sp_repr_css_set_property (css, "stroke", c);
+
+ if (modifier == 3) { // alpha
+ Inkscape::CSSOStringStream osalpha;
+ osalpha << hsla[3];
+ sp_repr_css_set_property(css, (fillstroke == SS_FILL) ? "fill-opacity" : "stroke-opacity", osalpha.str().c_str());
+ } else {
+ sp_repr_css_set_property (css, (fillstroke == SS_FILL) ? "fill" : "stroke", c);
+ }
sp_desktop_set_style (parent->getDesktop(), css);
sp_repr_css_attr_unref (css);
return diff;
@@ -1255,7 +1305,7 @@ RotateableSwatch::do_motion(double by, guint modifier) {
if (parent->_mode[fillstroke] != SS_COLOR)
return;
- if (!cr_set && modifier != 3) {
+ if (!scrolling && !cr_set) {
GtkWidget *w = GTK_WIDGET(gobj());
GdkPixbuf *pixbuf = NULL;
@@ -1263,6 +1313,8 @@ RotateableSwatch::do_motion(double by, guint modifier) {
pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_s_xpm);
} else if (modifier == 1) { // lightness
pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_l_xpm);
+ } else if (modifier == 3) { // alpha
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_a_xpm);
} else { // hue
pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_h_xpm);
}
@@ -1290,43 +1342,51 @@ RotateableSwatch::do_motion(double by, guint modifier) {
cc = startcolor;
}
- float hsl[3];
+ float hsla[4];
double diff = 0;
- if (modifier != 3) {
- diff = color_adjust(hsl, by, cc, modifier);
- }
- if (modifier == 3) { // Alt, do nothing
+ diff = color_adjust(hsla, by, cc, modifier);
+
+ if (modifier == 3) { // alpha
+ DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
+ SP_VERB_DIALOG_FILL_STROKE, (_("Adjust alpha")));
+ double ch = hsla[3];
+ parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>alpha</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff);
} else if (modifier == 2) { // saturation
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation")));
- double ch = hsl[1];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, without modifiers to adjust hue"), ch - diff, ch, diff);
+ double ch = hsla[1];
+ parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff);
} else if (modifier == 1) { // lightness
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness")));
- double ch = hsl[2];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff);
+ double ch = hsla[2];
+ parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff);
} else { // hue
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue")));
- double ch = hsl[0];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff);
+ double ch = hsla[0];
+ parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff);
}
}
+
+void
+RotateableSwatch::do_scroll(double by, guint modifier) {
+ do_motion(by/30.0, modifier);
+ do_release(by/30.0, modifier);
+}
+
void
RotateableSwatch::do_release(double by, guint modifier) {
if (parent->_mode[fillstroke] != SS_COLOR)
return;
- float hsl[3];
- if (modifier != 3) {
- color_adjust(hsl, by, startcolor, modifier);
- }
+ float hsla[4];
+ color_adjust(hsla, by, startcolor, modifier);
if (cr_set) {
GtkWidget *w = GTK_WIDGET(gobj());
@@ -1342,7 +1402,9 @@ RotateableSwatch::do_release(double by, guint modifier) {
cr_set = false;
}
- if (modifier == 3) { // Alt, do nothing
+ if (modifier == 3) { // alpha
+ DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
+ SP_VERB_DIALOG_FILL_STROKE, ("Adjust alpha"));
} else if (modifier == 2) { // saturation
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation"));
@@ -1452,6 +1514,11 @@ RotateableStrokeWidth::do_release(double by, guint modifier) {
parent->getDesktop()->event_context->_message_context->clear();
}
+void
+RotateableStrokeWidth::do_scroll(double by, guint modifier) {
+ do_motion(by/10.0, modifier);
+ startvalue_set = false;
+}
Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop)
{
diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h
index 542983b53..9b78cb17f 100644
--- a/src/ui/widget/selected-style.h
+++ b/src/ui/widget/selected-style.h
@@ -11,8 +11,18 @@
#ifndef INKSCAPE_UI_CURRENT_STYLE_H
#define INKSCAPE_UI_CURRENT_STYLE_H
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/label.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/enums.h>
@@ -27,9 +37,10 @@
#include <sigc++/sigc++.h>
#include "rotateable.h"
+#include "helper/units.h"
class SPDesktop;
-class SPUnit;
+struct SPUnit;
namespace Inkscape {
namespace UI {
@@ -60,8 +71,10 @@ public:
~RotateableSwatch();
double color_adjust (float *hsl, double by, guint32 cc, guint state);
+
virtual void do_motion (double by, guint state);
virtual void do_release (double by, guint state);
+ virtual void do_scroll (double by, guint state);
private:
guint fillstroke;
@@ -86,6 +99,7 @@ public:
double value_adjust(double current, double by, guint modifier, bool final);
virtual void do_motion (double by, guint state);
virtual void do_release (double by, guint state);
+ virtual void do_scroll (double by, guint state);
private:
SelectedStyle *parent;
@@ -123,7 +137,11 @@ public:
protected:
SPDesktop *_desktop;
+#if WITH_GTKMM_3_0
+ Gtk::Grid _table;
+#else
Gtk::Table _table;
+#endif
Gtk::Label _fill_label;
Gtk::Label _stroke_label;
@@ -250,12 +268,8 @@ protected:
Gtk::Menu _popup_sw;
Gtk::RadioButtonGroup _sw_group;
- Gtk::RadioMenuItem _popup_px;
- void on_popup_px();
- Gtk::RadioMenuItem _popup_pt;
- void on_popup_pt();
- Gtk::RadioMenuItem _popup_mm;
- void on_popup_mm();
+ GSList *_unit_mis;
+ void on_popup_units(SPUnitId id);
void on_popup_preset(int i);
Gtk::MenuItem _popup_sw_remove;
diff --git a/src/ui/widget/spin-scale.cpp b/src/ui/widget/spin-scale.cpp
new file mode 100644
index 000000000..548e9a6a6
--- /dev/null
+++ b/src/ui/widget/spin-scale.cpp
@@ -0,0 +1,246 @@
+/*
+ * Author:
+ *
+ * Copyright (C) 2012 Author
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#include <gtkmm/adjustment.h>
+#include <glibmm/i18n.h>
+#include <glibmm/stringutils.h>
+
+#include "spin-scale.h"
+#include "ui/widget/gimpspinscale.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+SpinScale::SpinScale(const char* label, double value, double lower, double upper, double step_inc,
+ double /*climb_rate*/, int digits, const SPAttributeEnum a, const char* tip_text)
+ : AttrWidget(a, value)
+{
+#if WITH_GTKMM_3_0
+ _adjustment = Gtk::Adjustment::create(value, lower, upper, step_inc);
+ _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits);
+#else
+ _adjustment = new Gtk::Adjustment(value, lower, upper, step_inc);
+ _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits);
+#endif
+
+ signal_value_changed().connect(signal_attr_changed().make_slot());
+
+ pack_start(*Gtk::manage(Glib::wrap(_spinscale)));
+
+ if (tip_text){
+ gtk_widget_set_tooltip_text( _spinscale, tip_text );
+ }
+
+ show_all_children();
+}
+
+SpinScale::SpinScale(const char* label,
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> adj,
+#else
+ Gtk::Adjustment *adj,
+#endif
+ int digits, const SPAttributeEnum a, const char* tip_text)
+ : AttrWidget(a, 0.0),
+ _adjustment(adj)
+
+{
+
+ _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits);
+
+ signal_value_changed().connect(signal_attr_changed().make_slot());
+
+ pack_start(*Gtk::manage(Glib::wrap(_spinscale)));
+
+ if (tip_text){
+ gtk_widget_set_tooltip_text( _spinscale, tip_text );
+ }
+
+ show_all_children();
+}
+
+Glib::ustring SpinScale::get_as_attribute() const
+{
+ const double val = _adjustment->get_value();
+
+ //if(_spin.get_digits() == 0)
+ // return Glib::Ascii::dtostr((int)val);
+ //else
+ return Glib::Ascii::dtostr(val);
+}
+
+void SpinScale::set_from_attribute(SPObject* o)
+{
+ const gchar* val = attribute_value(o);
+ if(val)
+ _adjustment->set_value(Glib::Ascii::strtod(val));
+ else
+ _adjustment->set_value(get_default()->as_double());
+}
+
+Glib::SignalProxy0<void> SpinScale::signal_value_changed()
+{
+ return _adjustment->signal_value_changed();
+}
+
+double SpinScale::get_value() const
+{
+ return _adjustment->get_value();
+}
+
+void SpinScale::set_value(const double val)
+{
+ _adjustment->set_value(val);
+}
+
+void SpinScale::set_focuswidget(GtkWidget *widget)
+{
+ gimp_spin_scale_set_focuswidget(_spinscale, widget);
+}
+
+
+void SpinScale::set_appearance(const gchar* appearance)
+{
+ gimp_spin_scale_set_appearance(_spinscale, appearance);
+}
+
+#if WITH_GTKMM_3_0
+const Glib::RefPtr<Gtk::Adjustment> SpinScale::get_adjustment() const
+#else
+const Gtk::Adjustment *SpinScale::get_adjustment() const
+#endif
+{
+ return _adjustment;
+}
+#if WITH_GTKMM_3_0
+Glib::RefPtr<Gtk::Adjustment> SpinScale::get_adjustment()
+#else
+Gtk::Adjustment *SpinScale::get_adjustment()
+#endif
+{
+ return _adjustment;
+}
+
+
+DualSpinScale::DualSpinScale(const char* label1, const char* label2, double value, double lower, double upper, double step_inc,
+ double climb_rate, int digits, const SPAttributeEnum a, char* tip_text1, char* tip_text2)
+ : AttrWidget(a),
+ _s1(label1, value, lower, upper, step_inc, climb_rate, digits, SP_ATTR_INVALID, tip_text1),
+ _s2(label2, value, lower, upper, step_inc, climb_rate, digits, SP_ATTR_INVALID, tip_text2),
+ //TRANSLATORS: "Link" means to _link_ two sliders together
+ _link(C_("Sliders", "Link"))
+{
+ signal_value_changed().connect(signal_attr_changed().make_slot());
+
+ _s1.get_adjustment()->signal_value_changed().connect(_signal_value_changed.make_slot());
+ _s2.get_adjustment()->signal_value_changed().connect(_signal_value_changed.make_slot());
+ _s1.get_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &DualSpinScale::update_linked));
+
+ _link.signal_toggled().connect(sigc::mem_fun(*this, &DualSpinScale::link_toggled));
+
+ Gtk::VBox* vb = Gtk::manage(new Gtk::VBox);
+ vb->add(_s1);
+ vb->add(_s2);
+ pack_start(*vb);
+ pack_start(_link, false, false);
+ _link.set_active(true);
+
+ show_all();
+}
+
+Glib::ustring DualSpinScale::get_as_attribute() const
+{
+ if(_link.get_active())
+ return _s1.get_as_attribute();
+ else
+ return _s1.get_as_attribute() + " " + _s2.get_as_attribute();
+}
+
+void DualSpinScale::set_from_attribute(SPObject* o)
+{
+ const gchar* val = attribute_value(o);
+ if(val) {
+ // Split val into parts
+ gchar** toks = g_strsplit(val, " ", 2);
+
+ if(toks) {
+ double v1 = 0.0, v2 = 0.0;
+ if(toks[0])
+ v1 = v2 = Glib::Ascii::strtod(toks[0]);
+ if(toks[1])
+ v2 = Glib::Ascii::strtod(toks[1]);
+
+ _link.set_active(toks[1] == 0);
+
+ _s1.get_adjustment()->set_value(v1);
+ _s2.get_adjustment()->set_value(v2);
+
+ g_strfreev(toks);
+ }
+ }
+}
+
+sigc::signal<void>& DualSpinScale::signal_value_changed()
+{
+ return _signal_value_changed;
+}
+
+const SpinScale& DualSpinScale::get_SpinScale1() const
+{
+ return _s1;
+}
+
+SpinScale& DualSpinScale::get_SpinScale1()
+{
+ return _s1;
+}
+
+const SpinScale& DualSpinScale::get_SpinScale2() const
+{
+ return _s2;
+}
+
+SpinScale& DualSpinScale::get_SpinScale2()
+{
+ return _s2;
+}
+
+/*void DualSpinScale::remove_scale()
+{
+ _s1.remove_scale();
+ _s2.remove_scale();
+}*/
+
+void DualSpinScale::link_toggled()
+{
+ _s2.set_sensitive(!_link.get_active());
+ update_linked();
+}
+
+void DualSpinScale::update_linked()
+{
+ if(_link.get_active())
+ _s2.set_value(_s1.get_value());
+}
+
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/spin-scale.h b/src/ui/widget/spin-scale.h
new file mode 100644
index 000000000..a8403307f
--- /dev/null
+++ b/src/ui/widget/spin-scale.h
@@ -0,0 +1,117 @@
+/*
+ * Author:
+ *
+ * Copyright (C) 2012 Author
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_SPIN_SCALE_H
+#define INKSCAPE_UI_WIDGET_SPIN_SCALE_H
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/togglebutton.h>
+#include "spinbutton.h"
+#include "attr-widget.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/**
+ * Wrap the gimpspinscale class
+ * A combo widget with label, scale slider, spinbutton and adjustment
+ */
+class SpinScale : public Gtk::HBox, public AttrWidget
+{
+
+public:
+ SpinScale(const char* label, double value, double lower, double upper, double step_inc, double climb_rate,
+ int digits, const SPAttributeEnum a = SP_ATTR_INVALID, const char* tip_text = NULL);
+
+ SpinScale(const char* label,
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> adj,
+#else
+ Gtk::Adjustment *adj,
+#endif
+ int digits, const SPAttributeEnum a = SP_ATTR_INVALID, const char* tip_text = NULL);
+
+ virtual Glib::ustring get_as_attribute() const;
+ virtual void set_from_attribute(SPObject*);
+
+ // Shortcuts to _adjustment
+ Glib::SignalProxy0<void> signal_value_changed();
+ double get_value() const;
+ void set_value(const double);
+ void set_focuswidget(GtkWidget *widget);
+ void set_appearance(const gchar* appearance);
+
+#if WITH_GTKMM_3_0
+ const Glib::RefPtr<Gtk::Adjustment> get_adjustment() const;
+ Glib::RefPtr<Gtk::Adjustment> get_adjustment();
+#else
+ const Gtk::Adjustment *get_adjustment() const;
+ Gtk::Adjustment *get_adjustment();
+#endif
+
+private:
+#if WITH_GTKMM_3_0
+ Glib::RefPtr<Gtk::Adjustment> _adjustment;
+#else
+ Gtk::Adjustment *_adjustment;
+#endif
+
+ GtkWidget *_spinscale;
+};
+
+
+/**
+ * Contains two SpinScales for controlling number-opt-number attributes.
+ *
+ * @see SpinScale
+ */
+class DualSpinScale : public Gtk::HBox, public AttrWidget
+{
+public:
+ DualSpinScale(const char* label1, const char* label2, double value, double lower, double upper, double step_inc,
+ double climb_rate, int digits, const SPAttributeEnum, char* tip_text1, char* tip_text2);
+
+ virtual Glib::ustring get_as_attribute() const;
+ virtual void set_from_attribute(SPObject*);
+
+ sigc::signal<void>& signal_value_changed();
+
+ const SpinScale& get_SpinScale1() const;
+ SpinScale& get_SpinScale1();
+
+ const SpinScale& get_SpinScale2() const;
+ SpinScale& get_SpinScale2();
+
+ //void remove_scale();
+private:
+ void link_toggled();
+ void update_linked();
+ sigc::signal<void> _signal_value_changed;
+ SpinScale _s1, _s2;
+ Gtk::ToggleButton _link;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_SPIN_SCALE_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp
index 97ae18e20..1cb59a7b3 100644
--- a/src/ui/widget/spin-slider.cpp
+++ b/src/ui/widget/spin-slider.cpp
@@ -8,12 +8,11 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
-#include <glib.h>
+#include "spin-slider.h"
+
#include <glibmm/i18n.h>
#include <glibmm/stringutils.h>
-#include "spin-slider.h"
-
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -116,11 +115,20 @@ Gtk::Adjustment& SpinSlider::get_adjustment()
return _adjustment;
}
+#if WITH_GTKMM_3_0
+const Gtk::Scale& SpinSlider::get_scale() const
+#else
const Gtk::HScale& SpinSlider::get_scale() const
+#endif
{
return _scale;
}
+
+#if WITH_GTKMM_3_0
+Gtk::Scale& SpinSlider::get_scale()
+#else
Gtk::HScale& SpinSlider::get_scale()
+#endif
{
return _scale;
}
@@ -186,7 +194,7 @@ void DualSpinSlider::set_from_attribute(SPObject* o)
gchar** toks = g_strsplit(val, " ", 2);
if(toks) {
- double v1, v2;
+ double v1 = 0.0, v2 = 0.0;
if(toks[0])
v1 = v2 = Glib::Ascii::strtod(toks[0]);
if(toks[1])
diff --git a/src/ui/widget/spin-slider.h b/src/ui/widget/spin-slider.h
index f4a62107b..8a45299e5 100644
--- a/src/ui/widget/spin-slider.h
+++ b/src/ui/widget/spin-slider.h
@@ -41,13 +41,14 @@ public:
#if WITH_GTKMM_3_0
const Glib::RefPtr<Gtk::Adjustment> get_adjustment() const;
Glib::RefPtr<Gtk::Adjustment> get_adjustment();
+ const Gtk::Scale& get_scale() const;
+ Gtk::Scale& get_scale();
#else
const Gtk::Adjustment& get_adjustment() const;
Gtk::Adjustment& get_adjustment();
-#endif
-
const Gtk::HScale& get_scale() const;
Gtk::HScale& get_scale();
+#endif
const Inkscape::UI::Widget::SpinButton& get_spin_button() const;
Inkscape::UI::Widget::SpinButton& get_spin_button();
@@ -57,10 +58,11 @@ public:
private:
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> _adjustment;
+ Gtk::Scale _scale;
#else
Gtk::Adjustment _adjustment;
-#endif
Gtk::HScale _scale;
+#endif
Inkscape::UI::Widget::SpinButton _spin;
};
diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h
index 47da91732..c2941d995 100644
--- a/src/ui/widget/style-subject.h
+++ b/src/ui/widget/style-subject.h
@@ -20,7 +20,7 @@
class SPDesktop;
class SPObject;
class SPCSSAttr;
-class SPStyle;
+struct SPStyle;
namespace Inkscape {
class Selection;
diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp
index 1ee26e803..a89f42575 100644
--- a/src/ui/widget/style-swatch.cpp
+++ b/src/ui/widget/style-swatch.cpp
@@ -11,15 +11,11 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include "style-swatch.h"
#include <cstring>
#include <string>
-#include "style-swatch.h"
-
#include "widgets/spw-utilities.h"
#include "ui/widget/color-preview.h"
@@ -28,6 +24,7 @@
#include "sp-radial-gradient-fns.h"
#include "sp-pattern.h"
#include "xml/repr.h"
+#include "xml/sp-css-attr.h"
#include "widgets/widget-sizes.h"
#include "helper/units.h"
#include "helper/action.h"
@@ -36,6 +33,12 @@
#include "verbs.h"
#include <glibmm/i18n.h>
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
enum {
SS_FILL,
SS_STROKE
@@ -113,7 +116,11 @@ StyleSwatch::StyleSwatch(SPCSSAttr *css, gchar const *main_tip)
_css(NULL),
_tool_obs(NULL),
_style_obs(NULL),
- _table(2, 6),
+#if WITH_GTKMM_3_0
+ _table(Gtk::manage(new Gtk::Grid())),
+#else
+ _table(Gtk::manage(new Gtk::Table(2, 6))),
+#endif
_sw_unit(NULL)
{
_label[SS_FILL].set_markup(_("Fill:"));
@@ -129,23 +136,35 @@ StyleSwatch::StyleSwatch(SPCSSAttr *css, gchar const *main_tip)
_opacity_value.set_alignment(0.0, 0.5);
_opacity_value.set_padding(0, 0);
- _table.set_col_spacings (2);
- _table.set_row_spacings (0);
+#if WITH_GTKMM_3_0
+ _table->set_column_spacing(2);
+ _table->set_row_spacing(0);
+#else
+ _table->set_col_spacings(2);
+ _table->set_row_spacings(0);
+#endif
_stroke.pack_start(_place[SS_STROKE]);
_stroke_width_place.add(_stroke_width);
_stroke.pack_start(_stroke_width_place, Gtk::PACK_SHRINK);
-
- _table.attach(_label[SS_FILL], 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
- _table.attach(_label[SS_STROKE], 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
-
- _table.attach(_place[SS_FILL], 1,2, 0,1);
- _table.attach(_stroke, 1,2, 1,2);
-
+
_opacity_place.add(_opacity_value);
- _table.attach(_opacity_place, 2,3, 0,2, Gtk::SHRINK, Gtk::SHRINK);
- _swatch.add(_table);
+#if WITH_GTKMM_3_0
+ _table->attach(_label[SS_FILL], 0, 0, 1, 1);
+ _table->attach(_label[SS_STROKE], 0, 1, 1, 1);
+ _table->attach(_place[SS_FILL], 1, 0, 1, 1);
+ _table->attach(_stroke, 1, 1, 1, 1);
+ _table->attach(_opacity_place, 2, 0, 1, 2);
+#else
+ _table->attach(_label[SS_FILL], 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
+ _table->attach(_label[SS_STROKE], 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
+ _table->attach(_place[SS_FILL], 1,2, 0,1);
+ _table->attach(_stroke, 1,2, 1,2);
+ _table->attach(_opacity_place, 2,3, 0,2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
+ _swatch.add(*_table);
pack_start(_swatch, true, true, 0);
set_size_request (STYLE_SWATCH_WIDTH, -1);
@@ -227,8 +246,7 @@ StyleSwatch::setWatchedTool(const char *path, bool synthesize)
}
-void
-StyleSwatch::setStyle(SPCSSAttr *css)
+void StyleSwatch::setStyle(SPCSSAttr *css)
{
if (_css)
sp_repr_css_attr_unref (_css);
@@ -239,18 +257,18 @@ StyleSwatch::setStyle(SPCSSAttr *css)
_css = sp_repr_css_attr_new();
sp_repr_css_merge(_css, css);
- gchar const *css_string = sp_repr_css_write_string (_css);
+ Glib::ustring css_string;
+ sp_repr_css_write_string (_css, css_string);
SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT);
- if (css_string)
- sp_style_merge_from_style_string (temp_spstyle, css_string);
-
+ if (~css_string.empty()) {
+ sp_style_merge_from_style_string (temp_spstyle, css_string.c_str());
+ }
+
setStyle (temp_spstyle);
-
sp_style_unref (temp_spstyle);
}
-void
-StyleSwatch::setStyle(SPStyle *query)
+void StyleSwatch::setStyle(SPStyle *query)
{
_place[SS_FILL].remove();
_place[SS_STROKE].remove();
@@ -341,15 +359,12 @@ StyleSwatch::setStyle(SPStyle *query)
if (op != 1) {
{
gchar *str;
- if (op == 0)
- str = g_strdup_printf(_("O:%.3g"), op);
- else
- str = g_strdup_printf(_("O:.%d"), (int) (op*10));
+ str = g_strdup_printf(_("O: %2.0f"), (op*100.0));
_opacity_value.set_markup (str);
g_free (str);
}
{
- gchar *str = g_strdup_printf(_("Opacity: %.3g"), op);
+ gchar *str = g_strdup_printf(_("Opacity: %2.1f %%"), (op*100.0));
_opacity_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 999bbd4ca..d7bab3732 100644
--- a/src/ui/widget/style-swatch.h
+++ b/src/ui/widget/style-swatch.h
@@ -13,8 +13,11 @@
#ifndef INKSCAPE_UI_CURRENT_STYLE_H
#define INKSCAPE_UI_CURRENT_STYLE_H
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
#include <gtkmm/label.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/enums.h>
@@ -23,10 +26,18 @@
#include "button.h"
#include "preferences.h"
-class SPUnit;
-class SPStyle;
+struct SPUnit;
+struct SPStyle;
class SPCSSAttr;
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -60,7 +71,13 @@ private:
Glib::ustring _tool_path;
Gtk::EventBox _swatch;
- Gtk::Table _table;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *_table;
+#else
+ Gtk::Table *_table;
+#endif
+
Gtk::Label _label[2];
Gtk::EventBox _place[2];
Gtk::EventBox _opacity_place;
diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp
index 16558f0ee..f92a08d0a 100644
--- a/src/ui/widget/tolerance-slider.cpp
+++ b/src/ui/widget/tolerance-slider.cpp
@@ -73,8 +73,15 @@ void ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& la
theLabel1->set_use_underline();
theLabel1->set_alignment(0, 0.5);
// align the label with the checkbox text above by indenting 22 px.
- _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22);
+ _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22);
+
+#if WITH_GTKMM_3_0
+ _hscale = manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+ _hscale->set_range(1.0, 51.0);
+#else
_hscale = manage (new Gtk::HScale (1.0, 51, 1.0));
+#endif
+
theLabel1->set_mnemonic_widget (*_hscale);
_hscale->set_draw_value (true);
_hscale->set_value_pos (Gtk::POS_RIGHT);
diff --git a/src/ui/widget/tolerance-slider.h b/src/ui/widget/tolerance-slider.h
index d0b78e3c1..2184cd52b 100644
--- a/src/ui/widget/tolerance-slider.h
+++ b/src/ui/widget/tolerance-slider.h
@@ -13,7 +13,12 @@
#include <gtkmm/radiobuttongroup.h>
namespace Gtk {
- class RadioButton;
+class RadioButton;
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
}
namespace Inkscape {
@@ -55,7 +60,13 @@ protected:
void on_toggled();
void update (double val);
Gtk::HBox *_hbox;
+
+#if WITH_GTKMM_3_0
+ Gtk::Scale *_hscale;
+#else
Gtk::HScale *_hscale;
+#endif
+
Gtk::RadioButtonGroup _radio_button_group;
Gtk::RadioButton *_button1;
Gtk::RadioButton *_button2;
diff --git a/src/ui/widget/unit-menu.cpp b/src/ui/widget/unit-menu.cpp
index 86e8c9e58..18b7bcab9 100644
--- a/src/ui/widget/unit-menu.cpp
+++ b/src/ui/widget/unit-menu.cpp
@@ -34,11 +34,7 @@ bool UnitMenu::setUnitType(UnitType unit_type)
UnitTable::UnitMap::iterator iter = m.begin();
while(iter != m.end()) {
Glib::ustring text = (*iter).first;
-#if WITH_GTKMM_2_24
append(text);
-#else
- append_text(text);
-#endif
++iter;
}
_type = unit_type;
@@ -49,11 +45,7 @@ bool UnitMenu::setUnitType(UnitType unit_type)
bool UnitMenu::resetUnitType(UnitType unit_type)
{
-#if WITH_GTKMM_2_24
- remove_all();
-#else
- clear_items();
-#endif
+ remove_all();
return setUnitType(unit_type);
}
@@ -61,11 +53,7 @@ bool UnitMenu::resetUnitType(UnitType unit_type)
void UnitMenu::addUnit(Unit const& u)
{
_unit_table.addUnit(u, false);
-#if WITH_GTKMM_2_24
append(u.abbr);
-#else
- append_text(u.abbr);
-#endif
}
Unit UnitMenu::getUnit() const