summaryrefslogtreecommitdiffstats
path: root/src/ui/dialog
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/dialog')
-rw-r--r--src/ui/dialog/Makefile_insert8
-rw-r--r--src/ui/dialog/aboutbox.cpp40
-rw-r--r--src/ui/dialog/aboutbox.h6
-rw-r--r--src/ui/dialog/align-and-distribute.cpp8
-rw-r--r--src/ui/dialog/calligraphic-profile-rename.h2
-rw-r--r--src/ui/dialog/clonetiler.cpp51
-rw-r--r--src/ui/dialog/clonetiler.h5
-rw-r--r--src/ui/dialog/color-item.cpp2
-rw-r--r--src/ui/dialog/desktop-tracker.cpp2
-rw-r--r--src/ui/dialog/desktop-tracker.h5
-rw-r--r--src/ui/dialog/dialog-manager.cpp25
-rw-r--r--src/ui/dialog/dialog.cpp20
-rw-r--r--src/ui/dialog/dialog.h4
-rw-r--r--src/ui/dialog/dock-behavior.cpp4
-rw-r--r--src/ui/dialog/document-metadata.cpp4
-rw-r--r--src/ui/dialog/document-metadata.h4
-rw-r--r--src/ui/dialog/document-properties.cpp65
-rw-r--r--src/ui/dialog/document-properties.h4
-rw-r--r--src/ui/dialog/export.cpp6
-rw-r--r--src/ui/dialog/export.h9
-rw-r--r--src/ui/dialog/extension-editor.cpp2
-rw-r--r--src/ui/dialog/filedialog.cpp2
-rw-r--r--src/ui/dialog/filedialog.h1
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.cpp47
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp14
-rw-r--r--src/ui/dialog/filedialogimpl-win32.h11
-rw-r--r--src/ui/dialog/fill-and-stroke.h2
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp2
-rw-r--r--src/ui/dialog/find.cpp97
-rw-r--r--src/ui/dialog/floating-behavior.cpp4
-rw-r--r--src/ui/dialog/font-substitution.cpp20
-rw-r--r--src/ui/dialog/grid-arrange-tab.cpp4
-rw-r--r--src/ui/dialog/grid-arrange-tab.h8
-rw-r--r--src/ui/dialog/guides.cpp23
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp42
-rw-r--r--src/ui/dialog/inkscape-preferences.h6
-rw-r--r--src/ui/dialog/input.cpp2
-rw-r--r--src/ui/dialog/layers.cpp12
-rw-r--r--src/ui/dialog/livepatheffect-add.cpp14
-rw-r--r--src/ui/dialog/livepatheffect-add.h4
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp127
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.cpp301
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.h115
-rw-r--r--src/ui/dialog/lpe-powerstroke-properties.cpp211
-rw-r--r--src/ui/dialog/lpe-powerstroke-properties.h99
-rw-r--r--src/ui/dialog/new-from-template.cpp15
-rw-r--r--src/ui/dialog/objects.cpp2144
-rw-r--r--src/ui/dialog/objects.h263
-rw-r--r--src/ui/dialog/ocaldialogs.cpp4
-rw-r--r--src/ui/dialog/ocaldialogs.h3
-rw-r--r--src/ui/dialog/panel-dialog.h12
-rw-r--r--src/ui/dialog/pixelartdialog.cpp4
-rw-r--r--src/ui/dialog/polar-arrange-tab.cpp32
-rw-r--r--src/ui/dialog/polar-arrange-tab.h19
-rw-r--r--src/ui/dialog/print.cpp12
-rw-r--r--src/ui/dialog/spellcheck.cpp78
-rw-r--r--src/ui/dialog/swatches.cpp103
-rw-r--r--src/ui/dialog/swatches.h2
-rw-r--r--src/ui/dialog/symbols.cpp121
-rw-r--r--src/ui/dialog/symbols.h9
-rw-r--r--src/ui/dialog/tags.cpp1166
-rw-r--r--src/ui/dialog/tags.h181
-rw-r--r--src/ui/dialog/template-load-tab.cpp2
-rw-r--r--src/ui/dialog/template-widget.cpp8
-rw-r--r--src/ui/dialog/text-edit.cpp17
-rw-r--r--src/ui/dialog/transformation.cpp4
-rw-r--r--src/ui/dialog/xml-tree.cpp5
67 files changed, 5186 insertions, 462 deletions
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert
index daa8aea22..cbdae1cb0 100644
--- a/src/ui/dialog/Makefile_insert
+++ b/src/ui/dialog/Makefile_insert
@@ -100,6 +100,8 @@ ink_common_sources += \
ui/dialog/template-load-tab.h \
ui/dialog/template-widget.cpp \
ui/dialog/template-widget.h \
+ ui/dialog/tags.cpp \
+ ui/dialog/tags.h \
ui/dialog/text-edit.cpp \
ui/dialog/text-edit.h \
ui/dialog/tile.cpp \
@@ -114,4 +116,10 @@ ink_common_sources += \
ui/dialog/undo-history.h \
ui/dialog/xml-tree.cpp \
ui/dialog/xml-tree.h \
+ ui/dialog/lpe-powerstroke-properties.cpp \
+ ui/dialog/lpe-powerstroke-properties.h \
+ ui/dialog/objects.cpp \
+ ui/dialog/objects.h \
+ ui/dialog/lpe-fillet-chamfer-properties.cpp \
+ ui/dialog/lpe-fillet-chamfer-properties.h \
$(inkboard_dialogs)
diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp
index 121773b6d..50b35ca2f 100644
--- a/src/ui/dialog/aboutbox.cpp
+++ b/src/ui/dialog/aboutbox.cpp
@@ -254,6 +254,7 @@ void AboutBox::initStrings() {
"Nicholas Bishop\n"
"Joshua L. Blocher\n"
"Hanno Böck\n"
+"Tomasz Boczkowski\n"
"Henrik Bohre\n"
"Boldewyn\n"
"Daniel Borgmann\n"
@@ -270,6 +271,7 @@ void AboutBox::initStrings() {
"Gail Carmichael\n"
"Ed Catmur\n"
"Chema Celorio\n"
+"Jabiertxo Arraiza Cenoz\n"
"Johan Ceuppens\n"
"Zbigniew Chyla\n"
"Alexander Clausen\n"
@@ -311,6 +313,7 @@ void AboutBox::initStrings() {
"Hannes Hochreiner\n"
"Thomas Holder\n"
"Joel Holdsworth\n"
+"Christoffer Holmstedt\n"
"Alan Horkan\n"
"Karl Ove Hufthammer\n"
"Richard Hughes\n"
@@ -319,6 +322,7 @@ void AboutBox::initStrings() {
"Thomas Ingham\n"
"Jean-Olivier Irisson\n"
"Bob Jamison\n"
+"Ted Janeczko\n"
"jEsuSdA\n"
"Fernando Lucchesi Bastos Jurema\n"
"Lauris Kaplinski\n"
@@ -342,7 +346,9 @@ void AboutBox::initStrings() {
"Aurel-Aimé Marmion\n"
"Colin Marquardt\n"
"Craig Marshall\n"
+"Ivan Masár\n"
"Dmitry G. Mastrukov\n"
+"David Mathog\n"
"Matiphas\n"
"Michael Meeks\n"
"Federico Mena\n"
@@ -360,8 +366,10 @@ void AboutBox::initStrings() {
"Nick\n"
"Andreas Nilsson\n"
"Mitsuru Oka\n"
+"Vinícius dos Santos Oliveira\n"
"Martin Owens\n"
"Alvin Penner\n"
+"Matthew Petroff\n"
"Jon Phillips\n"
"Zdenko Podobny\n"
"Alexandre Prokoudine\n"
@@ -398,6 +406,8 @@ void AboutBox::initStrings() {
"Joakim Verona\n"
"Lucas Vieites\n"
"Daniel Wagenaar\n"
+"Liam P. White\n"
+"Sebastian Wüst\n"
"Michael Wybrow\n"
"Gellule Xg\n"
"Daniel Yacob\n"
@@ -442,13 +452,13 @@ void AboutBox::initStrings() {
*/
gchar const *allTranslators =
"3ARRANO.com <3arrano@3arrano.com>, 2005.\n"
-"Adib Taraben <theadib@googlemail.com>, 2004.\n"
+"Adib Taraben <theadib@gmail.com>, 2004-2014.\n"
"Alan Monfort <alan.monfort@free.fr>, 2009-2010.\n"
"Alastair McKinstry <mckinstry@computer.org>, 2000.\n"
"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-2013.\n"
+"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005, 2010-2014.\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"
@@ -482,6 +492,7 @@ void AboutBox::initStrings() {
"Elias Norberg <elno0959 at student.su.se>, 2009.\n"
"Equipe de Tradução Inkscape Brasil <www.inkscapebrasil.org>, 2007.\n"
"Fatih Demir <kabalak@gtranslator.org>, 2000.\n"
+"Firas Hanife <FirasHanife@gmail.com>, 2014.\n"
"Foppe Benedictus <foppe.benedictus@gmail.com>, 2007-2009.\n"
"Francesc Dorca <f.dorca@filnet.es>, 2003. Traducció sodipodi.\n"
"Francisco Javier F. Serrador <serrador@arrakis.es>, 2003.\n"
@@ -492,9 +503,10 @@ void AboutBox::initStrings() {
"Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n"
"Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n"
"Ilia Penev <lichopicho@gmail.com>, 2006.\n"
-"Ivan Masár <helix84@centrum.sk>, 2006-2010. \n"
+"Ivan Masár <helix84@centrum.sk>, 2006-2014. \n"
+"Ivan Řihošek <irihosek@seznam.cz>, 2014.\n"
"Iñaki Larrañaga <dooteo@euskalgnu.org>, 2006.\n"
-"Jānis Eisaks <jancs@dv.lv>, 2012, 2013.\n"
+"Jānis Eisaks <jancs@dv.lv>, 2012-2014.\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"
@@ -516,7 +528,7 @@ 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-2013.\n"
+"Kris De Gussem <Kris.DeGussem@gmail.com>, 2008-2014.\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"
@@ -525,7 +537,7 @@ void AboutBox::initStrings() {
"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-2012.\n"
+"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2014.\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"
@@ -536,12 +548,12 @@ 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-2013.\n"
+"Nicolas Dufour <nicoduf@yahoo.fr>, 2008-2014.\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"
"Raymond Ostertag <raymond@linuxgraphic.org>, 2002, 2003.\n"
-"Riku Leino <tsoots@gmail.com>, 2006.\n"
+"Riku Leino <tsoots@gmail.com>, 2006-2011.\n"
"Rune Rønde Laursen <runerl@skjoldhoej.dk>, 2006.\n"
"Ruud Steltenpool <svg@steltenpower.com>, 2006.\n"
"Serdar Soytetir <sendirom@gmail.com>, 2005.\n"
@@ -557,9 +569,11 @@ 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-2013.\n"
+"Uwe Schöler <oss@oss-marketplace.com>, 2006-2014.\n"
"Valek Filippov <frob@df.ru>, 2000, 2003.\n"
"Victor Dachev <vdachev@gmail.com>, 2006.\n"
+"Victor Westmann <victor.westmann@gmail.com>, 2011, 2014.\n"
+"Ville Pätsi, 2013.\n"
"Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu>, 2003.\n"
"Vital Khilko <dojlid@mova.org>, 2003.\n"
"Vitaly Lipatov <lav@altlinux.ru>, 2002, 2004.\n"
@@ -572,7 +586,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-2013.\n"
+"Yuri Chornoivan <yurchor@ukr.net>, 2007-2014.\n"
"Yuri Syrota <rasta@renome.rovno.ua>, 2000.\n"
"Yves Guillou <yvesguillou@users.sourceforge.net>, 2004.\n"
"Zdenko Podobný <zdpo@mailbox.sk>, 2003, 2004."
@@ -941,13 +955,13 @@ void AboutBox::initStrings() {
} // namespace UI
} // namespace Inkscape
-/*
+/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0))
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
-// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/aboutbox.h b/src/ui/dialog/aboutbox.h
index 7b3308672..015e344a1 100644
--- a/src/ui/dialog/aboutbox.h
+++ b/src/ui/dialog/aboutbox.h
@@ -55,13 +55,13 @@ private:
#endif // INKSCAPE_UI_DIALOG_ABOUTBOX_H
-/*
+/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0))
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
-// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index 6b4aeebb9..431da7ad1 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -38,7 +38,7 @@
#include "sp-item-transform.h"
#include "sp-text.h"
#include "text-editing.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/icon-names.h"
#include "ui/tools/node-tool.h"
#include "ui/tool/multi-path-manipulator.h"
@@ -829,14 +829,14 @@ private :
-static void on_tool_changed(Inkscape::Application */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad)
+static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop && desktop->getEventContext())
daad->setMode(tools_active(desktop) == TOOLS_NODES);
}
-static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
+static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
{
daad->randomize_bbox = Geom::OptRect();
}
@@ -1002,7 +1002,7 @@ AlignAndDistribute::AlignAndDistribute()
_combo.append(_("Smallest object"));
_combo.append(_("Page"));
_combo.append(_("Drawing"));
- _combo.append(_("Selection"));
+ _combo.append(_("Selection Area"));
_combo.set_active(prefs->getInt("/dialogs/align/align-to", 6));
_combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change));
diff --git a/src/ui/dialog/calligraphic-profile-rename.h b/src/ui/dialog/calligraphic-profile-rename.h
index 3256338eb..fa13db196 100644
--- a/src/ui/dialog/calligraphic-profile-rename.h
+++ b/src/ui/dialog/calligraphic-profile-rename.h
@@ -16,7 +16,7 @@
#endif
#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
-#include <glibmm/threads.h>
+# include <glibmm/threads.h>
#endif
#include <gtkmm/dialog.h>
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index fb131d8da..d1a675735 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -1,5 +1,6 @@
-/** @file
+/**
+ * @file
* Clone tiling dialog
*/
/* Authors:
@@ -38,7 +39,7 @@
#include "util/units.h"
#include "helper/window.h"
#include "inkscape.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "macros.h"
#include "message-stack.h"
#include "preferences.h"
@@ -1349,7 +1350,7 @@ void CloneTiler::on_picker_color_changed(guint rgba)
is_updating = false;
}
-void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg)
+void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg)
{
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"));
@@ -1378,7 +1379,7 @@ void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*
}
}
-void CloneTiler::clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg)
+void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg)
{
clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg);
}
@@ -2002,7 +2003,7 @@ bool CloneTiler::clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj)
id_href = g_strdup_printf("#%s", obj_repr->attribute("id"));
}
- if (SP_IS_USE(tile) &&
+ if (dynamic_cast<SPUse *>(tile) &&
tile->getRepr()->attribute("xlink:href") &&
(!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) &&
tile->getRepr()->attribute("inkscape:tiled-clone-of") &&
@@ -2025,8 +2026,10 @@ void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from)
return;
for (SPObject *o = from->firstChild(); o != NULL; o = o->next) {
- if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL))
- SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too!
+ SPItem *item = dynamic_cast<SPItem *>(o);
+ if (item && clonetiler_is_a_clone_of(o, NULL)) {
+ item->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too!
+ }
clonetiler_trace_hide_tiled_clones_recursively (o);
}
}
@@ -2160,7 +2163,9 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d
}
}
for (GSList *i = to_delete; i; i = i->next) {
- SP_OBJECT(i->data)->deleteObject();
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ g_assert(obj != NULL);
+ obj->deleteObject();
}
g_slist_free (to_delete);
@@ -2235,13 +2240,19 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
gdk_window_process_all_updates();
SPObject *obj = selection->singleItem();
- SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0;
+ if (!obj) {
+ // Should never happen (empty selection checked above).
+ std::cerr << "CloneTiler::clonetile_apply(): No object in single item selection!!!" << std::endl;
+ return;
+ }
Inkscape::XML::Node *obj_repr = obj->getRepr();
const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id"));
SPObject *parent = obj->parent;
clonetiler_remove (NULL, dlg, false);
+ double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit());
+
double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000);
double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000);
double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000);
@@ -2311,8 +2322,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
int jmax = prefs->getInt(prefs_path + "jmax", 2);
bool fillrect = prefs->getBool(prefs_path + "fillrect");
- double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6);
- double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6);
+ double fillwidth = scale_units*prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6);
+ double fillheight = scale_units*prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6);
bool dotrace = prefs->getBool(prefs_path + "dotrace");
int pick = prefs->getInt(prefs_path + "pick");
@@ -2324,6 +2335,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
bool invert_picked = prefs->getBool(prefs_path + "invert_picked");
double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
if (dotrace) {
clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item);
}
@@ -2358,11 +2370,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX );
Geom::OptRect r = item->documentBounds(bbox_type);
if (r) {
- w = r->dimensions()[Geom::X];
- h = r->dimensions()[Geom::Y];
- x0 = r->min()[Geom::X];
- y0 = r->min()[Geom::Y];
- center = desktop->dt2doc(item->getCenter());
+ w = scale_units*r->dimensions()[Geom::X];
+ h = scale_units*r->dimensions()[Geom::Y];
+ x0 = scale_units*r->min()[Geom::X];
+ y0 = scale_units*r->min()[Geom::Y];
+ center = scale_units*desktop->dt2doc(item->getCenter());
sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]);
sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]);
@@ -2578,7 +2590,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
Geom::Point new_center;
bool center_set = false;
if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) {
- new_center = desktop->dt2doc(item->getCenter()) * t;
+ new_center = scale_units*desktop->dt2doc(item->getCenter()) * t;
center_set = true;
}
@@ -2614,9 +2626,10 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg)
if (center_set) {
SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone);
- if (clone_object && SP_IS_ITEM(clone_object)) {
+ SPItem *item = dynamic_cast<SPItem *>(clone_object);
+ if (clone_object && item) {
clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
- SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center));
+ item->setCenter(desktop->doc2dt(new_center));
clone_object->updateRepr();
}
}
diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h
index e2a0240ee..70da86338 100644
--- a/src/ui/dialog/clonetiler.h
+++ b/src/ui/dialog/clonetiler.h
@@ -11,7 +11,6 @@
#define __SP_CLONE_TILER_H__
#include "ui/widget/panel.h"
-#include <gtk/gtk.h>
#include "ui/dialog/desktop-tracker.h"
#include "ui/widget/color-picker.h"
@@ -58,8 +57,8 @@ protected:
static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/);
static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg);
static void clonetiler_unclump(GtkWidget */*widget*/, void *);
- static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg);
- static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg);
+ static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg);
+ static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg);
static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source);
static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg);
static guint clonetiler_number_of_clones(SPObject *obj);
diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp
index 7940c28ae..bab7e18e1 100644
--- a/src/ui/dialog/color-item.cpp
+++ b/src/ui/dialog/color-item.cpp
@@ -684,6 +684,7 @@ void ColorItem::buttonClicked(bool secondary)
descr = secondary? _("Set stroke color to none") : _("Set fill color to none");
break;
}
+//mark
case ege::PaintDef::RGB: {
Glib::ustring colorspec;
if ( _grad ){
@@ -696,6 +697,7 @@ void ColorItem::buttonClicked(bool secondary)
sp_svg_write_color(c, sizeof(c), rgba);
colorspec = c;
}
+//end mark
sp_repr_css_set_property( css, attrName, colorspec.c_str() );
descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch");
break;
diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp
index 8a359dd2d..3ed998252 100644
--- a/src/ui/dialog/desktop-tracker.cpp
+++ b/src/ui/dialog/desktop-tracker.cpp
@@ -94,7 +94,7 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot<void, S
return desktopChangedSig.connect(slot);
}
-gboolean DesktopTracker::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, DesktopTracker *self )
+gboolean DesktopTracker::activateDesktopCB(InkscapeApplication */*inkscape*/, SPDesktop *desktop, DesktopTracker *self )
{
if (self && self->trackActive) {
self->setDesktop(desktop);
diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h
index 7da55cf2f..7b944ddfa 100644
--- a/src/ui/dialog/desktop-tracker.h
+++ b/src/ui/dialog/desktop-tracker.h
@@ -12,11 +12,10 @@
typedef struct _GtkWidget GtkWidget;
class SPDesktop;
+struct InkscapeApplication;
namespace Inkscape {
-struct Application;
-
namespace UI {
namespace Dialog {
@@ -37,7 +36,7 @@ public:
sigc::connection connectDesktopChanged( const sigc::slot<void, SPDesktop*> & slot );
private:
- static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self );
+ static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self );
static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self);
void handleHierarchyChange();
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index 47e1fdd30..7b1b36908 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -54,6 +54,8 @@
#include "ui/dialog/xml-tree.h"
#include "ui/dialog/clonetiler.h"
#include "ui/dialog/svg-fonts-dialog.h"
+#include "ui/dialog/objects.h"
+#include "ui/dialog/tags.h"
namespace Inkscape {
namespace UI {
@@ -70,13 +72,13 @@ inline Dialog *create() { return PanelDialog<B>::template create<T>(); }
/**
* This class is provided as a container for Inkscape's various
- * dialogs. This allows Inkscape::Application to treat the various
+ * dialogs. This allows InkscapeApplication to treat the various
* dialogs it invokes, as abstractions.
*
* DialogManager is essentially a cache of dialogs. It lets us
* initialize dialogs lazily - instead of constructing them during
* application startup, they're constructed the first time they're
- * actually invoked by Inkscape::Application. The constructed
+ * actually invoked by InkscapeApplication. The constructed
* dialog is held here after that, so future invokations of the
* dialog don't need to get re-constructed each time. The memory for
* the dialogs are then reclaimed when the DialogManager is destroyed.
@@ -96,6 +98,9 @@ DialogManager::DialogManager() {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1);
+ // The preferences dialog is broken, the DockBehavior code resizes it's floating window to the smallest size
+ registerFactory("InkscapePreferences", &create<InkscapePreferences, FloatingBehavior>);
+
if (dialogs_type == FLOATING) {
registerFactory("AlignAndDistribute", &create<AlignAndDistribute, FloatingBehavior>);
registerFactory("DocumentMetadata", &create<DocumentMetadata, FloatingBehavior>);
@@ -106,8 +111,9 @@ DialogManager::DialogManager() {
registerFactory("Find", &create<Find, FloatingBehavior>);
registerFactory("Glyphs", &create<GlyphsPanel, FloatingBehavior>);
registerFactory("IconPreviewPanel", &create<IconPreviewPanel, FloatingBehavior>);
- registerFactory("InkscapePreferences", &create<InkscapePreferences, FloatingBehavior>);
registerFactory("LayersPanel", &create<LayersPanel, FloatingBehavior>);
+ registerFactory("ObjectsPanel", &create<ObjectsPanel, FloatingBehavior>);
+ registerFactory("TagsPanel", &create<TagsPanel, FloatingBehavior>);
registerFactory("LivePathEffect", &create<LivePathEffectEditor, FloatingBehavior>);
registerFactory("Memory", &create<Memory, FloatingBehavior>);
registerFactory("Messages", &create<Messages, FloatingBehavior>);
@@ -126,8 +132,8 @@ DialogManager::DialogManager() {
registerFactory("TextFont", &create<TextEdit, FloatingBehavior>);
registerFactory("SpellCheck", &create<SpellCheck, FloatingBehavior>);
registerFactory("Export", &create<Export, FloatingBehavior>);
- registerFactory("XmlTree", &create<XmlTree, FloatingBehavior>);
registerFactory("CloneTiler", &create<CloneTiler, FloatingBehavior>);
+ registerFactory("XmlTree", &create<XmlTree, FloatingBehavior>);
} else {
@@ -140,8 +146,9 @@ DialogManager::DialogManager() {
registerFactory("Find", &create<Find, DockBehavior>);
registerFactory("Glyphs", &create<GlyphsPanel, DockBehavior>);
registerFactory("IconPreviewPanel", &create<IconPreviewPanel, DockBehavior>);
- registerFactory("InkscapePreferences", &create<InkscapePreferences, DockBehavior>);
registerFactory("LayersPanel", &create<LayersPanel, DockBehavior>);
+ registerFactory("ObjectsPanel", &create<ObjectsPanel, DockBehavior>);
+ registerFactory("TagsPanel", &create<TagsPanel, DockBehavior>);
registerFactory("LivePathEffect", &create<LivePathEffectEditor, DockBehavior>);
registerFactory("Memory", &create<Memory, DockBehavior>);
registerFactory("Messages", &create<Messages, DockBehavior>);
@@ -160,8 +167,8 @@ DialogManager::DialogManager() {
registerFactory("TextFont", &create<TextEdit, DockBehavior>);
registerFactory("SpellCheck", &create<SpellCheck, DockBehavior>);
registerFactory("Export", &create<Export, DockBehavior>);
- registerFactory("XmlTree", &create<XmlTree, DockBehavior>);
registerFactory("CloneTiler", &create<CloneTiler, DockBehavior>);
+ registerFactory("XmlTree", &create<XmlTree, DockBehavior>);
}
}
@@ -250,7 +257,7 @@ void DialogManager::showDialog(gchar const *name, bool grabfocus) {
/**
* Shows the named dialog, creating it if necessary.
*/
-void DialogManager::showDialog(GQuark name, bool grabfocus) {
+void DialogManager::showDialog(GQuark name, bool /*grabfocus*/) {
bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false);
GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog()
Dialog *dialog = getDialog(name);
@@ -261,8 +268,8 @@ void DialogManager::showDialog(GQuark name, bool grabfocus) {
tracker->setAutodelete(true);
timer = 0;
}
- if (grabfocus)
- dialog->present();
+ // should check for grabfocus, but lp:1348927 prevents it
+ dialog->present();
}
if ( timer ) {
diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp
index 645294bb5..213965a18 100644
--- a/src/ui/dialog/dialog.cpp
+++ b/src/ui/dialog/dialog.cpp
@@ -28,7 +28,7 @@
#include "desktop-handles.h"
#include "shortcuts.h"
#include "preferences.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "verbs.h"
#include "ui/tool/event-utils.h"
@@ -41,7 +41,7 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-void sp_retransientize(Inkscape::Application */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr)
+void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr)
{
Dialog *dlg = static_cast<Dialog *>(dlgPtr);
dlg->onDesktopActivated (desktop);
@@ -317,20 +317,8 @@ void Dialog::_apply()
void Dialog::_close()
{
- GtkWidget *dlg = GTK_WIDGET(_behavior->gobj());
-
- GdkEventAny event;
- event.type = GDK_DELETE;
- event.window = gtk_widget_get_window(dlg);
- event.send_event = TRUE;
-
- if (event.window)
- g_object_ref(G_OBJECT(event.window));
-
- gtk_main_do_event ((GdkEvent*)&event);
-
- if (event.window)
- g_object_unref(G_OBJECT(event.window));
+ _behavior->hide();
+ _onDeleteEvent(NULL);
}
void Dialog::_defocus()
diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h
index ec5d203bc..ccff43a56 100644
--- a/src/ui/dialog/dialog.h
+++ b/src/ui/dialog/dialog.h
@@ -18,10 +18,10 @@
#include "floating-behavior.h"
class SPDesktop;
+struct InkscapeApplication;
namespace Inkscape {
class Selection;
-struct Application;
}
namespace Inkscape {
@@ -30,7 +30,7 @@ namespace Dialog {
enum BehaviorType { FLOATING, DOCK };
-void sp_retransientize(Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr);
+void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr);
gboolean sp_retransientize_again(gpointer dlgPtr);
void sp_dialog_shutdown(GObject *object, gpointer dlgPtr);
diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp
index 9b216e841..50a6db208 100644
--- a/src/ui/dialog/dock-behavior.cpp
+++ b/src/ui/dialog/dock-behavior.cpp
@@ -18,13 +18,13 @@
#include "dock-behavior.h"
#include "inkscape.h"
#include "desktop.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "widgets/icon.h"
#include "ui/widget/dock.h"
#include "verbs.h"
#include "dialog.h"
#include "preferences.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include <gtkmm/invisible.h>
#include <gtkmm/label.h>
diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp
index 09c505860..77ea175d9 100644
--- a/src/ui/dialog/document-metadata.cpp
+++ b/src/ui/dialog/document-metadata.cpp
@@ -223,7 +223,7 @@ DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *)
}
void
-DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop)
+DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop)
{
Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr();
repr->addListener(&_repr_events, this);
@@ -231,7 +231,7 @@ DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *des
}
void
-DocumentMetadata::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop)
+DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop)
{
Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr();
repr->removeListenerByData(this);
diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h
index 3b7ed1ec8..77084bc3d 100644
--- a/src/ui/dialog/document-metadata.h
+++ b/src/ui/dialog/document-metadata.h
@@ -56,8 +56,8 @@ protected:
void init();
void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document);
- void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop);
- void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop);
+ void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop);
+ void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop);
Gtk::Notebook _notebook;
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 67e788e21..6064c2a5e 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -31,13 +31,13 @@
#include "inkscape.h"
#include "io/sys.h"
#include "preferences.h"
-#include "shape-editor.h"
+#include "ui/shape-editor.h"
#include "sp-namedview.h"
#include "sp-root.h"
#include "sp-script.h"
#include "style.h"
#include "svg/stringstream.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/widget/color-picker.h"
#include "ui/widget/scalar-unit.h"
#include "ui/dialog/filedialog.h"
@@ -45,6 +45,7 @@
#include "widgets/icon.h"
#include "xml/node-event-vector.h"
#include "xml/repr.h"
+#include <algorithm> // std::min
#include "rdf.h"
#include "ui/widget/entity-entry.h"
@@ -596,6 +597,7 @@ void DocumentProperties::removeSelectedProfile(){
//XML Tree being used directly here while it shouldn't be.
sp_repr_unparent(obj->getRepr());
DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile"));
+ break; // removing the color profile likely invalidates part of the traversed list, stop traversing here.
}
current = g_slist_next(current);
}
@@ -1203,10 +1205,10 @@ void DocumentProperties::removeExternalScript(){
const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" );
while ( current ) {
- if (current->data && SP_IS_OBJECT(current->data)) {
- SPObject* obj = SP_OBJECT(current->data);
- SPScript* script = SP_SCRIPT(obj);
- if (name == script->xlinkhref){
+ SPObject* obj = reinterpret_cast<SPObject *>(current->data);
+ if (obj) {
+ SPScript* script = dynamic_cast<SPScript *>(obj);
+ if (script && (name == script->xlinkhref)) {
//XML Tree being used directly here while it shouldn't be.
Inkscape::XML::Node *repr = obj->getRepr();
@@ -1236,23 +1238,16 @@ void DocumentProperties::removeEmbeddedScript(){
}
}
- const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" );
- while ( current ) {
- 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);
+ SPObject* obj = SP_ACTIVE_DOCUMENT->getObjectById(id);
+ if (obj) {
+ //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);
}
populate_script_lists();
@@ -1359,10 +1354,15 @@ void DocumentProperties::populate_script_lists(){
_ExternalScriptsListStore->clear();
_EmbeddedScriptsListStore->clear();
const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" );
- if (current) _scripts_observer.set(SP_OBJECT(current->data)->parent);
+ if (current) {
+ SPObject *obj = reinterpret_cast<SPObject *>(current->data);
+ g_assert(obj != NULL);
+ _scripts_observer.set(obj->parent);
+ }
while ( current ) {
- SPObject* obj = SP_OBJECT(current->data);
- SPScript* script = SP_SCRIPT(obj);
+ SPObject* obj = reinterpret_cast<SPObject *>(current->data);
+ SPScript* script = dynamic_cast<SPScript *>(obj);
+ g_assert(script != NULL);
if (script->xlinkhref)
{
Gtk::TreeModel::Row row = *(_ExternalScriptsListStore->append());
@@ -1599,7 +1599,7 @@ void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument
update();
}
-void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop)
+void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop)
{
Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr();
repr->addListener(&_repr_events, this);
@@ -1608,7 +1608,7 @@ void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDeskt
update();
}
-void DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop)
+void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop)
{
Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr();
repr->removeListenerByData(this);
@@ -1741,14 +1741,19 @@ void DocumentProperties::onDocUnitChange()
prefs->setBool("/options/transform/gradient", true);
{
ShapeEditor::blockSetItem(true);
- gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width();
- if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale)
- viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height();
+ gdouble viewscale = 1.0;
+ Geom::Rect vb = doc->getRoot()->viewBox;
+ if ( !vb.hasZeroArea() ) {
+ gdouble viewscale_w = doc->getWidth().value("px") / vb.width();
+ gdouble viewscale_h = doc->getHeight().value("px")/ vb.height();
+ viewscale = std::min(viewscale_h, viewscale_w);
+ }
gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit);
doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] +
(doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2,
viewscale*doc->getRoot()->viewBox.min()[Geom::Y] +
- (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2));
+ (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2),
+ false);
ShapeEditor::blockSetItem(false);
}
prefs->setBool("/options/transform/stroke", transform_stroke);
diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h
index 495f3177d..ee7e88b18 100644
--- a/src/ui/dialog/document-properties.h
+++ b/src/ui/dialog/document-properties.h
@@ -94,8 +94,8 @@ protected:
void save_default_metadata();
void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document);
- void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop);
- void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop);
+ void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop);
+ void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop);
Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer;
Gtk::Notebook _notebook;
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 913713e5c..b044a6e2c 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -62,10 +62,10 @@
#include "sp-namedview.h"
#include "selection-chemistry.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "preferences.h"
#include "verbs.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "sp-root.h"
#include "extension/output.h"
@@ -537,7 +537,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
sb->set_sensitive (sensitive);
pos++;
- if (!ll.empty()) {
+ if (l) {
l->set_mnemonic_widget(*sb);
}
diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h
index 6f3c0dfac..23af0109b 100644
--- a/src/ui/dialog/export.h
+++ b/src/ui/dialog/export.h
@@ -12,20 +12,11 @@
#ifndef SP_EXPORT_H
#define SP_EXPORT_H
-#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 "desktop.h"
#include "ui/dialog/desktop-tracker.h"
#include "ui/widget/panel.h"
#include "ui/widget/button.h"
-#include "ui/widget/entry.h"
namespace Gtk {
class Dialog;
diff --git a/src/ui/dialog/extension-editor.cpp b/src/ui/dialog/extension-editor.cpp
index cd5491c24..9bdddc0e0 100644
--- a/src/ui/dialog/extension-editor.cpp
+++ b/src/ui/dialog/extension-editor.cpp
@@ -25,7 +25,7 @@
#include "verbs.h"
#include "preferences.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "extension/extension.h"
#include "extension/db.h"
diff --git a/src/ui/dialog/filedialog.cpp b/src/ui/dialog/filedialog.cpp
index e71605739..00ed09551 100644
--- a/src/ui/dialog/filedialog.cpp
+++ b/src/ui/dialog/filedialog.cpp
@@ -20,7 +20,7 @@
#include "filedialog.h"
#include "gc-core.h"
-#include <dialogs/dialog-events.h>
+#include "ui/dialog-events.h"
#include "extension/output.h"
#include "preferences.h"
diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h
index 8dfcf5dce..175031bcf 100644
--- a/src/ui/dialog/filedialog.h
+++ b/src/ui/dialog/filedialog.h
@@ -48,6 +48,7 @@ typedef enum {
IMPORT_TYPES,
EXPORT_TYPES,
EXE_TYPES,
+ SWATCH_TYPES,
CUSTOM_TYPE
} FileDialogType;
diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp
index 8ba3ad684..5d330f7f0 100644
--- a/src/ui/dialog/filedialogimpl-gtkmm.cpp
+++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp
@@ -21,9 +21,11 @@
#include <config.h>
#endif
+#include <iostream>
+
#include "filedialogimpl-gtkmm.h"
-#include "dialogs/dialog-events.h"
-#include "interface.h"
+#include "ui/dialog-events.h"
+#include "ui/interface.h"
#include "io/sys.h"
#include "path-prefix.h"
#include "preferences.h"
@@ -40,6 +42,9 @@
#include <glibmm/i18n.h>
#include <glibmm/miscutils.h>
+#include <glibmm/regex.h>
+
+#include "document.h"
#include "extension/input.h"
#include "extension/output.h"
#include "extension/db.h"
@@ -190,6 +195,40 @@ void SVGPreview::showImage(Glib::ustring &theFileName)
{
Glib::ustring fileName = theFileName;
+ // Let's get real width and height from SVG file. These are template
+ // files so we assume they are well formed.
+
+ // std::cout << "SVGPreview::showImage: " << theFileName << std::endl;
+ std::ifstream input(theFileName.c_str());
+
+ std::string width;
+ std::string height;
+
+ if( !input ) {
+ std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl;
+ } else {
+
+ std::string token;
+
+ Glib::MatchInfo match_info;
+ Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("width=\"(.*)\"");
+ Glib::RefPtr<Glib::Regex> regex2 = Glib::Regex::create("height=\"(.*)\"");
+
+ while( !input.eof() && (height.empty() || width.empty()) ) {
+
+ input >> token;
+ // std::cout << "|" << token << "|" << std::endl;
+
+ if (regex1->match(token, match_info)) {
+ width = match_info.fetch(1).raw();
+ }
+
+ if (regex2->match(token, match_info)) {
+ height = match_info.fetch(1).raw();
+ }
+
+ }
+ }
/*#####################################
# LET'S HAVE SOME FUN WITH SVG!
@@ -269,7 +308,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName)
" style=\"font-size:24.000000;font-style:normal;font-weight:normal;"
" fill:#000000;fill-opacity:1.0000000;stroke:none;"
" font-family:Sans\"\n"
- " x=\"10\" y=\"26\">%d x %d</text>\n" //# VALUES HERE
+ " x=\"10\" y=\"26\">%s x %s</text>\n" //# VALUES HERE
"</svg>\n\n";
// if (!Glib::get_charset()) //If we are not utf8
@@ -279,7 +318,7 @@ void SVGPreview::showImage(Glib::ustring &theFileName)
/* FIXME: Do proper XML quoting for fileName. */
gchar *xmlBuffer =
g_strdup_printf(xformat, previewWidth, previewHeight, imgX, imgY, scaledImgWidth, scaledImgHeight,
- fileName.c_str(), rectX, rectY, rectWidth, rectHeight, imgWidth, imgHeight);
+ fileName.c_str(), rectX, rectY, rectWidth, rectHeight, width.c_str(), height.c_str() );
// g_message("%s\n", xmlBuffer);
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index 9d91f5d56..ee6a0ef3a 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -31,7 +31,7 @@
//Inkscape includes
#include "inkscape.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "extension/input.h"
#include "extension/output.h"
#include "extension/db.h"
@@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB
#define IDC_SHOW_PREVIEW 1000
-// Windows 2000 version of OPENFILENAMEW
-struct OPENFILENAMEEXW : public OPENFILENAMEW {
- void * pvReserved;
- DWORD dwReserved;
- DWORD FlagsEx;
-};
-
struct Filter
{
gunichar2* name;
@@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu()
void FileOpenDialogImplWin32::GetOpenFileName_thread()
{
- OPENFILENAMEEXW ofn;
+ OPENFILENAMEW ofn;
g_assert(this != NULL);
g_assert(_mutex != NULL);
@@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt
void FileSaveDialogImplWin32::GetSaveFileName_thread()
{
- OPENFILENAMEEXW ofn;
+ OPENFILENAMEW ofn;
g_assert(this != NULL);
g_assert(_main_loop != NULL);
@@ -1860,7 +1853,6 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread()
ofn.nFilterIndex = _filter_index;
ofn.lpfnHook = GetSaveFileName_hookproc;
ofn.lCustData = (LPARAM)this;
-
_result = GetSaveFileNameW(&ofn) != 0;
g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count);
diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h
index 29bcb9a45..f77249abd 100644
--- a/src/ui/dialog/filedialogimpl-win32.h
+++ b/src/ui/dialog/filedialogimpl-win32.h
@@ -13,16 +13,23 @@
# include "config.h"
#endif
+#include <glibmm.h>
+
#ifdef WIN32
#if WITH_GLIBMM_2_32
#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
# include <glibmm/threads.h>
#endif
-
#endif
+
+#include "filedialogimpl-gtkmm.h"
+
#include "gc-core.h"
+ // define WINVER high enough so we get the correct OPENFILENAMEW size
+#ifndef WINVER
+#define WINVER 0x0500
+#endif
#include <windows.h>
-#include "filedialogimpl-gtkmm.h"
namespace Inkscape
diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h
index 340cb860f..35c98ef9c 100644
--- a/src/ui/dialog/fill-and-stroke.h
+++ b/src/ui/dialog/fill-and-stroke.h
@@ -41,7 +41,7 @@ public:
virtual void setDesktop(SPDesktop *desktop);
- void selectionChanged(Inkscape::Application *inkscape,
+ void selectionChanged(InkscapeApplication *inkscape,
Inkscape::Selection *selection);
void showPageFill();
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index c2367c2a2..bd44846a3 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -546,7 +546,7 @@ public:
_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),
- _label(_("None"), Gtk::ALIGN_START),
+ _label(C_("Label", "None"), Gtk::ALIGN_START),
_use_stored(false),
_saturation_store(0),
_angle_store(0)
diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp
index 37f2761df..1a7832688 100644
--- a/src/ui/dialog/find.cpp
+++ b/src/ui/dialog/find.cpp
@@ -31,9 +31,9 @@
#include "selection.h"
#include "desktop-handles.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "verbs.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "preferences.h"
#include "sp-text.h"
#include "sp-flowtext.h"
@@ -241,7 +241,7 @@ Find::Find()
Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP);
SPItem *item = selection->singleItem();
if (item) {
- if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
+ if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) {
gchar *str;
str = sp_te_get_string_multiline (item);
entry_find.getEntry()->set_text(str);
@@ -343,7 +343,7 @@ bool Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool ca
return false;
}
- if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
+ if (dynamic_cast<SPText *>(item) || dynamic_cast<SPFlowtext *>(item)) {
const gchar *item_text = sp_te_get_string_multiline (item);
if (item_text == NULL) {
return false;
@@ -388,7 +388,7 @@ bool Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casema
return false;
}
- if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching
+ if (dynamic_cast<SPString *>(item)) { // SPStrings have "on demand" ids which are useless for searching
return false;
}
@@ -561,11 +561,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (check_searchin_text.get_active()) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_text_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_text_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_text_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_text_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -581,11 +584,13 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (ids) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_id_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ if (item_id_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_id_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_id_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -595,12 +600,15 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (style) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_style_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_style_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data))
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_style_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_style_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -610,11 +618,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (attrname) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_attr_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_attr_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_attr_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_attr_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -624,11 +635,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (attrvalue) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_attrvalue_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_attrvalue_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -638,11 +652,14 @@ GSList *Find::filter_fields (GSList *l, bool exact, bool casematch)
if (font) {
for (GSList *i = in; i != NULL; i = i->next) {
- if (item_font_match (SP_ITEM(i->data), text, exact, casematch)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_font_match(item, text, exact, casematch)) {
if (!g_slist_find(out, i->data)) {
out = g_slist_prepend (out, i->data);
if (_action_replace) {
- item_font_match (SP_ITEM(i->data), text, exact, casematch, _action_replace);
+ item_font_match(item, text, exact, casematch, _action_replace);
}
}
}
@@ -661,34 +678,34 @@ bool Find::item_type_match (SPItem *item)
{
bool all =check_alltypes.get_active();
- if ( SP_IS_RECT(item)) {
+ if ( dynamic_cast<SPRect *>(item)) {
return ( all ||check_rects.get_active());
- } else if (SP_IS_GENERICELLIPSE(item)) {
+ } else if (dynamic_cast<SPGenericEllipse *>(item)) {
return ( all || check_ellipses.get_active());
- } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) {
+ } else if (dynamic_cast<SPStar *>(item) || dynamic_cast<SPPolygon *>(item)) {
return ( all || check_stars.get_active());
- } else if (SP_IS_SPIRAL(item)) {
+ } else if (dynamic_cast<SPSpiral *>(item)) {
return ( all || check_spirals.get_active());
- } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) {
+ } else if (dynamic_cast<SPPath *>(item) || dynamic_cast<SPLine *>(item) || dynamic_cast<SPPolyLine *>(item)) {
return (all || check_paths.get_active());
- } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) {
+ } else if (dynamic_cast<SPText *>(item) || dynamic_cast<SPTSpan *>(item) || dynamic_cast<SPTRef *>(item) || dynamic_cast<SPString *>(item)) {
return (all || check_texts.get_active());
- } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers!
+ } else if (dynamic_cast<SPGroup *>(item) && !desktop->isLayer(item) ) { // never select layers!
return (all || check_groups.get_active());
- } else if (SP_IS_USE(item)) {
+ } else if (dynamic_cast<SPUse *>(item)) {
return (all || check_clones.get_active());
- } else if (SP_IS_IMAGE(item)) {
+ } else if (dynamic_cast<SPImage *>(item)) {
return (all || check_images.get_active());
- } else if (SP_IS_OFFSET(item)) {
+ } else if (dynamic_cast<SPOffset *>(item)) {
return (all || check_offsets.get_active());
}
@@ -699,7 +716,10 @@ GSList *Find::filter_types (GSList *l)
{
GSList *n = NULL;
for (GSList *i = l; i != NULL; i = i->next) {
- if (item_type_match (SP_ITEM(i->data))) {
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item_type_match(item)) {
n = g_slist_prepend (n, i->data);
}
}
@@ -716,7 +736,7 @@ GSList *Find::filter_list (GSList *l, bool exact, bool casematch)
GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked)
{
- if (SP_IS_DEFS(r)) {
+ if (dynamic_cast<SPDefs *>(r)) {
return l; // we're not interested in items in defs
}
@@ -725,8 +745,8 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked)
}
for (SPObject *child = r->firstChild(); child; child = child->getNext()) {
- if (SP_IS_ITEM(child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) {
- SPItem *item = reinterpret_cast<SPItem *>(child);
+ SPItem *item = dynamic_cast<SPItem *>(child);
+ if (item && !child->cloned && !desktop->isLayer(item)) {
if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) {
l = g_slist_prepend (l, child);
}
@@ -739,16 +759,18 @@ GSList *Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked)
GSList *Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked)
{
for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) {
- if (SP_IS_ITEM (i->data) && !reinterpret_cast<SPItem *>(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) {
- SPItem *item = reinterpret_cast<SPItem *>(i->data);
+ SPObject *obj = reinterpret_cast<SPObject *>(i->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ if (item && !item->cloned && !desktop->isLayer(item)) {
if (!ancestor || ancestor->isAncestorOf(item)) {
if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) {
l = g_slist_prepend (l, i->data);
}
}
}
- if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) {
- l = all_items (SP_OBJECT (i->data), l, hidden, locked);
+ if (!ancestor || ancestor->isAncestorOf(item)) {
+ l = all_items(item, l, hidden, locked);
}
}
return l;
@@ -831,7 +853,10 @@ void Find::onAction()
Inkscape::Selection *selection = sp_desktop_selection (desktop);
selection->clear();
selection->setList(n);
- scroll_to_show_item (desktop, SP_ITEM(n->data));
+ SPObject *obj = reinterpret_cast<SPObject *>(n->data);
+ SPItem *item = dynamic_cast<SPItem *>(obj);
+ g_assert(item != NULL);
+ scroll_to_show_item(desktop, item);
if (_action_replace) {
DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Replace text or property"));
diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp
index dd07f009a..11db14801 100644
--- a/src/ui/dialog/floating-behavior.cpp
+++ b/src/ui/dialog/floating-behavior.cpp
@@ -28,8 +28,8 @@
#include "inkscape.h"
#include "desktop.h"
-#include "dialogs/dialog-events.h"
-#include "interface.h"
+#include "ui/dialog-events.h"
+#include "ui/interface.h"
#include "preferences.h"
#include "verbs.h"
diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp
index bf9133086..db7bdf222 100644
--- a/src/ui/dialog/font-substitution.cpp
+++ b/src/ui/dialog/font-substitution.cpp
@@ -27,7 +27,7 @@
#include "document.h"
#include "selection.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "desktop-handles.h"
#include "selection-chemistry.h"
#include "preferences.h"
@@ -200,16 +200,16 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring *
}
}
- if (style && style->text) {
+ if (style) {
gchar const *style_font = NULL;
- if (style->text->font_family.set)
- style_font = style->text->font_family.value;
- else if (style->text->font_specification.set)
- style_font = style->text->font_specification.value;
- else if (style->text->font_family.value)
- style_font = style->text->font_family.value;
- else if (style->text->font_specification.value)
- style_font = style->text->font_specification.value;
+ if (style->font_family.set)
+ style_font = style->font_family.value;
+ else if (style->font_specification.set)
+ style_font = style->font_specification.value;
+ else if (style->font_family.value)
+ style_font = style->font_family.value;
+ else if (style->font_specification.value)
+ style_font = style->font_specification.value;
if (style_font) {
if (has_visible_text(item)) {
diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp
index 8c0a4dc66..1417b39fa 100644
--- a/src/ui/dialog/grid-arrange-tab.cpp
+++ b/src/ui/dialog/grid-arrange-tab.cpp
@@ -572,7 +572,7 @@ void GridArrangeTab::updateSelection()
## Experimental
##########################*/
-static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg)
+static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg)
{
dlg->updateSelection();
}
@@ -708,7 +708,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent)
HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1);
// Anchor selection widget
- AlignLabel.set_label("Alignment:");
+ AlignLabel.set_label(_("Alignment:"));
AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
AlignmentSelector.setAlignment(HorizAlign, VertAlign);
AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed));
diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h
index 9d6700b39..a137d1694 100644
--- a/src/ui/dialog/grid-arrange-tab.h
+++ b/src/ui/dialog/grid-arrange-tab.h
@@ -17,14 +17,16 @@
#ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H
#define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H
-#include <gtkmm.h>
-
+#include "ui/widget/scalar-unit.h"
#include "ui/dialog/arrange-tab.h"
#include "ui/widget/anchor-selector.h"
-#include "ui/widget/scalar-unit.h"
#include "ui/widget/spinbutton.h"
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/radiobuttongroup.h>
+
namespace Inkscape {
namespace UI {
namespace Dialog {
diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp
index 80740113c..4519a905f 100644
--- a/src/ui/dialog/guides.cpp
+++ b/src/ui/dialog/guides.cpp
@@ -28,7 +28,7 @@
#include "ui/tools/tool-base.h"
#include "widgets/desktop-widget.h"
#include <glibmm/i18n.h>
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "message-context.h"
#include "xml/repr.h"
#include "verbs.h"
@@ -100,7 +100,7 @@ void GuidelinePropertiesDialog::_onOK()
double rad_angle = Geom::deg_to_rad( deg_angle );
normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0));
}
- sp_guide_set_normal(*_guide, normal, true);
+ _guide->set_normal(normal, true);
double const points_x = _spin_button_x.getValue("px");
double const points_y = _spin_button_y.getValue("px");
@@ -108,11 +108,11 @@ void GuidelinePropertiesDialog::_onOK()
if (!_mode)
newpos += _oldpos;
- sp_guide_moveto(*_guide, newpos, true);
+ _guide->moveto(newpos, true);
const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() );
- sp_guide_set_label(*_guide, name, true);
+ _guide->set_label(name, true);
g_free((gpointer) name);
#if WITH_GTKMM_3_0
@@ -124,7 +124,7 @@ void GuidelinePropertiesDialog::_onOK()
#endif
//TODO: why 257? verify this!
- sp_guide_set_color(*_guide, r, g, b, true);
+ _guide->set_color(r, g, b, true);
DocumentUndo::done(_guide->document, SP_VERB_NONE,
_("Set guide properties"));
@@ -295,16 +295,17 @@ void GuidelinePropertiesDialog::_setup() {
signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response));
// initialize dialog
- _oldpos = _guide->point_on_line;
+ _oldpos = _guide->getPoint();
if (_guide->isVertical()) {
_oldangle = 90;
} else if (_guide->isHorizontal()) {
_oldangle = 0;
} else {
- _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) );
+ _oldangle = Geom::rad_to_deg( std::atan2( - _guide->getNormal()[Geom::X], _guide->getNormal()[Geom::Y] ) );
}
{
+ // FIXME holy crap!!!
Inkscape::XML::Node *repr = _guide->getRepr();
const gchar *guide_id = repr->attribute("id");
gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id);
@@ -312,7 +313,7 @@ void GuidelinePropertiesDialog::_setup() {
g_free(label);
}
{
- gchar *guide_description = sp_guide_description(_guide, false);
+ gchar *guide_description = _guide->description(false);
gchar *label = g_strdup_printf(_("Current: %s"), guide_description);
g_free(guide_description);
_label_descr.set_markup(label);
@@ -320,15 +321,15 @@ void GuidelinePropertiesDialog::_setup() {
}
// init name entry
- _label_entry.getEntry()->set_text(_guide->label ? _guide->label : "");
+ _label_entry.getEntry()->set_text(_guide->getLabel() ? _guide->getLabel() : "");
#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);
+ c.set_rgba(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>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);
+ c.set_rgb_p(((_guide->getColor()>>24)&0xff) / 255.0, ((_guide->getColor()>>16)&0xff) / 255.0, ((_guide->getColor()>>8)&0xff) / 255.0);
_color.set_color(c);
#endif
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index d826ece09..75cfe5bfe 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -19,6 +19,7 @@
#include "inkscape-preferences.h"
#include <glibmm/i18n.h>
+#include <glibmm/markup.h>
#include <glibmm/miscutils.h>
#include <gtkmm/main.h>
#include <gtkmm/frame.h>
@@ -76,7 +77,8 @@ InkscapePreferences::InkscapePreferences()
: UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY),
_max_dialog_width(0),
_max_dialog_height(0),
- _current_page(0)
+ _current_page(0),
+ _init(true)
{
//get the width of a spinbutton
Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton;
@@ -232,6 +234,9 @@ static void StyleFromSelectionToTool(Glib::ustring const &prefs_path, StyleSwatc
if (!css) return;
+ // remove black-listed properties
+ css = sp_css_attr_unset_blacklist (css);
+
// only store text style for the text tool
if (prefs_path != "/tools/text") {
css = sp_css_attr_unset_text (css);
@@ -329,7 +334,7 @@ void InkscapePreferences::initPageTools()
_page_selector.add_line( true, "", _t_sel_trans_outl, "",
_("Show only a box outline of the objects when moving or transforming"));
_page_selector.add_group_header( _("Per-object selection cue"));
- _t_sel_cue_none.init ( _("None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0);
+ _t_sel_cue_none.init ( C_("Selection cue", "None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0);
_page_selector.add_line( true, "", _t_sel_cue_none, "",
_("No per-object selection indication"));
_t_sel_cue_mark.init ( _("Mark"), "/options/selcue/value", Inkscape::SelCue::MARK, true, &_t_sel_cue_none);
@@ -500,10 +505,12 @@ void InkscapePreferences::initPageTools()
_page_connector.add_line(false, "", _connector_ignore_text, "",
_("If on, connector attachment points will not be shown for text objects"));
+#ifdef WITH_LPETOOL
//LPETool
- // commented out, because the LPETool is not finished yet.
- //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL);
- //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool");
+ //disabled, because the LPETool is not finished yet.
+ this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL);
+ this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool");
+#endif // WITH_LPETOOL
}
void InkscapePreferences::initPageUI()
@@ -522,11 +529,11 @@ void InkscapePreferences::initPageUI()
_("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"),
_("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"),
_("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"),
- _("Swedish (sv)"),_("Telugu (te_IN)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")};
+ _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")};
Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl",
"dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga",
"gl", "he", "hu", "id", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa",
- "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te_IN", "th", "tr", "uk", "vi" };
+ "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" };
{
// sorting languages according to translated name
@@ -638,7 +645,7 @@ void InkscapePreferences::initPageUI()
_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);
+ _win_ontop_none.init ( C_("Dialog on top", "None"), "/options/transientpolicy/value", 0, false, 0);
_win_ontop_normal.init ( _("Normal"), "/options/transientpolicy/value", 1, true, &_win_ontop_none);
_win_ontop_agressive.init ( _("Aggressive"), "/options/transientpolicy/value", 2, false, &_win_ontop_none);
@@ -834,7 +841,7 @@ void InkscapePreferences::initPageIO()
_save_use_current_dir.init( _("Use current directory for \"Save As ...\""), "/dialogs/save_as/use_current_dir", true);
_page_io.add_line( false, "", _save_use_current_dir, "",
- _("When this option is on, the \"Save as...\" and \"Save a Copy\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true);
+ _("When this option is on, the \"Save as...\" and \"Save a Copy...\" dialogs will always open in the directory where the currently open document is; when it's off, each will open in the directory where you last saved a file using it"), true);
_misc_comment.init( _("Add label comments to printing output"), "/printing/debug/show-label-comments", false);
_page_io.add_line( false, "", _misc_comment, "",
@@ -1256,7 +1263,7 @@ void InkscapePreferences::initPageBehavior()
_page_steps.add_line( false, "", _steps_compass, "",
_("When on, angles are displayed with 0 at north, 0 to 360 range, positive clockwise; otherwise with 0 at east, -180 to 180 range, positive counterclockwise"));
int const num_items = 17;
- Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", _("None")};
+ Glib::ustring labels[num_items] = {"90", "60", "45", "36", "30", "22.5", "18", "15", "12", "10", "7.5", "6", "3", "2", "1", "0.5", C_("Rotation angle", "None")};
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);
@@ -1463,6 +1470,11 @@ void InkscapePreferences::initPageBitmaps()
_page_bitmaps.add_line( false, "", _importexport_import_res_override, "",
_("Use default bitmap resolution in favor of information from file"));
+ _page_bitmaps.add_group_header( _("Render"));
+ // rendering outlines for pixmap image tags
+ _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false);
+ _page_bitmaps.add_line(false, "", _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing."));
+
this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS);
}
@@ -1827,7 +1839,7 @@ void InkscapePreferences::initPageSpellcheck()
AspellDictInfoEnumeration *dels = aspell_dict_info_list_elements(dlist);
- languages.push_back(Glib::ustring(_("None")));
+ languages.push_back(Glib::ustring(C_("Spellchecker language", "None")));
langValues.push_back(Glib::ustring(""));
const AspellDictInfo *entry;
@@ -1993,6 +2005,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter)
Gtk::TreeModel::Row row = *iter;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int desired_page = prefs->getInt("/dialogs/preferences/page", 0);
+ _init = false;
if (desired_page == row[_page_list_columns._col_id])
{
if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR)
@@ -2042,8 +2055,11 @@ void InkscapePreferences::on_pagelist_selection_changed()
Gtk::TreeModel::Row row = *iter;
_current_page = row[_page_list_columns._col_page];
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]);
- _page_title.set_markup("<span size='large'><b>" + row[_page_list_columns._col_name] + "</b></span>");
+ if (!_init) {
+ prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]);
+ }
+ Glib::ustring col_name_escaped = Glib::Markup::escape_text( row[_page_list_columns._col_name] );
+ _page_title.set_markup("<span size='large'><b>" + col_name_escaped + "</b></span>");
_page_frame.add(*_current_page);
_current_page->show();
while (Gtk::Main::events_pending())
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index da85b805d..dcea91741 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -292,6 +292,7 @@ protected:
UI::Widget::PrefCheckButton _show_filters_info_box;
UI::Widget::PrefCombo _dockbar_style;
UI::Widget::PrefCombo _switcher_style;
+ UI::Widget::PrefCheckButton _rendering_image_outline;
UI::Widget::PrefSpinButton _rendering_cache_size;
UI::Widget::PrefSpinButton _filter_multi_threaded;
@@ -531,6 +532,7 @@ private:
InkscapePreferences();
InkscapePreferences(InkscapePreferences const &d);
InkscapePreferences operator=(InkscapePreferences const &d);
+ bool _init;
};
} // namespace Dialog
@@ -543,9 +545,9 @@ private:
Local Variables:
mode:c++
c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0))
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
-// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp
index 4be6716a5..8343cd6fe 100644
--- a/src/ui/dialog/input.cpp
+++ b/src/ui/dialog/input.cpp
@@ -1622,7 +1622,7 @@ void InputDialogImpl::ConfPanel::setAxis(gint count)
if (barNum < count) {
row[axisColumns.value] = Glib::ustring::format(barNum+1);
} else {
- row[axisColumns.value] = _("None");
+ row[axisColumns.value] = C_("Input device axe", "None");
}
}
diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp
index b5dac0595..65351cb68 100644
--- a/src/ui/dialog/layers.cpp
+++ b/src/ui/dialog/layers.cpp
@@ -926,9 +926,8 @@ LayersPanel::LayersPanel() :
// -------------------------------------------------------
{
- _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) );
- _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) );
_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) );
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
@@ -944,9 +943,14 @@ LayersPanel::LayersPanel() :
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
- _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) );
- _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) );
+ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("layer-raise"), "Up", (int)BUTTON_UP ) );
+ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("layer-lower"), "Down", (int)BUTTON_DOWN ) );
+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DELETE, 0, "Delete", (int)BUTTON_DELETE ) );
+
_popupMenu.show_all_children();
}
// -------------------------------------------------------
diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp
index b5f51d81d..c558eddaf 100644
--- a/src/ui/dialog/livepatheffect-add.cpp
+++ b/src/ui/dialog/livepatheffect-add.cpp
@@ -38,6 +38,7 @@ LivePathEffectAdd::LivePathEffectAdd() :
scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
scrolled_window.set_shadow_type(Gtk::SHADOW_IN);
scrolled_window.set_size_request(250, 200);
+ scrolled_window.set_can_focus();
/**
* Effect Store and Tree
@@ -83,10 +84,12 @@ LivePathEffectAdd::LivePathEffectAdd() :
add_action_widget(close_button, Gtk::RESPONSE_CLOSE);
add_action_widget(add_button, Gtk::RESPONSE_APPLY);
+
/**
* Signal handlers
*/
effectlist_treeview.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LivePathEffectAdd::onButtonEvent) );
+ effectlist_treeview.signal_key_press_event().connect_notify(sigc::mem_fun(*this, &LivePathEffectAdd::onKeyEvent));
close_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onClose));
add_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onAdd));
signal_delete_event().connect( sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)), true ) );
@@ -107,6 +110,16 @@ void LivePathEffectAdd::onClose()
hide();
}
+void LivePathEffectAdd::onKeyEvent(GdkEventKey* evt)
+{
+ if (evt->keyval == GDK_KEY_Return) {
+ onAdd();
+ }
+ if (evt->keyval == GDK_KEY_Escape) {
+ onClose();
+ }
+}
+
void LivePathEffectAdd::onButtonEvent(GdkEventButton* evt)
{
// Double click on tree is same as clicking the add button
@@ -135,6 +148,7 @@ void LivePathEffectAdd::show(SPDesktop *desktop)
dial.set_modal(true);
desktop->setWindowTransient (dial.gobj());
dial.property_destroy_with_parent() = true;
+ dial.effectlist_treeview.grab_focus();
dial.run();
}
diff --git a/src/ui/dialog/livepatheffect-add.h b/src/ui/dialog/livepatheffect-add.h
index 7fa766272..99ead878c 100644
--- a/src/ui/dialog/livepatheffect-add.h
+++ b/src/ui/dialog/livepatheffect-add.h
@@ -74,6 +74,10 @@ protected:
*/
void onButtonEvent(GdkEventButton* evt);
+ /**
+ * Key event
+ */
+ void onKeyEvent(GdkEventKey* evt);
private:
Gtk::TreeView effectlist_treeview;
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 9a569725c..eb3857ee7 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -295,9 +295,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
if ( item ) {
- if ( SP_IS_LPE_ITEM(item) ) {
- SPLPEItem *lpeitem = SP_LPE_ITEM(item);
-
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
+ if ( lpeitem ) {
effect_list_reload(lpeitem);
current_lpeitem = lpeitem;
@@ -318,25 +317,28 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
button_up.set_sensitive(false);
button_down.set_sensitive(false);
}
- } else if ( SP_IS_USE(item) ) {
- // test whether linked object is supported by the CLONE_ORIGINAL LPE
- SPItem *orig = SP_USE(item)->get_original();
- if ( SP_IS_SHAPE(orig) ||
- SP_IS_TEXT(orig) )
- {
- // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case.
- set_sensitize_all(true);
- showText(_("Click add button to convert clone"));
- button_remove.set_sensitive(false);
- button_up.set_sensitive(false);
- button_down.set_sensitive(false);
+ } else {
+ SPUse *use = dynamic_cast<SPUse *>(item);
+ if ( use ) {
+ // test whether linked object is supported by the CLONE_ORIGINAL LPE
+ SPItem *orig = use->get_original();
+ if ( dynamic_cast<SPShape *>(orig) ||
+ dynamic_cast<SPText *>(orig) )
+ {
+ // Note that an SP_USE cannot have an LPE applied, so we only need to worry about the "add effect" case.
+ set_sensitize_all(true);
+ showText(_("Click add button to convert clone"));
+ button_remove.set_sensitive(false);
+ button_up.set_sensitive(false);
+ button_down.set_sensitive(false);
+ } else {
+ showText(_("Select a path or shape"));
+ set_sensitize_all(false);
+ }
} else {
showText(_("Select a path or shape"));
set_sensitize_all(false);
}
- } else {
- showText(_("Select a path or shape"));
- set_sensitize_all(false);
}
} else {
showText(_("Only one item can be selected"));
@@ -423,7 +425,7 @@ LivePathEffectEditor::onAdd()
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
if (item) {
- if ( SP_IS_LPE_ITEM(item) ) {
+ if ( dynamic_cast<SPLPEItem *>(item) ) {
// show effectlist dialog
using Inkscape::UI::Dialog::LivePathEffectAdd;
LivePathEffectAdd::show(current_desktop);
@@ -439,7 +441,7 @@ LivePathEffectEditor::onAdd()
}
// If item is a SPRect, convert it to path first:
- if ( SP_IS_RECT(item) ) {
+ if ( dynamic_cast<SPRect *>(item) ) {
sp_selected_path_to_curves(sel, current_desktop, false);
item = sel->singleItem(); // get new item
}
@@ -451,41 +453,43 @@ LivePathEffectEditor::onAdd()
lpe_list_locked = false;
onSelectionChanged(sel);
- }
- else if ( SP_IS_USE(item) ) {
- // item is a clone. do not show effectlist dialog.
- // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path
-
- // test whether linked object is supported by the CLONE_ORIGINAL LPE
- SPItem *orig = SP_USE(item)->get_original();
- if ( SP_IS_SHAPE(orig) ||
- SP_IS_TEXT(orig) )
- {
- // select original
- sel->set(orig);
-
- // delete clone but remember its id and transform
- gchar *id = g_strdup(item->getRepr()->attribute("id"));
- gchar *transform = g_strdup(item->getRepr()->attribute("transform"));
- item->deleteObject(false);
- item = NULL;
-
- // run sp_selection_clone_original_path_lpe
- sp_selection_clone_original_path_lpe(current_desktop);
- SPItem *new_item = sel->singleItem();
- new_item->getRepr()->setAttribute("id", id);
- new_item->getRepr()->setAttribute("transform", transform);
- g_free(id);
- g_free(transform);
-
- /// \todo Add the LPE stack of the original path?
-
- SPDocument *doc = current_desktop->doc();
- DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT,
- _("Create and apply Clone original path effect"));
-
- lpe_list_locked = false;
- onSelectionChanged(sel);
+ } else {
+ SPUse *use = dynamic_cast<SPUse *>(item);
+ if ( use ) {
+ // item is a clone. do not show effectlist dialog.
+ // convert to path, apply CLONE_ORIGINAL LPE, link it to the cloned path
+
+ // test whether linked object is supported by the CLONE_ORIGINAL LPE
+ SPItem *orig = use->get_original();
+ if ( dynamic_cast<SPShape *>(orig) ||
+ dynamic_cast<SPText *>(orig) )
+ {
+ // select original
+ sel->set(orig);
+
+ // delete clone but remember its id and transform
+ gchar *id = g_strdup(item->getRepr()->attribute("id"));
+ gchar *transform = g_strdup(item->getRepr()->attribute("transform"));
+ item->deleteObject(false);
+ item = NULL;
+
+ // run sp_selection_clone_original_path_lpe
+ sp_selection_clone_original_path_lpe(current_desktop);
+ SPItem *new_item = sel->singleItem();
+ new_item->getRepr()->setAttribute("id", id);
+ new_item->getRepr()->setAttribute("transform", transform);
+ g_free(id);
+ g_free(transform);
+
+ /// \todo Add the LPE stack of the original path?
+
+ SPDocument *doc = current_desktop->doc();
+ DocumentUndo::done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT,
+ _("Create and apply Clone original path effect"));
+
+ lpe_list_locked = false;
+ onSelectionChanged(sel);
+ }
}
}
}
@@ -498,13 +502,14 @@ LivePathEffectEditor::onRemove()
Inkscape::Selection *sel = _getSelection();
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
- if ( item && SP_IS_LPE_ITEM(item) ) {
- SP_LPE_ITEM(item)->removeCurrentPathEffect(false);
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
+ if ( lpeitem ) {
+ lpeitem->removeCurrentPathEffect(false);
DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
_("Remove path effect") );
- effect_list_reload(SP_LPE_ITEM(item));
+ effect_list_reload(lpeitem);
}
}
@@ -515,7 +520,8 @@ void LivePathEffectEditor::onUp()
Inkscape::Selection *sel = _getSelection();
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
- if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) {
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
+ if ( lpeitem ) {
lpeitem->upCurrentPathEffect();
DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
@@ -531,7 +537,8 @@ void LivePathEffectEditor::onDown()
Inkscape::Selection *sel = _getSelection();
if ( sel && !sel->isEmpty() ) {
SPItem *item = sel->singleItem();
- if ( SPLPEItem *lpeitem = SP_LPE_ITEM(item) ) {
+ SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
+ if ( lpeitem ) {
lpeitem->downCurrentPathEffect();
DocumentUndo::done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT,
diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
new file mode 100644
index 000000000..55a19fc51
--- /dev/null
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
@@ -0,0 +1,301 @@
+/**
+ * From the code of Liam P.White from his Power Stroke Knot dialog
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED &&HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
+#include <gtkmm.h>
+#include "lpe-fillet-chamfer-properties.h"
+#include <boost/lexical_cast.hpp>
+#include <glibmm/main.h>
+#include <glibmm/i18n.h>
+#include "inkscape.h"
+#include "desktop.h"
+#include "document.h"
+#include "document-undo.h"
+#include "layer-manager.h"
+#include "message-stack.h"
+#include "desktop-handles.h"
+#include "sp-object.h"
+#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 "util/units.h"
+#include <cmath>
+
+//#include "event-context.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+FilletChamferPropertiesDialog::FilletChamferPropertiesDialog()
+ : _desktop(NULL), _knotpoint(NULL), _position_visible(false)
+{
+ Gtk::Box *mainVBox = get_vbox();
+ mainVBox->set_homogeneous(false);
+ _layout_table.set_spacings(4);
+ _layout_table.resize(3, 3);
+
+ // Layer name widgets
+ _fillet_chamfer_position_numeric.set_digits(4);
+ _fillet_chamfer_position_numeric.set_increments(1,1);
+ //todo: get tha max aloable infinity freeze the widget
+ _fillet_chamfer_position_numeric.set_range(0., 999999999999999999.);
+
+ _fillet_chamfer_position_label.set_label(_("Radius (pixels):"));
+ _fillet_chamfer_position_label.set_alignment(1.0, 0.5);
+
+ _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL,
+ Gtk::FILL);
+ _layout_table.attach(_fillet_chamfer_position_numeric, 1, 2, 0, 1,
+ Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+ _fillet_chamfer_chamfer_subdivisions.set_digits(0);
+ _fillet_chamfer_chamfer_subdivisions.set_increments(1,1);
+ //todo: get tha max aloable infinity freeze the widget
+ _fillet_chamfer_chamfer_subdivisions.set_range(0, 999999999999999999.0);
+
+ _fillet_chamfer_chamfer_subdivisions_label.set_label(_("Chamfer subdivisions:"));
+ _fillet_chamfer_chamfer_subdivisions_label.set_alignment(1.0, 0.5);
+
+ _layout_table.attach(_fillet_chamfer_chamfer_subdivisions_label, 0, 1, 1, 2, Gtk::FILL,
+ Gtk::FILL);
+ _layout_table.attach(_fillet_chamfer_chamfer_subdivisions, 1, 2, 1, 2,
+ Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+ _fillet_chamfer_type_fillet.set_label(_("Fillet"));
+ _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group);
+ _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet"));
+ _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group);
+ _fillet_chamfer_type_chamfer.set_label(_("Chamfer"));
+ _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group);
+ _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer"));
+ _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group);
+
+
+ mainVBox->pack_start(_layout_table, true, true, 4);
+ mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4);
+ mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4);
+ mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4);
+ mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4);
+
+ // Buttons
+ _close_button.set_use_stock(true);
+ _close_button.set_label(Gtk::Stock::CANCEL.id);
+ _close_button.set_can_default();
+
+ _apply_button.set_use_underline(true);
+ _apply_button.set_can_default();
+
+ _close_button.signal_clicked()
+ .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close));
+ _apply_button.signal_clicked()
+ .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_apply));
+
+ signal_delete_event().connect(sigc::bind_return(
+ sigc::hide(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)),
+ true));
+
+ add_action_widget(_close_button, Gtk::RESPONSE_CLOSE);
+ add_action_widget(_apply_button, Gtk::RESPONSE_APPLY);
+
+ _apply_button.grab_default();
+
+ show_all_children();
+
+ set_focus(_fillet_chamfer_position_numeric);
+}
+
+FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog()
+{
+
+ _set_desktop(NULL);
+}
+
+void FilletChamferPropertiesDialog::showDialog(
+ SPDesktop *desktop, Geom::Point knotpoint,
+ const Inkscape::LivePathEffect::
+ FilletChamferPointArrayParamKnotHolderEntity *pt,
+ const gchar *unit,
+ bool use_distance,
+ bool aprox_radius,
+ Glib::ustring const * documentUnit)
+{
+ FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog();
+
+ dialog->_set_desktop(desktop);
+ dialog->_set_unit(unit);
+ dialog->_set_use_distance(use_distance);
+ dialog->_set_aprox(aprox_radius);
+ dialog->_set_document_unit(documentUnit);
+ dialog->_set_knot_point(knotpoint);
+ dialog->_set_pt(pt);
+
+ dialog->set_title(_("Modify Fillet-Chamfer"));
+ dialog->_apply_button.set_label(_("_Modify"));
+
+ dialog->set_modal(true);
+ desktop->setWindowTransient(dialog->gobj());
+ dialog->property_destroy_with_parent() = true;
+
+ dialog->show();
+ dialog->present();
+}
+
+void FilletChamferPropertiesDialog::_apply()
+{
+ double d_width;
+ double d_pos = _fillet_chamfer_position_numeric.get_value();
+ if (d_pos) {
+ if (_fillet_chamfer_type_fillet.get_active() == true) {
+ d_width = 1;
+ } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) {
+ d_width = 2;
+ } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) {
+ d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000;
+ } else {
+ d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000;
+ }
+ if (_flexible) {
+ if (d_pos > 99.99999 || d_pos < 0) {
+ d_pos = 0;
+ }
+ d_pos = _index + (d_pos / 100);
+ } else {
+ d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, *document_unit);
+ d_pos = d_pos * -1;
+ }
+ _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width));
+ }
+ _close();
+}
+
+void FilletChamferPropertiesDialog::_close()
+{
+ _set_desktop(NULL);
+ destroy_();
+ Glib::signal_idle().connect(
+ sigc::bind_return(
+ sigc::bind(sigc::ptr_fun(&::operator delete), this),
+ false
+ )
+ );
+}
+
+bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/)
+{
+ return false;
+}
+
+void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event)
+{
+ if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) {
+ _apply();
+ }
+}
+
+void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint)
+{
+ double position;
+ std::string distance_or_radius = std::string(_("Radius "));
+ if(aprox){
+ distance_or_radius = std::string(_("Radius approximated "));
+ }
+ if(use_distance){
+ distance_or_radius = std::string(_("Knot distance "));
+ }
+ if (knotpoint.x() > 0) {
+ double intpart;
+ position = modf(knotpoint[Geom::X], &intpart) * 100;
+ _flexible = true;
+ _index = intpart;
+ _fillet_chamfer_position_label.set_label(_("Position (%):"));
+ } else {
+ _flexible = false;
+ std::string posConcat = distance_or_radius +
+ std::string(_("(")) + std::string(unit) + std::string(")");
+ _fillet_chamfer_position_label.set_label(_(posConcat.c_str()));
+ position = knotpoint[Geom::X] * -1;
+
+ position = Inkscape::Util::Quantity::convert(position, *document_unit, unit);
+ }
+ _fillet_chamfer_position_numeric.set_value(position);
+ if (knotpoint.y() == 1) {
+ _fillet_chamfer_type_fillet.set_active(true);
+ } else if (knotpoint.y() == 2) {
+ _fillet_chamfer_type_inverse_fillet.set_active(true);
+ } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) {
+ _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000);
+ _fillet_chamfer_type_chamfer.set_active(true);
+ } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) {
+ _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000);
+ _fillet_chamfer_type_inverse_chamfer.set_active(true);
+ }
+}
+
+void FilletChamferPropertiesDialog::_set_pt(
+ const Inkscape::LivePathEffect::
+ FilletChamferPointArrayParamKnotHolderEntity *pt)
+{
+ _knotpoint = const_cast<
+ Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity *>(
+ pt);
+}
+
+void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr)
+{
+ unit = abbr;
+}
+
+void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring const *abbr)
+{
+ document_unit = abbr;
+}
+
+void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance)
+{
+ use_distance = use_knot_distance;
+}
+
+void FilletChamferPropertiesDialog::_set_aprox(bool aprox_radius)
+{
+ aprox = aprox_radius;
+}
+
+void FilletChamferPropertiesDialog::_set_desktop(SPDesktop *desktop)
+{
+ if (desktop) {
+ Inkscape::GC::anchor(desktop);
+ }
+ if (_desktop) {
+ Inkscape::GC::release(_desktop);
+ }
+ _desktop = desktop;
+}
+
+} // namespace
+} // namespace
+} // namespace
+
+/*
+ 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/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h
new file mode 100644
index 000000000..3807e98c8
--- /dev/null
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h
@@ -0,0 +1,115 @@
+/**
+ *
+ * From the code of Liam P.White from his Power Stroke Knot dialog
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H
+#define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H
+
+#include <2geom/point.h>
+#include <gtkmm.h>
+#include "live_effects/parameter/filletchamferpointarray.h"
+
+class SPDesktop;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+class FilletChamferPropertiesDialog : public Gtk::Dialog {
+public:
+ FilletChamferPropertiesDialog();
+ virtual ~FilletChamferPropertiesDialog();
+
+ Glib::ustring getName() const {
+ return "LayerPropertiesDialog";
+ }
+
+ static void showDialog(SPDesktop *desktop, Geom::Point knotpoint,
+ const Inkscape::LivePathEffect::
+ FilletChamferPointArrayParamKnotHolderEntity *pt,
+ const gchar *unit,
+ bool use_distance,
+ bool aprox_radius,
+ Glib::ustring const * documentUnit);
+
+protected:
+
+ SPDesktop *_desktop;
+ Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity *
+ _knotpoint;
+
+ Gtk::Label _fillet_chamfer_position_label;
+ Gtk::SpinButton _fillet_chamfer_position_numeric;
+ Gtk::RadioButton::Group _fillet_chamfer_type_group;
+ Gtk::RadioButton _fillet_chamfer_type_fillet;
+ Gtk::RadioButton _fillet_chamfer_type_inverse_fillet;
+ Gtk::RadioButton _fillet_chamfer_type_chamfer;
+ Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer;
+ Gtk::Label _fillet_chamfer_chamfer_subdivisions_label;
+ Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions;
+
+ Gtk::Table _layout_table;
+ bool _position_visible;
+ double _index;
+
+ Gtk::Button _close_button;
+ Gtk::Button _apply_button;
+
+ sigc::connection _destroy_connection;
+
+ static FilletChamferPropertiesDialog &_instance() {
+ static FilletChamferPropertiesDialog instance;
+ return instance;
+ }
+
+ void _set_desktop(SPDesktop *desktop);
+ void _set_pt(const Inkscape::LivePathEffect::
+ FilletChamferPointArrayParamKnotHolderEntity *pt);
+ void _set_unit(const gchar *abbr);
+ void _set_document_unit(Glib::ustring const * abbr);
+ void _set_use_distance(bool use_knot_distance);
+ void _set_aprox(bool aprox_radius);
+ void _apply();
+ void _close();
+ bool _flexible;
+ const gchar *unit;
+ Glib::ustring const * document_unit;
+ bool use_distance;
+ bool aprox;
+ void _set_knot_point(Geom::Point knotpoint);
+ void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
+
+ bool _handleKeyEvent(GdkEventKey *event);
+ void _handleButtonEvent(GdkEventButton *event);
+
+ friend class Inkscape::LivePathEffect::
+ FilletChamferPointArrayParamKnotHolderEntity;
+
+private:
+ FilletChamferPropertiesDialog(
+ FilletChamferPropertiesDialog const &); // no copy
+ FilletChamferPropertiesDialog &operator=(
+ FilletChamferPropertiesDialog const &); // no assign
+};
+
+} // namespace
+} // namespace
+} // namespace
+
+#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_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/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp
new file mode 100644
index 000000000..55f938a48
--- /dev/null
+++ b/src/ui/dialog/lpe-powerstroke-properties.cpp
@@ -0,0 +1,211 @@
+/**
+ * @file
+ * Dialog for renaming layers.
+ */
+/* Author:
+ * Bryce W. Harrington <bryce@bryceharrington.com>
+ * Andrius R. <knutux@gmail.com>
+ * Abhishek Sharma
+ *
+ * Copyright (C) 2004 Bryce Harrington
+ * Copyright (C) 2006 Andrius R.
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
+#include "lpe-powerstroke-properties.h"
+#include <boost/lexical_cast.hpp>
+#include <gtkmm/stock.h>
+#include <glibmm/main.h>
+#include <glibmm/i18n.h>
+#include "inkscape.h"
+#include "desktop.h"
+#include "document.h"
+#include "document-undo.h"
+#include "layer-manager.h"
+#include "message-stack.h"
+#include "desktop-handles.h"
+#include "sp-object.h"
+#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 {
+namespace Dialogs {
+
+PowerstrokePropertiesDialog::PowerstrokePropertiesDialog()
+: _desktop(NULL), _knotpoint(NULL), _position_visible(false)
+{
+ Gtk::Box *mainVBox = get_vbox();
+
+ _layout_table.set_spacings(4);
+ _layout_table.resize (2, 2);
+
+ // Layer name widgets
+ _powerstroke_position_entry.set_activates_default(true);
+ _powerstroke_position_label.set_label(_("Position:"));
+ _powerstroke_position_label.set_alignment(1.0, 0.5);
+
+ _powerstroke_width_entry.set_activates_default(true);
+ _powerstroke_width_label.set_label(_("Width:"));
+ _powerstroke_width_label.set_alignment(1.0, 0.5);
+
+ _layout_table.attach(_powerstroke_position_label,
+ 0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
+ _layout_table.attach(_powerstroke_position_entry,
+ 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+
+ _layout_table.attach(_powerstroke_width_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
+ _layout_table.attach(_powerstroke_width_entry, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+
+ mainVBox->pack_start(_layout_table, true, true, 4);
+
+ // Buttons
+ _close_button.set_use_stock(true);
+ _close_button.set_label(Gtk::Stock::CANCEL.id);
+ _close_button.set_can_default();
+
+ _apply_button.set_use_underline(true);
+ _apply_button.set_can_default();
+
+ _close_button.signal_clicked()
+ .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close));
+ _apply_button.signal_clicked()
+ .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_apply));
+
+ signal_delete_event().connect(
+ sigc::bind_return(
+ sigc::hide(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)),
+ true
+ )
+ );
+
+ add_action_widget(_close_button, Gtk::RESPONSE_CLOSE);
+ add_action_widget(_apply_button, Gtk::RESPONSE_APPLY);
+
+ _apply_button.grab_default();
+
+ show_all_children();
+
+ set_focus(_powerstroke_width_entry);
+}
+
+PowerstrokePropertiesDialog::~PowerstrokePropertiesDialog() {
+
+ _setDesktop(NULL);
+}
+
+void PowerstrokePropertiesDialog::showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt)
+{
+ PowerstrokePropertiesDialog *dialog = new PowerstrokePropertiesDialog();
+
+ dialog->_setDesktop(desktop);
+ dialog->_setKnotPoint(knotpoint);
+ dialog->_setPt(pt);
+
+ dialog->set_title(_("Modify Node Position"));
+ dialog->_apply_button.set_label(_("_Move"));
+
+ dialog->set_modal(true);
+ desktop->setWindowTransient (dialog->gobj());
+ dialog->property_destroy_with_parent() = true;
+
+ dialog->show();
+ dialog->present();
+}
+
+void
+PowerstrokePropertiesDialog::_apply()
+{
+ std::istringstream i_pos(_powerstroke_position_entry.get_text());
+ std::istringstream i_width(_powerstroke_width_entry.get_text());
+ double d_pos, d_width;
+ if ((i_pos >> d_pos) && i_width >> d_width) {
+ _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width));
+ }
+ _close();
+}
+
+void
+PowerstrokePropertiesDialog::_close()
+{
+ _setDesktop(NULL);
+ destroy_();
+ Glib::signal_idle().connect(
+ sigc::bind_return(
+ sigc::bind(sigc::ptr_fun(&::operator delete), this),
+ false
+ )
+ );
+}
+
+bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey * /*event*/)
+{
+
+ /*switch (get_group0_keyval(event)) {
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter: {
+ _apply();
+ return true;
+ }
+ break;
+ }*/
+ return false;
+}
+
+void PowerstrokePropertiesDialog::_handleButtonEvent(GdkEventButton* event)
+{
+ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) {
+ _apply();
+ }
+}
+
+void PowerstrokePropertiesDialog::_setKnotPoint(Geom::Point knotpoint)
+{
+ _powerstroke_position_entry.set_text(boost::lexical_cast<std::string>(knotpoint.x()));
+ _powerstroke_width_entry.set_text(boost::lexical_cast<std::string>(knotpoint.y()));
+}
+
+void PowerstrokePropertiesDialog::_setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt)
+{
+ _knotpoint = const_cast<Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *>(pt);
+}
+
+void PowerstrokePropertiesDialog::_setDesktop(SPDesktop *desktop) {
+ if (desktop) {
+ Inkscape::GC::anchor (desktop);
+ }
+ if (_desktop) {
+ Inkscape::GC::release (_desktop);
+ }
+ _desktop = desktop;
+}
+
+} // namespace
+} // namespace
+} // namespace
+
+
+/*
+ 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/lpe-powerstroke-properties.h b/src/ui/dialog/lpe-powerstroke-properties.h
new file mode 100644
index 000000000..c53eac0d9
--- /dev/null
+++ b/src/ui/dialog/lpe-powerstroke-properties.h
@@ -0,0 +1,99 @@
+/** @file
+ * @brief Dialog for renaming layers
+ */
+/* Author:
+ * Bryce W. Harrington <bryce@bryceharrington.com>
+ *
+ * Copyright (C) 2004 Bryce Harrington
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H
+#define INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H
+
+#include <2geom/point.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/label.h>
+#include <gtkmm/table.h>
+#include <gtkmm/combobox.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
+#include "live_effects/parameter/powerstrokepointarray.h"
+
+class SPDesktop;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+class PowerstrokePropertiesDialog : public Gtk::Dialog {
+ public:
+ PowerstrokePropertiesDialog();
+ virtual ~PowerstrokePropertiesDialog();
+
+ Glib::ustring getName() const { return "LayerPropertiesDialog"; }
+
+ static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt);
+
+protected:
+
+ SPDesktop *_desktop;
+ Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *_knotpoint;
+
+ Gtk::Label _powerstroke_position_label;
+ Gtk::Entry _powerstroke_position_entry;
+ Gtk::Label _powerstroke_width_label;
+ Gtk::Entry _powerstroke_width_entry;
+ Gtk::Table _layout_table;
+ bool _position_visible;
+
+ Gtk::Button _close_button;
+ Gtk::Button _apply_button;
+
+ sigc::connection _destroy_connection;
+
+ static PowerstrokePropertiesDialog &_instance() {
+ static PowerstrokePropertiesDialog instance;
+ return instance;
+ }
+
+ void _setDesktop(SPDesktop *desktop);
+ void _setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt);
+
+ void _apply();
+ void _close();
+
+ void _setKnotPoint(Geom::Point knotpoint);
+ void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
+
+ bool _handleKeyEvent(GdkEventKey *event);
+ void _handleButtonEvent(GdkEventButton* event);
+
+ friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity;
+
+private:
+ PowerstrokePropertiesDialog(PowerstrokePropertiesDialog const &); // no copy
+ PowerstrokePropertiesDialog &operator=(PowerstrokePropertiesDialog const &); // no assign
+};
+
+} // namespace
+} // namespace
+} // namespace
+
+
+#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_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/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp
index f326bb3ee..e30b148bb 100644
--- a/src/ui/dialog/new-from-template.cpp
+++ b/src/ui/dialog/new-from-template.cpp
@@ -8,6 +8,9 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
#include "new-from-template.h"
#include "file.h"
@@ -25,12 +28,22 @@ NewFromTemplate::NewFromTemplate()
{
set_title(_("New From Template"));
resize(400, 400);
-
+
+#if WITH_GTKMM_3_0
+ get_content_area()->pack_start(_main_widget);
+#else
get_vbox()->pack_start(_main_widget);
+#endif
Gtk::Alignment *align;
align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0));
+
+#if WITH_GTKMM_3_0
+ get_content_area()->pack_end(*align, Gtk::PACK_SHRINK);
+#else
get_vbox()->pack_end(*align, Gtk::PACK_SHRINK);
+#endif
+
align->set_padding(0, 0, 0, 15);
align->add(_create_template_button);
diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp
new file mode 100644
index 000000000..c95529a56
--- /dev/null
+++ b/src/ui/dialog/objects.cpp
@@ -0,0 +1,2144 @@
+/*
+ * A simple panel for objects
+ *
+ * Authors:
+ * Theodore Janeczko
+ * Tweaked by Liam P White for use in Inkscape
+ *
+ * Copyright (C) Theodore Janeczko 2012 <flutterguy317@gmail.com>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "objects.h"
+#include <gtkmm/widget.h>
+#include <gtkmm/icontheme.h>
+#include <gtkmm/imagemenuitem.h>
+#include <gtkmm/separatormenuitem.h>
+#include <gtkmm/stock.h>
+
+#include <glibmm/i18n.h>
+#include <glibmm/main.h>
+
+#include "desktop.h"
+#include "desktop-style.h"
+#include "ui/dialog-events.h"
+#include "document.h"
+#include "document-undo.h"
+#include "filter-chemistry.h"
+#include "filters/blend.h"
+#include "filters/gaussian-blur.h"
+#include "helper/action.h"
+#include "inkscape.h"
+#include "layer-manager.h"
+#include "preferences.h"
+#include "selection.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
+#include "sp-item.h"
+#include "sp-object.h"
+#include "sp-root.h"
+#include "sp-shape.h"
+#include "style.h"
+#include "ui/tools-switch.h"
+#include "ui/icon-names.h"
+#include "ui/widget/imagetoggler.h"
+#include "ui/widget/layertypeicon.h"
+#include "ui/widget/insertordericon.h"
+#include "ui/widget/clipmaskicon.h"
+#include "ui/widget/highlight-picker.h"
+#include "ui/tools/node-tool.h"
+#include "ui/tools/tool-base.h"
+#include "verbs.h"
+#include "widgets/sp-color-notebook.h"
+#include "widgets/icon.h"
+#include "xml/node.h"
+#include "xml/node-observer.h"
+#include "xml/repr.h"
+
+//#define DUMP_LAYERS 1
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+using Inkscape::XML::Node;
+
+/**
+ * Gets an instance of the Objects panel
+ */
+ObjectsPanel& ObjectsPanel::getInstance()
+{
+ return *new ObjectsPanel();
+}
+
+/**
+ * Column enumeration
+ */
+enum {
+ COL_VISIBLE = 1,
+ COL_LOCKED,
+ COL_TYPE,
+// COL_INSERTORDER,
+ COL_CLIPMASK,
+ COL_HIGHLIGHT
+};
+
+/**
+ * Button enumeration
+ */
+enum {
+ BUTTON_NEW = 0,
+ BUTTON_RENAME,
+ BUTTON_TOP,
+ BUTTON_BOTTOM,
+ BUTTON_UP,
+ BUTTON_DOWN,
+ BUTTON_DUPLICATE,
+ BUTTON_DELETE,
+ BUTTON_SOLO,
+ BUTTON_SHOW_ALL,
+ BUTTON_HIDE_ALL,
+ BUTTON_LOCK_OTHERS,
+ BUTTON_LOCK_ALL,
+ BUTTON_UNLOCK_ALL,
+ BUTTON_SETCLIP,
+ BUTTON_CLIPGROUP,
+// BUTTON_SETINVCLIP,
+ BUTTON_UNSETCLIP,
+ BUTTON_SETMASK,
+ BUTTON_UNSETMASK,
+ BUTTON_GROUP,
+ BUTTON_UNGROUP,
+ BUTTON_COLLAPSE_ALL,
+ DRAGNDROP
+};
+
+/**
+ * Xml node observer for observing objects in the document
+ */
+class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver {
+public:
+ /**
+ * Creates a new object watcher
+ * @param pnl The panel to which the object watcher belongs
+ * @param obj The object to watch
+ */
+ ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) :
+ _pnl(pnl),
+ _obj(obj),
+ _repr(obj->getRepr()),
+ _highlightAttr(g_quark_from_string("inkscape:highlight-color")),
+ _lockedAttr(g_quark_from_string("sodipodi:insensitive")),
+ _labelAttr(g_quark_from_string("inkscape:label")),
+ _groupAttr(g_quark_from_string("inkscape:groupmode")),
+ _styleAttr(g_quark_from_string("style")),
+ _clipAttr(g_quark_from_string("clip-path")),
+ _maskAttr(g_quark_from_string("mask"))
+ {}
+
+ virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared<char> /*old_content*/, Util::ptr_shared<char> /*new_content*/ ) {}
+ virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared<char> /*old_value*/, Util::ptr_shared<char> /*new_value*/ ) {
+ if ( _pnl && _obj ) {
+ if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) {
+ _pnl->_updateObject(_obj, name == _highlightAttr);
+ if ( name == _styleAttr ) {
+ _pnl->_updateComposite();
+ }
+ }
+ }
+ }
+
+ /**
+ * Objects panel to which this watcher belongs
+ */
+ ObjectsPanel* _pnl;
+
+ /**
+ * The object that is being observed
+ */
+ SPObject* _obj;
+
+ /**
+ * The xml representation of the object that is being observed
+ */
+ Inkscape::XML::Node* _repr;
+
+ /* These are quarks which define the attributes that we are observing */
+ GQuark _highlightAttr;
+ GQuark _lockedAttr;
+ GQuark _labelAttr;
+ GQuark _groupAttr;
+ GQuark _styleAttr;
+ GQuark _clipAttr;
+ GQuark _maskAttr;
+};
+
+class ObjectsPanel::InternalUIBounce
+{
+public:
+ int _actionCode;
+};
+
+class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+
+ ModelColumns()
+ {
+ add(_colObject);
+ add(_colVisible);
+ add(_colLocked);
+ add(_colLabel);
+ add(_colType);
+ add(_colHighlight);
+ add(_colClipMask);
+ //add(_colInsertOrder);
+ }
+ virtual ~ModelColumns() {}
+
+ Gtk::TreeModelColumn<SPItem*> _colObject;
+ Gtk::TreeModelColumn<Glib::ustring> _colLabel;
+ Gtk::TreeModelColumn<bool> _colVisible;
+ Gtk::TreeModelColumn<bool> _colLocked;
+ Gtk::TreeModelColumn<int> _colType;
+ Gtk::TreeModelColumn<guint32> _colHighlight;
+ Gtk::TreeModelColumn<int> _colClipMask;
+ //Gtk::TreeModelColumn<int> _colInsertOrder;
+};
+
+/**
+ * Stylizes a button using the given icon name and tooltip
+ */
+void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip )
+{
+ GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName );
+ gtk_widget_show( child );
+ btn.add( *Gtk::manage(Glib::wrap(child)) );
+ btn.set_relief(Gtk::RELIEF_NONE);
+
+ btn.set_tooltip_text (tooltip);
+
+}
+
+/**
+ * Adds an item to the pop-up (right-click) menu
+ * @param desktop The active destktop
+ * @param code Action code
+ * @param iconName Icon name
+ * @param fallback Fallback text
+ * @param id Button id for callback function
+ * @return The generated menu item
+ */
+Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id )
+{
+ GtkWidget* iconWidget = 0;
+ const char* label = 0;
+
+ if ( iconName ) {
+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName );
+ }
+
+ if ( desktop ) {
+ Verb *verb = Verb::get( code );
+ if ( verb ) {
+ SPAction *action = verb->get_action(desktop);
+ if ( !iconWidget && action && action->image ) {
+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image );
+ }
+
+ if ( action ) {
+ // label = action->name;
+ }
+ }
+ }
+
+ if ( !label && fallback ) {
+ label = fallback;
+ }
+
+ Gtk::Widget* wrapped = 0;
+ if ( iconWidget ) {
+ wrapped = Gtk::manage(Glib::wrap(iconWidget));
+ wrapped->show();
+ }
+
+
+ Gtk::MenuItem* item = 0;
+
+ if (wrapped) {
+ item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true));
+ } else {
+ item = Gtk::manage(new Gtk::MenuItem(label, true));
+ }
+
+ item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id));
+ _popupMenu.append(*item);
+
+ return *item;
+}
+
+/**
+ * Callback function for when an object changes. Essentially refreshes the entire tree
+ * @param obj Object which was changed (currently not used as the entire tree is recreated)
+ */
+void ObjectsPanel::_objectsChanged(SPObject */*obj*/)
+{
+ //First, unattach the watchers
+ while (!_objectWatchers.empty())
+ {
+ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back();
+ w->_repr->removeObserver(*w);
+ _objectWatchers.pop_back();
+ delete w;
+ }
+
+ if (_desktop) {
+ //Get the current document's root and use that to enumerate the tree
+ SPDocument* document = _desktop->doc();
+ SPRoot* root = document->getRoot();
+ if ( root ) {
+ _selectedConnection.block();
+ //Clear the tree store
+ _store->clear();
+ //Add all items recursively
+ _addObject( root, 0 );
+ _selectedConnection.unblock();
+ //Set the tree selection
+ _objectsSelected(_desktop->selection);
+ //Handle button sensitivity
+ _checkTreeSelection();
+ }
+ }
+}
+
+/**
+ * Recursively adds the children of the given item to the tree
+ * @param obj Root object to add to the tree
+ * @param parentRow Parent tree row (or NULL if adding to tree root)
+ */
+void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow)
+{
+ if ( _desktop && obj ) {
+ for ( SPObject *child = obj->children; child != NULL; child = child->next) {
+
+ if (SP_IS_ITEM(child))
+ {
+ SPItem * item = SP_ITEM(child);
+ SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0;
+
+ //Add the item to the tree and set the column information
+ Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend();
+ Gtk::TreeModel::Row row = *iter;
+ row[_model->_colObject] = item;
+ //this seems to crash on convert stroke to path then undo (probably no ID?)
+ try {
+ row[_model->_colLabel] = item->label() ? item->label() : item->getId();
+ } catch (...) {
+ row[_model->_colLabel] = Glib::ustring("getId_failure");
+ g_critical("item->getId() failed, using \"getId_failure\"");
+ }
+ row[_model->_colVisible] = !item->isHidden();
+ row[_model->_colLocked] = !item->isSensitive();
+ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0;
+ row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00;
+ row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0);
+ //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0;
+
+ //If our parent object is a group and it's expanded, expand the tree
+ if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded())
+ {
+ _tree.expand_to_path( _store->get_path(iter) );
+ }
+
+ //Add an object watcher to the item
+ ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child);
+ child->getRepr()->addObserver(*w);
+ _objectWatchers.push_back(w);
+
+ //If the item is a group, recursively add its children
+ if (group)
+ {
+ _addObject( child, &row );
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Updates an item in the tree and optionally recursively updates the item's children
+ * @param obj The item to update in the tree
+ * @param recurse Whether to recurse through the item's children
+ */
+void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) {
+ //Find the object in the tree store and update it
+
+ //mark
+ _store->foreach_iter( sigc::bind<SPObject*>(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) );
+ //end mark
+ if (recurse)
+ {
+ for (SPObject * iter = obj->children; iter != NULL; iter = iter->next)
+ {
+ _updateObject(iter, recurse);
+ }
+ }
+}
+
+/**
+ * Checks items in the tree store and updates the given item
+ * @param iter Current item being looked at in the tree
+ * @param obj Object to update
+ * @return
+ */
+bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj)
+{
+ Gtk::TreeModel::Row row = *iter;
+ if ( obj == row[_model->_colObject] )
+ {
+ //We found our item in the tree!! Update it!
+ SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0;
+ SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0;
+
+ row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId();
+ row[_model->_colVisible] = item ? !item->isHidden() : false;
+ row[_model->_colLocked] = item ? !item->isSensitive() : false;
+ row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0;
+ row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0;
+ row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0;
+ //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0;
+
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Updates the composite controls for the selected item
+ */
+void ObjectsPanel::_updateComposite() {
+ if (!_blockCompositeUpdate)
+ {
+ //Set the default values
+ bool setValues = true;
+
+ //Get/set the values
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<bool *>(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues));
+ }
+}
+
+/**
+ * Sets the compositing values for the first selected item in the tree
+ * @param iter Current tree item
+ * @param setValues Whether to set the compositing values
+ * @param blur Blur value to use
+ */
+void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues )
+{
+ if (iter) {
+ Gtk::TreeModel::Row row = *iter;
+ SPItem *item = row[_model->_colObject];
+ if (*setValues)
+ {
+ _setCompositingValues(item);
+ *setValues = false;
+ }
+ }
+}
+
+/**
+ * Occurs when the current desktop selection changes
+ * @param sel The current selection
+ */
+void ObjectsPanel::_objectsSelected( Selection *sel ) {
+
+ bool setOpacity = true;
+ _selectedConnection.block();
+ _tree.get_selection()->unselect_all();
+ SPItem *item = NULL;
+ for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next)
+ {
+ item = reinterpret_cast<SPItem *>(iter->data);
+ if (setOpacity)
+ {
+ _setCompositingValues(item);
+ setOpacity = false;
+ }
+ _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL));
+ }
+ if (!item) {
+ if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) {
+ item = SP_ITEM(_desktop->currentLayer());
+ _setCompositingValues(item);
+ _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true));
+ }
+ }
+ _selectedConnection.unblock();
+ _checkTreeSelection();
+}
+
+/**
+ * Helper function for setting the compositing values
+ * @param item Item to use for setting the compositing values
+ */
+void ObjectsPanel::_setCompositingValues(SPItem *item)
+{
+ //Block the connections to avoid interference
+ _opacityConnection.block();
+ _blendConnection.block();
+ _blurConnection.block();
+
+ //Set the opacity
+#if WITH_GTKMM_3_0
+ _opacity_adjustment->set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment->get_upper());
+#else
+ _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper());
+#endif
+ SPFeBlend *spblend = NULL;
+ SPGaussianBlur *spblur = NULL;
+ if (item->style->getFilter())
+ {
+ for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) {
+ if(SP_IS_FEBLEND(primitive_obj) && !spblend) {
+ //Get the blend mode
+ spblend = SP_FEBLEND(primitive_obj);
+ }
+
+ if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) {
+ //Get the blur value
+ spblur = SP_GAUSSIANBLUR(primitive_obj);
+ }
+ }
+ }
+
+ //Set the blend mode
+ _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL);
+
+ //Set the blur value
+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX);
+ if (bbox && spblur) {
+ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct?
+ _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter);
+ } else {
+ _fe_blur.set_blur_value(0);
+ }
+
+ //Unblock connections
+ _blurConnection.unblock();
+ _blendConnection.unblock();
+ _opacityConnection.unblock();
+}
+
+/**
+ * Checks the tree and selects the specified item, optionally scrolling to the item
+ * @param path Current tree path
+ * @param iter Current tree item
+ * @param item Item to select in the tree
+ * @param scrollto Whether to scroll to the item
+ * @return Whether to continue searching the tree
+ */
+bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto)
+{
+ bool stopGoing = false;
+
+ Gtk::TreeModel::Row row = *iter;
+ if ( item == row[_model->_colObject] )
+ {
+ //We found the item! Expand to the path and select it in the tree.
+ _tree.expand_to_path( path );
+
+ Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
+
+ select->select(iter);
+ if (scrollto) {
+ //Scroll to the item in the tree
+ _tree.scroll_to_row(path);
+ }
+
+ stopGoing = true;
+ }
+
+ return stopGoing;
+}
+
+/**
+ * Pushes the current tree selection to the canvas
+ */
+void ObjectsPanel::_pushTreeSelectionToCurrent()
+{
+ if ( _desktop && _desktop->currentRoot() ) {
+ //block connections for selection and compositing values to prevent interference
+ _selectionChangedConnection.block();
+
+ //Clear the selection and then iterate over the tree selection, pushing each item to the desktop
+ _desktop->selection->clear();
+ bool setOpacity = true;
+ _tree.get_selection()->selected_foreach_iter( sigc::bind<bool *>(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity));
+ //unblock connections
+ _selectionChangedConnection.unblock();
+
+ _checkTreeSelection();
+ }
+}
+
+/**
+ * Helper function for pushing the current tree selection to the current desktop
+ * @param iter Current tree item
+ * @param setCompositingValues Whether to set the compositing values
+ * @param blur
+ */
+void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues )
+{
+ if (iter) {
+ Gtk::TreeModel::Row row = *iter;
+ SPItem *item = row[_model->_colObject];
+ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER)
+ {
+ //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item)
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent);
+ _desktop->selection->add(item);
+ }
+ else
+ {
+ //If the item is a layer, set the current layer
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item);
+ }
+ if (*setCompositingValues)
+ {
+ //Only set the compositing values for the first item
+ _setCompositingValues(item);
+ *setCompositingValues = false;
+ }
+ }
+}
+
+/**
+ * Handles button sensitivity
+ */
+void ObjectsPanel::_checkTreeSelection()
+{
+ bool sensitive = _tree.get_selection()->count_selected_rows() > 0;
+ //TODO: top/bottom sensitivity
+ bool sensitiveNonTop = true;
+ bool sensitiveNonBottom = true;
+
+ for ( std::vector<Gtk::Widget*>::iterator it = _watching.begin(); it != _watching.end(); ++it ) {
+ (*it)->set_sensitive( sensitive );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) {
+ (*it)->set_sensitive( sensitiveNonTop );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) {
+ (*it)->set_sensitive( sensitiveNonBottom );
+ }
+}
+
+/**
+ * Sets visibility of items in the tree
+ * @param iter Current item in the tree
+ * @param visible Whether the item should be visible or not
+ */
+void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible )
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ item->setHidden( !visible );
+ row[_model->_colVisible] = visible;
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+}
+
+/**
+ * Sets sensitivity of items in the tree
+ * @param iter Current item in the tree
+ * @param locked Whether the item should be locked
+ */
+void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked )
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ item->setLocked( locked );
+ row[_model->_colLocked] = locked;
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+}
+
+/**
+ * Handles keyboard events
+ * @param event Keyboard event passed in from GDK
+ * @return Whether the event should be eaten (om nom nom)
+ */
+bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event)
+{
+
+ bool empty = _desktop->selection->isEmpty();
+
+ switch (Inkscape::UI::Tools::get_group0_keyval(event)) {
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ case GDK_KEY_F2:
+ {
+ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
+ if (iter && !_text_renderer->property_editable()) {
+ //Rename item
+ Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter);
+ _text_renderer->property_editable() = true;
+ _tree.set_cursor(*path, *_name_column, true);
+ grab_focus();
+ return true;
+ }
+ }
+ break;
+ case GDK_KEY_Home:
+ //Move item(s) to top of containing group/layer
+ _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT );
+ break;
+ case GDK_KEY_End:
+ //Move item(s) to bottom of containing group/layer
+ _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK );
+ break;
+ case GDK_KEY_Page_Up:
+ {
+ //Move item(s) up in containing group/layer
+ int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE;
+ _fireAction( empty ? SP_VERB_LAYER_RAISE : ch );
+ break;
+ }
+ case GDK_KEY_Page_Down:
+ {
+ //Move item(s) down in containing group/layer
+ int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER;
+ _fireAction( empty ? SP_VERB_LAYER_LOWER : ch );
+ break;
+ }
+
+ //TODO: Handle Ctrl-A, etc.
+ default:
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Handles mouse events
+ * @param event Mouse event from GDK
+ * @return whether to eat the event (om nom nom)
+ */
+bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event)
+{
+ static unsigned doubleclick = 0;
+ static bool overVisible = false;
+
+ //Right mouse button was clicked, launch the pop-up menu
+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) {
+ 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);
+ if (_tree.get_selection()->is_selected(path)) {
+ return true;
+ }
+ }
+ }
+
+ //Left mouse button was pressed! In order to handle multiple item drag & drop,
+ //we need to defer selection by setting the select function so that the tree doesn't
+ //automatically select anything. In order to handle multiple item icon clicking,
+ //we need to eat the event. There might be a better way to do both of these...
+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
+ overVisible = false;
+ 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)) {
+ //Click on visible column, eat this event to keep row selection
+ overVisible = true;
+ return true;
+ } else if (col == _tree.get_column(COL_LOCKED-1) ||
+ col == _tree.get_column(COL_TYPE-1) ||
+ //col == _tree.get_column(COL_INSERTORDER - 1) ||
+ col == _tree.get_column(COL_HIGHLIGHT-1)) {
+ //Click on an icon column, eat this event to keep row selection
+ return true;
+ } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) {
+ //Click on a selected item with no modifiers, defer selection to the mouse-up by
+ //setting the select function to _noSelection
+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection));
+ _defer_target = path;
+ }
+ }
+ }
+
+ //Restore the selection function to allow tree selection on mouse button release
+ if ( event->type == GDK_BUTTON_RELEASE) {
+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction));
+ }
+
+ //CellRenderers do not have good support for dealing with multiple items, so
+ //we handle all events on them here
+ if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) {
+
+ 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 (_defer_target) {
+ //We had deferred a selection target, select it here (assuming no drag & drop)
+ if (_defer_target == path && !(event->x == 0 && event->y == 0))
+ {
+ _tree.set_cursor(path, *col, false);
+ }
+ _defer_target = Gtk::TreeModel::Path();
+ }
+ else {
+ 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;
+ SPItem *item = row[_model->_colObject];
+ if (col == _tree.get_column(COL_VISIBLE - 1)) {
+ _desktop->toggleLayerSolo( item );
+ DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo"));
+ } else if (col == _tree.get_column(COL_LOCKED - 1)) {
+ _desktop->toggleLockOtherLayers( item );
+ DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers"));
+ }
+ }
+ } else {
+ Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+
+ SPItem* item = row[_model->_colObject];
+
+ if (col == _tree.get_column(COL_VISIBLE - 1)) {
+ if (overVisible) {
+ //Toggle visibility
+ bool newValue = !row[_model->_colVisible];
+ if (_tree.get_selection()->is_selected(path))
+ {
+ //If the current row is selected, toggle the visibility
+ //for all selected items
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<bool>(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue));
+ }
+ else
+ {
+ //If the current row is not selected, toggle just its visibility
+ row[_model->_colVisible] = newValue;
+ item->setHidden(!newValue);
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS,
+ newValue? _("Unhide objects") : _("Hide objects"));
+ overVisible = false;
+ }
+ } else if (col == _tree.get_column(COL_LOCKED - 1)) {
+ //Toggle locking
+ bool newValue = !row[_model->_colLocked];
+ if (_tree.get_selection()->is_selected(path))
+ {
+ //If the current row is selected, toggle the sensitivity for
+ //all selected items
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<bool>(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue));
+ }
+ else
+ {
+ //If the current row is not selected, toggle just its sensitivity
+ row[_model->_colLocked] = newValue;
+ item->setLocked( newValue );
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS,
+ newValue? _("Lock objects") : _("Unlock objects"));
+
+ } else if (col == _tree.get_column(COL_TYPE - 1)) {
+ if (SP_IS_GROUP(item))
+ {
+ //Toggle the current item between a group and a layer
+ SPGroup * g = SP_GROUP(item);
+ bool newValue = g->layerMode() == SPGroup::LAYER;
+ row[_model->_colType] = newValue ? 1: 2;
+ g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER);
+ g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS,
+ newValue? _("Layer to group") : _("Group to layer"));
+ }
+ } /*else if (col == _tree.get_column(COL_INSERTORDER - 1)) {
+ if (SP_IS_GROUP(item))
+ {
+ //Toggle the current item's insert order
+ SPGroup * g = SP_GROUP(item);
+ bool newValue = !g->insertBottom();
+ row[_model->_colInsertOrder] = newValue ? 2: 1;
+ g->setInsertBottom(newValue);
+ g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS,
+ newValue? _("Set insert mode bottom") : _("Set insert mode top"));
+ }
+ }*/ else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) {
+ //Clear the highlight targets
+ _highlight_target.clear();
+ if (_tree.get_selection()->is_selected(path))
+ {
+ //If the current item is selected, store all selected items
+ //in the highlight source
+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget));
+ } else {
+ //If the current item is not selected, store only it in the highlight source
+ _storeHighlightTarget(iter);
+ }
+ if (_colorSelector)
+ {
+ //Set up the color selector
+ SPColor color;
+ color.set( row[_model->_colHighlight] );
+ _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight]));
+ }
+ //Show the color selector dialog
+ _colorSelectorDialog.show();
+ }
+ }
+ }
+ }
+ }
+
+ //Second mouse button press, set double click status for when the mouse is released
+ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) {
+ doubleclick = 1;
+ }
+
+ //Double click on mouse button release, if we're over the label column, edit
+ //the item name
+ if ( event->type == GDK_BUTTON_RELEASE && doubleclick) {
+ doubleclick = 0;
+ 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 ) && col == _name_column) {
+ // Double click on the Layer name, enable editing
+ _text_renderer->property_editable() = true;
+ _tree.set_cursor (path, *_name_column, true);
+ grab_focus();
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Stores items in the highlight target vector to manipulate with the color selector
+ * @param iter Current tree item to store
+ */
+void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ _highlight_target.push_back(item);
+ }
+}
+
+/*
+ * Drap and drop within the tree
+ */
+bool ObjectsPanel::_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;
+ Gtk::TreeView::Column *target_column;
+
+ //Set up our defaults and clear the source vector
+ _dnd_into = false;
+ _dnd_target = NULL;
+ _dnd_source.clear();
+
+ //Add all selected items to the source vector
+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource));
+
+ if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) {
+ // Are we before, inside or after the drop layer
+ Gdk::Rectangle rect;
+ _tree.get_background_area (target_path, *target_column, rect);
+ int cell_height = rect.get_height();
+ _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4));
+ if (cell_y > (int)(cell_height * 3/4)) {
+ Gtk::TreeModel::Path next_path = target_path;
+ next_path.next();
+ if (_store->iter_is_valid(_store->get_iter(next_path))) {
+ target_path = next_path;
+ } else {
+ // Dragging to the "end"
+ Gtk::TreeModel::Path up_path = target_path;
+ up_path.up();
+ if (_store->iter_is_valid(_store->get_iter(up_path))) {
+ // Drop into parent
+ target_path = up_path;
+ _dnd_into = true;
+ } else {
+ // Drop into the top level
+ _dnd_target = NULL;
+ }
+ }
+ }
+ Gtk::TreeModel::iterator iter = _store->get_iter(target_path);
+ if (_store->iter_is_valid(iter)) {
+ Gtk::TreeModel::Row row = *iter;
+ //Set the drop target. If we're not dropping into a group, we cannot
+ //drop into it, so set _dnd_into false.
+ _dnd_target = row[_model->_colObject];
+ if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false;
+ }
+ }
+
+ _takeAction(DRAGNDROP);
+
+ return false;
+}
+
+/**
+ * Stores all selected items as the drag source
+ * @param iter Current tree item
+ */
+void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ _dnd_source.push_back(item);
+ }
+}
+
+/*
+ * Move a layer in response to a drag & drop action
+ */
+void ObjectsPanel::_doTreeMove( )
+{
+ g_assert(_desktop != NULL);
+ g_assert(_document != NULL);
+
+ std::vector<gchar *> idvector;
+
+ //Clear the desktop selection
+ _desktop->selection->clear();
+ while (!_dnd_source.empty())
+ {
+ SPItem *obj = _dnd_source.back();
+ _dnd_source.pop_back();
+
+ if (obj != _dnd_target) {
+ //Store the object id (for selection later) and move the object
+ idvector.push_back(g_strdup(obj->getId()));
+ obj->moveTo(_dnd_target, _dnd_into);
+ }
+ }
+
+ //Select items
+ while (!idvector.empty()) {
+ //Grab the id from the vector, get the item in the document and select it
+ gchar * id = idvector.back();
+ idvector.pop_back();
+ SPObject *obj = _document->getObjectById(id);
+ g_free(id);
+ if (obj && SP_IS_ITEM(obj)) {
+ SPItem *item = SP_ITEM(obj);
+ if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER)
+ {
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent);
+ _desktop->selection->add(item);
+ }
+ else
+ {
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item);
+ }
+ }
+ }
+
+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
+ _("Moved objects"));
+}
+
+/**
+ * Fires the action verb
+ */
+void ObjectsPanel::_fireAction( unsigned int code )
+{
+ if ( _desktop ) {
+ Verb *verb = Verb::get( code );
+ if ( verb ) {
+ SPAction *action = verb->get_action(_desktop);
+ if ( action ) {
+ sp_action_perform( action, NULL );
+ }
+ }
+ }
+}
+
+/**
+ * Executes the given button action during the idle time
+ */
+void ObjectsPanel::_takeAction( int val )
+{
+ if ( !_pending ) {
+ _pending = new InternalUIBounce();
+ _pending->_actionCode = val;
+ Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 );
+ }
+}
+
+/**
+ * Executes the pending button action
+ */
+bool ObjectsPanel::_executeAction()
+{
+ // Make sure selected layer hasn't changed since the action was triggered
+ if ( _document && _pending)
+ {
+ int val = _pending->_actionCode;
+// SPObject* target = _pending->_target;
+
+ switch ( val ) {
+ case BUTTON_NEW:
+ {
+ _fireAction( SP_VERB_LAYER_NEW );
+ }
+ break;
+ case BUTTON_RENAME:
+ {
+ _fireAction( SP_VERB_LAYER_RENAME );
+ }
+ break;
+ case BUTTON_TOP:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_TO_TOP );
+ }
+ else
+ {
+ _fireAction( SP_VERB_SELECTION_TO_FRONT);
+ }
+ }
+ break;
+ case BUTTON_BOTTOM:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_TO_BOTTOM );
+ }
+ else
+ {
+ _fireAction( SP_VERB_SELECTION_TO_BACK);
+ }
+ }
+ break;
+ case BUTTON_UP:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_RAISE );
+ }
+ else
+ {
+ _fireAction( SP_VERB_SELECTION_RAISE );
+ }
+ }
+ break;
+ case BUTTON_DOWN:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_LOWER );
+ }
+ else
+ {
+ _fireAction( SP_VERB_SELECTION_LOWER );
+ }
+ }
+ break;
+ case BUTTON_DUPLICATE:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_DUPLICATE );
+ }
+ else
+ {
+ _fireAction( SP_VERB_EDIT_DUPLICATE );
+ }
+ }
+ break;
+ case BUTTON_DELETE:
+ {
+ if (_desktop->selection->isEmpty())
+ {
+ _fireAction( SP_VERB_LAYER_DELETE );
+ }
+ else
+ {
+ _fireAction( SP_VERB_EDIT_DELETE );
+ }
+ }
+ break;
+ case BUTTON_SOLO:
+ {
+ _fireAction( SP_VERB_LAYER_SOLO );
+ }
+ break;
+ case BUTTON_SHOW_ALL:
+ {
+ _fireAction( SP_VERB_LAYER_SHOW_ALL );
+ }
+ break;
+ case BUTTON_HIDE_ALL:
+ {
+ _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 BUTTON_CLIPGROUP:
+ {
+ _fireAction ( SP_VERB_OBJECT_CREATE_CLIP_GROUP );
+ }
+ case BUTTON_SETCLIP:
+ {
+ _fireAction( SP_VERB_OBJECT_SET_CLIPPATH );
+ }
+ break;
+ case BUTTON_UNSETCLIP:
+ {
+ _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH );
+ }
+ break;
+ case BUTTON_SETMASK:
+ {
+ _fireAction( SP_VERB_OBJECT_SET_MASK );
+ }
+ break;
+ case BUTTON_UNSETMASK:
+ {
+ _fireAction( SP_VERB_OBJECT_UNSET_MASK );
+ }
+ break;
+ case BUTTON_GROUP:
+ {
+ _fireAction( SP_VERB_SELECTION_GROUP );
+ }
+ break;
+ case BUTTON_UNGROUP:
+ {
+ _fireAction( SP_VERB_SELECTION_UNGROUP );
+ }
+ break;
+ case BUTTON_COLLAPSE_ALL:
+ {
+ for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) {
+ if (SP_IS_GROUP(obj)) {
+ _setCollapsed(SP_GROUP(obj));
+ }
+ }
+ _objectsChanged(_document->getRoot());
+ }
+ break;
+ case DRAGNDROP:
+ {
+ _doTreeMove( );
+ }
+ break;
+ }
+
+ delete _pending;
+ _pending = 0;
+ }
+
+ return false;
+}
+
+/**
+ * Handles an unsuccessful item label edit (escape pressed, etc.)
+ */
+void ObjectsPanel::_handleEditingCancelled()
+{
+ _text_renderer->property_editable() = false;
+}
+
+/**
+ * Handle a successful item label edit
+ * @param path Tree path of the item currently being edited
+ * @param new_text New label text
+ */
+void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text)
+{
+ Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+
+ _renameObject(row, new_text);
+ _text_renderer->property_editable() = false;
+}
+
+/**
+ * Renames an item in the tree
+ * @param row Tree row
+ * @param name New label to give to the item
+ */
+void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name)
+{
+ if ( row && _desktop) {
+ SPItem* item = row[_model->_colObject];
+ if ( item ) {
+ gchar const* oldLabel = item->label();
+ if ( !name.empty() && (!oldLabel || name != oldLabel) ) {
+ item->setLabel(name.c_str());
+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
+ _("Rename object"));
+ }
+ }
+ }
+}
+
+/**
+ * A row selection function used by the tree that doesn't allow any new items to be selected.
+ * Currently, this is used to allow multi-item drag & drop.
+ */
+bool ObjectsPanel::_noSelection( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ )
+{
+ return false;
+}
+
+/**
+ * Default row selection function taken from the layers dialog
+ */
+bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected )
+{
+ bool val = true;
+ if ( !currentlySelected && _toggleEvent )
+ {
+ GdkEvent* event = gtk_get_current_event();
+ if ( event ) {
+ // (keep these checks separate, so we know when to call gdk_event_free()
+ if ( event->type == GDK_BUTTON_PRESS ) {
+ GdkEventButton const* target = reinterpret_cast<GdkEventButton const*>(_toggleEvent);
+ GdkEventButton const* evtb = reinterpret_cast<GdkEventButton const*>(event);
+
+ if ( (evtb->window == target->window)
+ && (evtb->send_event == target->send_event)
+ && (evtb->time == target->time)
+ && (evtb->state == target->state)
+ )
+ {
+ // Ooooh! It's a magic one
+ val = false;
+ }
+ }
+ gdk_event_free(event);
+ }
+ }
+ return val;
+}
+
+/**
+ * Sets a group to be collapsed and recursively collapses its children
+ * @param group The group to collapse
+ */
+void ObjectsPanel::_setCollapsed(SPGroup * group)
+{
+ group->setExpanded(false);
+ group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ for (SPObject *iter = group->children; iter != NULL; iter = iter->next)
+ {
+ if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter));
+ }
+}
+
+/**
+ * Sets a group to be expanded or collapsed
+ * @param iter Current tree item
+ * @param isexpanded Whether to expand or collapse
+ */
+void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded)
+{
+ Gtk::TreeModel::Row row = *iter;
+
+ SPItem* item = row[_model->_colObject];
+ if (item && SP_IS_GROUP(item))
+ {
+ if (isexpanded)
+ {
+ //If we're expanding, simply perform the expansion
+ SP_GROUP(item)->setExpanded(isexpanded);
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+ else
+ {
+ //If we're collapsing, we need to recursively collapse, so call our helper function
+ _setCollapsed(SP_GROUP(item));
+ }
+ }
+}
+
+/**
+ * Callback for when the highlight color is changed
+ * @param csel Color selector
+ * @param cp Objects panel
+ */
+void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp)
+{
+ SPColor color;
+ float alpha = 0;
+ csel->base->getColorAlpha(color, alpha);
+ guint32 rgba = color.toRGBA32( alpha );
+
+ ObjectsPanel *ptr = reinterpret_cast<ObjectsPanel *>(cp);
+
+ //Set the highlight color for all items in the _highlight_target (all selected items)
+ for (std::vector<SPItem *>::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter)
+ {
+ SPItem * target = *iter;
+ target->setHighlightColor(rgba);
+ target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+ DocumentUndo::maybeDone(SP_ACTIVE_DOCUMENT, "highlight", SP_VERB_DIALOG_OBJECTS, _("Set object highlight color"));
+}
+
+/**
+ * Callback for when the opacity value is changed
+ */
+void ObjectsPanel::_opacityValueChanged()
+{
+ _blockCompositeUpdate = true;
+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter));
+ DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity"));
+ _blockCompositeUpdate = false;
+}
+
+/**
+ * Change the opacity of the selected items in the tree
+ * @param iter Current tree item
+ */
+void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ item->style->opacity.set = TRUE;
+#if WITH_GTKMM_3_0
+ item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment->get_value() / _opacity_adjustment->get_upper());
+#else
+ item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper());
+#endif
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+}
+
+/**
+ * Callback for when the blend mode is changed
+ */
+void ObjectsPanel::_blendValueChanged()
+{
+ _blockCompositeUpdate = true;
+ const Glib::ustring blendmode = _fe_cb.get_blend_mode();
+
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<Glib::ustring>(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode));
+ DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode"));
+ _blockCompositeUpdate = false;
+}
+
+/**
+ * Sets the blend mode of the selected tree items
+ * @param iter Current tree item
+ * @param blendmode Blend mode to set
+ */
+void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ //Since blur and blend are both filters, we need to set both at the same time
+ SPStyle *style = item->style;
+ g_assert(style != NULL);
+
+ if (blendmode != "normal") {
+ gdouble radius = 0;
+ if (item->style->getFilter()) {
+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) {
+ if (SP_IS_GAUSSIANBLUR(primitive)) {
+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX);
+ if (bbox) {
+ radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber();
+ }
+ }
+ }
+ }
+ SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius);
+ sp_style_set_property_url(item, "filter", filter, false);
+ } else {
+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) {
+ if (SP_IS_FEBLEND(primitive)) {
+ primitive->deleteObject();
+ break;
+ }
+ }
+ if (!item->style->getFilter()->children) {
+ remove_filter(item, false);
+ }
+ }
+
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+}
+
+/**
+ * Callback for when the blur value has changed
+ */
+void ObjectsPanel::_blurValueChanged()
+{
+ _blockCompositeUpdate = true;
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<double>(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value()));
+ DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur"));
+ _blockCompositeUpdate = false;
+}
+
+/**
+ * Sets the blur value for the selected items in the tree
+ * @param iter Current tree item
+ * @param blur Blur value to set
+ */
+void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPItem* item = row[_model->_colObject];
+ if (item)
+ {
+ //Since blur and blend are both filters, we need to set both at the same time
+ SPStyle *style = item->style;
+ if (style) {
+ Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX);
+ double radius;
+ if (bbox) {
+ double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct?
+ radius = blur * perimeter / 400;
+ } else {
+ radius = 0;
+ }
+
+ if (radius != 0) {
+ SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius);
+ sp_style_set_property_url(item, "filter", filter, false);
+ } else if (item->style->filter.set && item->style->getFilter()) {
+ for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) {
+ if (SP_IS_GAUSSIANBLUR(primitive)) {
+ primitive->deleteObject();
+ break;
+ }
+ }
+ if (!item->style->getFilter()->children) {
+ remove_filter(item, false);
+ }
+ }
+ item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+ }
+}
+
+/**
+ * Constructor
+ */
+ObjectsPanel::ObjectsPanel() :
+ UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS),
+ _rootWatcher(0),
+ _deskTrack(),
+ _desktop(0),
+ _document(0),
+ _model(0),
+ _pending(0),
+ _toggleEvent(0),
+ _defer_target(),
+ _composite_vbox(false, 0),
+ _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),
+ _fe_cb(UI::Widget::SimpleFilterModifier::BLEND),
+ _fe_vbox(false, 0),
+ _fe_alignment(1, 1, 1, 1),
+ _fe_blur(UI::Widget::SimpleFilterModifier::BLUR),
+ _blur_vbox(false, 0),
+ _blur_alignment(1, 1, 1, 1),
+ _colorSelectorDialog("dialogs.colorpickerwindow")
+{
+ //Create the tree model and store
+ ModelColumns *zoop = new ModelColumns();
+ _model = zoop;
+
+ _store = Gtk::TreeStore::create( *zoop );
+
+ //Set up the tree
+ _tree.set_model( _store );
+ _tree.set_headers_visible(false);
+ _tree.set_reorderable(true);
+ _tree.enable_model_drag_dest (Gdk::ACTION_MOVE);
+
+ //Create the column CellRenderers
+ //Visible
+ Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler(
+ INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) );
+ int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1;
+ eyeRenderer->property_activatable() = true;
+ Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum);
+ if ( col ) {
+ col->add_attribute( eyeRenderer->property_active(), _model->_colVisible );
+ }
+
+ //Locked
+ Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler(
+ INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) );
+ int lockedColNum = _tree.append_column("lock", *renderer) - 1;
+ renderer->property_activatable() = true;
+ col = _tree.get_column(lockedColNum);
+ if ( col ) {
+ col->add_attribute( renderer->property_active(), _model->_colLocked );
+ }
+
+ //Type
+ Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon());
+ int typeColNum = _tree.append_column("type", *typeRenderer) - 1;
+ typeRenderer->property_activatable() = true;
+ col = _tree.get_column(typeColNum);
+ if ( col ) {
+ col->add_attribute( typeRenderer->property_active(), _model->_colType );
+ }
+
+ //Insert order (LiamW: unused)
+ /*Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon());
+ int insertColNum = _tree.append_column("type", *insertRenderer) - 1;
+ col = _tree.get_column(insertColNum);
+ if ( col ) {
+ col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder );
+ }*/
+
+ //Clip/mask
+ Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon());
+ int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1;
+ col = _tree.get_column(clipColNum);
+ if ( col ) {
+ col->add_attribute( clipRenderer->property_active(), _model->_colClipMask );
+ }
+
+ //Highlight
+ Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker());
+ int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1;
+ col = _tree.get_column(highlightColNum);
+ if ( col ) {
+ col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight );
+ }
+
+ //Label
+ _text_renderer = Gtk::manage(new Gtk::CellRendererText());
+ int nameColNum = _tree.append_column("Name", *_text_renderer) - 1;
+ _name_column = _tree.get_column(nameColNum);
+ _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel);
+
+ //Set the expander and search columns
+ _tree.set_expander_column( *_tree.get_column(nameColNum) );
+ _tree.set_search_column(_model->_colLabel);
+
+ //Set up the tree selection
+ _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+ _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) );
+ _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) );
+
+ //Set up tree signals
+ _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false );
+ _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false );
+ _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false );
+ _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false);
+ _tree.signal_row_collapsed().connect( sigc::bind<bool>(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false));
+ _tree.signal_row_expanded().connect( sigc::bind<bool>(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true));
+
+ //Set up the label editing signals
+ _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) );
+ _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) );
+
+ //Set up the scroller window and pack the page
+ _scroller.add( _tree );
+ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
+ _scroller.set_shadow_type(Gtk::SHADOW_IN);
+ Gtk::Requisition sreq;
+#if WITH_GTKMM_3_0
+ Gtk::Requisition sreq_natural;
+ _scroller.get_preferred_size(sreq_natural, sreq);
+#else
+ sreq = _scroller.size_request();
+#endif
+ int minHeight = 70;
+ if (sreq.height < minHeight) {
+ // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar
+ _scroller.set_size_request(sreq.width, minHeight);
+ }
+
+ _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET );
+
+ //Set up the compositing items
+ //Blend mode filter effect
+ _composite_vbox.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);
+ _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged));
+
+ //Blur filter effect
+ _composite_vbox.pack_start(_blur_vbox, false, false, 2);
+ _blur_alignment.set_padding(0, 0, 4, 0);
+ _blur_alignment.add(_fe_blur);
+ _blur_vbox.pack_start(_blur_alignment, false, false, 0);
+ _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged));
+
+ //Opacity
+ _composite_vbox.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_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
+ _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged));
+ _opacity_label.set_mnemonic_widget(_opacity_hscale);
+#else
+ _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged));
+ _opacity_label.set_mnemonic_widget(_opacity_hscale);
+#endif
+
+ //Keep the labels aligned
+ GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ 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()));
+ gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj()));
+
+ //Pack the compositing functions and the button row
+ _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK);
+ _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK);
+
+ //Pack into the panel contents
+ _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET);
+
+ SPDesktop* targetDesktop = getDesktop();
+
+ //Set up the button row
+
+
+ //Add object/layer
+ Gtk::Button* btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Add layer..."));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ Gtk::Image *image_add = Gtk::manage(new Gtk::Image());
+ image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_add);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) );
+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK);
+
+
+ //Remove object
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Remove object"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ Gtk::Image *image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) );
+ _watching.push_back( btn );
+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK);
+
+ //Move to bottom
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Move To Bottom"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) );
+ _watchingNonBottom.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ //Move down
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Move Down"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) );
+ _watchingNonBottom.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ //Move up
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Move Up"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) );
+ _watchingNonTop.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ //Move to top
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Move To Top"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) );
+ _watchingNonTop.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ //Collapse all
+ btn = Gtk::manage( new Gtk::Button() );
+ btn->set_tooltip_text(_("Collapse All"));
+#if GTK_CHECK_VERSION(3,10,0)
+ btn->set_image_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+#else
+ image_remove = Gtk::manage(new Gtk::Image());
+ image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR);
+ btn->set_image(*image_remove);
+#endif
+ btn->set_relief(Gtk::RELIEF_NONE);
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) );
+ _watchingNonBottom.push_back( btn );
+ _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK);
+
+ _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET);
+ _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET);
+
+ _watching.push_back(&_composite_vbox);
+
+ //Set up the pop-up menu
+ // -------------------------------------------------------
+ {
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) );
+
+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) );
+
+ _popupMenu.append(*Gtk::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(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) );
+ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) );
+
+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) );
+
+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) );
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) );
+
+ //will never be implemented
+ //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) );
+
+ _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
+
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) );
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) );
+
+ _popupMenu.show_all_children();
+ }
+ // -------------------------------------------------------
+
+ //Set initial sensitivity of buttons
+ for ( std::vector<Gtk::Widget*>::iterator it = _watching.begin(); it != _watching.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+
+ //Set up the color selection dialog
+ GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj());
+ sp_transientize(dlg);
+
+ _colorSelectorDialog.hide();
+ _colorSelectorDialog.set_title (_("Select Highlight Color"));
+ _colorSelectorDialog.set_border_width (4);
+ _colorSelectorDialog.property_modal() = true;
+ _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
+ _colorSelectorDialog.get_vbox()->pack_start (
+ *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+
+ g_signal_connect(G_OBJECT(_colorSelector), "dragged",
+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
+ g_signal_connect(G_OBJECT(_colorSelector), "released",
+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
+ g_signal_connect(G_OBJECT(_colorSelector), "changed",
+ G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
+
+ gtk_widget_show(GTK_WIDGET(_colorSelector));
+
+ setDesktop( targetDesktop );
+
+ show_all_children();
+
+ //Connect the desktop changed connection
+ desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) );
+ _deskTrack.connect(GTK_WIDGET(gobj()));
+}
+
+/**
+ * Destructor
+ */
+ObjectsPanel::~ObjectsPanel()
+{
+ //Close the highlight selection dialog
+ _colorSelectorDialog.hide();
+ _colorSelector = NULL;
+
+ //Set the desktop to null, which will disconnect all object watchers
+ setDesktop(NULL);
+
+ if ( _model )
+ {
+ delete _model;
+ _model = 0;
+ }
+
+ if (_pending) {
+ delete _pending;
+ _pending = 0;
+ }
+
+ if ( _toggleEvent )
+ {
+ gdk_event_free( _toggleEvent );
+ _toggleEvent = 0;
+ }
+
+ desktopChangeConn.disconnect();
+ _deskTrack.disconnect();
+}
+
+/**
+ * Sets the current document
+ */
+void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document)
+{
+ //Clear all object watchers
+ while (!_objectWatchers.empty())
+ {
+ ObjectsPanel::ObjectWatcher *w = _objectWatchers.back();
+ w->_repr->removeObserver(*w);
+ _objectWatchers.pop_back();
+ delete w;
+ }
+
+ //Delete the root watcher
+ if (_rootWatcher)
+ {
+ _rootWatcher->_repr->removeObserver(*_rootWatcher);
+ delete _rootWatcher;
+ _rootWatcher = NULL;
+ }
+
+ _document = document;
+
+ if (document && document->getRoot() && document->getRoot()->getRepr())
+ {
+ //Create a new root watcher for the document and then call _objectsChanged to fill the tree
+ _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot());
+ document->getRoot()->getRepr()->addObserver(*_rootWatcher);
+ _objectsChanged(document->getRoot());
+ }
+}
+
+/**
+ * Set the current panel desktop
+ */
+void ObjectsPanel::setDesktop( SPDesktop* desktop )
+{
+ Panel::setDesktop(desktop);
+
+ if ( desktop != _desktop ) {
+ _documentChangedConnection.disconnect();
+ _selectionChangedConnection.disconnect();
+ if ( _desktop ) {
+ _desktop = 0;
+ }
+
+ _desktop = Panel::getDesktop();
+ if ( _desktop ) {
+ //Connect desktop signals
+ _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument));
+ _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected));
+
+ setDocument(_desktop, _desktop->doc());
+ } else {
+ setDocument(NULL, NULL);
+ }
+ }
+ _deskTrack.setBase(desktop);
+}
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+//should be okay to put these here because they are never referenced anywhere else
+using namespace Inkscape::UI::Tools;
+
+void SPItem::setHighlightColor(guint32 const color)
+{
+ g_free(_highlightColor);
+ if (color & 0x000000ff)
+ {
+ _highlightColor = g_strdup_printf("%u", color);
+ }
+ else
+ {
+ _highlightColor = NULL;
+ }
+
+ NodeTool *tool = 0;
+ if (SP_ACTIVE_DESKTOP ) {
+ Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context;
+ if (INK_IS_NODE_TOOL(ec)) {
+ tool = static_cast<NodeTool*>(ec);
+ tools_switch(tool->desktop, TOOLS_NODES);
+ }
+ }
+}
+
+void SPItem::unsetHighlightColor()
+{
+ g_free(_highlightColor);
+ _highlightColor = NULL;
+ NodeTool *tool = 0;
+ if (SP_ACTIVE_DESKTOP ) {
+ Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context;
+ if (INK_IS_NODE_TOOL(ec)) {
+ tool = static_cast<NodeTool*>(ec);
+ tools_switch(tool->desktop, TOOLS_NODES);
+ }
+ }
+}
+
+/*
+ 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/objects.h b/src/ui/dialog/objects.h
new file mode 100644
index 000000000..74c2382ac
--- /dev/null
+++ b/src/ui/dialog/objects.h
@@ -0,0 +1,263 @@
+/*
+ * A simple dialog for objects UI.
+ *
+ * Authors:
+ * Theodore Janeczko
+ *
+ * Copyright (C) Theodore Janeczko 2012 <flutterguy317@gmail.com>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_OBJECTS_PANEL_H
+#define SEEN_OBJECTS_PANEL_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+# include <glibmm/threads.h>
+#endif
+
+#include <gtkmm/box.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/dialog.h>
+#include "ui/widget/spinbutton.h"
+#include "ui/widget/panel.h"
+#include "ui/widget/object-composite-settings.h"
+#include "desktop-tracker.h"
+#include "ui/widget/style-subject.h"
+#include "selection.h"
+#include "ui/widget/filter-effect-chooser.h"
+
+class SPObject;
+class SPGroup;
+struct SPColorSelector;
+
+namespace Inkscape {
+
+namespace UI {
+namespace Dialog {
+
+
+/**
+ * A panel that displays objects.
+ */
+class ObjectsPanel : public UI::Widget::Panel
+{
+public:
+ ObjectsPanel();
+ virtual ~ObjectsPanel();
+
+ static ObjectsPanel& getInstance();
+
+ void setDesktop( SPDesktop* desktop );
+ void setDocument( SPDesktop* desktop, SPDocument* document);
+
+private:
+ //Internal Classes:
+ class ModelColumns;
+ class InternalUIBounce;
+ class ObjectWatcher;
+
+ //Connections, Watchers, Trackers:
+
+ //Document root watcher
+ ObjectsPanel::ObjectWatcher* _rootWatcher;
+
+ //All object watchers
+ std::vector<ObjectsPanel::ObjectWatcher*> _objectWatchers;
+
+ //Connection for when the desktop changes
+ sigc::connection desktopChangeConn;
+
+ //Connection for when the document changes
+ sigc::connection _documentChangedConnection;
+
+ //Connection for when the active selection in the document changes
+ sigc::connection _selectionChangedConnection;
+
+ //Connection for when the selection in the dialog changes
+ sigc::connection _selectedConnection;
+
+ //Connections for when the opacity/blend/blur of the active selection in the document changes
+ sigc::connection _opacityConnection;
+ sigc::connection _blendConnection;
+ sigc::connection _blurConnection;
+
+ //Desktop tracker for grabbing the desktop changed connection
+ DesktopTracker _deskTrack;
+
+ //Members:
+
+ //The current desktop
+ SPDesktop* _desktop;
+
+ //The current document
+ SPDocument* _document;
+
+ //Tree data model
+ ModelColumns* _model;
+
+ //Prevents the composite controls from updating
+ bool _blockCompositeUpdate;
+
+ //
+ InternalUIBounce* _pending;
+
+ //Whether the drag & drop was dragged into an item
+ gboolean _dnd_into;
+
+ //List of drag & drop source items
+ std::vector<SPItem*> _dnd_source;
+
+ //Drag & drop target item
+ SPItem* _dnd_target;
+
+ //List of items to change the highlight on
+ std::vector<SPItem*> _highlight_target;
+
+ //GUI Members:
+
+ GdkEvent* _toggleEvent;
+
+ Gtk::TreeModel::Path _defer_target;
+
+ Glib::RefPtr<Gtk::TreeStore> _store;
+ std::vector<Gtk::Widget*> _watching;
+ std::vector<Gtk::Widget*> _watchingNonTop;
+ std::vector<Gtk::Widget*> _watchingNonBottom;
+
+ Gtk::TreeView _tree;
+ Gtk::CellRendererText *_text_renderer;
+ Gtk::TreeView::Column *_name_column;
+#if WITH_GTKMM_3_0
+ Gtk::Box _buttonsRow;
+ Gtk::Box _buttonsPrimary;
+ Gtk::Box _buttonsSecondary;
+#else
+ Gtk::HBox _buttonsRow;
+ Gtk::HBox _buttonsPrimary;
+ Gtk::HBox _buttonsSecondary;
+#endif
+ Gtk::ScrolledWindow _scroller;
+ Gtk::Menu _popupMenu;
+ Inkscape::UI::Widget::SpinButton _spinBtn;
+ Gtk::VBox _page;
+
+ /* Composite Settings */
+ Gtk::VBox _composite_vbox;
+ 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::SimpleFilterModifier _fe_cb;
+ Gtk::VBox _fe_vbox;
+ Gtk::Alignment _fe_alignment;
+ Inkscape::UI::Widget::SimpleFilterModifier _fe_blur;
+ Gtk::VBox _blur_vbox;
+ Gtk::Alignment _blur_alignment;
+
+ Gtk::Dialog _colorSelectorDialog;
+ SPColorSelector *_colorSelector;
+
+
+ //Methods:
+
+ ObjectsPanel(ObjectsPanel const &); // no copy
+ ObjectsPanel &operator=(ObjectsPanel const &); // no assign
+
+ void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip );
+ void _fireAction( unsigned int code );
+
+ Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id );
+
+ void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible );
+ void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked );
+
+ bool _handleButtonEvent(GdkEventButton *event);
+ bool _handleKeyEvent(GdkEventKey *event);
+
+ void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter);
+ void _storeDragSource(const Gtk::TreeModel::iterator& iter);
+ 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);
+ void _handleEditingCancelled();
+
+ void _doTreeMove();
+ void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name);
+
+ void _pushTreeSelectionToCurrent();
+ void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity );
+
+ void _checkTreeSelection();
+
+ void _takeAction( int val );
+ bool _executeAction();
+
+ void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded );
+ void _setCollapsed(SPGroup * group);
+
+ bool _noSelection( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
+ bool _rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
+
+ void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues );
+ void _updateComposite();
+ void _setCompositingValues(SPItem *item);
+
+ void _updateObject(SPObject *obj, bool recurse);
+ bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj);
+
+ void _objectsSelected(Selection *sel);
+ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto);
+
+ void _objectsChanged(SPObject *obj);
+ void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow );
+
+ void _opacityChangedIter(const Gtk::TreeIter& iter);
+ void _opacityValueChanged();
+
+ void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode);
+ void _blendValueChanged();
+
+ void _blurChangedIter(const Gtk::TreeIter& iter, double blur);
+ void _blurValueChanged();
+
+
+ void setupDialog(const Glib::ustring &title);
+
+ friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp);
+
+};
+
+
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+
+#endif // SEEN_OBJECTS_PANEL_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/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp
index f676e75fd..c4dd9df98 100644
--- a/src/ui/dialog/ocaldialogs.cpp
+++ b/src/ui/dialog/ocaldialogs.cpp
@@ -25,9 +25,9 @@
#include "path-prefix.h"
#include "filedialogimpl-gtkmm.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "gc-core.h"
-#include <dialogs/dialog-events.h>
+#include "ui/dialog-events.h"
#include "io/sys.h"
#include "preferences.h"
diff --git a/src/ui/dialog/ocaldialogs.h b/src/ui/dialog/ocaldialogs.h
index e21030bcd..bd028c145 100644
--- a/src/ui/dialog/ocaldialogs.h
+++ b/src/ui/dialog/ocaldialogs.h
@@ -38,8 +38,7 @@
//Inkscape includes
#include "ui/dialog/filedialog.h"
-
-#include <dialogs/dialog-events.h>
+#include "ui/dialog-events.h"
struct _xmlNode;
typedef _xmlNode xmlNode;
diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h
index 1fefd811e..b4a355083 100644
--- a/src/ui/dialog/panel-dialog.h
+++ b/src/ui/dialog/panel-dialog.h
@@ -49,19 +49,19 @@ public:
virtual UI::Widget::Panel &getPanel() { return _panel; }
protected:
- static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
+ static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) {
g_return_if_fail(data != NULL);
static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop);
}
- static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
+ static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) {
g_return_if_fail(data != NULL);
static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop);
}
inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document);
- inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *);
- inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *);
+ inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *);
+ inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *);
UI::Widget::Panel &_panel;
sigc::connection _document_replaced_connection;
@@ -134,14 +134,14 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument
_panel.signalDocumentReplaced().emit(desktop, document);
}
-void PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop)
+void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop)
{
_document_replaced_connection =
desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced));
_panel.signalActivateDesktop().emit(application, desktop);
}
-void PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop)
+void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop)
{
_document_replaced_connection.disconnect();
_panel.signalDeactiveDesktop().emit(application, desktop);
diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp
index 2d25f54d7..5113f172a 100644
--- a/src/ui/dialog/pixelartdialog.cpp
+++ b/src/ui/dialog/pixelartdialog.cpp
@@ -385,8 +385,8 @@ void PixelArtDialogImpl::vectorize()
if ( input.pixbuf->get_width() > 256
|| input.pixbuf->get_height() > 256 ) {
- char *msg = _("Image looks too big. Process may take a while and is"
- " wise to save your document before continue."
+ char *msg = _("Image looks too big. Process may take a while and it is"
+ " wise to save your document before continuing."
"\n\nContinue the procedure (without saving)?");
Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING,
Gtk::BUTTONS_OK_CANCEL, true);
diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp
index a00b8fc02..80579c9d3 100644
--- a/src/ui/dialog/polar-arrange-tab.cpp
+++ b/src/ui/dialog/polar-arrange-tab.cpp
@@ -25,6 +25,7 @@
#include "desktop.h"
#include "sp-ellipse.h"
#include "sp-item-transform.h"
+#include <gtkmm/messagedialog.h>
namespace Inkscape {
namespace UI {
@@ -32,7 +33,11 @@ namespace Dialog {
PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
: parent(parent_),
+#if WITH_GTKMM_3_0
+ parametersTable(),
+#else
parametersTable(3, 3, false),
+#endif
centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR),
centerX("", "X coordinate of the center", centerY),
radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR),
@@ -76,7 +81,11 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
pack_start(arrangeOnParametersRadio, false, false);
centerLabel.set_text(_("Center X/Y:"));
+#if WITH_GTKMM_3_0
+ parametersTable.attach(centerLabel, 0, 0, 1, 1);
+#else
parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL);
+#endif
centerX.setDigits(2);
centerX.setIncrements(0.2, 0);
centerX.setRange(-10000, 10000);
@@ -85,11 +94,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
centerY.setIncrements(0.2, 0);
centerY.setRange(-10000, 10000);
centerY.setValue(0, "px");
+#if WITH_GTKMM_3_0
+ parametersTable.attach(centerX, 1, 0, 1, 1);
+ parametersTable.attach(centerY, 2, 0, 1, 1);
+#else
parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL);
parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL);
+#endif
radiusLabel.set_text(_("Radius X/Y:"));
+#if WITH_GTKMM_3_0
+ parametersTable.attach(radiusLabel, 0, 1, 1, 1);
+#else
parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL);
+#endif
radiusX.setDigits(2);
radiusX.setIncrements(0.2, 0);
radiusX.setRange(0.001, 10000);
@@ -98,11 +116,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
radiusY.setIncrements(0.2, 0);
radiusY.setRange(0.001, 10000);
radiusY.setValue(100, "px");
+#if WITH_GTKMM_3_0
+ parametersTable.attach(radiusX, 1, 1, 1, 1);
+ parametersTable.attach(radiusY, 2, 1, 1, 1);
+#else
parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL);
parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL);
+#endif
angleLabel.set_text(_("Angle X/Y:"));
+#if WITH_GTKMM_3_0
+ parametersTable.attach(angleLabel, 0, 2, 1, 1);
+#else
parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL);
+#endif
angleX.setDigits(2);
angleX.setIncrements(0.2, 0);
angleX.setRange(-10000, 10000);
@@ -111,8 +138,13 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_)
angleY.setIncrements(0.2, 0);
angleY.setRange(-10000, 10000);
angleY.setValue(180, "°");
+#if WITH_GTKMM_3_0
+ parametersTable.attach(angleX, 1, 2, 1, 1);
+ parametersTable.attach(angleY, 2, 2, 1, 1);
+#else
parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL);
parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL);
+#endif
pack_start(parametersTable, false, false);
rotateObjectsCheckBox.set_label(_("Rotate objects"));
diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h
index f6c3b2906..f7d7bf11f 100644
--- a/src/ui/dialog/polar-arrange-tab.h
+++ b/src/ui/dialog/polar-arrange-tab.h
@@ -10,9 +10,22 @@
#ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H
#define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "ui/widget/scalar-unit.h"
#include "ui/widget/anchor-selector.h"
#include "ui/dialog/arrange-tab.h"
-#include "ui/widget/scalar-unit.h"
+
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/radiobuttongroup.h>
+
+#if WITH_GTKMM_3_0
+ #include <gtkmm/grid.h>
+#else
+ #include <gtkmm/table.h>
+#endif
namespace Inkscape {
namespace UI {
@@ -62,7 +75,11 @@ private:
Gtk::RadioButton arrangeOnLastCircleRadio;
Gtk::RadioButton arrangeOnParametersRadio;
+#if WITH_GTKMM_3_0
+ Gtk::Grid parametersTable;
+#else
Gtk::Table parametersTable;
+#endif
Gtk::Label centerLabel;
Inkscape::UI::Widget::ScalarUnit centerY;
diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp
index 03ac9dc64..a015d28f9 100644
--- a/src/ui/dialog/print.cpp
+++ b/src/ui/dialog/print.cpp
@@ -13,13 +13,16 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+
+#include <gtkmm.h>
+
#ifdef WIN32
#include <io.h>
#include <windows.h>
#endif
+#include "preferences.h"
#include "print.h"
-#include <gtkmm/stock.h>
#include "extension/internal/cairo-render-context.h"
#include "extension/internal/cairo-renderer.h"
@@ -44,14 +47,18 @@ static void draw_page(
gint /*page_nr*/,
gpointer user_data)
{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data;
//printf("%s %d\n",__FUNCTION__, page_nr);
if (junk->_tab->as_bitmap()) {
// Render as exported PNG
+ prefs->setBool("/dialogs/printing/asbitmap", true);
gdouble width = (junk->_doc)->getWidth().value("px");
gdouble height = (junk->_doc)->getHeight().value("px");
gdouble dpi = junk->_tab->bitmap_dpi();
+ prefs->setDouble("/dialogs/printing/dpi", dpi);
+
std::string tmp_png;
std::string tmp_base = "inkscape-print-png-XXXXXX";
@@ -92,7 +99,7 @@ static void draw_page(
cairo_get_matrix(cr, &m);
cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi);
// FIXME: why is the origin offset??
- cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0);
+ cairo_set_source_surface(cr, png->cobj(), 0, 0);
cairo_paint(cr);
cairo_set_matrix(cr, &m);
}
@@ -106,6 +113,7 @@ static void draw_page(
}
else {
// Render as vectors
+ prefs->setBool("/dialogs/printing/asbitmap", false);
Inkscape::Extension::Internal::CairoRenderer renderer;
Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext();
diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp
index 8a4ddc57e..9faa8a2cb 100644
--- a/src/ui/dialog/spellcheck.cpp
+++ b/src/ui/dialog/spellcheck.cpp
@@ -23,9 +23,9 @@
#include "selection.h"
#include "desktop.h"
#include "desktop-handles.h"
-#include "tools-switch.h"
+#include "ui/tools-switch.h"
#include "ui/tools/text-tool.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "preferences.h"
#include "sp-text.h"
#include "sp-flowtext.h"
@@ -347,7 +347,7 @@ SpellCheck::init(SPDesktop *d)
char *slashPos = strrchr(exeName, '\\');
if (slashPos)
*slashPos = '\0';
- g_print ("%s\n", exeName);
+ //g_print ("Aspell prefix path: %s\n", exeName);
#endif
_stops = 0;
@@ -356,54 +356,54 @@ SpellCheck::init(SPDesktop *d)
#ifdef HAVE_ASPELL
{
- AspellConfig *config = new_aspell_config();
+ AspellConfig *config = new_aspell_config();
#ifdef WIN32
- aspell_config_replace(config, "prefix", exeName);
+ aspell_config_replace(config, "prefix", exeName);
#endif
- aspell_config_replace(config, "lang", _lang.c_str());
- aspell_config_replace(config, "encoding", "UTF-8");
- AspellCanHaveError *ret = new_aspell_speller(config);
- delete_aspell_config(config);
- if (aspell_error(ret) != 0) {
- g_warning("Error: %s\n", aspell_error_message(ret));
- delete_aspell_can_have_error(ret);
- return false;
- }
- _speller = to_aspell_speller(ret);
+ aspell_config_replace(config, "lang", _lang.c_str());
+ aspell_config_replace(config, "encoding", "UTF-8");
+ AspellCanHaveError *ret = new_aspell_speller(config);
+ delete_aspell_config(config);
+ if (aspell_error(ret) != 0) {
+ g_warning("Error: %s\n", aspell_error_message(ret));
+ delete_aspell_can_have_error(ret);
+ return false;
+ }
+ _speller = to_aspell_speller(ret);
}
if (_lang2 != "") {
- AspellConfig *config = new_aspell_config();
+ AspellConfig *config = new_aspell_config();
#ifdef WIN32
- aspell_config_replace(config, "prefix", exeName);
+ aspell_config_replace(config, "prefix", exeName);
#endif
- aspell_config_replace(config, "lang", _lang2.c_str());
- aspell_config_replace(config, "encoding", "UTF-8");
- AspellCanHaveError *ret = new_aspell_speller(config);
- delete_aspell_config(config);
- if (aspell_error(ret) != 0) {
- g_warning("Error: %s\n", aspell_error_message(ret));
- delete_aspell_can_have_error(ret);
- return false;
- }
- _speller2 = to_aspell_speller(ret);
+ aspell_config_replace(config, "lang", _lang2.c_str());
+ aspell_config_replace(config, "encoding", "UTF-8");
+ AspellCanHaveError *ret = new_aspell_speller(config);
+ delete_aspell_config(config);
+ if (aspell_error(ret) != 0) {
+ g_warning("Error: %s\n", aspell_error_message(ret));
+ delete_aspell_can_have_error(ret);
+ return false;
+ }
+ _speller2 = to_aspell_speller(ret);
}
if (_lang3 != "") {
- AspellConfig *config = new_aspell_config();
+ AspellConfig *config = new_aspell_config();
#ifdef WIN32
- aspell_config_replace(config, "prefix", exeName);
+ aspell_config_replace(config, "prefix", exeName);
#endif
- aspell_config_replace(config, "lang", _lang3.c_str());
- aspell_config_replace(config, "encoding", "UTF-8");
- AspellCanHaveError *ret = new_aspell_speller(config);
- delete_aspell_config(config);
- if (aspell_error(ret) != 0) {
- g_warning("Error: %s\n", aspell_error_message(ret));
- delete_aspell_can_have_error(ret);
- return false;
- }
- _speller3 = to_aspell_speller(ret);
+ aspell_config_replace(config, "lang", _lang3.c_str());
+ aspell_config_replace(config, "encoding", "UTF-8");
+ AspellCanHaveError *ret = new_aspell_speller(config);
+ delete_aspell_config(config);
+ if (aspell_error(ret) != 0) {
+ g_warning("Error: %s\n", aspell_error_message(ret));
+ delete_aspell_can_have_error(ret);
+ return false;
+ }
+ _speller3 = to_aspell_speller(ret);
}
#endif /* HAVE_ASPELL */
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
index 4f0cb211a..a3cfeeba8 100644
--- a/src/ui/dialog/swatches.cpp
+++ b/src/ui/dialog/swatches.cpp
@@ -745,11 +745,10 @@ void SwatchesPanel::setDesktop( SPDesktop* desktop )
class DocTrack
{
public:
- DocTrack(SPDocument *doc, sigc::connection &docDestroy, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) :
- doc(doc),
+ DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) :
+ doc(doc->doRef()),
updatePending(false),
lastGradientUpdate(0.0),
- docDestroy(docDestroy),
gradientRsrcChanged(gradientRsrcChanged),
defsChanged(defsChanged),
defsModified(defsModified)
@@ -774,10 +773,10 @@ public:
}
}
if (doc) {
- docDestroy.disconnect();
gradientRsrcChanged.disconnect();
defsChanged.disconnect();
defsModified.disconnect();
+ doc->doUnref();
doc = NULL;
}
}
@@ -798,7 +797,6 @@ public:
SPDocument *doc;
bool updatePending;
double lastGradientUpdate;
- sigc::connection docDestroy;
sigc::connection gradientRsrcChanged;
sigc::connection defsChanged;
sigc::connection defsModified;
@@ -894,12 +892,11 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document )
}
docPerPanel[panel] = document;
if (!found) {
- sigc::connection conn0 = document->connectDestroy(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDocumentDestroy), document));
sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) );
sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) );
sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) );
- DocTrack *dt = new DocTrack(document, conn0, conn1, conn2, conn3);
+ DocTrack *dt = new DocTrack(document, conn1, conn2, conn3);
docTrackings.push_back(dt);
if (docPalettes.find(document) == docPalettes.end()) {
@@ -928,13 +925,11 @@ static void recalcSwatchContents(SPDocument* doc,
{
std::vector<SPGradient*> newList;
- if (doc) {
- const GSList *gradients = doc->getResourceList("gradient");
- for (const GSList *item = gradients; item; item = item->next) {
- SPGradient* grad = SP_GRADIENT(item->data);
- if ( grad->isSwatch() ) {
- newList.push_back(SP_GRADIENT(item->data));
- }
+ const GSList *gradients = doc->getResourceList("gradient");
+ for (const GSList *item = gradients; item; item = item->next) {
+ SPGradient* grad = SP_GRADIENT(item->data);
+ if ( grad->isSwatch() ) {
+ newList.push_back(SP_GRADIENT(item->data));
}
}
@@ -973,37 +968,6 @@ static void recalcSwatchContents(SPDocument* doc,
}
}
-void SwatchesPanel::handleDocumentDestroy(SPDocument *document)
-{
- if (document) {
- for (std::vector<DocTrack*>::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){
- if ((*it)->doc == document) {
- delete *it;
- docTrackings.erase(it);
- break;
- }
- }
-
- if (docPalettes.find(document) != docPalettes.end()) {
- docPalettes.erase(document);
- }
-
- for (std::map<SwatchesPanel*, SPDocument*>::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) {
- if (it->second == document) {
- SwatchesPanel* swp = it->first;
- std::vector<SwatchPage*> pages = swp->_getSwatchSets();
- if ((swp->_currentIndex >= static_cast<int>(pages.size())) && (pages.size() > 0))
- {
- swp->_setSelectedIndex(swp->_getSwatchSets().size() - 1);
- }
- swp->_rebuild();
- docPerPanel.erase(it);
- break;
- }
- }
- }
-}
-
void SwatchesPanel::handleGradientsChange(SPDocument *document)
{
SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0;
@@ -1178,45 +1142,38 @@ void SwatchesPanel::_handleAction( int setId, int itemId )
switch( setId ) {
case 3:
{
- _setSelectedIndex(itemId);
- }
- break;
- }
-}
+ std::vector<SwatchPage*> pages = _getSwatchSets();
+ if ( itemId >= 0 && itemId < static_cast<int>(pages.size()) ) {
+ _currentIndex = itemId;
-void SwatchesPanel::_setSelectedIndex( int index )
-{
- std::vector<SwatchPage*> pages = _getSwatchSets();
- if ( index >= 0 && index < static_cast<int>(pages.size()) ) {
- _currentIndex = index;
+ if ( !_prefs_path.empty() ) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name);
+ }
- if ( !_prefs_path.empty() ) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name);
+ _rebuild();
+ }
}
-
- _rebuild();
+ break;
}
}
void SwatchesPanel::_rebuild()
{
std::vector<SwatchPage*> pages = _getSwatchSets();
- if (_currentIndex < static_cast<int>(pages.size())) {
- SwatchPage* curr = pages[_currentIndex];
- _holder->clear();
+ SwatchPage* curr = pages[_currentIndex];
+ _holder->clear();
- if ( curr->_prefWidth > 0 ) {
- _holder->setColumnPref( curr->_prefWidth );
- }
- _holder->freezeUpdates();
- // TODO restore once 'clear' works _holder->addPreview(_clear);
- _holder->addPreview(_remove);
- for ( boost::ptr_vector<ColorItem>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) {
- _holder->addPreview(&*it);
- }
- _holder->thawUpdates();
+ if ( curr->_prefWidth > 0 ) {
+ _holder->setColumnPref( curr->_prefWidth );
+ }
+ _holder->freezeUpdates();
+ // TODO restore once 'clear' works _holder->addPreview(_clear);
+ _holder->addPreview(_remove);
+ for ( boost::ptr_vector<ColorItem>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) {
+ _holder->addPreview(&*it);
}
+ _holder->thawUpdates();
}
} //namespace Dialogs
diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h
index 3abb81d98..ca4c1687d 100644
--- a/src/ui/dialog/swatches.h
+++ b/src/ui/dialog/swatches.h
@@ -43,13 +43,11 @@ public:
virtual int getSelectedIndex() {return _currentIndex;} // temporary
protected:
- static void handleDocumentDestroy(SPDocument *document);
static void handleGradientsChange(SPDocument *document);
virtual void _updateFromSelection();
virtual void _handleAction( int setId, int itemId );
virtual void _setDocument( SPDocument *document );
- virtual void _setSelectedIndex( int index );
virtual void _rebuild();
virtual std::vector<SwatchPage*> _getSwatchSets() const;
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index 8e0d085a4..a17a03861 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -62,8 +62,20 @@
#include "widgets/icon.h"
#ifdef WITH_LIBVISIO
-#include <libvisio/libvisio.h>
-#include <libwpd-stream/libwpd-stream.h>
+ #include <libvisio/libvisio.h>
+
+ // TODO: Drop this check when librevenge is widespread.
+ #if WITH_LIBVISIO01
+ #include <librevenge-stream/librevenge-stream.h>
+
+ using librevenge::RVNGFileStream;
+ using librevenge::RVNGStringVector;
+ #else
+ #include <libwpd-stream/libwpd-stream.h>
+
+ typedef WPXFileStream RVNGFileStream;
+ typedef libvisio::VSDStringVector RVNGStringVector;
+ #endif
#endif
#include "verbs.h"
@@ -219,25 +231,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
Gtk::Label* spacer = Gtk::manage(new Gtk::Label(""));
tools->pack_start(* Gtk::manage(spacer));
- in_sizes = 2; // Default 32px
+ // Pack size (controls display area)
+ pack_size = 2; // Default 32px
button = Gtk::manage(new Gtk::Button());
button->add(*Gtk::manage(Glib::wrap(
- sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) );
- button->set_tooltip_text(_("Make Icons bigger by zooming in."));
+ sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) );
+ button->set_tooltip_text(_("Display more icons in row."));
button->set_relief( Gtk::RELIEF_NONE );
button->set_focus_on_click( false );
- button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin));
+ button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore));
tools->pack_start(* button, Gtk::PACK_SHRINK);
button = Gtk::manage(new Gtk::Button());
button->add(*Gtk::manage(Glib::wrap(
- sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) );
- button->set_tooltip_text(_("Make Icons smaller by zooming out."));
+ sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) );
+ button->set_tooltip_text(_("Display fewer icons in row."));
button->set_relief( Gtk::RELIEF_NONE );
button->set_focus_on_click( false );
- button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout));
+ button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless));
tools->pack_start(* button, Gtk::PACK_SHRINK);
+ // Toggle scale to fit on/off
fitSymbol = Gtk::manage(new Gtk::ToggleButton());
fitSymbol->add(*Gtk::manage(Glib::wrap(
sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) );
@@ -248,6 +262,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild));
tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK);
+ // Render size (scales symbols within display area)
+ scale_factor = 0; // Default 1:1 * pack_size/pack_size default
+ zoomOut = Gtk::manage(new Gtk::Button());
+ zoomOut->add(*Gtk::manage(Glib::wrap(
+ sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) );
+ zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out."));
+ zoomOut->set_relief( Gtk::RELIEF_NONE );
+ zoomOut->set_focus_on_click( false );
+ zoomOut->set_sensitive( false );
+ zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout));
+ tools->pack_start(* zoomOut, Gtk::PACK_SHRINK);
+
+ zoomIn = Gtk::manage(new Gtk::Button());
+ zoomIn->add(*Gtk::manage(Glib::wrap(
+ sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) );
+ zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in."));
+ zoomIn->set_relief( Gtk::RELIEF_NONE );
+ zoomIn->set_focus_on_click( false );
+ zoomIn->set_sensitive( false );
+ zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin));
+ tools->pack_start(* zoomIn, Gtk::PACK_SHRINK);
+
++row;
/**********************************************************/
@@ -262,8 +298,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
// This might need to be a global variable so setTargetDesktop can modify it
SPDefs *defs = currentDocument->getDefs();
- sigc::connection defsModifiedConn = (SP_OBJECT(defs))->connectModified(
- sigc::mem_fun(*this, &SymbolsDialog::defsModified));
+ sigc::connection defsModifiedConn = defs->connectModified(sigc::mem_fun(*this, &SymbolsDialog::defsModified));
instanceConns.push_back(defsModifiedConn);
sigc::connection selectionChangedConn = currentDesktop->selection->connectChanged(
@@ -298,22 +333,44 @@ SymbolsDialog& SymbolsDialog::getInstance()
return *new SymbolsDialog();
}
+void SymbolsDialog::packless() {
+ if(pack_size < 4) {
+ pack_size++;
+ rebuild();
+ }
+}
+
+void SymbolsDialog::packmore() {
+ if(pack_size > 0) {
+ pack_size--;
+ rebuild();
+ }
+}
+
void SymbolsDialog::zoomin() {
- if(in_sizes < 4) {
- in_sizes++;
+ if(scale_factor < 4) {
+ scale_factor++;
rebuild();
}
}
void SymbolsDialog::zoomout() {
- if(in_sizes > 0) {
- in_sizes--;
+ if(scale_factor > -8) {
+ scale_factor--;
rebuild();
}
}
void SymbolsDialog::rebuild() {
+ if( fitSymbol->get_active() ) {
+ zoomIn->set_sensitive( false );
+ zoomOut->set_sensitive( false );
+ } else {
+ zoomIn->set_sensitive( true);
+ zoomOut->set_sensitive( true );
+ }
+
store->clear();
Glib::ustring symbolSetString = symbolSet->get_active_text();
@@ -449,14 +506,20 @@ void SymbolsDialog::iconChanged() {
// Read Visio stencil files
SPDocument* read_vss( gchar* fullname, gchar* filename ) {
- WPXFileStream input(fullname);
+ RVNGFileStream input(fullname);
if (!libvisio::VisioDocument::isSupported(&input)) {
return NULL;
}
- libvisio::VSDStringVector output;
+ RVNGStringVector output;
+#if WITH_LIBVISIO01
+ librevenge::RVNGSVGDrawingGenerator generator(output, "svg");
+
+ if (!libvisio::VisioDocument::parseStencils(&input, &generator)) {
+#else
if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) {
+#endif
return NULL;
}
@@ -594,11 +657,11 @@ GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l)
g_return_val_if_fail(r != NULL, l);
// Stop multiple counting of same symbol
- if( SP_IS_USE(r) ) {
+ if ( dynamic_cast<SPUse *>(r) ) {
return l;
}
- if( SP_IS_SYMBOL(r) ) {
+ if ( dynamic_cast<SPSymbol *>(r) ) {
l = g_slist_prepend (l, r);
}
@@ -613,13 +676,14 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) {
GSList *l = NULL;
l = symbols_in_doc_recursive (symbolDocument->getRoot(), l );
+ l = g_slist_reverse( l );
return l;
}
GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l)
{
- if( SP_IS_USE(r) ) {
+ if ( dynamic_cast<SPUse *>(r) ) {
l = g_slist_prepend (l, r);
}
@@ -644,8 +708,9 @@ gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* documen
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 ) ) {
+ SPObject *obj = reinterpret_cast<SPObject *>(l->data);
+ SPUse *use = dynamic_cast<SPUse *>(obj);
+ if ( use ) {
gchar const *href = use->getRepr()->attribute("xlink:href");
if( href ) {
Glib::ustring href2(href);
@@ -665,8 +730,9 @@ void SymbolsDialog::add_symbols( SPDocument* symbolDocument ) {
GSList* l = symbols_in_doc( symbolDocument );
for( ; l != NULL; l = l->next ) {
- SPObject* symbol = SP_OBJECT(l->data);
- if (SP_IS_SYMBOL(symbol)) {
+ SPObject *obj = reinterpret_cast<SPObject *>(l->data);
+ SPSymbol *symbol = dynamic_cast<SPSymbol *>(obj);
+ if (symbol) {
add_symbol( symbol );
}
}
@@ -755,8 +821,9 @@ SymbolsDialog::draw_symbol(SPObject *symbol)
previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
previewDocument->ensureUpToDate();
- SPItem *item = SP_ITEM(object_temp);
- unsigned psize = SYMBOL_ICON_SIZES[in_sizes];
+ SPItem *item = dynamic_cast<SPItem *>(object_temp);
+ g_assert(item != NULL);
+ unsigned psize = SYMBOL_ICON_SIZES[pack_size];
Glib::RefPtr<Gdk::Pixbuf> pixbuf(NULL);
// We could use cache here, but it doesn't really work with the structure
@@ -778,6 +845,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol)
if( fitSymbol->get_active() )
scale = psize / std::max(width, height);
+ else
+ scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0;
pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize));
}
diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h
index 8021fb0c1..5dc1e3cad 100644
--- a/src/ui/dialog/symbols.h
+++ b/src/ui/dialog/symbols.h
@@ -65,6 +65,8 @@ private:
static SymbolColumns *getColumns();
+ void packless();
+ void packmore();
void zoomin();
void zoomout();
void rebuild();
@@ -95,13 +97,18 @@ private:
std::map<Glib::ustring, SPDocument*> symbolSets;
// Index into sizes which is selected
- int in_sizes;
+ int pack_size;
+
+ // Scale factor
+ int scale_factor;
Glib::RefPtr<Gtk::ListStore> store;
Gtk::ComboBoxText* symbolSet;
Gtk::IconView* iconView;
Gtk::Button* addSymbol;
Gtk::Button* removeSymbol;
+ Gtk::Button* zoomIn;
+ Gtk::Button* zoomOut;
Gtk::ToggleButton* fitSymbol;
void setTargetDesktop(SPDesktop *desktop);
diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp
new file mode 100644
index 000000000..8a104d137
--- /dev/null
+++ b/src/ui/dialog/tags.cpp
@@ -0,0 +1,1166 @@
+/*
+ * A simple panel for tags
+ *
+ * Authors:
+ * Theodore Janeczko
+ *
+ * Copyright (C) Theodore Janeczko 2012 <flutterguy317@gmail.com>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if WITH_GLIBMM_2_32
+# include <glibmm/threads.h>
+#endif
+
+#include "tags.h"
+#include <gtkmm/widget.h>
+#include <gtkmm/icontheme.h>
+#include <gtkmm/imagemenuitem.h>
+#include <gtkmm/separatormenuitem.h>
+
+#include <glibmm/main.h>
+#include <glibmm/i18n.h>
+
+#include "desktop.h"
+#include "desktop-style.h"
+#include "document.h"
+#include "document-undo.h"
+#include "helper/action.h"
+#include "inkscape.h"
+#include "layer-fns.h"
+#include "layer-manager.h"
+#include "preferences.h"
+#include "sp-item.h"
+#include "sp-object.h"
+#include "sp-shape.h"
+#include "svg/css-ostringstream.h"
+#include "ui/icon-names.h"
+#include "ui/widget/layertypeicon.h"
+#include "ui/widget/addtoicon.h"
+#include "verbs.h"
+#include "widgets/icon.h"
+#include "xml/node.h"
+#include "xml/node-observer.h"
+#include "xml/repr.h"
+#include "sp-root.h"
+#include "ui/tools/tool-base.h" //"event-context.h"
+#include "selection.h"
+//#include "dialogs/dialog-events.h"
+#include "widgets/sp-color-notebook.h"
+#include "style.h"
+#include "filter-chemistry.h"
+#include "filters/blend.h"
+#include "filters/gaussian-blur.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
+#include "sp-tag.h"
+#include "sp-defs.h"
+#include "sp-tag-use.h"
+#include "sp-tag-use-reference.h"
+
+//#define DUMP_LAYERS 1
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+using Inkscape::XML::Node;
+
+TagsPanel& TagsPanel::getInstance()
+{
+ return *new TagsPanel();
+}
+
+enum {
+ COL_ADD = 1
+};
+
+enum {
+ BUTTON_NEW = 0,
+ BUTTON_TOP,
+ BUTTON_BOTTOM,
+ BUTTON_UP,
+ BUTTON_DOWN,
+ BUTTON_DELETE,
+ DRAGNDROP
+};
+
+class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver {
+public:
+ ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) :
+ _pnl(pnl),
+ _obj(obj),
+ _repr(repr),
+ _labelAttr(g_quark_from_string("inkscape:label"))
+ {}
+
+ ObjectWatcher(TagsPanel* pnl, SPObject* obj) :
+ _pnl(pnl),
+ _obj(obj),
+ _repr(obj->getRepr()),
+ _labelAttr(g_quark_from_string("inkscape:label"))
+ {}
+
+ virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ )
+ {
+ if ( _pnl && _obj ) {
+ _pnl->_objectsChanged( _obj );
+ }
+ }
+ virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared<char> /*old_content*/, Util::ptr_shared<char> /*new_content*/ ) {}
+ virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared<char> /*old_value*/, Util::ptr_shared<char> /*new_value*/ ) {
+ if ( _pnl && _obj ) {
+ if ( name == _labelAttr ) {
+ _pnl->_updateObject( _obj);
+ }
+ }
+ }
+
+ TagsPanel* _pnl;
+ SPObject* _obj;
+ Inkscape::XML::Node* _repr;
+ GQuark _labelAttr;
+};
+
+class TagsPanel::InternalUIBounce
+{
+public:
+ int _actionCode;
+};
+
+void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip )
+{
+ bool set = false;
+
+ if ( iconName ) {
+ GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName );
+ gtk_widget_show( child );
+ btn.add( *manage(Glib::wrap(child)) );
+ btn.set_relief(Gtk::RELIEF_NONE);
+ set = true;
+ }
+
+ if ( desktop ) {
+ Verb *verb = Verb::get( code );
+ if ( verb ) {
+ SPAction *action = verb->get_action(desktop);
+ if ( !set && action && action->image ) {
+ GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image );
+ gtk_widget_show( child );
+ btn.add( *manage(Glib::wrap(child)) );
+ set = true;
+ }
+ }
+ }
+
+ btn.set_tooltip_text (tooltip);
+}
+
+
+Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id )
+{
+ GtkWidget* iconWidget = 0;
+ const char* label = 0;
+
+ if ( iconName ) {
+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName );
+ }
+
+ if ( desktop ) {
+ Verb *verb = Verb::get( code );
+ if ( verb ) {
+ SPAction *action = verb->get_action(desktop);
+ if ( !iconWidget && action && action->image ) {
+ iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image );
+ }
+
+ if ( action ) {
+ label = action->name;
+ }
+ }
+ }
+
+ if ( !label && fallback ) {
+ label = fallback;
+ }
+
+ Gtk::Widget* wrapped = 0;
+ if ( iconWidget ) {
+ wrapped = manage(Glib::wrap(iconWidget));
+ wrapped->show();
+ }
+
+
+ Gtk::MenuItem* item = 0;
+
+ if (wrapped) {
+ item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true));
+ } else {
+ item = Gtk::manage(new Gtk::MenuItem(label, true));
+ }
+
+ item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id));
+ _popupMenu.append(*item);
+
+ return *item;
+}
+
+void TagsPanel::_fireAction( unsigned int code )
+{
+ if ( _desktop ) {
+ Verb *verb = Verb::get( code );
+ if ( verb ) {
+ SPAction *action = verb->get_action(_desktop);
+ if ( action ) {
+ sp_action_perform( action, NULL );
+ }
+ }
+ }
+}
+
+void TagsPanel::_takeAction( int val )
+{
+ if ( !_pending ) {
+ _pending = new InternalUIBounce();
+ _pending->_actionCode = val;
+ Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 );
+ }
+}
+
+bool TagsPanel::_executeAction()
+{
+ // Make sure selected layer hasn't changed since the action was triggered
+ if ( _pending)
+ {
+ int val = _pending->_actionCode;
+// SPObject* target = _pending->_target;
+ bool empty = _desktop->selection->isEmpty();
+
+ switch ( val ) {
+ case BUTTON_NEW:
+ {
+ _fireAction( SP_VERB_TAG_NEW );
+ }
+ break;
+ case BUTTON_TOP:
+ {
+ _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT);
+ }
+ break;
+ case BUTTON_BOTTOM:
+ {
+ _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK );
+ }
+ break;
+ case BUTTON_UP:
+ {
+ _fireAction( empty ? SP_VERB_LAYER_RAISE : SP_VERB_SELECTION_RAISE );
+ }
+ break;
+ case BUTTON_DOWN:
+ {
+ _fireAction( empty ? SP_VERB_LAYER_LOWER : SP_VERB_SELECTION_LOWER );
+ }
+ break;
+ case BUTTON_DELETE:
+ {
+ std::vector<SPObject *> todelete;
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<std::vector<SPObject *>*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete));
+ for (std::vector<SPObject *>::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) {
+ SPObject * obj = *iter;
+ if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) {
+ //obj->parent->getRepr()->removeChild(obj->getRepr());
+ obj->deleteObject(true, true);
+ }
+ }
+ DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set"));
+ }
+ break;
+ case DRAGNDROP:
+ {
+ _doTreeMove( );
+ }
+ break;
+ }
+
+ delete _pending;
+ _pending = 0;
+ }
+
+ return false;
+}
+
+
+class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+
+ ModelColumns()
+ {
+ add(_colParentObject);
+ add(_colObject);
+ add(_colLabel);
+ add(_colAddRemove);
+ add(_colAllowAddRemove);
+ }
+ virtual ~ModelColumns() {}
+
+ Gtk::TreeModelColumn<SPObject*> _colParentObject;
+ Gtk::TreeModelColumn<SPObject*> _colObject;
+ Gtk::TreeModelColumn<Glib::ustring> _colLabel;
+ Gtk::TreeModelColumn<bool> _colAddRemove;
+ Gtk::TreeModelColumn<bool> _colAllowAddRemove;
+};
+
+void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector<SPObject *>* todelete)
+{
+ Gtk::TreeRow row = *iter;
+ SPObject * obj = row[_model->_colObject];
+ if (obj && obj->parent) {
+ todelete->push_back(obj);
+ }
+}
+
+void TagsPanel::_updateObject( SPObject *obj ) {
+ _store->foreach( sigc::bind<SPObject*>(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) );
+}
+
+bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj)
+{
+ Gtk::TreeModel::Row row = *iter;
+ if ( obj == row[_model->_colObject] )
+ {
+ /*
+ * We get notified of layer update here (from layer->setLabel()) before layer->label() is set
+ * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which
+ * has the correct value (bug #168351)
+ */
+ //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId();
+ gchar const *label;
+ SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0;
+ if (use && use->ref->isAttached()) {
+ label = use->ref->getObject()->getAttribute("inkscape:label");
+ } else {
+ label = obj->getAttribute("inkscape:label");
+ }
+ row[_model->_colLabel] = label ? label : obj->getId();
+ row[_model->_colAddRemove] = SP_IS_TAG(obj);
+ }
+
+ return false;
+}
+
+void TagsPanel::_objectsSelected( Selection *sel ) {
+
+ _selectedConnection.block();
+ _tree.get_selection()->unselect_all();
+ for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next)
+ {
+ SPObject *obj = reinterpret_cast<SPObject *>(iter->data);
+ _store->foreach(sigc::bind<SPObject *>( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj));
+ }
+ _selectedConnection.unblock();
+ _checkTreeSelection();
+}
+
+bool TagsPanel::_checkForSelected(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPObject * it = row[_model->_colObject];
+ if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj )
+ {
+ Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
+
+ select->select(iter);
+ }
+ return false;
+}
+
+// TODO does not look good that we're ignoring the passed in root. Investigate.
+void TagsPanel::_objectsChanged(SPObject* root)
+{
+ while (!_objectWatchers.empty())
+ {
+ TagsPanel::ObjectWatcher *w = _objectWatchers.back();
+ w->_repr->removeObserver(*w);
+ _objectWatchers.pop_back();
+ delete w;
+ }
+
+ if (_desktop) {
+ SPDocument* document = _desktop->doc();
+ SPDefs* root = document->getDefs();
+ if ( root ) {
+ _selectedConnection.block();
+ _store->clear();
+ _addObject( document, root, 0 );
+ _selectedConnection.unblock();
+ _objectsSelected(_desktop->selection);
+ _checkTreeSelection();
+ }
+ }
+}
+
+void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow )
+{
+ if ( _desktop && obj ) {
+ for ( SPObject *child = obj->children; child != NULL; child = child->next) {
+ if (SP_IS_TAG(child))
+ {
+ Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend();
+ Gtk::TreeModel::Row row = *iter;
+ row[_model->_colObject] = child;
+ row[_model->_colParentObject] = NULL;
+ row[_model->_colLabel] = child->label() ? child->label() : child->getId();
+ row[_model->_colAddRemove] = true;
+ row[_model->_colAllowAddRemove] = true;
+
+ _tree.expand_to_path( _store->get_path(iter) );
+
+ TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child);
+ child->getRepr()->addObserver(*w);
+ _objectWatchers.push_back(w);
+ _addObject( doc, child, &row );
+ }
+ }
+ if (SP_IS_TAG(obj) && obj->children)
+ {
+ Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend();
+ Gtk::TreeModel::Row rowitems = *iteritems;
+ rowitems[_model->_colObject] = NULL;
+ rowitems[_model->_colParentObject] = obj;
+ rowitems[_model->_colLabel] = _("Items");
+ rowitems[_model->_colAddRemove] = false;
+ rowitems[_model->_colAllowAddRemove] = false;
+
+ _tree.expand_to_path( _store->get_path(iteritems) );
+
+ for ( SPObject *child = obj->children; child != NULL; child = child->next) {
+ if (SP_IS_TAG_USE(child))
+ {
+ SPItem *item = SP_TAG_USE(child)->ref->getObject();
+ Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children());
+ Gtk::TreeModel::Row row = *iter;
+ row[_model->_colObject] = child;
+ row[_model->_colParentObject] = NULL;
+ row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href;
+ row[_model->_colAddRemove] = false;
+ row[_model->_colAllowAddRemove] = true;
+
+ if (SP_TAG(obj)->expanded()) {
+ _tree.expand_to_path( _store->get_path(iter) );
+ }
+
+ if (item) {
+ TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr());
+ item->getRepr()->addObserver(*w);
+ _objectWatchers.push_back(w);
+ }
+ }
+ }
+ }
+ }
+}
+
+void TagsPanel::_select_tag( SPTag * tag )
+{
+ for (SPObject * child = tag->children; child != NULL; child = child->next)
+ {
+ if (SP_IS_TAG(child)) {
+ _select_tag(SP_TAG(child));
+ } else if (SP_IS_TAG_USE(child)) {
+ SPObject * obj = SP_TAG_USE(child)->ref->getObject();
+ if (obj) {
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent);
+ _desktop->selection->add(obj);
+ }
+ }
+ }
+}
+
+void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter )
+{
+ if (iter) {
+ Gtk::TreeModel::Row row = *iter;
+ SPObject *obj = row[_model->_colObject];
+ if (obj) {
+ if (SP_IS_TAG(obj)) {
+ _select_tag(SP_TAG(obj));
+ } else if (SP_IS_TAG_USE(obj)) {
+ SPObject * item = SP_TAG_USE(obj)->ref->getObject();
+ if (item) {
+ if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent);
+ _desktop->selection->add(item);
+ }
+ }
+ }
+ }
+}
+
+void TagsPanel::_pushTreeSelectionToCurrent()
+{
+ _selectionChangedConnection.block();
+ // TODO hunt down the possible API abuse in getting NULL
+ if ( _desktop && _desktop->currentRoot() ) {
+ _desktop->selection->clear();
+ _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback));
+ }
+ _selectionChangedConnection.unblock();
+
+ _checkTreeSelection();
+}
+
+void TagsPanel::_checkTreeSelection()
+{
+ bool sensitive = _tree.get_selection()->count_selected_rows() > 0;
+ bool sensitiveNonTop = true;
+ bool sensitiveNonBottom = true;
+// if ( _tree.get_selection()->count_selected_rows() > 0 ) {
+// sensitive = true;
+//
+// SPObject* inTree = _selectedLayer();
+// if ( inTree ) {
+//
+// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0);
+// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0);
+//
+// }
+// }
+
+
+ for ( std::vector<Gtk::Widget*>::iterator it = _watching.begin(); it != _watching.end(); ++it ) {
+ (*it)->set_sensitive( sensitive );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) {
+ (*it)->set_sensitive( sensitiveNonTop );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) {
+ (*it)->set_sensitive( sensitiveNonBottom );
+ }
+}
+
+bool TagsPanel::_handleKeyEvent(GdkEventKey *event)
+{
+
+ switch (Inkscape::UI::Tools::get_group0_keyval(event)) {
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ case GDK_KEY_F2: {
+ Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
+ if (iter && !_text_renderer->property_editable()) {
+ Gtk::TreeRow row = *iter;
+ SPObject * obj = row[_model->_colObject];
+ if (obj && SP_IS_TAG(obj)) {
+ Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter);
+ // Edit the layer label
+ _text_renderer->property_editable() = true;
+ _tree.set_cursor(*path, *_name_column, true);
+ grab_focus();
+ return true;
+ }
+ }
+ }
+ case GDK_KEY_Delete: {
+ std::vector<SPObject *> todelete;
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<std::vector<SPObject *>*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete));
+ if (!todelete.empty()) {
+ for (std::vector<SPObject *>::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) {
+ SPObject * obj = *iter;
+ if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) {
+ //obj->parent->getRepr()->removeChild(obj->getRepr());
+ obj->deleteObject(true, true);
+ }
+ }
+ DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set"));
+ }
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+bool TagsPanel::_handleButtonEvent(GdkEventButton* event)
+{
+ static unsigned doubleclick = 0;
+
+ 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);
+ if (_tree.get_selection()->is_selected(path)) {
+ return true;
+ }
+ }
+ }
+
+ if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
+ // 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_ADD-1)) {
+ down_at_add = true;
+ return true;
+ } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) {
+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection));
+ _defer_target = path;
+ } else {
+ down_at_add = false;
+ }
+ } else {
+ down_at_add = false;
+ }
+ }
+
+ if ( event->type == GDK_BUTTON_RELEASE) {
+ _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction));
+ }
+
+ // 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)) {
+
+ 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 (_defer_target) {
+ if (_defer_target == path && !(event->x == 0 && event->y == 0))
+ {
+ _tree.set_cursor(path, *col, false);
+ }
+ _defer_target = Gtk::TreeModel::Path();
+ } else {
+ Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+
+ SPObject* obj = row[_model->_colObject];
+
+ if (obj) {
+ if (col == _tree.get_column(COL_ADD - 1) && down_at_add) {
+ if (SP_IS_TAG(obj)) {
+ bool wasadded = false;
+ for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next)
+ {
+ SPObject *newobj = reinterpret_cast<SPObject *>(iter->data);
+ bool addchild = true;
+ for ( SPObject *child = obj->children; child != NULL; child = child->next) {
+ if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) {
+ addchild = false;
+ }
+ }
+ if (addchild) {
+ Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref");
+ clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false);
+ obj->appendChild(clone);
+ wasadded = true;
+ }
+ }
+ if (wasadded) {
+ DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to set"));
+ }
+ } else {
+ std::vector<SPObject *> todelete;
+ // FIXME unnecessary use of XML tree
+ _tree.get_selection()->selected_foreach_iter(sigc::bind<std::vector<SPObject *>*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete));
+ if (!todelete.empty()) {
+ for (std::vector<SPObject *>::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) {
+ SPObject * tobj = *iter;
+ if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) {
+ //tobj->parent->getRepr()->removeChild(tobj->getRepr());
+ tobj->deleteObject(true, true);
+ }
+ }
+ } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) {
+ obj->parent->getRepr()->removeChild(obj->getRepr());
+ }
+ DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set"));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) {
+ doubleclick = 1;
+ }
+
+ if ( event->type == GDK_BUTTON_RELEASE && doubleclick) {
+ doubleclick = 0;
+ 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 ) && col == _name_column) {
+ Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+
+ SPObject* obj = row[_model->_colObject];
+ if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) {
+ // Double click on the Layer name, enable editing
+ _text_renderer->property_editable() = true;
+ _tree.set_cursor (path, *_name_column, true);
+ grab_focus();
+ }
+ }
+ }
+
+ return false;
+}
+
+void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter)
+{
+ Gtk::TreeModel::Row row = *iter;
+ SPObject* obj = row[_model->_colObject];
+ SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0;
+ if (item)
+ {
+ _dnd_source.push_back(item);
+ }
+}
+
+/*
+ * 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 TagsPanel::_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;
+ Gtk::TreeView::Column *target_column;
+
+ _dnd_into = true;
+ _dnd_target = _document->getDefs();
+ _dnd_source.clear();
+ _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource));
+
+ if (_dnd_source.empty()) {
+ return true;
+ }
+
+ if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) {
+ // Are we before, inside or after the drop layer
+ Gdk::Rectangle rect;
+ _tree.get_background_area (target_path, *target_column, rect);
+ int cell_height = rect.get_height();
+ _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3));
+ if (cell_y > (int)(cell_height * 2/3)) {
+ Gtk::TreeModel::Path next_path = target_path;
+ next_path.next();
+ if (_store->iter_is_valid(_store->get_iter(next_path))) {
+ target_path = next_path;
+ } else {
+ // Dragging to the "end"
+ Gtk::TreeModel::Path up_path = target_path;
+ up_path.up();
+ if (_store->iter_is_valid(_store->get_iter(up_path))) {
+ // Drop into parent
+ target_path = up_path;
+ _dnd_into = true;
+ } else {
+ // Drop into the top level
+ _dnd_target = _document->getDefs();
+ _dnd_into = true;
+ }
+ }
+ }
+ Gtk::TreeModel::iterator iter = _store->get_iter(target_path);
+ if (_store->iter_is_valid(iter)) {
+ Gtk::TreeModel::Row row = *iter;
+ SPObject *obj = row[_model->_colObject];
+ SPObject *pobj = row[_model->_colParentObject];
+ if (obj) {
+ if (SP_IS_TAG(obj)) {
+ _dnd_target = SP_TAG(obj);
+ } else if (SP_IS_TAG(obj->parent)) {
+ _dnd_target = SP_TAG(obj->parent);
+ _dnd_into = true;
+ }
+ } else if (pobj && SP_IS_TAG(pobj)) {
+ _dnd_target = SP_TAG(pobj);
+ _dnd_into = true;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ _takeAction(DRAGNDROP);
+
+ return false;
+}
+
+/*
+ * Move a layer in response to a drag & drop action
+ */
+void TagsPanel::_doTreeMove( )
+{
+ if (_dnd_target) {
+ for (std::vector<SPTag *>::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter)
+ {
+ SPTag *src = *iter;
+ if (src != _dnd_target) {
+ src->moveTo(_dnd_target, _dnd_into);
+ }
+ }
+ _desktop->selection->clear();
+ while (!_dnd_source.empty())
+ {
+ SPTag *src = _dnd_source.back();
+ _select_tag(src);
+ _dnd_source.pop_back();
+ }
+ DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS,
+ _("Moved sets"));
+ }
+}
+
+
+void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text)
+{
+ Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+
+ _renameObject(row, new_text);
+ _text_renderer->property_editable() = false;
+}
+
+void TagsPanel::_handleEditingCancelled()
+{
+ _text_renderer->property_editable() = false;
+}
+
+void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name)
+{
+ if ( row && _desktop) {
+ SPObject* obj = row[_model->_colObject];
+ if ( obj ) {
+ if (SP_IS_TAG(obj)) {
+ gchar const* oldLabel = obj->label();
+ if ( !name.empty() && (!oldLabel || name != oldLabel) ) {
+ obj->setLabel(name.c_str());
+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
+ _("Rename object"));
+ }
+ } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) {
+ gchar const* oldLabel = obj->label();
+ if ( !name.empty() && (!oldLabel || name != oldLabel) ) {
+ obj->setLabel(name.c_str());
+ DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
+ _("Rename object"));
+ }
+ }
+ }
+ }
+}
+
+bool TagsPanel::_noSelection( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ )
+{
+ return false;
+}
+
+bool TagsPanel::_rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected )
+{
+ bool val = true;
+ if ( !currentlySelected && _toggleEvent )
+ {
+ GdkEvent* event = gtk_get_current_event();
+ if ( event ) {
+ // (keep these checks separate, so we know when to call gdk_event_free()
+ if ( event->type == GDK_BUTTON_PRESS ) {
+ GdkEventButton const* target = reinterpret_cast<GdkEventButton const*>(_toggleEvent);
+ GdkEventButton const* evtb = reinterpret_cast<GdkEventButton const*>(event);
+
+ if ( (evtb->window == target->window)
+ && (evtb->send_event == target->send_event)
+ && (evtb->time == target->time)
+ && (evtb->state == target->state)
+ )
+ {
+ // Ooooh! It's a magic one
+ val = false;
+ }
+ }
+ gdk_event_free(event);
+ }
+ }
+ return val;
+}
+
+void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded)
+{
+ Gtk::TreeModel::Row row = *iter;
+
+ SPObject* obj = row[_model->_colParentObject];
+ if (obj && SP_IS_TAG(obj))
+ {
+ SP_TAG(obj)->setExpanded(isexpanded);
+ obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT);
+ }
+}
+
+/**
+ * Constructor
+ */
+TagsPanel::TagsPanel() :
+ UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS),
+ _rootWatcher(0),
+ deskTrack(),
+ _desktop(0),
+ _document(0),
+ _model(0),
+ _pending(0),
+ _toggleEvent(0),
+ _defer_target(),
+ desktopChangeConn()
+{
+ //Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ ModelColumns *zoop = new ModelColumns();
+ _model = zoop;
+
+ _store = Gtk::TreeStore::create( *zoop );
+
+ _tree.set_model( _store );
+ _tree.set_headers_visible(false);
+ _tree.set_reorderable(true);
+ _tree.enable_model_drag_dest (Gdk::ACTION_MOVE);
+
+ Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon());
+ int addColNum = _tree.append_column("type", *addRenderer) - 1;
+ Gtk::TreeViewColumn *col = _tree.get_column(addColNum);
+ if ( col ) {
+ col->add_attribute( addRenderer->property_active(), _model->_colAddRemove );
+ col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove );
+ }
+
+ _text_renderer = manage(new Gtk::CellRendererText());
+ int nameColNum = _tree.append_column("Name", *_text_renderer) - 1;
+ _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.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+ _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) );
+ _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) );
+
+ _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false);
+ _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind<bool>(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false));
+ _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind<bool>(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true));
+
+ _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) );
+ _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) );
+
+ _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false );
+ _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false );
+ _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false );
+
+ _scroller.add( _tree );
+ _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
+ _scroller.set_shadow_type(Gtk::SHADOW_IN);
+ Gtk::Requisition sreq;
+#if WITH_GTKMM_3_0
+ Gtk::Requisition sreq_natural;
+ _scroller.get_preferred_size(sreq_natural, sreq);
+#else
+ sreq = _scroller.size_request();
+#endif
+ int minHeight = 70;
+ if (sreq.height < minHeight) {
+ // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar
+ _scroller.set_size_request(sreq.width, minHeight);
+ }
+
+ _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET );
+
+ _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK);
+
+ _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET);
+
+ SPDesktop* targetDesktop = getDesktop();
+
+ Gtk::Button* btn = manage( new Gtk::Button() );
+ _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new selection set") );
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) );
+ _buttonsSecondary.pack_start(*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) );
+// _buttonsRow.add( *btn );
+
+ btn = manage( new Gtk::Button() );
+ _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Set") );
+ btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) );
+ _watching.push_back( btn );
+ _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK);
+
+ _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET);
+ _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET);
+
+ // -------------------------------------------------------
+ {
+ _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "Add a new selection set", (int)BUTTON_NEW ) );
+
+ _popupMenu.show_all_children();
+ }
+ // -------------------------------------------------------
+
+
+
+ for ( std::vector<Gtk::Widget*>::iterator it = _watching.begin(); it != _watching.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+ for ( std::vector<Gtk::Widget*>::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) {
+ (*it)->set_sensitive( false );
+ }
+
+ setDesktop( targetDesktop );
+
+ show_all_children();
+
+ // restorePanelPrefs();
+
+ // Connect this up last
+ desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) );
+ deskTrack.connect(GTK_WIDGET(gobj()));
+}
+
+TagsPanel::~TagsPanel()
+{
+
+ setDesktop(NULL);
+
+ if ( _model )
+ {
+ delete _model;
+ _model = 0;
+ }
+
+ if (_pending) {
+ delete _pending;
+ _pending = 0;
+ }
+
+ if ( _toggleEvent )
+ {
+ gdk_event_free( _toggleEvent );
+ _toggleEvent = 0;
+ }
+
+ desktopChangeConn.disconnect();
+ deskTrack.disconnect();
+}
+
+void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document)
+{
+ while (!_objectWatchers.empty())
+ {
+ TagsPanel::ObjectWatcher *w = _objectWatchers.back();
+ w->_repr->removeObserver(*w);
+ _objectWatchers.pop_back();
+ delete w;
+ }
+
+ if (_rootWatcher)
+ {
+ _rootWatcher->_repr->removeObserver(*_rootWatcher);
+ delete _rootWatcher;
+ _rootWatcher = NULL;
+ }
+
+ _document = document;
+
+ if (document && document->getDefs() && document->getDefs()->getRepr())
+ {
+ _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs());
+ document->getDefs()->getRepr()->addObserver(*_rootWatcher);
+ _objectsChanged(document->getDefs());
+ }
+}
+
+void TagsPanel::setDesktop( SPDesktop* desktop )
+{
+ Panel::setDesktop(desktop);
+
+ if ( desktop != _desktop ) {
+ _documentChangedConnection.disconnect();
+ _selectionChangedConnection.disconnect();
+ if ( _desktop ) {
+ _desktop = 0;
+ }
+
+ _desktop = Panel::getDesktop();
+ if ( _desktop ) {
+ //setLabel( _desktop->doc()->name );
+ _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument));
+ _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected));
+
+ setDocument(_desktop, _desktop->doc());
+ }
+ }
+/*
+ GSList const *layers = _desktop->doc()->getResourceList( "layer" );
+ g_message( "layers list starts at %p", layers );
+ for ( GSList const *iter=layers ; iter ; iter = iter->next ) {
+ SPObject *layer=static_cast<SPObject *>(iter->data);
+ g_message(" {%s} [%s]", layer->id, layer->label() );
+ }
+*/
+ deskTrack.setBase(desktop);
+}
+
+
+
+
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h
new file mode 100644
index 000000000..d35dfba01
--- /dev/null
+++ b/src/ui/dialog/tags.h
@@ -0,0 +1,181 @@
+/*
+ * A simple dialog for tags UI.
+ *
+ * Authors:
+ * Theodore Janeczko
+ *
+ * Copyright (C) Theodore Janeczko 2012 <flutterguy317@gmail.com>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_TAGS_PANEL_H
+#define SEEN_TAGS_PANEL_H
+
+#include <gtkmm/box.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/dialog.h>
+#include "ui/widget/spinbutton.h"
+#include "ui/widget/panel.h"
+#include "ui/widget/object-composite-settings.h"
+#include "desktop-tracker.h"
+#include "ui/widget/style-subject.h"
+#include "selection.h"
+#include "ui/widget/filter-effect-chooser.h"
+
+class SPObject;
+class SPTag;
+struct SPColorSelector;
+
+namespace Inkscape {
+
+namespace UI {
+namespace Dialog {
+
+
+/**
+ * A panel that displays layers.
+ */
+class TagsPanel : public UI::Widget::Panel
+{
+public:
+ TagsPanel();
+ virtual ~TagsPanel();
+
+ //virtual void setOrientation( Gtk::AnchorType how );
+
+ static TagsPanel& getInstance();
+
+ void setDesktop( SPDesktop* desktop );
+ void setDocument( SPDesktop* desktop, SPDocument* document);
+
+protected:
+ //virtual void _handleAction( int setId, int itemId );
+ friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp);
+private:
+ class ModelColumns;
+ class InternalUIBounce;
+ class ObjectWatcher;
+
+ TagsPanel(TagsPanel const &); // no copy
+ TagsPanel &operator=(TagsPanel const &); // no assign
+
+ void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip );
+ void _fireAction( unsigned int code );
+ Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id );
+
+ bool _handleButtonEvent(GdkEventButton *event);
+ bool _handleKeyEvent(GdkEventKey *event);
+
+ void _storeDragSource(const Gtk::TreeModel::iterator& iter);
+ 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);
+ void _handleEditingCancelled();
+
+ void _doTreeMove();
+ void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name);
+
+ void _pushTreeSelectionToCurrent();
+ void _selected_row_callback( const Gtk::TreeModel::iterator& iter );
+ void _select_tag( SPTag * tag );
+
+ void _checkTreeSelection();
+
+ void _takeAction( int val );
+ bool _executeAction();
+
+ void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded );
+
+ bool _noSelection( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
+ bool _rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
+
+ void _updateObject(SPObject *obj);
+ bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj);
+
+ void _objectsSelected(Selection *sel);
+ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer);
+
+ void _objectsChanged(SPObject *root);
+ void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow );
+
+ void _checkForDeleted(const Gtk::TreeIter& iter, std::vector<SPObject *>* todelete);
+
+// std::vector<sigc::connection> groupConnections;
+ TagsPanel::ObjectWatcher* _rootWatcher;
+ std::vector<TagsPanel::ObjectWatcher*> _objectWatchers;
+
+ // Hooked to the layer manager:
+ sigc::connection _documentChangedConnection;
+ sigc::connection _selectionChangedConnection;
+
+ sigc::connection _changedConnection;
+ sigc::connection _addedConnection;
+ sigc::connection _removedConnection;
+
+ // Internal
+ sigc::connection _selectedConnection;
+ sigc::connection _expandedConnection;
+ sigc::connection _collapsedConnection;
+
+ DesktopTracker deskTrack;
+ SPDesktop* _desktop;
+ SPDocument* _document;
+ ModelColumns* _model;
+ InternalUIBounce* _pending;
+ gboolean _dnd_into;
+ std::vector<SPTag*> _dnd_source;
+ SPObject* _dnd_target;
+
+ GdkEvent* _toggleEvent;
+ bool down_at_add;
+
+ Gtk::TreeModel::Path _defer_target;
+
+ Glib::RefPtr<Gtk::TreeStore> _store;
+ std::vector<Gtk::Widget*> _watching;
+ std::vector<Gtk::Widget*> _watchingNonTop;
+ std::vector<Gtk::Widget*> _watchingNonBottom;
+
+ Gtk::TreeView _tree;
+ Gtk::CellRendererText *_text_renderer;
+ Gtk::TreeView::Column *_name_column;
+#if WITH_GTKMM_3_0
+ Gtk::Box _buttonsRow;
+ Gtk::Box _buttonsPrimary;
+ Gtk::Box _buttonsSecondary;
+#else
+ Gtk::HBox _buttonsRow;
+ Gtk::HBox _buttonsPrimary;
+ Gtk::HBox _buttonsSecondary;
+#endif
+ Gtk::ScrolledWindow _scroller;
+ Gtk::Menu _popupMenu;
+ Inkscape::UI::Widget::SpinButton _spinBtn;
+ Gtk::VBox _layersPage;
+
+ sigc::connection desktopChangeConn;
+
+};
+
+
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+
+#endif // SEEN_OBJECTS_PANEL_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/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp
index d75f81456..13cb01eef 100644
--- a/src/ui/dialog/template-load-tab.cpp
+++ b/src/ui/dialog/template-load-tab.cpp
@@ -24,7 +24,7 @@
#include "extension/db.h"
#include "extension/effect.h"
#include "inkscape.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "file.h"
#include "path-prefix.h"
#include "preferences.h"
diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp
index ef91962d4..f79d166f2 100644
--- a/src/ui/dialog/template-widget.cpp
+++ b/src/ui/dialog/template-widget.cpp
@@ -24,6 +24,7 @@
#include "document.h"
#include "document-undo.h"
#include "file.h"
+#include "sp-namedview.h"
#include "extension/implementation/implementation.h"
#include "inkscape.h"
@@ -69,7 +70,10 @@ void TemplateWidget::create()
_current_template.tpl_effect->effect(desc);
DocumentUndo::clearUndo(sp_desktop_document(desc));
sp_desktop_document(desc)->setModifiedSinceSave(false);
-
+
+ // Apply cx,cy etc. from document
+ sp_namedview_window_from_document( desc );
+
if (desktop)
desktop->clearWaitingCursor();
}
@@ -120,7 +124,7 @@ void TemplateWidget::_displayTemplateDetails()
if (_current_template.long_description != "")
message += _("Description: ") + _current_template.long_description + "\n\n";
- if (~_current_template.keywords.empty()){
+ if (!_current_template.keywords.empty()){
message += _("Keywords: ");
for (std::set<Glib::ustring>::iterator it = _current_template.keywords.begin(); it != _current_template.keywords.end(); ++it)
message += *it + " ";
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 17c29c69f..0f4a6f7f1 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -32,7 +32,6 @@ 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>
@@ -52,7 +51,7 @@ extern "C" {
#include "ui/icon-names.h"
#include "preferences.h"
#include "verbs.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "svg/css-ostringstream.h"
#include "widgets/icon.h"
#include "widgets/font-selector.h"
@@ -344,9 +343,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
- // 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();
+ // This is normally done for us by text-toolbar but only when we are in text editing context
+ fontlister->update_font_list(sp_desktop_document(this->desktop));
+ fontlister->selection_update();
Glib::ustring fontspec = fontlister->get_fontspec();
@@ -404,12 +403,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt");
// Pango font size is in 1024ths of a point
- // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE );
+ // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) );
std::ostringstream size_st;
- size_st << pt_size * PANGO_SCALE;
+ size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers
- Glib::ustring markup = "<span font=\"" + font_spec +
- "\" size=\"" + size_st.str() + "\">" + phrase_escaped + "</span>";
+ Glib::ustring markup = "<span font=\'" + font_spec +
+ "\' size=\'" + size_st.str() + "\'>" + phrase_escaped + "</span>";
preview_label.set_markup(markup.c_str());
}
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index a7f0b068e..3e135b9b2 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -47,13 +47,13 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
+static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
{
int page = daad->getCurrentPage();
daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection);
}
-static void on_selection_modified( Inkscape::Application */*inkscape*/,
+static void on_selection_modified( InkscapeApplication */*inkscape*/,
Inkscape::Selection *selection,
guint /*flags*/,
Transformation *daad )
diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp
index 55d0aff09..7ab6c78ba 100644
--- a/src/ui/dialog/xml-tree.cpp
+++ b/src/ui/dialog/xml-tree.cpp
@@ -24,13 +24,13 @@
#include "desktop.h"
#include "desktop-handles.h"
-#include "dialogs/dialog-events.h"
+#include "ui/dialog-events.h"
#include "document.h"
#include "document-undo.h"
#include "ui/tools/tool-base.h"
#include "helper/window.h"
#include "inkscape.h"
-#include "interface.h"
+#include "ui/interface.h"
#include "macros.h"
#include "message-context.h"
#include "message-stack.h"
@@ -1033,6 +1033,7 @@ void XmlTree::cmd_set_attr()
updated->updateRepr();
}
+ reinterpret_cast<SPObject *>(current_desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
DocumentUndo::done(current_document, SP_VERB_DIALOG_XML_EDITOR,
_("Change attribute"));