Code

Move files from the src/dialogs/ directory to the places where they
authortweenk <tweenk@users.sourceforge.net>
Sat, 21 Feb 2009 01:59:56 +0000 (01:59 +0000)
committertweenk <tweenk@users.sourceforge.net>
Sat, 21 Feb 2009 01:59:56 +0000 (01:59 +0000)
should be. Build libinkscape.a - should reduce link time.

93 files changed:
src/Makefile.am
src/Makefile_insert
src/conditions.cpp
src/desktop-events.cpp
src/dialogs/Makefile_insert
src/dialogs/eek-color-def.cpp [deleted file]
src/dialogs/eek-color-def.h [deleted file]
src/dialogs/eek-preview.cpp [deleted file]
src/dialogs/eek-preview.h [deleted file]
src/dialogs/extensions.cpp [deleted file]
src/dialogs/extensions.h [deleted file]
src/dialogs/fill-style.cpp [deleted file]
src/dialogs/fill-style.h [deleted file]
src/dialogs/guidelinedialog.cpp [deleted file]
src/dialogs/guidelinedialog.h [deleted file]
src/dialogs/iconpreview.cpp [deleted file]
src/dialogs/iconpreview.h [deleted file]
src/dialogs/in-dt-coordsys.cpp [deleted file]
src/dialogs/in-dt-coordsys.h [deleted file]
src/dialogs/item-properties.cpp
src/dialogs/layer-properties.cpp [deleted file]
src/dialogs/layer-properties.h [deleted file]
src/dialogs/layers-panel.cpp [deleted file]
src/dialogs/layers-panel.h [deleted file]
src/dialogs/object-attributes.cpp
src/dialogs/rdf.cpp [deleted file]
src/dialogs/rdf.h [deleted file]
src/dialogs/sp-attribute-widget.cpp [deleted file]
src/dialogs/sp-attribute-widget.h [deleted file]
src/dialogs/stroke-style.cpp [deleted file]
src/dialogs/stroke-style.h [deleted file]
src/dialogs/swatches.cpp [deleted file]
src/dialogs/swatches.h [deleted file]
src/dialogs/unclump.cpp [deleted file]
src/dialogs/unclump.h [deleted file]
src/dialogs/xml-tree.cpp
src/document.cpp
src/extension/error-file.cpp
src/file.cpp
src/helper/png-write.cpp
src/rdf.cpp [new file with mode: 0644]
src/rdf.h [new file with mode: 0644]
src/ui/Makefile_insert
src/ui/dialog/Makefile_insert
src/ui/dialog/align-and-distribute.cpp
src/ui/dialog/calligraphic-profile-rename.cpp [new file with mode: 0644]
src/ui/dialog/calligraphic-profile-rename.h [new file with mode: 0644]
src/ui/dialog/dialog-manager.cpp
src/ui/dialog/document-metadata.cpp
src/ui/dialog/extensions.cpp [new file with mode: 0644]
src/ui/dialog/extensions.h [new file with mode: 0644]
src/ui/dialog/fill-and-stroke.cpp
src/ui/dialog/guides.cpp [new file with mode: 0644]
src/ui/dialog/guides.h [new file with mode: 0644]
src/ui/dialog/icon-preview.cpp [new file with mode: 0644]
src/ui/dialog/icon-preview.h [new file with mode: 0644]
src/ui/dialog/layer-properties.cpp [new file with mode: 0644]
src/ui/dialog/layer-properties.h [new file with mode: 0644]
src/ui/dialog/layers.cpp [new file with mode: 0644]
src/ui/dialog/layers.h [new file with mode: 0644]
src/ui/dialog/panel-dialog.h
src/ui/dialog/swatches.cpp [new file with mode: 0644]
src/ui/dialog/swatches.h [new file with mode: 0644]
src/ui/previewable.h
src/ui/previewfillable.h
src/ui/previewholder.h
src/ui/view/edit-widget.h
src/ui/widget/Makefile_insert
src/ui/widget/entity-entry.cpp
src/ui/widget/layer-selector.cpp [new file with mode: 0644]
src/ui/widget/layer-selector.h [new file with mode: 0644]
src/ui/widget/licensor.cpp
src/ui/widget/panel.cpp
src/unclump.cpp [new file with mode: 0644]
src/unclump.h [new file with mode: 0644]
src/verbs.cpp
src/widgets/Makefile_insert
src/widgets/calligraphic-profile-rename.cpp [deleted file]
src/widgets/calligraphic-profile-rename.h [deleted file]
src/widgets/desktop-widget.cpp
src/widgets/eek-color-def.cpp [new file with mode: 0644]
src/widgets/eek-color-def.h [new file with mode: 0644]
src/widgets/eek-preview.cpp [new file with mode: 0644]
src/widgets/eek-preview.h [new file with mode: 0644]
src/widgets/fill-style.cpp [new file with mode: 0644]
src/widgets/fill-style.h [new file with mode: 0644]
src/widgets/layer-selector.cpp [deleted file]
src/widgets/layer-selector.h [deleted file]
src/widgets/sp-attribute-widget.cpp [new file with mode: 0644]
src/widgets/sp-attribute-widget.h [new file with mode: 0644]
src/widgets/stroke-style.cpp [new file with mode: 0644]
src/widgets/stroke-style.h [new file with mode: 0644]
src/widgets/toolbox.cpp

index dece3edcfe9e4c2fefdbece3159c6edf11a728a9..517e89f1afd8e4057eb395810ce470af0492557c 100644 (file)
@@ -1,10 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 
-
 # ################################################
-#
 #  G L O B A L
-#
 # ################################################
 
 # Should work in either automake1.7 or 1.8, but 1.6 doesn't
@@ -16,6 +13,40 @@ AUTOMAKE_OPTIONS = 1.7 subdir-objects
 # Executables compiled by "make" and installed by "make install"
 bin_PROGRAMS = inkscape inkview
 
+# Libraries which should be compiled by "make" but not installed.
+# Use this only for libraries that are really standalone, rather than for
+# source tree subdirectories.
+if WITH_INKBOARD
+libpedro = pedro/libpedro.a
+endif
+noinst_LIBRARIES =     \
+       libinkscape.a           \
+       dom/libdom.a            \
+       libcroco/libcroco.a     \
+       libavoid/libavoid.a     \
+       libgdl/libgdl.a         \
+       libcola/libcola.a       \
+       libvpsc/libvpsc.a       \
+       livarot/libvarot.a      \
+       2geom/lib2geom.a        \
+       $(libpedro)             \
+       libinkversion.a
+
+all_libs =                     \
+       $(noinst_LIBRARIES)     \
+       $(INKSCAPE_LIBS)        \
+       $(GNOME_VFS_LIBS)       \
+       $(XFT_LIBS)             \
+       $(FREETYPE_LIBS)        \
+       $(kdeldadd)             \
+       $(win32ldflags)         \
+       $(CARBON_LDFLAGS)       \
+       $(PERL_LIBS)            \
+       $(PYTHON_LIBS)          \
+       $(INKBOARD_LIBS)        \
+       $(LIBWPG_LIBS)          \
+       $(IMAGEMAGICK_LIBS)
+
 # Add sources common for Inkscape and Inkview to this variable.
 ink_common_sources =
 # Add Inkscape-only sources here.
@@ -23,11 +54,6 @@ inkscape_SOURCES =
 # Add Inkview-only sources here.
 inkview_SOURCES =
 
-# Libraries which should be compiled by "make" but not installed.
-# Use this only for libraries that are really standalone, rather than for
-# source tree subdirectories.
-noinst_LIBRARIES = $(inkscape_private_libs)
-
 INCLUDES =     \
        $(PERL_CFLAGS) $(PYTHON_CFLAGS) \
        $(FREETYPE_CFLAGS)      \
@@ -70,43 +96,6 @@ inkjar_dir = inkjar
 inkjar_libs = inkjar/libinkjar.a
 endif
 
-# Extra files to remove when doing "make distclean"
-DISTCLEANFILES =       \
-       helper/sp-marshal.cpp   \
-       helper/sp-marshal.h     \
-       inkscape-version.cpp
-
-if WITH_INKBOARD
-libpedro = pedro/libpedro.a
-endif
-
-inkscape_private_libs =        \
-       dom/libdom.a            \
-       libcroco/libcroco.a     \
-       libavoid/libavoid.a     \
-       libgdl/libgdl.a         \
-       libcola/libcola.a       \
-       libvpsc/libvpsc.a       \
-       livarot/libvarot.a      \
-       2geom/lib2geom.a        \
-       $(libpedro)             \
-       libinkversion.a
-
-all_libs =                     \
-       $(inkscape_private_libs)        \
-       $(INKSCAPE_LIBS)        \
-       $(GNOME_VFS_LIBS)       \
-       $(XFT_LIBS)             \
-       $(FREETYPE_LIBS)        \
-       $(kdeldadd)             \
-       $(win32ldflags)         \
-       $(CARBON_LDFLAGS)       \
-       $(PERL_LIBS)            \
-       $(PYTHON_LIBS)          \
-       $(INKBOARD_LIBS)        \
-       $(LIBWPG_LIBS)          \
-       $(IMAGEMAGICK_LIBS)
-
 # Include all partial makefiles from subdirectories
 include Makefile_insert
 include application/Makefile_insert
@@ -208,19 +197,57 @@ EXTRA_DIST =      \
        traits/reference.h \
        $(jabber_whiteboard_SOURCES)
 
+# Extra files to remove when doing "make distclean"
+DISTCLEANFILES =       \
+       helper/sp-marshal.cpp   \
+       helper/sp-marshal.h     \
+       inkscape-version.cpp
+
 # ################################################
-#
 #  B I N A R I E S
-#
 # ################################################
 
-inkscape_SOURCES += main.cpp $(ink_common_sources) $(win32_sources)
+# this should speed up the build
+libinkscape_a_SOURCES = $(ink_common_sources)
+
+inkscape_SOURCES += main.cpp $(win32_sources)
 inkscape_LDADD = $(all_libs)
 inkscape_LDFLAGS = --export-dynamic $(kdeldflags)
 
-inkview_SOURCES += inkview.cpp $(ink_common_sources) $(win32_sources)
+inkview_SOURCES += inkview.cpp $(win32_sources)
 inkview_LDADD = $(all_libs)
 
+# ################################################
+#  VERSION REPORTING
+# ################################################
+
+libinkversion_a_SOURCES = inkscape-version.cpp inkscape-version.h
+
+if USE_SVN_VERSION
+inkscape_version_deps = $(top_srcdir)/.svn/entries
+endif
+
+# If this is an SVN snapshot build, regenerate this file every time
+# someone updates the SVN working directory.
+inkscape-version.cpp: $(inkscape_version_deps)
+       VER_PREFIX="$(VERSION)"; \
+       if test -x "$(srcdir)/.svn" -a ! -z `which svn`; then \
+           VER_SVNREV=" r`svn info $(srcdir) | sed -n -e '/^Revision:/s/Revision: \(.*\)/\1/p'`"; \
+           if test ! -z "`svn status -q $(srcdir)`"; then \
+                VER_CUSTOM=" custom"; \
+           fi; \
+       fi; \
+       VERSION="$$VER_PREFIX$$VER_SVNREV$$VER_CUSTOM"; \
+       echo "namespace Inkscape { " \
+            "char const *version_string = \"$$VERSION\"; " \
+            "}" > inkscape-version.new.cpp; \
+       if cmp -s inkscape-version.new.cpp inkscape-version.cpp; then \
+            rm inkscape-version.new.cpp; \
+       else \
+            mv inkscape-version.new.cpp inkscape-version.cpp; \
+       fi; \
+       echo $$VERSION
+
 # #################################
 # ## TESTING STUFF (make check) ###
 # #################################
index 360f69cc45ad8bbae941c5e36fafd8ab4a959fc3..a3babf265720d4c24cc29e0886b06f42909d0c38 100644 (file)
@@ -1,22 +1,5 @@
 ## Makefile.am fragment, included by src/Makefile.am.
 
-
-# ################################################
-#
-#  I N K S C A P E
-#
-# ################################################
-
-# libinkpre.a: any object that's sharable between inkscape & inkview,
-# and isn't needed by object files in subdirectories (i.e. libinkpre.a
-# comes before subdirectory libraries on the link line).
-#
-# Excludes winmain.cpp (a gui wrapper around main): I'm guessing that
-# it needs to be explicitly listed as a source of each graphical
-# binary: it isn't (to my knowledge) called by main (whether directly
-# or indirectly), so I don't think that putting it in a library will
-# suffice to get it linked in.  Windows devel please confirm.  -- pjrm.
-
 ink_common_sources +=  \
        algorithms/find-last-if.h                                       \
        algorithms/longest-common-suffix.h                              \
@@ -137,6 +120,7 @@ ink_common_sources +=       \
        print.cpp print.h                                               \
        profile-manager.cpp profile-manager.h                           \
        proj_pt.cpp proj_pt.h                                           \
+       rdf.cpp rdf.h                                                   \
        rect-context.cpp rect-context.h                                 \
        require-config.h                                                \
        round.h                                                         \
@@ -254,8 +238,7 @@ ink_common_sources +=       \
        tools-switch.cpp tools-switch.h         \
        transf_mat_3x4.cpp transf_mat_3x4.h     \
        tweak-context.h tweak-context.cpp       \
-       ui/context-menu.cpp                     \
-       ui/context-menu.h                       \
+       unclump.cpp unclump.h                   \
        undo-stack-observer.h                   \
        unicoderange.cpp unicoderange.h         \
        unit-constants.h                        \
@@ -276,33 +259,6 @@ selection.$(OBJEXT): helper/sp-marshal.h
 sp-object.$(OBJEXT): helper/sp-marshal.h
 view.$(OBJEXT): helper/sp-marshal.h
 
-libinkversion_a_SOURCES = inkscape-version.cpp inkscape-version.h
-
-if USE_SVN_VERSION
-inkscape_version_deps = $(top_srcdir)/.svn/entries
-endif
-
-# If this is an SVN snapshot build, regenerate this file every time
-# someone updates the SVN working directory.
-inkscape-version.cpp: $(inkscape_version_deps)
-       VER_PREFIX="$(VERSION)"; \
-       if test -x "$(srcdir)/.svn" -a ! -z `which svn`; then \
-           VER_SVNREV=" r`svn info $(srcdir) | sed -n -e '/^Revision:/s/Revision: \(.*\)/\1/p'`"; \
-           if test ! -z "`svn status -q $(srcdir)`"; then \
-                VER_CUSTOM=" custom"; \
-           fi; \
-       fi; \
-       VERSION="$$VER_PREFIX$$VER_SVNREV$$VER_CUSTOM"; \
-       echo "namespace Inkscape { " \
-            "char const *version_string = \"$$VERSION\"; " \
-            "}" > inkscape-version.new.cpp; \
-       if cmp -s inkscape-version.new.cpp inkscape-version.cpp; then \
-            rm inkscape-version.new.cpp; \
-       else \
-            mv inkscape-version.new.cpp inkscape-version.cpp; \
-       fi; \
-       echo $$VERSION
-
 # ######################
 # ### CxxTest stuff ####
 # ######################
index 9a46f27d13f536caed9b4aa3c0c4734cd4e50080..4a18a6913be5ddebf2bae19315a599260f279f39 100644 (file)
@@ -19,7 +19,7 @@
 #include <glibmm/ustring.h>
 #include "conditions.h"
 #include "xml/repr.h"
-#include "dialogs/rdf.h"
+#include "rdf.h"
 
 typedef bool (* condition_evaluator)(SPItem const *item, gchar const *value);
 
index 46fb00cca773cf27eeaac5f3b4df20ceb32d5e98..73cd646650d0f66077bac56885ec4d54229c3846 100644 (file)
@@ -1,9 +1,7 @@
-#define __SP_DESKTOP_EVENTS_C__
-
-/*
- * Event handlers for SPDesktop
- *
- * Author:
+/** @file
+ * @brief Event handlers for SPDesktop
+ */
+/* Author:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *
  * Copyright (C) 1999-2002 Lauris Kaplinski
 #endif
 #include <map>
 #include <string>
+#include <2geom/line.h>
+#include <glibmm/i18n.h>
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "dialogs/dialog-events.h"
+#include "display/canvas-axonomgrid.h"
+#include "display/canvas-grid.h"
 #include "display/guideline.h"
 #include "display/snap-indicator.h"
+#include "document.h"
+#include "event-context.h"
+#include "helper/action.h"
 #include "helper/unit-menu.h"
 #include "helper/units.h"
-#include "desktop.h"
-#include "document.h"
+#include "message-context.h"
+#include "preferences.h"
+#include "snap.h"
 #include "sp-guide.h"
+#include "sp-metrics.h"
 #include "sp-namedview.h"
-#include "desktop-handles.h"
-#include "event-context.h"
+#include "tools-switch.h"
+#include "ui/dialog/guides.h"
 #include "widgets/desktop-widget.h"
-#include "sp-metrics.h"
-#include <glibmm/i18n.h>
-#include "dialogs/dialog-events.h"
-#include "message-context.h"
 #include "xml/repr.h"
-#include "dialogs/guidelinedialog.h"
-#include "snap.h"
-#include "display/canvas-grid.h"
-#include "display/canvas-axonomgrid.h"
-#include "preferences.h"
-#include "helper/action.h"
-#include "tools-switch.h"
-#include <2geom/line.h>
 
 static void snoop_extended(GdkEvent* event, SPDesktop *desktop);
 static void init_extended();
index f7404a8b2146e7c50bdd0a2f48eb7ddc54169c7c..32a11e83115b8403a88122b9ca2c90451d5c5601 100644 (file)
@@ -5,47 +5,19 @@ ink_common_sources += \
        dialogs/clonetiler.h            \
        dialogs/dialog-events.cpp       \
        dialogs/dialog-events.h         \
-       dialogs/eek-color-def.cpp       \
-       dialogs/eek-color-def.h         \
-       dialogs/eek-preview.cpp         \
-       dialogs/eek-preview.h           \
        dialogs/export.cpp              \
        dialogs/export.h                \
-       dialogs/extensions.cpp          \
-       dialogs/extensions.h            \
-       dialogs/fill-style.cpp          \
-       dialogs/fill-style.h            \
        dialogs/find.cpp                \
        dialogs/find.h                  \
-       dialogs/guidelinedialog.cpp     \
-       dialogs/guidelinedialog.h       \
-       dialogs/iconpreview.cpp         \
-       dialogs/iconpreview.h           \
-       dialogs/in-dt-coordsys.cpp      \
-       dialogs/in-dt-coordsys.h        \
        dialogs/input.cpp               \
        dialogs/input.h                 \
        dialogs/item-properties.cpp     \
        dialogs/item-properties.h       \
-       dialogs/layer-properties.cpp    \
-       dialogs/layer-properties.h      \
-       dialogs/layers-panel.cpp        \
-       dialogs/layers-panel.h          \
        dialogs/object-attributes.cpp   \
        dialogs/object-attributes.h     \
-       dialogs/rdf.cpp                 \
-       dialogs/rdf.h                   \
-       dialogs/sp-attribute-widget.cpp \
-       dialogs/sp-attribute-widget.h   \
        dialogs/spellcheck.cpp          \
        dialogs/spellcheck.h            \
-       dialogs/stroke-style.cpp        \
-       dialogs/stroke-style.h          \
-       dialogs/swatches.cpp            \
-       dialogs/swatches.h              \
        dialogs/text-edit.cpp           \
        dialogs/text-edit.h             \
-       dialogs/unclump.cpp             \
-       dialogs/unclump.h               \
        dialogs/xml-tree.cpp            \
        dialogs/xml-tree.h
diff --git a/src/dialogs/eek-color-def.cpp b/src/dialogs/eek-color-def.cpp
deleted file mode 100644 (file)
index 85b00b2..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/** @file
- * @brief EEK color definition
- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Eek Color Definition.
- *
- * The Initial Developer of the Original Code is
- * Jon A. Cruz.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "config.h"
-
-#ifdef HAVE_LIBINTL_H
-#include <libintl.h>
-#endif
-
-#if !defined(_)
-#define _(s) gettext(s)
-#endif // !defined(_)
-
-#include "eek-color-def.h"
-
-namespace eek
-{
-
-ColorDef::ColorDef() :
-    descr(_("none")),
-    r(0),
-    g(0),
-    b(0),
-    none(true),
-    editable(false)
-{
-}
-
-ColorDef::ColorDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description ) :
-    descr(description),
-    r(r),
-    g(g),
-    b(b),
-    none(false),
-    editable(false)
-{
-}
-
-ColorDef::~ColorDef()
-{
-}
-
-ColorDef::ColorDef( ColorDef const &other )
-{
-    if ( this != &other ) {
-        *this = other;
-    }
-}
-
-ColorDef& ColorDef::operator=( ColorDef const &other )
-{
-    if ( this != & other )
-    {
-        r = other.r;
-        g = other.g;
-        b = other.b;
-        descr = other.descr;
-        none = other.none;
-        editable = other.editable;
-    }
-    return *this;
-}
-
-class ColorDef::HookData {
-public:
-    HookData( ColorCallback cb, void* data ) {_cb = cb; _data = data;}
-    ColorCallback _cb;
-    void* _data;
-};
-
-void ColorDef::setRGB( unsigned int r, unsigned int g, unsigned int b )
-{
-    if ( r != this->r || g != this->g || b != this->b ) {
-        this->r = r;
-        this->g = g;
-        this->b = b;
-
-        // beware of callbacks changing things
-        for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
-        {
-            if ( (*it)->_cb )
-            {
-                (*it)->_cb( (*it)->_data );
-            }
-        }
-    }
-}
-
-void ColorDef::addCallback( ColorCallback cb, void* data )
-{
-    _listeners.push_back( new HookData(cb, data) );
-}
-
-void ColorDef::removeCallback( ColorCallback cb, void* data )
-{
-    (void)cb;
-    (void)data;
-}
-
-} // namespace eek
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/eek-color-def.h b/src/dialogs/eek-color-def.h
deleted file mode 100644 (file)
index 63cd096..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/** @file
- * @brief EEK color definition
- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Eek Color Definition.
- *
- * The Initial Developer of the Original Code is
- * Jon A. Cruz.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef SEEN_EEK_COLOR_DEF_H
-#define SEEN_EEK_COLOR_DEF_H
-
-#include <string>
-#include <vector>
-
-namespace eek
-{
-
-typedef void (*ColorCallback)( void* data );
-
-
-class ColorDef
-{
-public:
-    ColorDef();
-    ColorDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description );
-    virtual ~ColorDef();
-
-    ColorDef( ColorDef const &other );
-    virtual ColorDef& operator=( ColorDef const &other );
-
-    void setRGB( unsigned int r, unsigned int g, unsigned int b );
-    unsigned int getR() const { return r; }
-    unsigned int getG() const { return g; }
-    unsigned int getB() const { return b; }
-
-    void addCallback( ColorCallback cb, void* data );
-    void removeCallback( ColorCallback cb, void* data );
-
-    bool isEditable() const { return editable; }
-    void setEditable( bool edit ) { editable = edit; }
-
-    std::string descr;
-
-protected:
-    unsigned int r;
-    unsigned int g;
-    unsigned int b;
-    bool none;
-    bool editable;
-
-private:
-    class HookData;
-
-    std::vector<HookData*> _listeners;
-};
-
-
-} // namespace eek
-
-#endif // SEEN_EEK_COLOR_DEF_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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/eek-preview.cpp b/src/dialogs/eek-preview.cpp
deleted file mode 100644 (file)
index 1c1adf5..0000000
+++ /dev/null
@@ -1,736 +0,0 @@
-/** @file
- * @brief EEK preview stuff
- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Eek Preview Stuffs.
- *
- * The Initial Developer of the Original Code is
- * Jon A. Cruz.
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <gtk/gtk.h>
-#include "eek-preview.h"
-
-#define PRIME_BUTTON_MAGIC_NUMBER 1
-
-#define FOCUS_PROP_ID 1
-
-/* Keep in sycn with last value in eek-preview.h */
-#define PREVIEW_SIZE_LAST PREVIEW_SIZE_HUGE
-#define PREVIEW_SIZE_NEXTFREE (PREVIEW_SIZE_HUGE + 1)
-
-#define PREVIEW_MAX_RATIO 500
-
-static void eek_preview_class_init( EekPreviewClass *klass );
-static void eek_preview_init( EekPreview *preview );
-
-static GtkWidgetClass* parent_class = 0;
-
-void eek_preview_set_color( EekPreview* preview, int r, int g, int b )
-{
-    preview->_r = r;
-    preview->_g = g;
-    preview->_b = b;
-
-    gtk_widget_queue_draw(GTK_WIDGET(preview));
-}
-
-
-void eek_preview_set_pixbuf( EekPreview* preview, GdkPixbuf* pixbuf )
-{
-    preview->_previewPixbuf = pixbuf;
-
-    gtk_widget_queue_draw(GTK_WIDGET(preview));
-
-    if (preview->_scaled) {
-        g_object_unref(preview->_scaled);
-        preview->_scaled = 0;
-    }
-    preview->_scaledW = gdk_pixbuf_get_width(preview->_previewPixbuf);
-    preview->_scaledH = gdk_pixbuf_get_height(preview->_previewPixbuf);
-}
-
-
-GType eek_preview_get_type(void)
-{
-    static GType preview_type = 0;
-
-    if (!preview_type) {
-      static const GTypeInfo preview_info = {
-          sizeof( EekPreviewClass ),
-          NULL, /* base_init */
-          NULL, /* base_finalize */
-          (GClassInitFunc)eek_preview_class_init,
-          NULL, /* class_finalize */
-          NULL, /* class_data */
-          sizeof( EekPreview ),
-          0,    /* n_preallocs */
-          (GInstanceInitFunc)eek_preview_init,
-          NULL /* value_table */
-      };
-
-
-      preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 );
-    }
-
-    return preview_type;
-}
-
-static gboolean setupDone = FALSE;
-static GtkRequisition sizeThings[PREVIEW_SIZE_NEXTFREE];
-
-void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes )
-{
-    gint width = 0;
-    gint height = 0;
-    gint smallest = 512;
-    gint largest = 0;
-    guint i = 0;
-    guint delta = 0;
-
-    for ( i = 0; i < count; ++i ) {
-        gboolean worked = gtk_icon_size_lookup( sizes[i], &width, &height );
-        if ( worked ) {
-            if ( width < smallest ) {
-                smallest = width;
-            }
-            if ( width > largest ) {
-                largest = width;
-            }
-        }
-    }
-
-    smallest = (smallest * 3) / 4;
-
-    delta = largest - smallest;
-
-    for ( i = 0; i < G_N_ELEMENTS(sizeThings); ++i ) {
-        guint val = smallest + ( (i * delta) / (G_N_ELEMENTS(sizeThings) - 1) );
-        sizeThings[i].width = val;
-        sizeThings[i].height = val;
-    }
-
-    setupDone = TRUE;
-}
-
-static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
-{
-    gint width = 0;
-    gint height = 0;
-    EekPreview* preview = EEK_PREVIEW(widget);
-
-    if ( !setupDone ) {
-        GtkIconSize sizes[] = {
-            GTK_ICON_SIZE_MENU,
-            GTK_ICON_SIZE_SMALL_TOOLBAR,
-            GTK_ICON_SIZE_LARGE_TOOLBAR,
-            GTK_ICON_SIZE_BUTTON,
-            GTK_ICON_SIZE_DIALOG
-        };
-        eek_preview_set_size_mappings( G_N_ELEMENTS(sizes), sizes );
-    }
-
-    width = sizeThings[preview->_size].width;
-    height = sizeThings[preview->_size].height;
-
-    if ( preview->_view == VIEW_TYPE_LIST ) {
-        width *= 3;
-    }
-
-    if ( preview->_ratio != 100 ) {
-        width = (width * preview->_ratio) / 100;
-        if ( width < 0 ) {
-            width = 1;
-        }
-    }
-
-    req->width = width;
-    req->height = height;
-}
-
-enum {
-  CLICKED_SIGNAL,
-  ALTCLICKED_SIGNAL,
-  LAST_SIGNAL
-};
-
-
-static guint eek_preview_signals[LAST_SIGNAL] = { 0 };
-
-
-gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
-{
-/*     g_message("Exposed!!!   %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */
-    gint insetX = 0;
-    gint insetY = 0;
-
-    (void)event;
-/*
-    gint lower = widget->allocation.width;
-    lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
-    if ( lower > 16 ) {
-        insetX++;
-        if ( lower > 18 ) {
-            insetX++;
-            if ( lower > 22 ) {
-                insetX++;
-                if ( lower > 24 ) {
-                    insetX++;
-                    if ( lower > 32 ) {
-                        insetX++;
-                    }
-                }
-            }
-        }
-        insetY = insetX;
-    }
-*/
-
-    if ( GTK_WIDGET_DRAWABLE( widget ) ) {
-        GtkStyle* style = gtk_widget_get_style( widget );
-
-        if ( insetX > 0 || insetY > 0 ) {
-            gtk_paint_flat_box( style,
-                                widget->window,
-                                (GtkStateType)GTK_WIDGET_STATE(widget),
-                                GTK_SHADOW_NONE,
-                                NULL,
-                                widget,
-                                NULL,
-                                0, 0,
-                                widget->allocation.width, widget->allocation.height);
-        }
-
-        GdkGC *gc = gdk_gc_new( widget->window );
-        EekPreview* preview = EEK_PREVIEW(widget);
-        GdkColor fg = {0, preview->_r, preview->_g, preview->_b};
-
-        gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE );
-
-        gdk_gc_set_foreground( gc, &fg );
-
-        gdk_draw_rectangle( widget->window,
-                            gc,
-                            TRUE,
-                            insetX, insetY,
-                            widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) );
-
-        if ( preview->_linked ) {
-            /* Draw arrow */
-            GdkRectangle possible = {insetX, insetY, (widget->allocation.width - (insetX * 2)), (widget->allocation.height - (insetY * 2)) };
-            GdkRectangle area = {possible.x, possible.y, possible.width / 2, possible.height / 2 };
-
-            /* Make it square */
-            if ( area.width > area.height )
-                area.width = area.height;
-            if ( area.height > area.width )
-                area.height = area.width;
-
-            /* Center it horizontally */
-            if ( area.width < possible.width ) {
-                int diff = (possible.width - area.width) / 2;
-                area.x += diff;
-            }
-
-
-            if ( preview->_linked & PREVIEW_LINK_IN ) {
-                gtk_paint_arrow( style,
-                                 widget->window,
-                                 (GtkStateType)widget->state,
-                                 GTK_SHADOW_ETCHED_IN,
-                                 NULL, /* clip area.  &area, */
-                                 widget, /* may be NULL */
-                                 NULL, /* detail */
-                                 GTK_ARROW_DOWN,
-                                 FALSE,
-                                 area.x, area.y,
-                                 area.width, area.height
-                                 );
-            }
-
-            if ( preview->_linked & PREVIEW_LINK_OUT ) {
-                GdkRectangle otherArea = {area.x, area.y, area.width, area.height};
-                if ( otherArea.height < possible.height ) {
-                    otherArea.y = possible.y + (possible.height - otherArea.height);
-                }
-
-                gtk_paint_arrow( style,
-                                 widget->window,
-                                 (GtkStateType)widget->state,
-                                 GTK_SHADOW_ETCHED_OUT,
-                                 NULL, /* clip area.  &area, */
-                                 widget, /* may be NULL */
-                                 NULL, /* detail */
-                                 GTK_ARROW_UP,
-                                 FALSE,
-                                 otherArea.x, otherArea.y,
-                                 otherArea.width, otherArea.height
-                                 );
-            }
-
-            if ( preview->_linked & PREVIEW_LINK_OTHER ) {
-                GdkRectangle otherArea = {insetX, area.y, area.width, area.height};
-                if ( otherArea.height < possible.height ) {
-                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
-                }
-
-                gtk_paint_arrow( style,
-                                 widget->window,
-                                 (GtkStateType)widget->state,
-                                 GTK_SHADOW_ETCHED_OUT,
-                                 NULL, /* clip area.  &area, */
-                                 widget, /* may be NULL */
-                                 NULL, /* detail */
-                                 GTK_ARROW_LEFT,
-                                 FALSE,
-                                 otherArea.x, otherArea.y,
-                                 otherArea.width, otherArea.height
-                                 );
-            }
-        }
-
-        if ( preview->_previewPixbuf ) {
-            GtkDrawingArea* da = &(preview->drawing);
-            GdkDrawable* drawable = (GdkDrawable*) (((GtkWidget*)da)->window);
-            gint w = 0;
-            gint h = 0;
-            gdk_drawable_get_size(drawable, &w, &h);
-            if ((w != preview->_scaledW) || (h != preview->_scaledH)) {
-                if (preview->_scaled) {
-                    g_object_unref(preview->_scaled);
-                }
-                preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR);
-                preview->_scaledW = w;
-                preview->_scaledH = h;
-            }
-
-            GdkPixbuf* pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf;
-            gdk_draw_pixbuf( drawable, 0, pix, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0 );
-        }
-
-
-        if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
-            gtk_paint_focus( style,
-                             widget->window,
-                             GTK_STATE_NORMAL,
-                             NULL, /* GdkRectangle *area, */
-                             widget,
-                             NULL,
-                             0 + 1, 0 + 1,
-                             widget->allocation.width - 2, widget->allocation.height - 2 );
-        }
-    }
-
-
-    return FALSE;
-}
-
-
-static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event )
-{
-    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
-        EekPreview* preview = EEK_PREVIEW(widget);
-        preview->_within = TRUE;
-        gtk_widget_set_state( widget, preview->_hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT );
-    }
-    return FALSE;
-}
-
-static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event )
-{
-    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
-        EekPreview* preview = EEK_PREVIEW(widget);
-        preview->_within = FALSE;
-        gtk_widget_set_state( widget, GTK_STATE_NORMAL );
-    }
-    return FALSE;
-}
-
-/*
-static gboolean eek_preview_focus_in_event( GtkWidget* widget, GdkEventFocus* event )
-{
-    g_message("focus IN");
-    gboolean blip = parent_class->focus_in_event ? parent_class->focus_in_event(widget, event) : FALSE;
-    return blip;
-}
-
-static gboolean eek_preview_focus_out_event( GtkWidget* widget, GdkEventFocus* event )
-{
-    g_message("focus OUT");
-    gboolean blip = parent_class->focus_out_event ? parent_class->focus_out_event(widget, event) : FALSE;
-    return blip;
-}
-*/
-
-static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* event )
-{
-    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
-        EekPreview* preview = EEK_PREVIEW(widget);
-
-        if ( preview->_takesFocus && !GTK_WIDGET_HAS_FOCUS(widget) ) {
-            gtk_widget_grab_focus(widget);
-        }
-
-        if ( event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
-            preview->_hot = TRUE;
-            if ( preview->_within ) {
-                gtk_widget_set_state( widget, GTK_STATE_ACTIVE );
-            }
-        }
-    }
-
-    return FALSE;
-}
-
-static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton* event )
-{
-    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
-        EekPreview* preview = EEK_PREVIEW(widget);
-        preview->_hot = FALSE;
-        gtk_widget_set_state( widget, GTK_STATE_NORMAL );
-        if ( preview->_within && event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
-            gboolean isAlt = (event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
-
-            if ( isAlt ) {
-                g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 );
-            } else {
-                g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 );
-            }
-        }
-    }
-    return FALSE;
-}
-
-gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event)
-{
-    (void)widget;
-    (void)event;
-    g_message("TICK");
-    return FALSE;
-}
-
-gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event)
-{
-    (void)widget;
-    (void)event;
-    g_message("tock");
-    return FALSE;
-}
-
-static void eek_preview_get_property( GObject *object,
-                                      guint property_id,
-                                      GValue *value,
-                                      GParamSpec *pspec)
-{
-    GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
-    switch ( property_id ) {
-        case FOCUS_PROP_ID:
-        {
-            EekPreview* preview = EEK_PREVIEW( object );
-            g_value_set_boolean( value, preview->_takesFocus );
-        }
-        break;
-        default:
-        {
-            if ( gobjClass->get_property ) {
-                gobjClass->get_property( object, property_id, value, pspec );
-            }
-        }
-    }
-}
-
-static void eek_preview_set_property( GObject *object,
-                                      guint property_id,
-                                      const GValue *value,
-                                      GParamSpec *pspec)
-{
-    GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
-    switch ( property_id ) {
-        case FOCUS_PROP_ID:
-        {
-            EekPreview* preview = EEK_PREVIEW( object );
-            gboolean val = g_value_get_boolean( value );
-            if ( val != preview->_takesFocus ) {
-                preview->_takesFocus = val;
-            }
-        }
-        break;
-        default:
-        {
-            if ( gobjClass->set_property ) {
-                gobjClass->set_property( object, property_id, value, pspec );
-            }
-        }
-    }
-}
-
-
-static gboolean eek_preview_popup_menu( GtkWidget* widget )
-{
-/*     g_message("Do the popup!"); */
-    gboolean blip = parent_class->popup_menu ? parent_class->popup_menu(widget) : FALSE;
-    return blip;
-}
-
-
-static void eek_preview_class_init( EekPreviewClass *klass )
-{
-    GObjectClass* gobjClass = G_OBJECT_CLASS(klass);
-    /*GtkObjectClass* objectClass = (GtkObjectClass*)klass;*/
-    GtkWidgetClass* widgetClass = (GtkWidgetClass*)klass;
-
-    gobjClass->set_property = eek_preview_set_property;
-    gobjClass->get_property = eek_preview_get_property;
-
-    /*objectClass->destroy = eek_preview_destroy;*/
-
-    parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass );
-
-    /*widgetClass->map = ;*/
-    /*widgetClass->unmap = ;*/
-    /*widgetClass->realize = ;*/
-    /*widgetClass->unrealize = ;*/
-    widgetClass->size_request = eek_preview_size_request;
-    /*widgetClass->size_allocate = ;*/
-    /*widgetClass->state_changed = ;*/
-    /*widgetClass->style_set = ;*/
-    /*widgetClass->grab_notify = ;*/
-
-    widgetClass->button_press_event = eek_preview_button_press_cb;
-    widgetClass->button_release_event = eek_preview_button_release_cb;
-    /*widgetClass->delete_event = ;*/
-    /*widgetClass->destroy_event = ;*/
-    widgetClass->expose_event = eek_preview_expose_event;
-/*     widgetClass->key_press_event = eek_preview_key_press_event; */
-/*     widgetClass->key_release_event = eek_preview_key_release_event; */
-    widgetClass->enter_notify_event = eek_preview_enter_cb;
-    widgetClass->leave_notify_event = eek_preview_leave_cb;
-    /*widgetClass->configure_event = ;*/
-    /*widgetClass->focus_in_event = eek_preview_focus_in_event;*/
-    /*widgetClass->focus_out_event = eek_preview_focus_out_event;*/
-
-    /* selection */
-    /*widgetClass->selection_get = ;*/
-    /*widgetClass->selection_received = ;*/
-
-
-    /* drag source: */
-    /*widgetClass->drag_begin = ;*/
-    /*widgetClass->drag_end = ;*/
-    /*widgetClass->drag_data_get = ;*/
-    /*widgetClass->drag_data_delete = ;*/
-
-    /* drag target: */
-    /*widgetClass->drag_leave = ;*/
-    /*widgetClass->drag_motion = ;*/
-    /*widgetClass->drag_drop = ;*/
-    /*widgetClass->drag_data_received = ;*/
-
-    /* For keybindings: */
-    widgetClass->popup_menu = eek_preview_popup_menu;
-    /*widgetClass->show_help = ;*/
-
-    /* Accessibility support: */
-    /*widgetClass->get_accessible = ;*/
-    /*widgetClass->screen_changed = ;*/
-    /*widgetClass->can_activate_accel = ;*/
-
-
-    eek_preview_signals[CLICKED_SIGNAL] =
-        g_signal_new( "clicked",
-                      G_TYPE_FROM_CLASS( klass ),
-                      (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
-                      G_STRUCT_OFFSET( EekPreviewClass, clicked ),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 );
-
-    eek_preview_signals[ALTCLICKED_SIGNAL] =
-        g_signal_new( "alt-clicked",
-                      G_TYPE_FROM_CLASS( klass ),
-                      (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
-                      G_STRUCT_OFFSET( EekPreviewClass, clicked ),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
-                      1, G_TYPE_INT );
-
-
-    g_object_class_install_property( gobjClass,
-                                     FOCUS_PROP_ID,
-                                     g_param_spec_boolean(
-                                         "focus-on-click",
-                                         NULL,
-                                         "flag to grab focus when clicked",
-                                         TRUE,
-                                         (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
-                                         )
-        );
-}
-
-void eek_preview_set_linked( EekPreview* splat, LinkType link )
-{
-    link = (LinkType)(link & PREVIEW_LINK_ALL);
-    if ( link != (LinkType)splat->_linked ) {
-        splat->_linked = link;
-
-        gtk_widget_queue_draw( GTK_WIDGET(splat) );
-    }
-}
-
-LinkType eek_preview_get_linked( EekPreview* splat )
-{
-    return (LinkType)splat->_linked;
-}
-
-gboolean eek_preview_get_focus_on_click( EekPreview* preview )
-{
-    return preview->_takesFocus;
-}
-
-void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click )
-{
-    if ( focus_on_click != preview->_takesFocus ) {
-        preview->_takesFocus = focus_on_click;
-    }
-}
-
-void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio )
-{
-    preview->_prevstyle = prevstyle;
-    preview->_view = view;
-
-    if ( size > PREVIEW_SIZE_LAST ) {
-        size = PREVIEW_SIZE_LAST;
-    }
-    preview->_size = size;
-
-    if ( ratio > PREVIEW_MAX_RATIO ) {
-        ratio = PREVIEW_MAX_RATIO;
-    }
-    preview->_ratio = ratio;
-
-    gtk_widget_queue_draw(GTK_WIDGET(preview));
-}
-
-static void eek_preview_init( EekPreview *preview )
-{
-    GtkWidget* widg = GTK_WIDGET(preview);
-    GTK_WIDGET_SET_FLAGS( widg, GTK_CAN_FOCUS );
-    GTK_WIDGET_SET_FLAGS( widg, GTK_RECEIVES_DEFAULT );
-
-    gtk_widget_set_sensitive( widg, TRUE );
-
-    gtk_widget_add_events(widg, GDK_BUTTON_PRESS_MASK
-                          | GDK_BUTTON_RELEASE_MASK
-                          | GDK_KEY_PRESS_MASK
-                          | GDK_KEY_RELEASE_MASK
-                          | GDK_FOCUS_CHANGE_MASK
-                          | GDK_ENTER_NOTIFY_MASK
-                          | GDK_LEAVE_NOTIFY_MASK );
-
-/*    gtk_widget_add_events( widg, GDK_ALL_EVENTS_MASK );*/
-
-    preview->_r = 0x80;
-    preview->_g = 0x80;
-    preview->_b = 0xcc;
-    preview->_scaledW = 0;
-    preview->_scaledH = 0;
-
-    preview->_hot = FALSE;
-    preview->_within = FALSE;
-    preview->_takesFocus = FALSE;
-
-    preview->_prevstyle = PREVIEW_STYLE_ICON;
-    preview->_view = VIEW_TYPE_LIST;
-    preview->_size = PREVIEW_SIZE_SMALL;
-    preview->_ratio = 100;
-
-    preview->_previewPixbuf = 0;
-    preview->_scaled = 0;
-
-/*
-    GdkColor color = {0};
-    color.red = (255 << 8) | 255;
-
-    GdkColor whack = {0};
-    whack.green = (255 << 8) | 255;
-
-    gtk_widget_modify_bg( widg, GTK_STATE_NORMAL, &color );
-    gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &whack );
-*/
-
-/*   GTK_STATE_ACTIVE, */
-/*   GTK_STATE_PRELIGHT, */
-/*   GTK_STATE_SELECTED, */
-/*   GTK_STATE_INSENSITIVE */
-
-    if ( 0 ) {
-        GdkColor color = {0,0,0,0};
-
-        color.red = 0xffff;
-        color.green = 0;
-        color.blue = 0xffff;
-        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-        gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
-
-        color.red = 0;
-        color.green = 0xffff;
-        color.blue = 0;
-        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-        gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
-
-        color.red = 0xffff;
-        color.green = 0;
-        color.blue = 0;
-        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
-        gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
-    }
-}
-
-
-GtkWidget* eek_preview_new(void)
-{
-    return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) );
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/eek-preview.h b/src/dialogs/eek-preview.h
deleted file mode 100644 (file)
index 6eb5c89..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/** @file
- * @brief EEK preview stuff
- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Eek Preview Stuffs.
- *
- * The Initial Developer of the Original Code is
- * Jon A. Cruz.
- * Portions created by the Initial Developer are Copyright (C) 2005-2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef SEEN_EEK_PREVIEW_H
-#define SEEN_EEK_PREVIEW_H
-
-#include <gdk/gdkpixbuf.h>
-#include <gtk/gtkdrawingarea.h>
-
-G_BEGIN_DECLS
-
-
-#define EEK_PREVIEW_TYPE            (eek_preview_get_type())
-#define EEK_PREVIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST( (obj), EEK_PREVIEW_TYPE, EekPreview))
-#define EEK_PREVIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST( (klass), EEK_PREVIEW_TYPE, EekPreviewClass))
-#define IS_EEK_PREVIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE( (obj), EEK_PREVIEW_TYPE))
-#define IS_EEK_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE( (klass), EEK_PREVIEW_TYPE))
-#define EEK_PREVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS( (obj), EEK_PREVIEW_TYPE, EekPreviewClass))
-
-typedef enum {
-    PREVIEW_STYLE_ICON = 0,
-    PREVIEW_STYLE_PREVIEW,
-    PREVIEW_STYLE_NAME,
-    PREVIEW_STYLE_BLURB,
-    PREVIEW_STYLE_ICON_NAME,
-    PREVIEW_STYLE_ICON_BLURB,
-    PREVIEW_STYLE_PREVIEW_NAME,
-    PREVIEW_STYLE_PREVIEW_BLURB
-} PreviewStyle;
-
-typedef enum {
-    VIEW_TYPE_LIST = 0,
-    VIEW_TYPE_GRID
-} ViewType;
-
-typedef enum {
-    PREVIEW_SIZE_TINY = 0,
-    PREVIEW_SIZE_SMALL,
-    PREVIEW_SIZE_MEDIUM,
-    PREVIEW_SIZE_BIG,
-    PREVIEW_SIZE_BIGGER,
-    PREVIEW_SIZE_HUGE
-} PreviewSize;
-
-typedef enum {
-  PREVIEW_LINK_NONE = 0,
-  PREVIEW_LINK_IN = 1,
-  PREVIEW_LINK_OUT = 2,
-  PREVIEW_LINK_OTHER = 4,
-  PREVIEW_LINK_ALL = 7
-} LinkType;
-
-typedef struct _EekPreview       EekPreview;
-typedef struct _EekPreviewClass  EekPreviewClass;
-
-
-struct _EekPreview
-{
-    GtkDrawingArea drawing;
-
-    int _r;
-    int _g;
-    int _b;
-    int _scaledW;
-    int _scaledH;
-
-    gboolean _hot;
-    gboolean _within;
-    gboolean _takesFocus;
-
-    PreviewStyle _prevstyle;
-    ViewType _view;
-    PreviewSize _size;
-    guint _ratio;
-    guint _linked;
-    GdkPixbuf* _previewPixbuf;
-    GdkPixbuf* _scaled;
-};
-
-struct _EekPreviewClass
-{
-    GtkDrawingAreaClass parent_class;
-
-    void (*clicked) (EekPreview* splat);
-};
-
-
-GType      eek_preview_get_type(void) G_GNUC_CONST;
-GtkWidget* eek_preview_new(void);
-
-void eek_preview_set_details( EekPreview* splat, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio );
-void eek_preview_set_color( EekPreview* splat, int r, int g, int b );
-void eek_preview_set_pixbuf( EekPreview* splat, GdkPixbuf* pixbuf );
-
-void eek_preview_set_linked( EekPreview* splat, LinkType link );
-LinkType eek_preview_get_linked( EekPreview* splat );
-
-gboolean eek_preview_get_focus_on_click( EekPreview* preview );
-void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click );
-
-void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes );
-
-G_END_DECLS
-
-#endif /* SEEN_EEK_PREVIEW_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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/extensions.cpp b/src/dialogs/extensions.cpp
deleted file mode 100644 (file)
index f168da3..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/** @file
- * @brief A simple dialog with information about extensions
- */
-/* Authors:
- *   Jon A. Cruz
- *
- * Copyright (C) 2005 Jon A. Cruz
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
-#include <gtkmm/scrolledwindow.h>
-
-#include "extension/db.h"
-#include "extensions.h"
-
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-using Inkscape::Extension::Extension;
-
-ExtensionsPanel &ExtensionsPanel::getInstance()
-{
-    ExtensionsPanel &instance = *new ExtensionsPanel();
-
-    instance.rescan();
-
-    return instance;
-}
-
-
-
-/**
- * Constructor
- */
-ExtensionsPanel::ExtensionsPanel() :
-        _showAll(false)
-{
-    Gtk::ScrolledWindow* scroller = new Gtk::ScrolledWindow();
-
-    _view.set_editable(false);
-
-    scroller->add(_view);
-    add(*scroller);
-
-    rescan();
-
-    show_all_children();
-}
-
-void ExtensionsPanel::set_full(bool full)
-{
-    if ( full != _showAll ) {
-        _showAll = full;
-        rescan();
-    }
-}
-
-void ExtensionsPanel::listCB( Inkscape::Extension::Extension * in_plug, gpointer in_data )
-{
-    ExtensionsPanel * self = (ExtensionsPanel*)in_data;
-
-    const char* stateStr;
-    Extension::state_t state = in_plug->get_state();
-    switch ( state ) {
-        case Extension::STATE_LOADED:
-        {
-            stateStr = "loaded";
-        }
-        break;
-        case Extension::STATE_UNLOADED:
-        {
-            stateStr = "unloaded";
-        }
-        break;
-        case Extension::STATE_DEACTIVATED:
-        {
-            stateStr = "deactivated";
-        }
-        break;
-        default:
-            stateStr = "unknown";
-    }
-
-    if ( self->_showAll || in_plug->deactivated() ) {
-//         gchar* line = g_strdup_printf( " extension   %c %c  %s   |%s|%s|",
-//                                        (in_plug->loaded() ? 'X' : '-'),
-//                                        (in_plug->deactivated() ? 'X' : '-'),
-//                                        stateStr, in_plug->get_id(),
-//                                        in_plug->get_name() );
-        gchar* line = g_strdup_printf( "%s   %s\n        \"%s\"", stateStr, in_plug->get_name(), in_plug->get_id() );
-
-        self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), line );
-        self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), "\n" );
-        //g_message( "%s", line );
-    }
-
-
-
-    return;
-}
-
-void ExtensionsPanel::rescan()
-{
-    _view.get_buffer()->set_text("Extensions:\n");
-//     g_message("/------------------");
-
-    Inkscape::Extension::db.foreach(listCB, (gpointer)this);
-
-//     g_message("\\------------------");
-}
-
-} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/extensions.h b/src/dialogs/extensions.h
deleted file mode 100644 (file)
index 8b0fc27..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/** @file
- * A simple dialog with information about extensions
- */
-/* Authors:
- *   Jon A. Cruz
- *
- * Copyright (C) 2005 The Inkscape Organization
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifndef SEEN_EXTENSIONS_H
-#define SEEN_EXTENSIONS_H
-
-#include <gtkmm/textview.h>
-#include "ui/widget/panel.h"
-
-namespace Inkscape {
-namespace Extension {
-class Extension;
-}
-}
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-
-/**
- * A panel that displays information about extensions.
- */
-class ExtensionsPanel : public Inkscape::UI::Widget::Panel
-{
-public:
-    ExtensionsPanel();
-
-    static ExtensionsPanel &getInstance();
-
-    void set_full(bool full);
-
-private:
-    ExtensionsPanel(ExtensionsPanel const &); // no copy
-    ExtensionsPanel &operator=(ExtensionsPanel const &); // no assign
-
-    static void listCB(Inkscape::Extension::Extension *in_plug, gpointer in_data);
-
-    void rescan();
-
-    bool _showAll;
-    Gtk::TextView _view;
-};
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-#endif // SEEN_EXTENSIONS_H
diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp
deleted file mode 100644 (file)
index 24e46f0..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-/** @file
- * @brief  Fill style widget
- */
-/* Authors:
- *   Lauris Kaplinski <lauris@kaplinski.com>
- *   Frank Felfe <innerspace@iname.com>
- *   bulia byak <buliabyak@users.sf.net>
- *
- * Copyright (C) 1999-2005 authors
- * Copyright (C) 2001-2002 Ximian, Inc.
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#define noSP_FS_VERBOSE
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glibmm/i18n.h>
-
-#include "desktop-handles.h"
-#include "desktop-style.h"
-#include "display/sp-canvas.h"
-#include "document-private.h"
-#include "gradient-chemistry.h"
-#include "inkscape.h"
-#include "selection.h"
-#include "sp-linear-gradient.h"
-#include "sp-pattern.h"
-#include "sp-radial-gradient.h"
-#include "style.h"
-#include "widgets/paint-selector.h"
-#include "widgets/sp-widget.h"
-#include "xml/repr.h"
-
-#include "dialogs/fill-style.h"
-
-
-// These can be deleted once we sort out the libart dependence.
-
-#define ART_WIND_RULE_NONZERO 0
-
-static void sp_fill_style_widget_construct          ( SPWidget *spw,
-                                                      SPPaintSelector *psel );
-
-static void sp_fill_style_widget_modify_selection   ( SPWidget *spw,
-                                                      Inkscape::Selection *selection,
-                                                      guint flags,
-                                                      SPPaintSelector *psel );
-
-static void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
-
-static void sp_fill_style_widget_change_selection   ( SPWidget *spw,
-                                                      Inkscape::Selection *selection,
-                                                      SPPaintSelector *psel );
-
-static void sp_fill_style_widget_update (SPWidget *spw);
-
-static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
-                                                      SPPaintSelectorMode mode,
-                                                      SPWidget *spw );
-static void sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel,
-                                          SPPaintSelectorFillRule mode,
-                                                    SPWidget *spw );
-
-static void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw );
-static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw );
-
-GtkWidget *
-sp_fill_style_widget_new (void)
-{
-    GtkWidget *spw = sp_widget_new_global (INKSCAPE);
-
-    GtkWidget *vb = gtk_vbox_new (FALSE, 0);
-    gtk_widget_show (vb);
-    gtk_container_add (GTK_CONTAINER (spw), vb);
-
-    GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector
-    gtk_widget_show (psel);
-    gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
-    g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
-
-    g_signal_connect ( G_OBJECT (psel), "mode_changed",
-                       G_CALLBACK (sp_fill_style_widget_paint_mode_changed),
-                       spw );
-
-    g_signal_connect ( G_OBJECT (psel), "dragged",
-                       G_CALLBACK (sp_fill_style_widget_paint_dragged),
-                       spw );
-
-    g_signal_connect ( G_OBJECT (psel), "changed",
-                       G_CALLBACK (sp_fill_style_widget_paint_changed),
-                       spw );
-
-    g_signal_connect ( G_OBJECT (psel), "fillrule_changed",
-                       G_CALLBACK (sp_fill_style_widget_fillrule_changed),
-                       spw );
-
-
-    g_signal_connect ( G_OBJECT (spw), "construct",
-                       G_CALLBACK (sp_fill_style_widget_construct), psel);
-
-//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
-//those anyway; then eliminate spw
-    g_signal_connect ( G_OBJECT (spw), "modify_selection",
-                       G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
-
-    g_signal_connect ( G_OBJECT (spw), "change_selection",
-                       G_CALLBACK (sp_fill_style_widget_change_selection), psel);
-
-    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw);
-
-    sp_fill_style_widget_update (SP_WIDGET (spw));
-
-    return spw;
-
-} // end of sp_fill_style_widget_new()
-
-
-
-static void
-sp_fill_style_widget_construct( SPWidget *spw, SPPaintSelector */*psel*/ )
-{
-#ifdef SP_FS_VERBOSE
-    g_print ( "Fill style widget constructed: inkscape %p repr %p\n",
-              spw->inkscape, spw->repr );
-#endif
-    if (spw->inkscape) {
-        sp_fill_style_widget_update (spw);
-    }
-
-} // end of sp_fill_style_widget_construct()
-
-static void
-sp_fill_style_widget_modify_selection( SPWidget *spw,
-                                       Inkscape::Selection */*selection*/,
-                                       guint flags,
-                                       SPPaintSelector */*psel*/ )
-{
-    if (flags & ( SP_OBJECT_MODIFIED_FLAG |
-                  SP_OBJECT_PARENT_MODIFIED_FLAG |
-                  SP_OBJECT_STYLE_MODIFIED_FLAG) )
-    {
-        sp_fill_style_widget_update (spw);
-    }
-}
-
-static void
-sp_fill_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
-                                          SPDesktop */*desktop*/,
-                                          SPWidget *spw )
-{
-    sp_fill_style_widget_update (spw);
-}
-
-static void
-sp_fill_style_widget_change_selection( SPWidget *spw,
-                                       Inkscape::Selection */*selection*/,
-                                       SPPaintSelector */*psel*/ )
-{
-    sp_fill_style_widget_update (spw);
-}
-
-/**
-* \param sel Selection to use, or NULL.
-*/
-static void
-sp_fill_style_widget_update (SPWidget *spw)
-{
-    if (g_object_get_data (G_OBJECT (spw), "update"))
-        return;
-
-    if (g_object_get_data (G_OBJECT (spw), "local")) {
-        g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag
-        return;
-    }
-
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
-
-    SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
-
-    // create temporary style
-    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-    // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
-    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); 
-
-    switch (result) {
-        case QUERY_STYLE_NOTHING:
-        {
-            /* No paint at all */
-            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
-            break;
-        }
-
-        case QUERY_STYLE_SINGLE:
-        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
-        case QUERY_STYLE_MULTIPLE_SAME: 
-        {
-            SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, true);
-            sp_paint_selector_set_mode (psel, pselmode);
-
-            sp_paint_selector_set_fillrule (psel, query->fill_rule.computed == ART_WIND_RULE_NONZERO? 
-                                     SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD);
-
-            if (query->fill.set && query->fill.isColor()) {
-                sp_paint_selector_set_color_alpha (psel, &query->fill.value.color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
-            } else if (query->fill.set && query->fill.isPaintserver()) {
-
-                SPPaintServer *server = SP_STYLE_FILL_SERVER (query);
-
-                if (SP_IS_LINEARGRADIENT (server)) {
-                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
-                    sp_paint_selector_set_gradient_linear (psel, vector);
-
-                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
-                    sp_paint_selector_set_gradient_properties (psel,
-                                                       SP_GRADIENT_UNITS (lg),
-                                                       SP_GRADIENT_SPREAD (lg));
-                } else if (SP_IS_RADIALGRADIENT (server)) {
-                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
-                    sp_paint_selector_set_gradient_radial (psel, vector);
-
-                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
-                    sp_paint_selector_set_gradient_properties (psel,
-                                                       SP_GRADIENT_UNITS (rg),
-                                                       SP_GRADIENT_SPREAD (rg));
-                } else if (SP_IS_PATTERN (server)) {
-                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
-                    sp_update_pattern_list (psel, pat);
-                }
-            }
-            break;
-        }
-
-        case QUERY_STYLE_MULTIPLE_DIFFERENT:
-        {
-            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
-            break;
-        }
-    }
-
-    sp_style_unref(query);
-
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
-
-}
-
-
-static void
-sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
-                                          SPPaintSelectorMode /*mode*/,
-                                          SPWidget *spw )
-{
-    if (g_object_get_data (G_OBJECT (spw), "update"))
-        return;
-
-    /* TODO: Does this work? */
-    /* TODO: Not really, here we have to get old color back from object */
-    /* Instead of relying on paint widget having meaningful colors set */
-    sp_fill_style_widget_paint_changed (psel, spw);
-}
-
-static void
-sp_fill_style_widget_fillrule_changed ( SPPaintSelector */*psel*/,
-                                          SPPaintSelectorFillRule mode,
-                                          SPWidget *spw )
-{
-    if (g_object_get_data (G_OBJECT (spw), "update"))
-        return;
-
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
-    SPCSSAttr *css = sp_repr_css_attr_new ();
-    sp_repr_css_set_property (css, "fill-rule", mode == SP_PAINT_SELECTOR_FILLRULE_EVENODD? "evenodd":"nonzero");
-
-    sp_desktop_set_style (desktop, css);
-
-    sp_repr_css_attr_unref (css);
-
-    sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, 
-                      _("Change fill rule"));
-}
-
-static gchar const *undo_label_1 = "fill:flatcolor:1";
-static gchar const *undo_label_2 = "fill:flatcolor:2";
-static gchar const *undo_label = undo_label_1;
-
-/**
-This is called repeatedly while you are dragging a color slider, only for flat color
-modes. Previously it set the color in style but did not update the repr for efficiency, however
-this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
-lumps all its changes for undo.
- */
-static void
-sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
-{
-    if (!spw->inkscape) {
-        return;
-    }
-
-    if (g_object_get_data (G_OBJECT (spw), "update")) {
-        return;
-    }
-
-    if (g_object_get_data (G_OBJECT (spw), "local")) {
-        // previous local flag not cleared yet; 
-        // this means dragged events come too fast, so we better skip this one to speed up display 
-        // (it's safe to do this in any case)
-        return;
-    }
-
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
-
-    switch (psel->mode) {
-
-        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
-        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
-        {
-            sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "fill", "fill-opacity");
-            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE, 
-                                    _("Set fill color"));
-            g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection
-            break;
-        }
-
-        default:
-            g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
-                        __FILE__, __LINE__, psel->mode );
-            break;
-
-    }
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
-}
-
-
-/**
-This is called (at least) when:
-1  paint selector mode is switched (e.g. flat color -> gradient)
-2  you finished dragging a gradient node and released mouse
-3  you changed a gradient selector parameter (e.g. spread)
-Must update repr.
- */
-static void
-sp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
-                                     SPWidget *spw )
-{
-    if (g_object_get_data (G_OBJECT (spw), "update")) {
-        return;
-    }
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
-
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    if (!desktop) {
-        return;
-    }
-    SPDocument *document = sp_desktop_document (desktop);
-    Inkscape::Selection *selection = sp_desktop_selection (desktop);
-
-    GSList const *items = selection->itemList();
-
-    switch (psel->mode) {
-
-        case SP_PAINT_SELECTOR_MODE_EMPTY:
-            // This should not happen.
-            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
-                        __FILE__, __LINE__, psel->mode);
-            break;
-        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
-            // This happens when you switch multiple objects with different gradients to flat color;
-            // nothing to do here.
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_NONE:
-        {
-            SPCSSAttr *css = sp_repr_css_attr_new ();
-            sp_repr_css_set_property (css, "fill", "none");
-
-            sp_desktop_set_style (desktop, css);
-
-            sp_repr_css_attr_unref (css);
-
-            sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
-                              _("Remove fill"));
-            break;
-        }
-
-        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
-        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
-        {
-            // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
-            sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
-
-            sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity");
-            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
-                                    _("Set fill color"));
-            // resume interruptibility
-            sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
-
-            // on release, toggle undo_label so that the next drag will not be lumped with this one
-            if (undo_label == undo_label_1)
-                undo_label = undo_label_2;
-            else
-                undo_label = undo_label_1;
-
-            break;
-        }
-
-        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
-        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
-            if (items) {
-                SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
-                                                       ? SP_GRADIENT_TYPE_LINEAR
-                                                       : SP_GRADIENT_TYPE_RADIAL );
-
-                // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
-                SPCSSAttr *css = sp_repr_css_attr_new();
-                sp_repr_css_set_property(css, "fill-opacity", "1.0");
-
-                SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
-                if (!vector) {
-                    /* No vector in paint selector should mean that we just changed mode */
-
-                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-                    int result = objects_query_fillstroke ((GSList *) items, query, true);
-                    guint32 common_rgb = 0;
-                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
-                        if (!query->fill.isColor()) {
-                            common_rgb = sp_desktop_get_color(desktop, true);
-                        } else {
-                            common_rgb = query->fill.value.color.toRGBA32( 0xff );
-                        }
-                        vector = sp_document_default_gradient_vector(document, common_rgb);
-                    }
-                    sp_style_unref(query);
-
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                        //FIXME: see above
-                        sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
-
-                        if (!vector) {
-                            sp_item_set_gradient(SP_ITEM(i->data),
-                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true),
-                                                 gradient_type, true);
-                        } else {
-                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
-                        }
-                    }
-                } else {
-                    /* We have changed from another gradient type, or modified spread/units within
-                     * this gradient type. */
-                    vector = sp_gradient_ensure_vector_normalized (vector);
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                        //FIXME: see above
-                        sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style");
-
-                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
-                        sp_gradient_selector_attrs_to_gradient (gr, psel);
-                    }
-                }
-
-                sp_repr_css_attr_unref (css);
-
-                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
-                                  _("Set gradient on fill"));
-            }
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_PATTERN:
-
-            if (items) {
-
-                SPPattern *pattern = sp_paint_selector_get_pattern (psel);
-                if (!pattern) {
-
-                    /* No Pattern in paint selector should mean that we just
-                     * changed mode - dont do jack.
-                     */
-
-                } else {
-                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
-                    SPCSSAttr *css = sp_repr_css_attr_new ();
-                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
-                    sp_repr_css_set_property (css, "fill", urltext);
-
-                    // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
-                    sp_repr_css_set_property(css, "fill-opacity", "1.0");
-
-                    // cannot just call sp_desktop_set_style, because we don't want to touch those
-                    // objects who already have the same root pattern but through a different href
-                    // chain. FIXME: move this to a sp_item_set_pattern
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                         SPObject *selobj = SP_OBJECT (i->data);
-
-                         SPStyle *style = SP_OBJECT_STYLE (selobj);
-                         if (style && style->fill.isPaintserver()) {
-                             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj);
-                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
-                                // only if this object's pattern is not rooted in our selected pattern, apply
-                                 continue;
-                         }
-
-                         sp_desktop_apply_css_recursive (selobj, css, true);
-                     }
-
-                    sp_repr_css_attr_unref (css);
-                    g_free (urltext);
-
-                } // end if
-
-                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
-                                  _("Set pattern on fill"));
-
-            } // end if
-
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_UNSET:
-            if (items) {
-                    SPCSSAttr *css = sp_repr_css_attr_new ();
-                    sp_repr_css_unset_property (css, "fill");
-
-                    sp_desktop_set_style (desktop, css);
-                    sp_repr_css_attr_unref (css);
-
-                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
-                                      _("Unset fill"));
-            }
-            break;
-
-        default:
-            g_warning ( "file %s: line %d: Paint selector should not be in "
-                        "mode %d",
-                        __FILE__, __LINE__, psel->mode );
-            break;
-    }
-
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
-}
-
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/fill-style.h b/src/dialogs/fill-style.h
deleted file mode 100644 (file)
index 3924412..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/** @file
- * @brief  Fill style configuration
- */
-/* Authors:
- *   Lauris Kaplinski <lauris@kaplinski.com>
- *
- * Copyright (C) 2002 Lauris Kaplinski
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_DIALOGS_SP_FILL_STYLE_H
-#define SEEN_DIALOGS_SP_FILL_STYLE_H
-
-#include <glib.h>
-#include <gtk/gtkwidget.h>
-#include "forward.h"
-
-
-GtkWidget *sp_fill_style_widget_new (void);
-
-#endif
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/guidelinedialog.cpp b/src/dialogs/guidelinedialog.cpp
deleted file mode 100644 (file)
index f0115ee..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/** @file
- * @brief Simple guideline dialog
- */
-/* Authors:
- *   Lauris Kaplinski <lauris@kaplinski.com>
- *   Andrius R. <knutux@gmail.com>
- *   Johan Engelen
- *
- * Copyright (C) 1999-2007 Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include "display/guideline.h"
-#include "helper/unit-menu.h"
-#include "helper/units.h"
-#include "desktop.h"
-#include "document.h"
-#include "sp-guide.h"
-#include "sp-namedview.h"
-#include "desktop-handles.h"
-#include "event-context.h"
-#include "widgets/desktop-widget.h"
-#include "sp-metrics.h"
-#include <glibmm/i18n.h>
-#include "dialogs/dialog-events.h"
-#include "message-context.h"
-#include "xml/repr.h"
-#include <2geom/point.h>
-#include <2geom/angle.h>
-#include "guidelinedialog.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop)
-: _desktop(desktop), _guide(guide),
-  _label_units(_("Unit:")),
-  _label_X(_("X:")),
-  _label_Y(_("Y:")),
-  _label_degrees(_("Angle (degrees):")),
-  _relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")),
-  _adjustment_x(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
-  _adjustment_y(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
-  _adj_angle(0.0, -360, 360, 1.0, 10.0, 10.0),  
-  _unit_selector(NULL), _mode(true), _oldpos(0.,0.), _oldangle(0.0)
-{
-}
-
-GuidelinePropertiesDialog::~GuidelinePropertiesDialog() {
-}
-
-void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) {
-    GuidelinePropertiesDialog dialog(guide, desktop);
-    dialog._setup();
-    dialog.run();
-}
-
-void GuidelinePropertiesDialog::_modeChanged()
-{
-    _mode = !_relative_toggle.get_active();
-    if (!_mode) {
-        // relative
-        _spin_angle.set_value(0);
-
-        _spin_button_y.set_value(0);
-        _spin_button_x.set_value(0);
-    } else {
-        // absolute
-        _spin_angle.set_value(_oldangle);
-
-        SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
-        gdouble const val_y = sp_pixels_get_units(_oldpos[Geom::Y], unit);
-        _spin_button_y.set_value(val_y);
-        gdouble const val_x = sp_pixels_get_units(_oldpos[Geom::X], unit);
-        _spin_button_x.set_value(val_x);
-    }
-}
-
-void GuidelinePropertiesDialog::_onApply()
-{
-    double deg_angle = _spin_angle.get_value();
-    if (!_mode)
-        deg_angle += _oldangle;
-    Geom::Point normal;
-    if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) {
-        normal = Geom::Point(1.,0.);
-    } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) {
-        normal = Geom::Point(0.,1.);
-    } else {
-        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);
-
-    SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
-    gdouble const raw_dist_x = _spin_button_x.get_value();
-    gdouble const points_x = sp_units_get_pixels(raw_dist_x, unit);
-    gdouble const raw_dist_y = _spin_button_y.get_value();
-    gdouble const points_y = sp_units_get_pixels(raw_dist_y, unit);
-    Geom::Point newpos(points_x, points_y);
-    if (!_mode)
-        newpos += _oldpos;
-
-    sp_guide_moveto(*_guide, newpos, true);
-
-    sp_document_done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, 
-                     _("Set guide properties"));
-}
-
-void GuidelinePropertiesDialog::_onOK()
-{
-    _onApply();
-}
-
-void GuidelinePropertiesDialog::_onDelete()
-{
-    SPDocument *doc = SP_OBJECT_DOCUMENT(_guide);
-    sp_guide_remove(_guide);
-    sp_document_done(doc, SP_VERB_NONE, 
-                     _("Delete guide"));
-}
-
-void GuidelinePropertiesDialog::_response(gint response)
-{
-    switch (response) {
-       case Gtk::RESPONSE_OK:
-            _onOK();
-            break;
-       case -12:
-            _onDelete();
-            break;
-       case Gtk::RESPONSE_CANCEL:
-            break;
-       case Gtk::RESPONSE_DELETE_EVENT:
-            break;
-/*     case GTK_RESPONSE_APPLY:
-        _onApply();
-        break;
-*/
-       default:
-            g_assert_not_reached();
-    }
-}
-
-void GuidelinePropertiesDialog::_setup() {
-    set_title(_("Guideline"));
-    add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
-    add_button(Gtk::Stock::DELETE, -12);
-    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-
-    Gtk::VBox *mainVBox = get_vbox();
-
-    _layout_table.set_spacings(4);
-    _layout_table.resize (3, 4);
-
-    mainVBox->pack_start(_layout_table, false, false, 0);
-
-    _label_name.set_label("foo0");
-    _layout_table.attach(_label_name,
-                         0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
-    _label_name.set_alignment(0, 0.5);
-
-    _label_descr.set_label("foo1");
-    _layout_table.attach(_label_descr,
-                         0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
-    _label_descr.set_alignment(0, 0.5);
-
-    // indent
-    _layout_table.attach(*manage(new Gtk::Label(" ")),
-                         0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10);
-
-    // mode radio button
-    _layout_table.attach(_relative_toggle,
-                         1, 3, 9, 10, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
-
-    // unitmenu
-    /* fixme: We should allow percents here too, as percents of the canvas size */
-    GtkWidget *unit_selector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
-    sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unit_selector), _desktop->namedview->doc_units);
-    _unit_selector = Gtk::manage(Glib::wrap(unit_selector));
-
-    // position spinbuttons
-    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_x.gobj()));
-    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_y.gobj()));
-    _spin_button_x.configure(_adjustment_x, 1.0 , 3);
-    _spin_button_x.set_numeric();
-    _spin_button_y.configure(_adjustment_y, 1.0 , 3);
-    _spin_button_y.set_numeric();
-    _layout_table.attach(_label_X,
-                         1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_spin_button_x,
-                         2, 3, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_label_Y,
-                         1, 2, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_spin_button_y,
-                         2, 3, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    gtk_signal_connect_object(GTK_OBJECT(_spin_button_x.gobj()), "activate",
-                              GTK_SIGNAL_FUNC(gtk_window_activate_default),
-                              gobj());
-
-    _layout_table.attach(_label_units,
-                         1, 2, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(*_unit_selector,
-                         2, 3, 6, 7, Gtk::FILL, Gtk::FILL);
-
-    // angle spinbutton
-    _spin_angle.configure(_adj_angle, 5.0 , 3);
-    _spin_angle.set_numeric();
-    _spin_angle.show();
-    _layout_table.attach(_label_degrees,
-                         1, 2, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_spin_angle,
-                         2, 3, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
-
-
-    // dialog
-    set_default_response(Gtk::RESPONSE_OK);
-    signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response));
-
-    // initialize dialog
-    _oldpos = _guide->point_on_line;
-    if (_guide->is_vertical()) {
-        _oldangle = 90;
-    } else if (_guide->is_horizontal()) {
-        _oldangle = 0;
-    } else {
-        _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) );
-    }
-
-    {
-        Inkscape::XML::Node *repr = SP_OBJECT_REPR (_guide);
-        const gchar *guide_id = repr->attribute("id");
-        gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id);
-        _label_name.set_label(label);
-        g_free(label);
-    }
-    {
-        gchar *guide_description = sp_guide_description(_guide);
-        gchar *label = g_strdup_printf(_("Current: %s"), guide_description);
-        g_free(guide_description);
-        _label_descr.set_markup(label);
-        g_free(label);
-    }
-
-    _modeChanged(); // sets values of spinboxes.
-
-    if ( _oldangle == 90. || _oldangle == 270. || _oldangle == -90. || _oldangle == -270.) {
-        _spin_button_x.grab_focus();
-        _spin_button_x.select_region(0, 20);
-    } else if ( _oldangle == 0. || _oldangle == 180. || _oldangle == -180.) {
-        _spin_button_y.grab_focus();
-        _spin_button_y.select_region(0, 20);
-    } else {
-        _spin_angle.grab_focus();
-        _spin_angle.select_region(0, 20);
-    }
-
-    set_position(Gtk::WIN_POS_MOUSE);
-
-    show_all_children();
-    set_modal(true);
-    _desktop->setWindowTransient (gobj());
-    property_destroy_with_parent() = true;
-}
-
-}
-}
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/guidelinedialog.h b/src/dialogs/guidelinedialog.h
deleted file mode 100644 (file)
index 49f94de..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- *
- * \brief  Dialog for modifying guidelines
- *
- * Author:
- *   Andrius R. <knutux@gmail.com>
- *   Johan Engelen
- *
- * Copyright (C) 2006-2007 Authors
- *
- * Released under GNU GPL.  Read the file 'COPYING' for more information
- */
-
-#ifndef INKSCAPE_DIALOG_GUIDELINE_H
-#define INKSCAPE_DIALOG_GUIDELINE_H
-
-#include <gtkmm/dialog.h>
-#include <gtkmm/table.h>
-#include <gtkmm/spinbutton.h>
-#include <gtkmm/label.h>
-#include <gtkmm/stock.h>
-#include <gtkmm/adjustment.h>
-#include "ui/widget/button.h"
-#include <2geom/point.h>
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-class GuidelinePropertiesDialog : public Gtk::Dialog {
-public:
-    GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop);
-    virtual ~GuidelinePropertiesDialog();
-
-    Glib::ustring     getName() const { return "GuidelinePropertiesDialog"; }
-
-    static void showDialog(SPGuide *guide, SPDesktop *desktop);
-
-protected:
-    void _setup();
-
-    void _onApply();
-    void _onOK();
-    void _onDelete();
-
-    void _response(gint response);
-    void _modeChanged();
-
-private:
-    GuidelinePropertiesDialog(GuidelinePropertiesDialog const &); // no copy
-    GuidelinePropertiesDialog &operator=(GuidelinePropertiesDialog const &); // no assign
-
-    SPDesktop *_desktop;
-    SPGuide *_guide;
-    Gtk::Table  _layout_table;
-    Gtk::Label  _label_name;
-    Gtk::Label  _label_descr;
-    Gtk::Label  _label_units;
-    Gtk::Label  _label_X;
-    Gtk::Label  _label_Y;
-    Gtk::Label  _label_degrees;
-    Inkscape::UI::Widget::CheckButton _relative_toggle;
-    Gtk::Adjustment _adjustment_x;
-    Gtk::SpinButton _spin_button_x;
-    Gtk::Adjustment _adjustment_y;
-    Gtk::SpinButton _spin_button_y;
-
-    Gtk::Adjustment _adj_angle;
-    Gtk::SpinButton _spin_angle;
-
-    Gtk::Widget *_unit_selector;
-    bool _mode;
-    Geom::Point _oldpos;
-    gdouble _oldangle;
-};
-
-} // namespace
-} // namespace
-} // namespace
-
-
-#endif // INKSCAPE_DIALOG_GUIDELINE_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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/iconpreview.cpp b/src/dialogs/iconpreview.cpp
deleted file mode 100644 (file)
index 4d402d2..0000000
+++ /dev/null
@@ -1,309 +0,0 @@
-/** @file
- * @brief A simple dialog for previewing icon representation.
- */
-/* Authors:
- *   Jon A. Cruz
- *   Bob Jamison
- *   Other dudes from The Inkscape Organization
- *
- * Copyright (C) 2004 Bob Jamison
- * Copyright (C) 2005 Jon A. Cruz
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "iconpreview.h"
-
-#include <gtk/gtk.h>
-
-#include <glib/gmem.h>
-#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
-#include <glibmm/i18n.h>
-#include <gtkmm/buttonbox.h>
-#include <gtkmm/stock.h>
-
-#include "preferences.h"
-#include "inkscape.h"
-#include "document.h"
-#include "desktop-handles.h"
-#include "selection.h"
-#include "desktop.h"
-#include "display/nr-arena.h"
-#include "sp-root.h"
-#include "xml/repr.h"
-
-extern "C" {
-// takes doc, root, icon, and icon name to produce pixels
-guchar *
-sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root,
-                  const gchar *name, unsigned int psize );
-}
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-
-IconPreviewPanel&
-IconPreviewPanel::getInstance()
-{
-    static IconPreviewPanel &instance = *new IconPreviewPanel();
-
-    instance.refreshPreview();
-
-    return instance;
-}
-
-//#########################################################################
-//## E V E N T S
-//#########################################################################
-
-void IconPreviewPanel::on_button_clicked(int which)
-{
-    if ( hot != which ) {
-        buttons[hot]->set_active( false );
-
-        hot = which;
-        updateMagnify();
-        _getContents()->queue_draw();
-    }
-}
-
-
-
-
-//#########################################################################
-//## C O N S T R U C T O R    /    D E S T R U C T O R
-//#########################################################################
-/**
- * Constructor
- */
-IconPreviewPanel::IconPreviewPanel() :
-    UI::Widget::Panel("", "/dialogs/iconpreview", SP_VERB_VIEW_ICON_PREVIEW),
-    hot(1),
-    refreshButton(0),
-    selectionButton(0)
-{
-    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-    numEntries = 0;
-
-    std::vector<Glib::ustring> pref_sizes = prefs->getAllDirs("/iconpreview/sizes/default");
-    std::vector<int> rawSizes;
-    
-    for (std::vector<Glib::ustring>::iterator i = pref_sizes.begin(); i != pref_sizes.end(); ++i) {
-        if (prefs->getBool(*i + "/show", true)) {
-            int sizeVal = prefs->getInt(*i + "/value", -1);
-            if (sizeVal > 0) {
-                rawSizes.push_back(sizeVal);
-            }
-        }
-    }
-
-    if ( !rawSizes.empty() ) {
-        numEntries = rawSizes.size();
-        sizes = new int[numEntries];
-        int i = 0;
-        for ( std::vector<int>::iterator it = rawSizes.begin(); it != rawSizes.end(); ++it, ++i ) {
-            sizes[i] = *it;
-        }
-    }
-
-    if ( numEntries < 1 )
-    {
-        numEntries = 5;
-        sizes = new int[numEntries];
-        sizes[0] = 16;
-        sizes[1] = 24;
-        sizes[2] = 32;
-        sizes[3] = 48;
-        sizes[4] = 128;
-    }
-
-    pixMem = new guchar*[numEntries];
-    images = new Gtk::Image*[numEntries];
-    labels = new Glib::ustring*[numEntries];
-    buttons = new Gtk::ToggleToolButton*[numEntries];
-
-
-    for ( int i = 0; i < numEntries; i++ ) {
-        char *label = g_strdup_printf(_("%d x %d"), sizes[i], sizes[i]);
-        labels[i] = new Glib::ustring(label);
-        g_free(label);
-        pixMem[i] = 0;
-        images[i] = 0;
-    }
-
-
-    magLabel.set_label( *labels[hot] );
-
-    Gtk::VBox* magBox = new Gtk::VBox();
-
-    magBox->pack_start( magnified );
-    magBox->pack_start( magLabel, Gtk::PACK_SHRINK );
-
-
-    Gtk::VBox * verts = new Gtk::VBox();
-    for ( int i = 0; i < numEntries; i++ ) {
-        pixMem[i] = new guchar[4 * sizes[i] * sizes[i]];
-        memset( pixMem[i], 0x00, 4 *  sizes[i] * sizes[i] );
-
-        GdkPixbuf *pb = gdk_pixbuf_new_from_data( pixMem[i], GDK_COLORSPACE_RGB, TRUE, 8, sizes[i], sizes[i], sizes[i] * 4, /*(GdkPixbufDestroyNotify)g_free*/NULL, NULL );
-        GtkImage* img = GTK_IMAGE( gtk_image_new_from_pixbuf( pb ) );
-        images[i] = Glib::wrap(img);
-        Glib::ustring label(*labels[i]);
-        buttons[i] = new Gtk::ToggleToolButton(label);
-        buttons[i]->set_active( i == hot );
-        buttons[i]->set_icon_widget(*images[i]);
-
-        tips.set_tip((*buttons[i]), label);
-
-        buttons[i]->signal_clicked().connect( sigc::bind<int>( sigc::mem_fun(*this, &IconPreviewPanel::on_button_clicked), i) );
-
-
-        verts->add(*buttons[i]);
-    }
-
-    iconBox.pack_start(splitter);
-    splitter.pack1( *magBox, true, true );
-    splitter.pack2( *verts, false, false );
-
-
-    //## The Refresh button
-
-
-    Gtk::HButtonBox* holder = new Gtk::HButtonBox( Gtk::BUTTONBOX_END );
-    _getContents()->pack_end(*holder, false, false);
-
-    selectionButton = new Gtk::ToggleButton(_("Selection")); // , GTK_RESPONSE_APPLY
-    holder->pack_start( *selectionButton, false, false );
-    tips.set_tip((*selectionButton), _("Selection only or whole document"));
-    selectionButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::modeToggled) );
-
-    gint val = prefs->getBool("/iconpreview/selectionOnly");
-    selectionButton->set_active( val != 0 );
-
-    refreshButton = new Gtk::Button(Gtk::Stock::REFRESH); // , GTK_RESPONSE_APPLY
-    holder->pack_end( *refreshButton, false, false );
-    tips.set_tip((*refreshButton), _("Refresh the icons"));
-    refreshButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::refreshPreview) );
-
-
-    _getContents()->pack_start(iconBox, Gtk::PACK_EXPAND_WIDGET);
-
-    show_all_children();
-}
-
-//#########################################################################
-//## M E T H O D S
-//#########################################################################
-
-
-void IconPreviewPanel::refreshPreview()
-{
-    SPDesktop *desktop = getDesktop();
-    if ( desktop ) {
-
-        if ( selectionButton && selectionButton->get_active() )
-        {
-            Inkscape::Selection * sel = sp_desktop_selection(desktop);
-            if ( sel ) {
-                //g_message("found a selection to play with");
-
-                GSList const *items = sel->itemList();
-                SPObject *target = 0;
-                while ( items && !target ) {
-                    SPItem* item = SP_ITEM( items->data );
-                    SPObject * obj = SP_OBJECT(item);
-                    gchar const *id = SP_OBJECT_ID( obj );
-                    if ( id ) {
-                        target = obj;
-                    }
-
-                    items = g_slist_next(items);
-                }
-                if ( target ) {
-                    renderPreview(target);
-                }
-            }
-        }
-        else
-        {
-            SPObject *target = desktop->currentRoot();
-            if ( target ) {
-                renderPreview(target);
-            }
-        }
-    }
-}
-
-void IconPreviewPanel::modeToggled()
-{
-    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-    prefs->setBool("/iconpreview/selectionOnly", (selectionButton && selectionButton->get_active()));
-
-    refreshPreview();
-}
-
-void IconPreviewPanel::renderPreview( SPObject* obj )
-{
-    SPDocument * doc = SP_OBJECT_DOCUMENT(obj);
-    gchar * id = SP_OBJECT_ID(obj);
-
-//    g_message(" setting up to render '%s' as the icon", id );
-
-    NRArenaItem *root = NULL;
-
-    /* Create new arena */
-    NRArena *arena = NRArena::create();
-
-    /* Create ArenaItem and set transform */
-    unsigned int visionkey = sp_item_display_key_new(1);
-
-    root = sp_item_invoke_show ( SP_ITEM( SP_DOCUMENT_ROOT(doc) ),
-                                 arena, visionkey, SP_ITEM_SHOW_DISPLAY );
-
-    for ( int i = 0; i < numEntries; i++ ) {
-        guchar * px = sp_icon_doc_icon( doc, root, id, sizes[i] );
-//         g_message( " size %d %s", sizes[i], (px ? "worked" : "failed") );
-        if ( px ) {
-            memcpy( pixMem[i], px, sizes[i] * sizes[i] * 4 );
-            g_free( px );
-            px = 0;
-        } else {
-            memset( pixMem[i], 0, sizes[i] * sizes[i] * 4 );
-        }
-        images[i]->queue_draw();
-    }
-    updateMagnify();
-
-    sp_item_invoke_hide(SP_ITEM(sp_document_root(doc)), visionkey);
-    nr_object_unref((NRObject *) arena);
-}
-
-void IconPreviewPanel::updateMagnify()
-{
-    Glib::RefPtr<Gdk::Pixbuf> buf = images[hot]->get_pixbuf()->scale_simple( 128, 128, Gdk::INTERP_NEAREST );
-    magLabel.set_label( *labels[hot] );
-    magnified.set( buf );
-    magnified.queue_draw();
-    magnified.get_parent()->queue_draw();
-}
-
-
-} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/iconpreview.h b/src/dialogs/iconpreview.h
deleted file mode 100644 (file)
index 8f14372..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/** @file
- * @brief A simple dialog for previewing icon representation.
- */
-/* Authors:
- *   Jon A. Cruz
- *   Bob Jamison
- *   Other dudes from The Inkscape Organization
- *
- * Copyright (C) 2004,2005 The Inkscape Organization
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_ICON_PREVIEW_H
-#define SEEN_ICON_PREVIEW_H
-
-#include <gtkmm/box.h>
-#include <gtkmm/button.h>
-#include <gtkmm/label.h>
-#include <gtkmm/paned.h>
-#include <gtkmm/image.h>
-#include <gtkmm/togglebutton.h>
-#include <gtkmm/toggletoolbutton.h>
-
-#include "ui/widget/panel.h"
-
-struct SPObject;
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-
-/**
- * A panel that displays an icon preview
- */
-class IconPreviewPanel : public UI::Widget::Panel
-{
-public:
-    IconPreviewPanel();
-    //IconPreviewPanel(Glib::ustring const &label);
-
-    static IconPreviewPanel& getInstance();
-
-    void refreshPreview();
-    void modeToggled();
-
-private:
-    IconPreviewPanel(IconPreviewPanel const &); // no copy
-    IconPreviewPanel &operator=(IconPreviewPanel const &); // no assign
-
-
-    void on_button_clicked(int which);
-    void renderPreview( SPObject* obj );
-    void updateMagnify();
-
-    Gtk::Tooltips   tips;
-
-    Gtk::VBox       iconBox;
-    Gtk::HPaned     splitter;
-
-    int hot;
-    int numEntries;
-    int* sizes;
-
-    Gtk::Image      magnified;
-    Gtk::Label      magLabel;
-
-    Gtk::Button           *refreshButton;
-    Gtk::ToggleButton     *selectionButton;
-
-    guchar** pixMem;
-    Gtk::Image** images;
-    Glib::ustring** labels;
-    Gtk::ToggleToolButton** buttons;
-};
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-
-
-#endif // SEEN_ICON_PREVIEW_H
diff --git a/src/dialogs/in-dt-coordsys.cpp b/src/dialogs/in-dt-coordsys.cpp
deleted file mode 100644 (file)
index 54d9ac3..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "sp-root.h"
-
-/** Returns true iff \a item is suitable to be included in the selection, in particular
-    whether it has a bounding box in the desktop coordinate system for rendering resize handles.
-
-    Descendents of <defs> nodes (markers etc.) return false, for example.
-*/
-bool in_dt_coordsys(SPObject const &item)
-{
-    /* Definition based on sp_item_i2doc_affine. */
-    SPObject const *child = &item;
-    g_return_val_if_fail(child != NULL, false);
-    for(;;) {
-        if (!SP_IS_ITEM(child)) {
-            return false;
-        }
-        SPObject const * const parent = SP_OBJECT_PARENT(child);
-        if (parent == NULL) {
-            break;
-        }
-        child = parent;
-    }
-    g_assert(SP_IS_ROOT(child));
-    /* Relevance: Otherwise, I'm not sure whether to return true or false. */
-    return true;
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/in-dt-coordsys.h b/src/dialogs/in-dt-coordsys.h
deleted file mode 100644 (file)
index c2ec96d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef SEEN_IN_DT_COORDSYS
-#define SEEN_IN_DT_COORDSYS
-#include "forward.h"
-
-bool in_dt_coordsys(SPObject const &item);
-
-#endif /* !SEEN_IN_DT_COORDSYS */
-
-/*
-  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:encoding=utf-8:textwidth=99 :
index 076358082cd1a5ca1589c9c70ad22f134c89b9f5..44a479b6cafb67d223d1101d26b31b0bb9bcca40 100644 (file)
 #include <gtk/gtktextview.h>
 #include <gtk/gtktooltips.h>
 
+#include "../desktop-handles.h"
+#include "dialog-events.h"
+#include "../document.h"
 #include <glibmm/i18n.h>
-#include "helper/window.h"
-#include "../widgets/sp-widget.h"
+#include "../helper/window.h"
 #include "../inkscape.h"
-#include "../document.h"
-#include "../desktop-handles.h"
+#include "../interface.h"
+#include "../macros.h"
+#include "../preferences.h"
 #include "../selection.h"
 #include "../sp-item.h"
-#include "../macros.h"
 #include "../verbs.h"
-#include "../interface.h"
-#include "sp-attribute-widget.h"
-
-#include "dialog-events.h"
-#include "../preferences.h"
+#include "../widgets/sp-attribute-widget.h"
+#include "../widgets/sp-widget.h"
 
 #define MIN_ONSCREEN_DISTANCE 50
 
diff --git a/src/dialogs/layer-properties.cpp b/src/dialogs/layer-properties.cpp
deleted file mode 100644 (file)
index ccd91fa..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/** @file
- * @brief Dialog for renaming layers
- */
-/* Author:
- *   Bryce W. Harrington <bryce@bryceharrington.com>
- *   Andrius R. <knutux@gmail.com>
- *
- * Copyright (C) 2004 Bryce Harrington
- * Copyright (C) 2006 Andrius R.
- *
- * Released under GNU GPL.  Read the file 'COPYING' for more information
- */
-
-#include <gtkmm/stock.h>
-#include <glibmm/i18n.h>
-#include "inkscape.h"
-#include "desktop.h"
-#include "document.h"
-#include "layer-manager.h"
-#include "message-stack.h"
-#include "desktop-handles.h"
-#include "sp-object.h"
-#include "sp-item.h"
-
-#include "layer-properties.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-LayerPropertiesDialog::LayerPropertiesDialog()
-: _strategy(NULL), _desktop(NULL), _layer(NULL), _position_visible(false)
-{
-    Gtk::VBox *mainVBox = get_vbox();
-
-    _layout_table.set_spacings(4);
-    _layout_table.resize (1, 2);
-
-    // Layer name widgets
-    _layer_name_entry.set_activates_default(true);
-    _layer_name_label.set_label(_("Layer name:"));
-    _layer_name_label.set_alignment(1.0, 0.5);
-
-    _layout_table.attach(_layer_name_label,
-                         0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_layer_name_entry,
-                         1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
-    mainVBox->pack_start(_layout_table, false, false, 4);
-
-    // Buttons
-    _close_button.set_use_stock(true);
-    _close_button.set_label(Gtk::Stock::CANCEL.id);
-    _close_button.set_flags(Gtk::CAN_DEFAULT);
-
-    _apply_button.set_use_underline(true);
-    _apply_button.set_flags(Gtk::CAN_DEFAULT);
-
-    _close_button.signal_clicked()
-        .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_close));
-    _apply_button.signal_clicked()
-        .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_apply));
-
-    signal_delete_event().connect(
-        sigc::bind_return(
-            sigc::hide(sigc::mem_fun(*this, &LayerPropertiesDialog::_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();
-}
-
-LayerPropertiesDialog::~LayerPropertiesDialog() {
-    _setDesktop(NULL);
-    _setLayer(NULL);
-}
-
-void LayerPropertiesDialog::_showDialog(LayerPropertiesDialog::Strategy &strategy,
-                                        SPDesktop *desktop, SPObject *layer)
-{
-    LayerPropertiesDialog *dialog = new LayerPropertiesDialog();
-
-    dialog->_strategy = &strategy;
-    dialog->_setDesktop(desktop);
-    dialog->_setLayer(layer);
-
-    dialog->_strategy->setup(*dialog);
-
-    dialog->set_modal(true);
-    desktop->setWindowTransient (dialog->gobj());
-    dialog->property_destroy_with_parent() = true;
-
-    dialog->show();
-    dialog->present();
-}
-
-void
-LayerPropertiesDialog::_apply()
-{
-    g_assert(_strategy != NULL);
-
-    _strategy->perform(*this);
-    sp_document_done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE,
-                     _("Add layer"));
-
-    _close();
-}
-
-void
-LayerPropertiesDialog::_close()
-{
-    _setLayer(NULL);
-    _setDesktop(NULL);
-    destroy_();
-    Glib::signal_idle().connect(
-        sigc::bind_return(
-            sigc::bind(sigc::ptr_fun(&::operator delete), this),
-            false 
-        )
-    );
-}
-
-void
-LayerPropertiesDialog::_setup_position_controls() {
-    if ( NULL == _layer || _desktop->currentRoot() == _layer ) {
-        // no layers yet, so option above/below/sublayer is useless
-        return;
-    }
-
-    _position_visible = true;
-    _dropdown_list = Gtk::ListStore::create(_dropdown_columns);
-    _layer_position_combo.set_model(_dropdown_list);
-    _layer_position_combo.pack_start(_label_renderer);
-    _layer_position_combo.set_cell_data_func(_label_renderer,
-                                             sigc::mem_fun(*this, &LayerPropertiesDialog::_prepareLabelRenderer));
-
-    _layout_table.resize (2, 2);
-
-    Gtk::ListStore::iterator row;
-    row = _dropdown_list->append();
-    row->set_value(_dropdown_columns.position, LPOS_ABOVE);
-    row->set_value(_dropdown_columns.name, Glib::ustring(_("Above current")));
-    _layer_position_combo.set_active(row);
-    row = _dropdown_list->append();
-    row->set_value(_dropdown_columns.position, LPOS_BELOW);
-    row->set_value(_dropdown_columns.name, Glib::ustring(_("Below current")));
-    row = _dropdown_list->append();
-    row->set_value(_dropdown_columns.position, LPOS_CHILD);
-    row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current")));
-
-    _layout_table.attach(_layer_position_combo,
-                         1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
-    _layer_position_label.set_label(_("Position:"));
-    _layer_position_label.set_alignment(1.0, 0.5);
-    _layout_table.attach(_layer_position_label,
-                         0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
-    show_all_children();
-}
-
-/** Formats the label for a given layer row 
- */
-void LayerPropertiesDialog::_prepareLabelRenderer(
-    Gtk::TreeModel::const_iterator const &row
-) {
-    Glib::ustring name=(*row)[_dropdown_columns.name];
-    _label_renderer.property_markup() = name.c_str();
-}
-
-void LayerPropertiesDialog::Rename::setup(LayerPropertiesDialog &dialog) {
-    SPDesktop *desktop=dialog._desktop;
-    dialog.set_title(_("Rename Layer"));
-    gchar const *name = desktop->currentLayer()->label();
-    dialog._layer_name_entry.set_text(( name ? name : "" ));
-    dialog._apply_button.set_label(_("_Rename"));
-}
-
-void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) {
-    SPDesktop *desktop=dialog._desktop;
-    Glib::ustring name(dialog._layer_name_entry.get_text());
-    desktop->layer_manager->renameLayer( desktop->currentLayer(),
-                                         ( name.empty() ? NULL : (gchar *)name.c_str() )
-    );
-    sp_document_done(sp_desktop_document(desktop), SP_VERB_NONE, 
-                     _("Rename layer"));
-    // TRANSLATORS: This means "The layer has been renamed"
-    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Renamed layer"));
-}
-
-void LayerPropertiesDialog::Create::setup(LayerPropertiesDialog &dialog) {
-    dialog.set_title(_("Add Layer"));
-    dialog._layer_name_entry.set_text("");
-    dialog._apply_button.set_label(_("_Add"));
-    dialog._setup_position_controls();
-}
-
-void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) {
-    SPDesktop *desktop=dialog._desktop;
-
-    LayerRelativePosition position = LPOS_ABOVE;
-    
-    if (dialog._position_visible) {
-        Gtk::ListStore::iterator activeRow(dialog._layer_position_combo.get_active());
-        position = activeRow->get_value(dialog._dropdown_columns.position);
-    }
-
-    SPObject *new_layer=Inkscape::create_layer(desktop->currentRoot(), dialog._layer, position);
-    
-    Glib::ustring name(dialog._layer_name_entry.get_text());
-    if (!name.empty()) {
-        desktop->layer_manager->renameLayer( new_layer, (gchar *)name.c_str() );
-    }
-    sp_desktop_selection(desktop)->clear();
-    desktop->setCurrentLayer(new_layer);
-    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created."));
-}
-
-void LayerPropertiesDialog::_setDesktop(SPDesktop *desktop) {
-    if (desktop) {
-        Inkscape::GC::anchor (desktop);
-    }
-    if (_desktop) {
-        Inkscape::GC::release (_desktop);
-    }
-    _desktop = desktop;
-}
-
-void LayerPropertiesDialog::_setLayer(SPObject *layer) {
-    if (layer) {
-        sp_object_ref(layer, NULL);
-    }
-    if (_layer) {
-        sp_object_unref(_layer, NULL);
-    }
-    _layer = layer;
-}
-
-} // 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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/layer-properties.h b/src/dialogs/layer-properties.h
deleted file mode 100644 (file)
index 807967e..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/** @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_LAYER_PROPERTIES_H
-#define INKSCAPE_DIALOG_LAYER_PROPERTIES_H
-
-#include <gtkmm/dialog.h>
-#include <gtkmm/notebook.h>
-#include <gtkmm/separator.h>
-#include <gtkmm/frame.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/label.h>
-#include <gtkmm/table.h>
-#include <gtkmm/combobox.h>
-#include <gtkmm/liststore.h>
-
-#include "selection.h"
-#include "layer-fns.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-class LayerPropertiesDialog : public Gtk::Dialog {
- public:
-    LayerPropertiesDialog();
-    virtual ~LayerPropertiesDialog();
-
-    Glib::ustring     getName() const { return "LayerPropertiesDialog"; }
-
-    static void showRename(SPDesktop *desktop, SPObject *layer) {
-        _showDialog(Rename::instance(), desktop, layer);
-    }
-    static void showCreate(SPDesktop *desktop, SPObject *layer) {
-        _showDialog(Create::instance(), desktop, layer);
-    }
-
-protected:
-    struct Strategy {
-        virtual ~Strategy() {}
-        virtual void setup(LayerPropertiesDialog &)=0;
-        virtual void perform(LayerPropertiesDialog &)=0;
-    };
-    struct Rename : public Strategy {
-        static Rename &instance() { static Rename instance; return instance; }
-        void setup(LayerPropertiesDialog &dialog);
-        void perform(LayerPropertiesDialog &dialog);
-    };
-    struct Create : public Strategy {
-        static Create &instance() { static Create instance; return instance; }
-        void setup(LayerPropertiesDialog &dialog);
-        void perform(LayerPropertiesDialog &dialog);
-    };
-
-    friend class Rename;
-    friend class Create;
-
-    Strategy *_strategy;
-    SPDesktop *_desktop;
-    SPObject *_layer;
-
-    class PositionDropdownColumns : public Gtk::TreeModel::ColumnRecord {
-    public:
-        Gtk::TreeModelColumn<LayerRelativePosition> position;
-        Gtk::TreeModelColumn<Glib::ustring> name;
-
-        PositionDropdownColumns() {
-            add(position); add(name);
-        }
-    };
-
-    Gtk::Label        _layer_name_label;
-    Gtk::Entry        _layer_name_entry;
-    Gtk::Label        _layer_position_label;
-    Gtk::ComboBox     _layer_position_combo;
-    Gtk::Table        _layout_table;
-    bool              _position_visible;
-
-    PositionDropdownColumns _dropdown_columns;
-    Gtk::CellRendererText _label_renderer;
-    Glib::RefPtr<Gtk::ListStore> _dropdown_list;
-
-    Gtk::Button       _close_button;
-    Gtk::Button       _apply_button;
-
-    sigc::connection    _destroy_connection;
-
-    static LayerPropertiesDialog &_instance() {
-        static LayerPropertiesDialog instance;
-        return instance;
-    }
-
-    void _setDesktop(SPDesktop *desktop);
-    void _setLayer(SPObject *layer);
-
-    static void _showDialog(Strategy &strategy, SPDesktop *desktop, SPObject *layer);
-    void _apply();
-    void _close();
-
-    void _setup_position_controls();
-    void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
-
-private:
-    LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy
-    LayerPropertiesDialog &operator=(LayerPropertiesDialog 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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/layers-panel.cpp b/src/dialogs/layers-panel.cpp
deleted file mode 100644 (file)
index c826777..0000000
+++ /dev/null
@@ -1,810 +0,0 @@
-/*
- * A simple panel for layers
- *
- * Authors:
- *   Jon A. Cruz
- *
- * Copyright (C) 2006 Jon A. Cruz
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <glibmm/i18n.h>
-
-#include <gtk/gtkstock.h>
-#include <gtk/gtkmain.h>
-
-#include <gtkmm/icontheme.h>
-
-#include "inkscape.h"
-
-#include "layers-panel.h"
-
-#include "layer-manager.h"
-#include "layer-fns.h"
-
-#include "verbs.h"
-#include "helper/action.h"
-
-#include "document.h"
-#include "desktop.h"
-#include "sp-object.h"
-#include "sp-item.h"
-#include "widgets/icon.h"
-#include "ui/widget/imagetoggler.h"
-#include <gtkmm/widget.h>
-#include "preferences.h"
-#include "xml/repr.h"
-#include "svg/css-ostringstream.h"
-#include "desktop-style.h"
-#include "ui/icon-names.h"
-
-//#define DUMP_LAYERS 1
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-LayersPanel&
-LayersPanel::getInstance()
-{
-    return *new LayersPanel();
-}
-
-enum {
-    COL_VISIBLE = 1,
-    COL_LOCKED
-};
-
-enum {
-    BUTTON_NEW = 0,
-    BUTTON_RENAME,
-    BUTTON_TOP,
-    BUTTON_BOTTOM,
-    BUTTON_UP,
-    BUTTON_DOWN,
-    BUTTON_DUPLICATE,
-    BUTTON_DELETE,
-    BUTTON_SOLO
-};
-
-class LayersPanel::InternalUIBounce
-{
-public:
-    int _actionCode;
-    SPObject* _target;
-};
-
-static gboolean layers_panel_activated( GtkObject */*object*/, GdkEvent * /*event*/, gpointer data )
-{
-    if ( data )
-    {
-        LayersPanel* panel = reinterpret_cast<LayersPanel*>(data);
-        panel->setDesktop(panel->getDesktop());
-    }
-
-    return FALSE;
-}
-
-static gboolean layers_panel_deactivated( GtkObject */*object*/, GdkEvent * /*event*/, gpointer data )
-{
-    if ( data )
-    {
-        LayersPanel* panel = reinterpret_cast<LayersPanel*>(data);
-        panel->setDesktop(NULL);
-    }
-
-    return FALSE;
-}
-
-
-void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback )
-{
-    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)) );
-        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;
-            }
-
-            if ( action && action->tip ) {
-                _tips.set_tip( btn, action->tip );
-            }
-        }
-    }
-
-    if ( !set && fallback ) {
-        btn.set_label( fallback );
-    }
-}
-
-
-Gtk::MenuItem& LayersPanel::_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::Menu::MenuList& menulist = _popupMenu.items();
-
-    if ( wrapped ) {
-        menulist.push_back( Gtk::Menu_Helpers::ImageMenuElem( label, *wrapped, sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), id)) );
-    } else {
-        menulist.push_back( Gtk::Menu_Helpers::MenuElem( label, sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), id)) );
-    }
-    return menulist.back();
-}
-
-void LayersPanel::_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 );
-//             } else {
-//                 g_message("no action");
-            }
-//         } else {
-//             g_message("no verb for %u", code);
-        }
-//     } else {
-//         g_message("no active desktop");
-    }
-}
-
-//     SP_VERB_LAYER_NEXT,
-//     SP_VERB_LAYER_PREV,
-void LayersPanel::_takeAction( int val )
-{
-    if ( !_pending ) {
-        _pending = new InternalUIBounce();
-        _pending->_actionCode = val;
-        _pending->_target = _selectedLayer();
-        Glib::signal_timeout().connect( sigc::mem_fun(*this, &LayersPanel::_executeAction), 0 );
-    }
-}
-
-bool LayersPanel::_executeAction()
-{
-    // Make sure selected layer hasn't changed since the action was triggered
-    if ( _pending
-         && (
-             (_pending->_actionCode == BUTTON_NEW)
-             || !( (_desktop && _desktop->currentLayer())
-                   && (_desktop->currentLayer() != _pending->_target)
-                 )
-             )
-        ) {
-        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:
-            {
-                _fireAction( SP_VERB_LAYER_TO_TOP );
-            }
-            break;
-            case BUTTON_BOTTOM:
-            {
-                _fireAction( SP_VERB_LAYER_TO_BOTTOM );
-            }
-            break;
-            case BUTTON_UP:
-            {
-                _fireAction( SP_VERB_LAYER_RAISE );
-            }
-            break;
-            case BUTTON_DOWN:
-            {
-                _fireAction( SP_VERB_LAYER_LOWER );
-            }
-            break;
-            case BUTTON_DUPLICATE:
-            {
-                _fireAction( SP_VERB_LAYER_DUPLICATE );
-            }
-            break;
-            case BUTTON_DELETE:
-            {
-                _fireAction( SP_VERB_LAYER_DELETE );
-            }
-            case BUTTON_SOLO:
-            {
-                _fireAction( SP_VERB_LAYER_SOLO );
-            }
-            break;
-        }
-
-        delete _pending;
-        _pending = 0;
-    }
-
-    return false;
-}
-
-class LayersPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord
-{
-public:
-
-    ModelColumns()
-    {
-        add(_colObject);
-        add(_colVisible);
-        add(_colLocked);
-        add(_colLabel);
-    }
-    virtual ~ModelColumns() {}
-
-    Gtk::TreeModelColumn<SPObject*> _colObject;
-    Gtk::TreeModelColumn<Glib::ustring> _colLabel;
-    Gtk::TreeModelColumn<bool> _colVisible;
-    Gtk::TreeModelColumn<bool> _colLocked;
-};
-
-void LayersPanel::_updateLayer( SPObject *layer ) {
-    _store->foreach( sigc::bind<SPObject*>(sigc::mem_fun(*this, &LayersPanel::_checkForUpdated), layer) );
-}
-
-bool LayersPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* layer)
-{
-    bool stopGoing = false;
-    Gtk::TreeModel::Row row = *iter;
-    Glib::ustring tmp = row[_model->_colLabel];
-    if ( layer == row[_model->_colObject] )
-    {
-        row[_model->_colLabel] = layer->label() ? layer->label() : SP_OBJECT_ID(layer);
-        row[_model->_colVisible] = SP_IS_ITEM(layer) ? !SP_ITEM(layer)->isHidden() : false;
-        row[_model->_colLocked] = SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false;
-
-        stopGoing = true;
-    }
-
-    return stopGoing;
-}
-
-void LayersPanel::_selectLayer( SPObject *layer ) {
-    if ( !layer || (_desktop && _desktop->doc() && (layer == _desktop->doc()->root)) ) {
-        if ( _tree.get_selection()->count_selected_rows() != 0 ) {
-            _tree.get_selection()->unselect_all();
-        }
-    } else {
-        _store->foreach( sigc::bind<SPObject*>(sigc::mem_fun(*this, &LayersPanel::_checkForSelected), layer) );
-    }
-
-    _checkTreeSelection();
-}
-
-bool LayersPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* layer)
-{
-    bool stopGoing = false;
-
-    Gtk::TreeModel::Row row = *iter;
-    if ( layer == row[_model->_colObject] )
-    {
-        _tree.expand_to_path( path );
-
-        Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
-
-        select->select(iter);
-
-        stopGoing = true;
-    }
-
-    return stopGoing;
-}
-
-void LayersPanel::_layersChanged()
-{
-//    g_message("_layersChanged()");
-    SPDocument* document = _desktop->doc();
-    SPObject* root = document->root;
-    if ( root ) {
-        _selectedConnection.block();
-        if ( _mgr && _mgr->includes( root ) ) {
-            SPObject* target = _desktop->currentLayer();
-            _store->clear();
-
-#if DUMP_LAYERS
-            g_message("root:%p  {%s}   [%s]", root, root->id, root->label() );
-#endif // DUMP_LAYERS
-            _addLayer( document, root, 0, target, 0 );
-        }
-        _selectedConnection.unblock();
-    }
-}
-
-void LayersPanel::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level )
-{
-    if ( layer && (level < _maxNestDepth) ) {
-        unsigned int counter = _mgr->childCount(layer);
-        for ( unsigned int i = 0; i < counter; i++ ) {
-            SPObject *child = _mgr->nthChildOf(layer, i);
-            if ( child ) {
-#if DUMP_LAYERS
-                g_message(" %3d    layer:%p  {%s}   [%s]", level, child, child->id, child->label() );
-#endif // DUMP_LAYERS
-
-                Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend();
-                Gtk::TreeModel::Row row = *iter;
-                row[_model->_colObject] = child;
-                row[_model->_colLabel] = child->label() ? child->label() : SP_OBJECT_ID(child);
-                row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false;
-                row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false;
-
-                if ( target && child == target ) {
-                    _tree.expand_to_path( _store->get_path(iter) );
-
-                    Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
-                    select->select(iter);
-
-                    _checkTreeSelection();
-                }
-
-                _addLayer( doc, child, &row, target, level + 1 );
-            }
-        }
-    }
-}
-
-SPObject* LayersPanel::_selectedLayer()
-{
-    SPObject* obj = 0;
-
-    Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
-    if ( iter ) {
-        Gtk::TreeModel::Row row = *iter;
-        obj = row[_model->_colObject];
-    }
-
-    return obj;
-}
-
-void LayersPanel::_pushTreeSelectionToCurrent()
-{
-    SPObject* inTree = _selectedLayer();
-    // TODO hunt down the possible API abuse in getting NULL
-    if ( _desktop->currentRoot() ) {
-        if ( inTree ) {
-            SPObject* curr = _desktop->currentLayer();
-            if ( curr != inTree ) {
-                _mgr->setCurrentLayer( inTree );
-            }
-        } else {
-            _mgr->setCurrentLayer( _desktop->doc()->root );
-        }
-    }
-}
-
-void LayersPanel::_checkTreeSelection()
-{
-    bool sensitive = false;
-    bool sensitiveNonTop = false;
-    bool sensitiveNonBottom = false;
-    if ( _tree.get_selection()->count_selected_rows() > 0 ) {
-        sensitive = true;
-
-        SPObject* inTree = _selectedLayer();
-        if ( inTree ) {
-
-            sensitiveNonTop = (Inkscape::next_layer(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 );
-    }
-}
-
-void LayersPanel::_preToggle( GdkEvent const *event )
-{
-    if ( _toggleEvent ) {
-        gdk_event_free(_toggleEvent);
-        _toggleEvent = 0;
-    }
-
-    if ( event && (event->type == GDK_BUTTON_PRESS) ) {
-        // Make a copy so we can keep it around.
-        _toggleEvent = gdk_event_copy(const_cast<GdkEvent*>(event));
-    }
-}
-
-void LayersPanel::_toggled( Glib::ustring const& str, int targetCol )
-{
-    Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(str);
-    Gtk::TreeModel::Row row = *iter;
-
-    Glib::ustring tmp = row[_model->_colLabel];
-
-    SPObject* obj = row[_model->_colObject];
-    SPItem* item = ( obj && SP_IS_ITEM(obj) ) ? SP_ITEM(obj) : 0;
-    if ( item ) {
-        switch ( targetCol ) {
-            case COL_VISIBLE:
-            {
-                bool newValue = !row[_model->_colVisible];
-                row[_model->_colVisible] = newValue;
-                item->setHidden( !newValue  );
-                item->updateRepr();
-                sp_document_done( _desktop->doc() , SP_VERB_DIALOG_LAYERS,
-                                  newValue? _("Unhide layer") : _("Hide layer"));
-            }
-            break;
-
-            case COL_LOCKED:
-            {
-                bool newValue = !row[_model->_colLocked];
-                row[_model->_colLocked] = newValue;
-                item->setLocked( newValue );
-                item->updateRepr();
-                sp_document_done( _desktop->doc() , SP_VERB_DIALOG_LAYERS,
-                                  newValue? _("Lock layer") : _("Unlock layer"));
-            }
-            break;
-        }
-    }
-}
-
-void LayersPanel::_handleButtonEvent(GdkEventButton* evt)
-{
-    // TODO - fix to a better is-popup function
-    if ( (evt->type == GDK_BUTTON_PRESS) && (evt->button == 3) ) {
-
-
-        {
-            Gtk::TreeModel::Path path;
-            Gtk::TreeViewColumn* col = 0;
-            int x = static_cast<int>(evt->x);
-            int y = static_cast<int>(evt->y);
-            int x2 = 0;
-            int y2 = 0;
-            if ( _tree.get_path_at_pos( x, y,
-                                        path, col,
-                                        x2, y2 ) ) {
-                _checkTreeSelection();
-                _popupMenu.popup(evt->button, evt->time);
-            }
-        }
-
-    }
-}
-
-void LayersPanel::_handleRowChange( Gtk::TreeModel::Path const& /*path*/, Gtk::TreeModel::iterator const& iter )
-{
-    Gtk::TreeModel::Row row = *iter;
-    if ( row ) {
-        SPObject* obj = row[_model->_colObject];
-        if ( obj ) {
-            gchar const* oldLabel = obj->label();
-            Glib::ustring tmp = row[_model->_colLabel];
-            if ( oldLabel && oldLabel[0] && !tmp.empty() && (tmp != oldLabel) ) {
-                _mgr->renameLayer( obj, tmp.c_str() );
-                row[_model->_colLabel] = obj->label();
-            }
-        }
-    }
-}
-
-bool LayersPanel::_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;
-}
-
-/**
- * Constructor
- */
-LayersPanel::LayersPanel() :
-    UI::Widget::Panel("", "/dialogs/layers", SP_VERB_DIALOG_LAYERS),
-    _maxNestDepth(20),
-    _mgr(0),
-    _desktop(0),
-    _model(0),
-    _pending(0),
-    _toggleEvent(0),
-    _compositeSettings(SP_VERB_DIALOG_LAYERS, "layers", UI::Widget::SimpleFilterModifier::BLEND)
-{
-    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-    _maxNestDepth = prefs->getIntLimited("/dialogs/layers/maxDepth", 20, 1, 1000);
-
-    ModelColumns *zoop = new ModelColumns();
-    _model = zoop;
-
-    _store = Gtk::TreeStore::create( *zoop );
-
-    _tree.set_model( _store );
-    _tree.set_headers_visible(false);
-
-    Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler(
-        INKSCAPE_ICON_OBJECT_VISIBLE, INKSCAPE_ICON_OBJECT_HIDDEN) );
-    int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1;
-    eyeRenderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) );
-    eyeRenderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_toggled), (int)COL_VISIBLE) );
-    eyeRenderer->property_activatable() = true;
-    Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum);
-    if ( col ) {
-        col->add_attribute( eyeRenderer->property_active(), _model->_colVisible );
-    }
-
-    Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler(
-        INKSCAPE_ICON_OBJECT_LOCKED, INKSCAPE_ICON_OBJECT_UNLOCKED) );
-    int lockedColNum = _tree.append_column("lock", *renderer) - 1;
-    renderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) );
-    renderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_toggled), (int)COL_LOCKED) );
-    renderer->property_activatable() = true;
-    col = _tree.get_column(lockedColNum);
-    if ( col ) {
-        col->add_attribute( renderer->property_active(), _model->_colLocked );
-    }
-
-    int nameColNum = _tree.append_column_editable("Name", _model->_colLabel) - 1;
-
-    _tree.set_expander_column( *_tree.get_column(nameColNum) );
-
-    _compositeSettings.setSubject(&_subject);
-
-    _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &LayersPanel::_pushTreeSelectionToCurrent) );
-    _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &LayersPanel::_rowSelectFunction) );
-
-    _tree.get_model()->signal_row_changed().connect( sigc::mem_fun(*this, &LayersPanel::_handleRowChange) );
-    _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) );
-
-    _scroller.add( _tree );
-    _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
-    _scroller.set_shadow_type(Gtk::SHADOW_IN);
-
-    _watching.push_back( &_compositeSettings );
-
-    _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET );
-    _layersPage.pack_end(_compositeSettings, Gtk::PACK_SHRINK);
-    _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK);
-
-    _notebook.append_page(_layersPage, _("Layers"));
-
-    _getContents()->pack_start(_notebook, Gtk::PACK_EXPAND_WIDGET);
-
-    SPDesktop* targetDesktop = getDesktop();
-
-    _buttonsRow.set_child_min_width( 16 );
-
-    Gtk::Button* btn = manage( new Gtk::Button() );
-    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("New") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) );
-    _buttonsRow.add( *btn );
-
-    btn = manage( new Gtk::Button() );
-    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, _("Top") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) );
-    _watchingNonTop.push_back( btn );
-    _buttonsRow.add( *btn );
-
-    btn = manage( new Gtk::Button() );
-    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, _("Up") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) );
-    _watchingNonTop.push_back( btn );
-    _buttonsRow.add( *btn );
-
-    btn = manage( new Gtk::Button() );
-    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, _("Dn") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) );
-    _watchingNonBottom.push_back( btn );
-    _buttonsRow.add( *btn );
-
-    btn = manage( new Gtk::Button() );
-    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, _("Bot") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) );
-    _watchingNonBottom.push_back( btn );
-    _buttonsRow.add( *btn );
-
-//     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, _("X") );
-    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) );
-    _watching.push_back( btn );
-    _buttonsRow.add( *btn );
-
-
-
-
-    // -------------------------------------------------------
-    {
-        _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_SOLO, 0, "Solo", (int)BUTTON_SOLO ) );
-
-         _popupMenu.items().push_back( Gtk::Menu_Helpers::SeparatorElem() );
-
-        _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) );
-        _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) );
-
-        _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 );
-    }
-
-    g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( layers_panel_activated ), this );
-    g_signal_connect( G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK( layers_panel_deactivated ), this );
-    setDesktop( targetDesktop );
-
-    show_all_children();
-
-    // restorePanelPrefs();
-}
-
-LayersPanel::~LayersPanel()
-{
-    setDesktop(NULL);
-
-    _compositeSettings.setSubject(NULL);
-
-    if ( _model )
-    {
-        delete _model;
-    }
-
-    if ( _toggleEvent )
-    {
-        gdk_event_free( _toggleEvent );
-        _toggleEvent = 0;
-    }
-}
-
-
-void LayersPanel::setDesktop( SPDesktop* desktop )
-{
-    Panel::setDesktop(desktop);
-
-    if ( desktop != _desktop ) {
-        _layerChangedConnection.disconnect();
-        _layerUpdatedConnection.disconnect();
-        _changedConnection.disconnect();
-        if ( _mgr ) {
-            _mgr = 0;
-        }
-        if ( _desktop ) {
-            _desktop = 0;
-        }
-
-        _desktop = getDesktop();
-        if ( _desktop ) {
-            //setLabel( _desktop->doc()->name );
-
-            _mgr = _desktop->layer_manager;
-            if ( _mgr ) {
-                _layerChangedConnection = _mgr->connectCurrentLayerChanged( sigc::mem_fun(*this, &LayersPanel::_selectLayer) );
-                _layerUpdatedConnection = _mgr->connectLayerDetailsChanged( sigc::mem_fun(*this, &LayersPanel::_updateLayer) );
-                _changedConnection = _mgr->connectChanged( sigc::mem_fun(*this, &LayersPanel::_layersChanged) );
-            }
-
-            _layersChanged();
-        }
-    }
-/*
-    GSList const *layers=sp_document_get_resource_list( _desktop->doc(), "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() );
-    }
-*/
-}
-
-
-
-} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/layers-panel.h b/src/dialogs/layers-panel.h
deleted file mode 100644 (file)
index 1f593b9..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * A simple dialog for layer UI.
- *
- * Authors:
- *   Jon A. Cruz
- *
- * Copyright (C) 2006 Jon A. Cruz
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_LAYERS_PANEL_H
-#define SEEN_LAYERS_PANEL_H
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/box.h>
-#include <gtkmm/buttonbox.h>
-#include <gtkmm/spinbutton.h>
-#include <gtkmm/notebook.h>
-
-//#include "ui/previewholder.h"
-#include "ui/widget/panel.h"
-#include "ui/widget/object-composite-settings.h"
-
-class SPObject;
-
-namespace Inkscape {
-
-class LayerManager;
-
-namespace UI {
-namespace Dialogs {
-
-
-/**
- * A panel that displays layers.
- */
-class LayersPanel : public UI::Widget::Panel
-{
-public:
-    LayersPanel();
-    virtual ~LayersPanel();
-
-    //virtual void setOrientation( Gtk::AnchorType how );
-    
-    static LayersPanel& getInstance();
-
-    void setDesktop( SPDesktop* desktop );
-
-protected:
-    //virtual void _handleAction( int setId, int itemId );
-
-private:
-    class ModelColumns;
-    class InternalUIBounce;
-
-    LayersPanel(LayersPanel const &); // no copy
-    LayersPanel &operator=(LayersPanel const &); // no assign
-
-    void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback );
-    void _fireAction( unsigned int code );
-    Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id );
-
-    void _preToggle( GdkEvent const *event );
-    void _toggled( Glib::ustring const& str, int targetCol );
-
-    void _handleButtonEvent(GdkEventButton* evt);
-    void _handleRowChange( Gtk::TreeModel::Path const& path, Gtk::TreeModel::iterator const& iter );
-
-    void _pushTreeSelectionToCurrent();
-    void _checkTreeSelection();
-
-    void _takeAction( int val );
-    bool _executeAction();
-
-    bool _rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
-
-    void _updateLayer(SPObject *layer);
-    bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* layer);
-
-    void _selectLayer(SPObject *layer);
-    bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer);
-
-    void _layersChanged();
-    void _addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level );
-
-    SPObject* _selectedLayer();
-
-    // Hooked to the layer manager:
-    sigc::connection _layerChangedConnection;
-    sigc::connection _layerUpdatedConnection;
-    sigc::connection _changedConnection;
-    sigc::connection _addedConnection;
-    sigc::connection _removedConnection;
-
-    // Internal
-    sigc::connection _selectedConnection;
-
-    int _maxNestDepth;
-    Inkscape::LayerManager* _mgr;
-    SPDesktop* _desktop;
-    ModelColumns* _model;
-    InternalUIBounce* _pending;
-    GdkEvent* _toggleEvent;
-    Glib::RefPtr<Gtk::TreeStore> _store;
-    std::vector<Gtk::Widget*> _watching;
-    std::vector<Gtk::Widget*> _watchingNonTop;
-    std::vector<Gtk::Widget*> _watchingNonBottom;
-
-    Gtk::Tooltips _tips;
-    Gtk::TreeView _tree;
-    Gtk::HButtonBox _buttonsRow;
-    Gtk::ScrolledWindow _scroller;
-    Gtk::Menu _popupMenu;
-    Gtk::SpinButton _spinBtn;
-    Gtk::Notebook _notebook;
-    Gtk::VBox _layersPage;
-
-    UI::Widget::StyleSubject::CurrentLayer _subject;
-    UI::Widget::ObjectCompositeSettings _compositeSettings;
-};
-
-
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-
-
-#endif // SEEN_LAYERS_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:encoding=utf-8:textwidth=99 :
index d9bcf148943efb75e9753f18778db5c95beab2c6..320840f76bc5387188c819367a6a9b0974c963c4 100644 (file)
 #include <glibmm/i18n.h>
 #include <string>
 #include <cstring>
+#include <sigc++/connection.h>
+#include <sigc++/functors/ptr_fun.h>
+#include <sigc++/adaptors/bind.h>
 
 #include "helper/window.h"
 #include "macros.h"
 #include "sp-anchor.h"
-#include "sp-attribute-widget.h"
+#include "widgets/sp-attribute-widget.h"
 #include "../xml/repr.h"
 
-#include <sigc++/connection.h>
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
-
 struct SPAttrDesc {
     gchar const *label;
     gchar const *attribute;
diff --git a/src/dialogs/rdf.cpp b/src/dialogs/rdf.cpp
deleted file mode 100644 (file)
index f0b1749..0000000
+++ /dev/null
@@ -1,1023 +0,0 @@
-/** @file
- * @brief  RDF manipulation functions
- *
- * @todo move these to xml/ instead of dialogs/
- */
-/* Authors:
- *   Kees Cook <kees@outflux.net>
- *   Jon Phillips <jon@rejon.org>
- *
- * Copyright (C) 2004 Kees Cook <kees@outflux.net>
- * Copyright (C) 2006 Jon Phillips <jon@rejon.org>
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "xml/repr.h"
-#include "rdf.h"
-#include "sp-item-group.h"
-#include "inkscape.h"
-
-/*
-   Example RDF XML from various places...
-<rdf:RDF xmlns="http://creativecommons.org/ns#"
-    xmlns:dc="http://purl.org/dc/elements/1.1/"
-    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-<Work rdf:about="">
-   <dc:title>title of work</dc:title>
-   <dc:date>year</dc:date>
-   <dc:description>description of work</dc:description>
-   <dc:creator><Agent>
-      <dc:title>creator</dc:title>
-   </Agent></dc:creator>
-   <dc:rights><Agent>
-      <dc:title>holder</dc:title>
-   </Agent></dc:rights>
-   <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-   <dc:source rdf:resource="source"/>
-   <license rdf:resource="http://creativecommons.org/licenses/by/2.0/" 
-/>
-</Work>
-
-
-  <rdf:RDF xmlns="http://creativecommons.org/ns#"
-      xmlns:dc="http://purl.org/dc/elements/1.1/"
-      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-  <Work rdf:about="">
-     <dc:title>SVG Road Signs</dc:title>
-     <dc:rights><Agent>
-        <dc:title>John Cliff</dc:title>
-     </Agent></dc:rights>
-     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-     <license rdf:resource="http://creativecommons.org/ns#PublicDomain" />
-  </Work>
-  
-  <License rdf:about="http://creativecommons.org/ns#PublicDomain">
-     <permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
-     <permits rdf:resource="http://creativecommons.org/ns#Distribution" />
-     <permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
-  </License>
-  
-</rdf:RDF>
-
-
-Bag example:
-
-<dc:subject>
-<rdf:Bag>
-<rdf:li>open clip art logo</rdf:li>
-<rdf:li>images</rdf:li>
-<rdf:li>logo</rdf:li>
-<rdf:li>clip art</rdf:li>
-<rdf:li>ocal</rdf:li>
-<rdf:li>logotype</rdf:li>
-<rdf:li>filetype</rdf:li>
-</rdf:Bag>
-</dc:subject>
-*/
-
-struct rdf_double_t rdf_license_empty [] = {
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a_sa [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a_nd [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a_nc [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a_nc_sa [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_cc_a_nc_nd [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_pd [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_freeart [] = {
-    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
-    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
-    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
-    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
-    { "cc:requires", "http://creativecommons.org/ns#Notice", },
-    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
-    { NULL, NULL }
-};
-
-struct rdf_double_t rdf_license_ofl [] = {
-    { "cc:permits", "http://scripts.sil.org/pub/OFL/Reproduction", },
-    { "cc:permits", "http://scripts.sil.org/pub/OFL/Distribution", },
-    { "cc:permits", "http://scripts.sil.org/pub/OFL/Embedding", },
-    { "cc:permits", "http://scripts.sil.org/pub/OFL/DerivativeWorks", },
-    { "cc:requires", "http://scripts.sil.org/pub/OFL/Notice", },
-    { "cc:requires", "http://scripts.sil.org/pub/OFL/Attribution", },
-    { "cc:requires", "http://scripts.sil.org/pub/OFL/ShareAlike", },
-    { "cc:requires", "http://scripts.sil.org/pub/OFL/DerivativeRenaming", },
-    { "cc:requires", "http://scripts.sil.org/pub/OFL/BundlingWhenSelling", },
-    { NULL, NULL }
-};
-
-struct rdf_license_t rdf_licenses [] = {
-    { N_("CC Attribution"), 
-      "http://creativecommons.org/licenses/by/3.0/",
-      rdf_license_cc_a,
-    },
-
-    { N_("CC Attribution-ShareAlike"), 
-      "http://creativecommons.org/licenses/by-sa/3.0/",
-      rdf_license_cc_a_sa,
-    },
-
-    { N_("CC Attribution-NoDerivs"), 
-      "http://creativecommons.org/licenses/by-nd/3.0/",
-      rdf_license_cc_a_nd,
-    },
-
-    { N_("CC Attribution-NonCommercial"), 
-      "http://creativecommons.org/licenses/by-nc/3.0/",
-      rdf_license_cc_a_nc,
-    },
-
-    { N_("CC Attribution-NonCommercial-ShareAlike"), 
-      "http://creativecommons.org/licenses/by-nc-sa/3.0/",
-      rdf_license_cc_a_nc_sa,
-    },
-
-    { N_("CC Attribution-NonCommercial-NoDerivs"), 
-      "http://creativecommons.org/licenses/by-nc-nd/3.0/",
-      rdf_license_cc_a_nc_nd,
-    },
-
-    { N_("Public Domain"),
-      "http://creativecommons.org/licenses/publicdomain/",
-      rdf_license_pd,
-    },
-
-    { N_("FreeArt"),
-      "http://artlibre.org/licence.php/lalgb.html",
-      rdf_license_freeart,
-    },
-
-    { N_("Open Font License"),
-      "http://scripts.sil.org/OFL",
-      rdf_license_ofl,
-    },
-
-    { NULL, NULL, rdf_license_empty, }
-};
-
-#define XML_TAG_NAME_SVG      "svg:svg"
-#define XML_TAG_NAME_METADATA "svg:metadata"
-#define XML_TAG_NAME_RDF      "rdf:RDF"
-#define XML_TAG_NAME_WORK     "cc:Work"
-#define XML_TAG_NAME_LICENSE  "cc:License"
-
-// Remember when using the "title" and "tip" elements to pass them through
-// the localization functions when you use them!
-struct rdf_work_entity_t rdf_work_entities [] = {
-    { "title", N_("Title"), "dc:title", RDF_CONTENT,
-      N_("Name by which this document is formally known."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "date", N_("Date"), "dc:date", RDF_CONTENT,
-      N_("Date associated with the creation of this document (YYYY-MM-DD)."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "format", N_("Format"), "dc:format", RDF_CONTENT,
-      N_("The physical or digital manifestation of this document (MIME type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
-    },
-    { "type", N_("Type"), "dc:type", RDF_RESOURCE,
-      N_("Type of document (DCMI Type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
-    },
-
-    { "creator", N_("Creator"), "dc:creator", RDF_AGENT,
-      N_("Name of entity primarily responsible for making the content of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "rights", N_("Rights"), "dc:rights", RDF_AGENT,
-      N_("Name of entity with rights to the Intellectual Property of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "publisher", N_("Publisher"), "dc:publisher", RDF_AGENT,
-      N_("Name of entity responsible for making this document available."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-
-    { "identifier", N_("Identifier"), "dc:identifier", RDF_CONTENT,
-      N_("Unique URI to reference this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "source", N_("Source"), "dc:source", RDF_CONTENT,
-      N_("Unique URI to reference the source of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "relation", N_("Relation"), "dc:relation", RDF_CONTENT,
-      N_("Unique URI to a related document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "language", N_("Language"), "dc:language", RDF_CONTENT,
-      N_("Two-letter language tag with optional subtags for the language of this document.  (e.g. 'en-GB')"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    { "subject", N_("Keywords"), "dc:subject", RDF_BAG,
-      N_("The topic of this document as comma-separated key words, phrases, or classifications."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-    // TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content.
-    // For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/
-    { "coverage", N_("Coverage"), "dc:coverage", RDF_CONTENT,
-      N_("Extent or scope of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
-    },
-
-    { "description", N_("Description"), "dc:description", RDF_CONTENT,
-      N_("A short account of the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
-    },
-
-    // FIXME: need to handle 1 agent per line of input
-    { "contributor", N_("Contributors"), "dc:contributor", RDF_AGENT,
-      N_("Names of entities responsible for making contributions to the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
-    },
-
-    // TRANSLATORS: URL to a page that defines the license for the document
-    { "license_uri", N_("URI"), "cc:license", RDF_RESOURCE,
-      // TRANSLATORS: this is where you put a URL to a page that defines the license
-      N_("URI to this document's license's namespace definition."), RDF_FORMAT_LINE, RDF_EDIT_SPECIAL,
-    },
-
-      // TRANSLATORS: fragment of XML representing the license of the document
-    { "license_fragment", N_("Fragment"), "License", RDF_XML,
-      N_("XML fragment for the RDF 'License' section."), RDF_FORMAT_MULTILINE, RDF_EDIT_SPECIAL,
-    },
-    
-    { NULL, NULL, NULL, RDF_CONTENT,
-      NULL, RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
-    }
-};
-
-/**
- *  \brief   Retrieves a known RDF/Work entity by name
- *  \return  A pointer to an RDF/Work entity
- *  \param   name  The desired RDF/Work entity
- *  
- */
-struct rdf_work_entity_t *
-rdf_find_entity(gchar const * name)
-{
-    struct rdf_work_entity_t *entity;
-    for (entity=rdf_work_entities; entity->name; entity++) {
-        if (strcmp(entity->name,name)==0) break;
-    }
-    if (entity->name) return entity;
-    return NULL;
-}
-
-/*
- * Takes the inkscape rdf struct and spits out a static RDF, which is only
- * useful for testing.  We must merge the rdf struct into the XML DOM for
- * changes to be saved.
- */
-/*
-
-   Since g_markup_printf_escaped doesn't exist for most people's glib
-   right now, this function will remain commented out since it's only
-   for generic debug anyway.  --Kees
-
-gchar *
-rdf_string(struct rdf_t * rdf)
-{
-    gulong overall=0;
-    gchar *string=NULL;
-
-    gchar *rdf_head="\
-<rdf:RDF xmlns=\"http://creativecommons.org/ns#\"\
-    xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\
-    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\
-";
-    gchar *work_head="\
-<Work rdf:about=\"\">\
-   <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\
-";
-    gchar *work_title=NULL;
-    gchar *work_date=NULL;
-    gchar *work_description=NULL;
-    gchar *work_creator=NULL;
-    gchar *work_owner=NULL;
-    gchar *work_source=NULL;
-    gchar *work_license=NULL;
-    gchar *license_head=NULL;
-    gchar *license=NULL;
-    gchar *license_end="</License>\n";
-    gchar *work_end="</Work>\n";
-    gchar *rdf_end="</rdf:RDF>\n";
-
-    if (rdf && rdf->work_title && rdf->work_title[0]) {
-        work_title=g_markup_printf_escaped("   <dc:title>%s</dc:title>\n",
-            rdf->work_title);
-    overall+=strlen(work_title);
-    }
-    if (rdf && rdf->work_date && rdf->work_date[0]) {
-        work_date=g_markup_printf_escaped("   <dc:date>%s</dc:date>\n",
-            rdf->work_date);
-    overall+=strlen(work_date);
-    }
-    if (rdf && rdf->work_description && rdf->work_description[0]) {
-        work_description=g_markup_printf_escaped("   <dc:description>%s</dc:description>\n",
-            rdf->work_description);
-    overall+=strlen(work_description);
-    }
-    if (rdf && rdf->work_creator && rdf->work_creator[0]) {
-        work_creator=g_markup_printf_escaped("   <dc:creator><Agent>\
-      <dc:title>%s</dc:title>\
-   </Agent></dc:creator>\n",
-            rdf->work_creator);
-    overall+=strlen(work_creator);
-    }
-    if (rdf && rdf->work_owner && rdf->work_owner[0]) {
-        work_owner=g_markup_printf_escaped("   <dc:rights><Agent>\
-      <dc:title>%s</dc:title>\
-   </Agent></dc:rights>\n",
-            rdf->work_owner);
-    overall+=strlen(work_owner);
-    }
-    if (rdf && rdf->work_source && rdf->work_source[0]) {
-        work_source=g_markup_printf_escaped("   <dc:source rdf:resource=\"%s\" />\n",
-            rdf->work_source);
-    overall+=strlen(work_source);
-    }
-    if (rdf && rdf->license && rdf->license->work_rdf && rdf->license->work_rdf[0]) {
-        work_license=g_markup_printf_escaped("   <license rdf:resource=\"%s\" />\n",
-            rdf->license->work_rdf);
-    overall+=strlen(work_license);
-
-    license_head=g_markup_printf_escaped("<License rdf:about=\"%s\">\n",
-            rdf->license->work_rdf);
-    overall+=strlen(license_head);
-    overall+=strlen(rdf->license->license_rdf);
-    overall+=strlen(license_end);
-    }
-
-    overall+=strlen(rdf_head)+strlen(rdf_end);
-    overall+=strlen(work_head)+strlen(work_end);
-
-    overall++; // NULL term
-
-    if (!(string=(gchar*)g_malloc(overall))) {
-        return NULL;
-    }
-
-    string[0]='\0';
-    strcat(string,rdf_head);
-    strcat(string,work_head);
-
-    if (work_title)       strcat(string,work_title);
-    if (work_date)        strcat(string,work_date);
-    if (work_description) strcat(string,work_description);
-    if (work_creator)     strcat(string,work_creator);
-    if (work_owner)       strcat(string,work_owner);
-    if (work_source)      strcat(string,work_source);
-    if (work_license)     strcat(string,work_license);
-
-    strcat(string,work_end);
-    if (license_head) {
-        strcat(string,license_head);
-    strcat(string,rdf->license->license_rdf);
-    strcat(string,license_end);
-    }
-    strcat(string,rdf_end);
-
-    return string;
-}
-*/
-
-
-/**
- *  \brief   Pull the text out of an RDF entity, depends on how it's stored
- *  \return  A pointer to the entity's static contents as a string
- *  \param   repr    The XML element to extract from
- *  \param   entity  The desired RDF/Work entity
- *  
- */
-const gchar *
-rdf_get_repr_text ( Inkscape::XML::Node * repr, struct rdf_work_entity_t * entity )
-{
-    g_return_val_if_fail (repr != NULL, NULL);
-    g_return_val_if_fail (entity != NULL, NULL);
-    static gchar * bag = NULL;
-    gchar * holder = NULL;
-
-    Inkscape::XML::Node * temp=NULL;
-    switch (entity->datatype) {
-        case RDF_CONTENT:
-            temp = sp_repr_children(repr);
-            if ( temp == NULL ) return NULL;
-            
-            return temp->content();
-
-        case RDF_AGENT:
-            temp = sp_repr_lookup_name ( repr, "cc:Agent", 1 );
-            if ( temp == NULL ) return NULL;
-
-            temp = sp_repr_lookup_name ( temp, "dc:title", 1 );
-            if ( temp == NULL ) return NULL;
-
-            temp = sp_repr_children(temp);
-            if ( temp == NULL ) return NULL;
-
-            return temp->content();
-
-        case RDF_RESOURCE:
-            return repr->attribute("rdf:resource");
-
-        case RDF_XML:
-            return "xml goes here";
-
-        case RDF_BAG:
-            /* clear the static string.  yucky. */
-            if (bag) g_free(bag);
-            bag = NULL;
-
-            temp = sp_repr_lookup_name ( repr, "rdf:Bag", 1 );
-            if ( temp == NULL ) {
-                /* backwards compatible: read contents */
-                temp = sp_repr_children(repr);
-                if ( temp == NULL ) return NULL;
-            
-                return temp->content();
-            }
-
-            for ( temp = sp_repr_children(temp) ;
-                  temp ;
-                  temp = sp_repr_next(temp) ) {
-                if (!strcmp(temp->name(),"rdf:li") &&
-                    temp->firstChild()) {
-                    const gchar * str = temp->firstChild()->content();
-                    if (bag) {
-                        holder = bag;
-                        bag = g_strconcat(holder, ", ", str, NULL);
-                        g_free(holder);
-                    }
-                    else {
-                        bag = g_strdup(str);
-                    }
-                }
-            }
-            return bag;
-
-        default:
-            break;
-    }
-    return NULL;
-}
-
-unsigned int
-rdf_set_repr_text ( Inkscape::XML::Node * repr,
-                    struct rdf_work_entity_t * entity,
-                    gchar const * text )
-{
-    g_return_val_if_fail ( repr != NULL, 0);
-    g_return_val_if_fail ( entity != NULL, 0);
-    g_return_val_if_fail ( text != NULL, 0);
-    gchar * str = NULL;
-    gchar** strlist = NULL;
-    int i;
-
-    Inkscape::XML::Node * temp=NULL;
-    Inkscape::XML::Node * child=NULL;
-    Inkscape::XML::Node * parent=repr;
-
-    Inkscape::XML::Document * xmldoc = parent->document();
-    g_return_val_if_fail (xmldoc != NULL, FALSE);
-
-    // set document's title element to the RDF title
-    if (!strcmp(entity->name, "title")) {
-        SPDocument *doc = SP_ACTIVE_DOCUMENT;
-        if(doc && doc->root) doc->root->setTitle(text);
-    }
-
-    switch (entity->datatype) {
-        case RDF_CONTENT:
-            temp = sp_repr_children(parent);
-            if ( temp == NULL ) {
-                temp = xmldoc->createTextNode( text );
-                g_return_val_if_fail (temp != NULL, FALSE);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-
-                return TRUE;
-            }
-            else {
-                temp->setContent(text);
-                return TRUE;
-            }
-
-        case RDF_AGENT:
-            temp = sp_repr_lookup_name ( parent, "cc:Agent", 1 );
-            if ( temp == NULL ) {
-                temp = xmldoc->createElement ( "cc:Agent" );
-                g_return_val_if_fail (temp != NULL, FALSE);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-            }
-            parent = temp;
-
-            temp = sp_repr_lookup_name ( parent, "dc:title", 1 );
-            if ( temp == NULL ) {
-                temp = xmldoc->createElement ( "dc:title" );
-                g_return_val_if_fail (temp != NULL, FALSE);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-            }
-            parent = temp;
-
-            temp = sp_repr_children(parent);
-            if ( temp == NULL ) {
-                temp = xmldoc->createTextNode( text );
-                g_return_val_if_fail (temp != NULL, FALSE);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-
-                return TRUE;
-            }
-            else {
-                temp->setContent(text);
-                               return TRUE;
-            }
-
-        case RDF_RESOURCE:
-            parent->setAttribute("rdf:resource", text );
-            return true;
-
-        case RDF_XML:
-            return 1;
-
-        case RDF_BAG:
-            /* find/create the rdf:Bag item */
-            temp = sp_repr_lookup_name ( parent, "rdf:Bag", 1 );
-            if ( temp == NULL ) {
-                /* backward compatibility: drop the dc:subject contents */
-                while ( (temp = sp_repr_children( parent )) ) {
-                    parent->removeChild(temp);
-                }
-
-                temp = xmldoc->createElement ( "rdf:Bag" );
-                g_return_val_if_fail (temp != NULL, FALSE);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-            }
-            parent = temp;
-
-            /* toss all the old list items */
-            while ( (temp = sp_repr_children( parent )) ) {
-                parent->removeChild(temp);
-            }
-
-            /* chop our list up on commas */
-            strlist = g_strsplit( text, ",", 0);
-
-            for (i = 0; (str = strlist[i]); i++) {
-                temp = xmldoc->createElement ( "rdf:li" );
-                g_return_val_if_fail (temp != NULL, 0);
-
-                parent->appendChild(temp);
-                Inkscape::GC::release(temp);
-
-                child = xmldoc->createTextNode( g_strstrip(str) );
-                g_return_val_if_fail (child != NULL, 0);
-
-                temp->appendChild(child);
-                Inkscape::GC::release(child);
-            }
-            g_strfreev( strlist );
-
-            return 1;
-
-        default:
-            break;
-    }
-    return 0;
-}
-
-Inkscape::XML::Node *
-rdf_get_rdf_root_repr ( SPDocument * doc, bool build )
-{
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
-
-    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-    g_return_val_if_fail (xmldoc != NULL, NULL);
-
-    Inkscape::XML::Node * rdf = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_RDF );
-
-    if (rdf == NULL) {
-        //printf("missing XML '%s'\n",XML_TAG_NAME_RDF);
-        if (!build) return NULL;
-
-        Inkscape::XML::Node * svg = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_SVG );
-        g_return_val_if_fail ( svg != NULL, NULL );
-
-        Inkscape::XML::Node * parent = sp_repr_lookup_name ( svg, XML_TAG_NAME_METADATA );
-        if ( parent == NULL ) {
-            parent = xmldoc->createElement( XML_TAG_NAME_METADATA );
-            g_return_val_if_fail ( parent != NULL, NULL);
-
-            svg->appendChild(parent);
-            Inkscape::GC::release(parent);
-        }
-
-        Inkscape::XML::Document * xmldoc = parent->document();
-        g_return_val_if_fail (xmldoc != NULL, FALSE);
-
-        rdf = xmldoc->createElement( XML_TAG_NAME_RDF );
-        g_return_val_if_fail (rdf != NULL, NULL);
-
-        parent->appendChild(rdf);
-        Inkscape::GC::release(rdf);
-    }
-
-    /*
-     * some implementations do not put RDF stuff inside <metadata>,
-     * so we need to check for it and add it if we don't see it
-     */
-    Inkscape::XML::Node * want_metadata = sp_repr_parent ( rdf );
-    g_return_val_if_fail (want_metadata != NULL, NULL);
-    if (strcmp( want_metadata->name(), XML_TAG_NAME_METADATA )) {
-            Inkscape::XML::Node * metadata = xmldoc->createElement( XML_TAG_NAME_METADATA );
-            g_return_val_if_fail (metadata != NULL, NULL);
-
-            /* attach the metadata node */
-            want_metadata->appendChild(metadata);
-            Inkscape::GC::release(metadata);
-
-            /* move the RDF into it */
-            Inkscape::GC::anchor(rdf);
-            sp_repr_unparent ( rdf );
-            metadata->appendChild(rdf);
-            Inkscape::GC::release(rdf);
-    }
-    
-    return rdf;
-}
-
-Inkscape::XML::Node *
-rdf_get_xml_repr( SPDocument * doc, gchar const * name, bool build )
-{
-    g_return_val_if_fail (name       != NULL, NULL);
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
-
-    Inkscape::XML::Node * rdf = rdf_get_rdf_root_repr ( doc, build );
-    if (!rdf) return NULL;
-
-    Inkscape::XML::Node * xml = sp_repr_lookup_name ( rdf, name );
-    if (xml == NULL) {
-        //printf("missing XML '%s'\n",name);
-        if (!build) return NULL;
-
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_val_if_fail (xmldoc != NULL, NULL);
-
-        xml = xmldoc->createElement( name );
-        g_return_val_if_fail (xml != NULL, NULL);
-
-        xml->setAttribute("rdf:about", "" );
-
-        rdf->appendChild(xml);
-        Inkscape::GC::release(xml);
-    }
-
-    return xml;
-}
-
-Inkscape::XML::Node *
-rdf_get_work_repr( SPDocument * doc, gchar const * name, bool build )
-{
-    g_return_val_if_fail (name       != NULL, NULL);
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
-
-    Inkscape::XML::Node * work = rdf_get_xml_repr ( doc, XML_TAG_NAME_WORK, build );
-    if (!work) return NULL;
-
-    Inkscape::XML::Node * item = sp_repr_lookup_name ( work, name, 1 );
-    if (item == NULL) {
-        //printf("missing XML '%s'\n",name);
-        if (!build) return NULL;
-
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_val_if_fail (xmldoc != NULL, NULL);
-
-        item = xmldoc->createElement( name );
-        g_return_val_if_fail (item != NULL, NULL);
-
-        work->appendChild(item);
-        Inkscape::GC::release(item);
-    }
-
-    return item;
-}
-
-
-
-/**
- *  \brief   Retrieves a known RDF/Work entity's contents from the document XML by name
- *  \return  A pointer to the entity's static contents as a string, or NULL if no entity exists
- *  \param   entity  The desired RDF/Work entity
- *  
- */
-const gchar *
-rdf_get_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity)
-{
-    g_return_val_if_fail (doc    != NULL, NULL);
-    if ( entity == NULL ) return NULL;
-    //printf("want '%s'\n",entity->title);
-    bool bIsTitle = !strcmp(entity->name, "title");
-
-    Inkscape::XML::Node * item;
-    if ( entity->datatype == RDF_XML ) {
-        item = rdf_get_xml_repr ( doc, entity->tag, FALSE );
-    }
-    else {
-        item = rdf_get_work_repr( doc, entity->tag, bIsTitle ); // build title if necessary
-    }
-    if ( item == NULL ) return NULL;
-    const gchar * result = rdf_get_repr_text ( item, entity );
-    if(!result && bIsTitle && doc->root) {         // if RDF title not set
-        result = doc->root->title();               // get the document's <title>
-        rdf_set_work_entity(doc, entity, result);  // and set the RDF
-    }
-    //printf("found '%s' == '%s'\n", entity->title, result );
-    return result;
-}
-
-/**
- *  \brief   Stores a string into a named RDF/Work entity in the document XML
- *  \param   entity The desired RDF/Work entity to replace
- *  \param   string The string to replace the entity contents with
- *  
- */
-unsigned int
-rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity,
-                    const gchar * text)
-{
-    g_return_val_if_fail ( entity != NULL, 0 );
-    if (text == NULL) {
-        // FIXME: on a "NULL" text, delete the entity.  For now, blank it.
-        text="";
-    }
-
-    /*
-    printf("changing '%s' (%s) to '%s'\n",
-        entity->title,
-        entity->tag,
-        text);
-    */
-
-    Inkscape::XML::Node * item = rdf_get_work_repr( doc, entity->tag, TRUE );
-    g_return_val_if_fail ( item != NULL, 0 );
-
-    return rdf_set_repr_text ( item, entity, text );
-}
-
-#undef DEBUG_MATCH
-
-static bool
-rdf_match_license(Inkscape::XML::Node const *repr, struct rdf_license_t const *license)
-{
-    g_assert ( repr != NULL );
-    g_assert ( license != NULL );
-
-    bool result=TRUE;
-#ifdef DEBUG_MATCH
-    printf("checking against '%s'\n",license->name);
-#endif
-
-    int count = 0;
-    for (struct rdf_double_t const *details = license->details;
-         details->name; details++ ) {
-        count++;
-    }
-    bool * matched = (bool*)calloc(count,sizeof(bool));
-
-    for (Inkscape::XML::Node const *current = sp_repr_children(repr);
-         current;
-         current = sp_repr_next ( current ) ) {
-
-        gchar const * attr = current->attribute("rdf:resource");
-        if ( attr == NULL ) continue;
-
-#ifdef DEBUG_MATCH
-        printf("\texamining '%s' => '%s'\n", current->name(), attr);
-#endif
-
-        bool found_match=FALSE;
-        for (int i=0; i<count; i++) {
-            // skip already matched items
-            if (matched[i]) continue;
-
-#ifdef DEBUG_MATCH
-            printf("\t\t'%s' vs '%s'\n", current->name(), license->details[i].name);
-            printf("\t\t'%s' vs '%s'\n", attr, license->details[i].resource);
-#endif
-
-            if (!strcmp( current->name(),
-                         license->details[i].name ) &&
-                !strcmp( attr,
-                         license->details[i].resource )) {
-                matched[i]=TRUE;
-                found_match=TRUE;
-#ifdef DEBUG_MATCH
-                printf("\t\tgood!\n");
-#endif
-                break;
-            }
-        }
-        if (!found_match) {
-            // if we checked each known item of the license
-            // and didn't find it, we must abort
-            result=FALSE;
-#ifdef DEBUG_MATCH
-            printf("\t\tno '%s' element matched XML (bong)!\n",license->name);
-#endif
-            break;
-        }
-    }
-#ifdef DEBUG_MATCH
-    if (result) printf("\t\tall XML found matching elements!\n");
-#endif
-    for (int i=0; result && i<count; i++) {
-        // scan looking for an unmatched item
-        if (matched[i]==0) {
-            result=FALSE;
-#ifdef DEBUG_MATCH
-            printf("\t\tnot all '%s' elements used to match (bong)!\n", license->name);
-#endif
-        }
-    }
-
-#ifdef DEBUG_MATCH
-    printf("\t\tall '%s' elements used to match!\n",license->name);
-#endif
-
-    free(matched);
-
-#ifdef DEBUG_MATCH
-    if (result) printf("matched '%s'\n",license->name);
-#endif
-    return result;
-}
-
-/**
- *  \brief   Attempts to match and retrieve a known RDF/License from the document XML
- *  \return  A pointer to the static RDF license structure
- *  
- */
-struct rdf_license_t *
-rdf_get_license(SPDocument * document)
-{
-    Inkscape::XML::Node const *repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, FALSE );
-    if (repr) {
-        for (struct rdf_license_t * license = rdf_licenses;
-             license->name; license++ ) {
-            if ( rdf_match_license ( repr, license ) ) return license;
-        }
-    }
-#ifdef DEBUG_MATCH
-    else {
-        printf("no license XML\n");
-    }
-#endif
-    return NULL;
-}
-
-/**
- *  \brief   Stores an RDF/License XML in the document XML
- *  \param   document  Which document to update
- *  \param   license   The desired RDF/License structure to store; NULL drops old license, so can be used for proprietary license. 
- *  
- */
-void
-rdf_set_license(SPDocument * doc, struct rdf_license_t const * license)
-{
-    // drop old license section
-    Inkscape::XML::Node * repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, FALSE );
-    if (repr) sp_repr_unparent(repr);
-
-    if (!license) return;
-
-    // build new license section
-    repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, TRUE );
-    g_assert ( repr );
-
-    repr->setAttribute("rdf:about", license->uri );
-
-    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-    g_return_if_fail (xmldoc != NULL);
-
-    for (struct rdf_double_t const * detail = license->details;
-         detail->name; detail++) {
-        Inkscape::XML::Node * child = xmldoc->createElement( detail->name );
-        g_assert ( child != NULL );
-
-        child->setAttribute("rdf:resource", detail->resource );
-        repr->appendChild(child);
-        Inkscape::GC::release(child);
-    }
-}
-
-struct rdf_entity_default_t {
-    gchar const * name;
-    gchar const * text;
-};
-struct rdf_entity_default_t rdf_defaults[] = {
-    { "format",      "image/svg+xml", },
-    { "type",        "http://purl.org/dc/dcmitype/StillImage", },
-    { NULL,          NULL, }
-};
-
-void
-rdf_set_defaults ( SPDocument * doc )
-{
-    g_assert ( doc != NULL );
-
-    // Create metadata node if it doesn't already exist
-    if (!sp_item_group_get_child_by_name ((SPGroup *) doc->root, NULL,
-                                          XML_TAG_NAME_METADATA)) {
-        // create repr
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_if_fail (xmldoc != NULL);
-        Inkscape::XML::Node * rnew = xmldoc->createElement (XML_TAG_NAME_METADATA);
-        // insert into the document
-        doc->rroot->addChild(rnew, NULL);
-        // clean up
-        Inkscape::GC::release(rnew);
-    }
-
-    /* install defaults */
-    for ( struct rdf_entity_default_t * rdf_default = rdf_defaults;
-          rdf_default->name;
-          rdf_default++) {
-        struct rdf_work_entity_t * entity = rdf_find_entity ( rdf_default->name );
-        g_assert ( entity != NULL );
-
-        if ( rdf_get_work_entity ( doc, entity ) == NULL ) {
-            rdf_set_work_entity ( doc, entity, rdf_default->text );
-        }
-    }
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/rdf.h b/src/dialogs/rdf.h
deleted file mode 100644 (file)
index a98f5a1..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/** @file
- * @brief headers for RDF types
- */
-/* Authors:
- *  Kees Cook <kees@outflux.net>
- *
- * Copyright (C) 2004 Authors
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifndef _RDF_H_
-#define _RDF_H_
-
-#include <glib.h>
-#include <glibmm/i18n.h>
-#include "document.h"
-
-// yeah, it's not a triple yet...
-/**
- * \brief Holds license name/resource doubles for rdf_license_t entries
- */
-struct rdf_double_t {
-    gchar const *name;
-    gchar const *resource;
-};
-
-/**
- * \brief Holds license name and RDF information
- */
-struct rdf_license_t {
-    gchar const *name;        /* localized name of this license */
-    gchar const *uri;         /* URL for the RDF/Work/license element */
-    struct rdf_double_t *details; /* the license details */
-//    gchar const *fragment;    /* XML contents for the RDF/License tag */
-};
-
-extern rdf_license_t rdf_licenses [];
-
-/**
- * \brief Describes how a given RDF entity is stored in XML
- */
-enum RDFType {
-    RDF_CONTENT,  // direct between-XML-tags content
-    RDF_AGENT,    // requires the "Agent" hierarchy before doing content
-    RDF_RESOURCE, // stored in "rdf:resource" element
-    RDF_XML,      // literal XML
-    RDF_BAG       // rdf:Bag resources
-};
-
-/**
- * \brief Describes how a given RDF entity should be edited
- */
-enum RDF_Format {
-    RDF_FORMAT_LINE,          // uses single line data (GtkEntry)
-    RDF_FORMAT_MULTILINE,     // uses multiline data (GtkTextView)
-    RDF_FORMAT_SPECIAL        // uses some other edit methods
-};
-
-enum RDF_Editable {
-    RDF_EDIT_GENERIC,       // editable via generic widgets
-    RDF_EDIT_SPECIAL,       // special widgets are needed
-    RDF_EDIT_HARDCODED      // isn't editable
-};
-
-/**
- * \brief Holds known RDF/Work tags
- */
-struct rdf_work_entity_t {
-    char const *name;       /* unique name of this entity for internal reference */
-    gchar const *title;      /* localized title of this entity for data entry */
-    gchar const *tag;        /* namespace tag for the RDF/Work element */
-    RDFType datatype;   /* how to extract/inject the RDF information */
-    gchar const *tip;        /* tool tip to explain the meaning of the entity */
-    RDF_Format format;  /* in what format is this data edited? */
-    RDF_Editable editable;/* in what way is the data editable? */
-};
-
-extern rdf_work_entity_t rdf_work_entities [];
-
-/**
- * \brief Generic collection of RDF information for the RDF debug function
- */
-struct rdf_t {
-    gchar*                work_title;
-    gchar*                work_date;
-    gchar*                work_creator;
-    gchar*                work_owner;
-    gchar*                work_publisher;
-    gchar*                work_type;
-    gchar*                work_source;
-    gchar*                work_subject;
-    gchar*                work_description;
-    struct rdf_license_t* license;
-};
-
-struct rdf_work_entity_t * rdf_find_entity(gchar const * name);
-
-const gchar * rdf_get_work_entity(SPDocument * doc,
-                                  struct rdf_work_entity_t * entity);
-unsigned int  rdf_set_work_entity(SPDocument * doc,
-                                  struct rdf_work_entity_t * entity,
-                                  const gchar * text);
-
-struct rdf_license_t * rdf_get_license(SPDocument * doc);
-void                   rdf_set_license(SPDocument * doc,
-                                       struct rdf_license_t const * license);
-
-void rdf_set_defaults ( SPDocument * doc );
-
-#endif // _RDF_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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/sp-attribute-widget.cpp b/src/dialogs/sp-attribute-widget.cpp
deleted file mode 100644 (file)
index de14fc1..0000000
+++ /dev/null
@@ -1,790 +0,0 @@
-/** @file
- * @brief Widget that listens and modifies repr attributes
- */
-/* Authors:
- *  Lauris Kaplinski <lauris@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc.
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <gtk/gtktable.h>
-#include <gtk/gtklabel.h>
-#include "xml/repr.h"
-#include "macros.h"
-#include "document.h"
-#include "sp-object.h"
-#include <glibmm/i18n.h>
-
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
-
-#include "sp-attribute-widget.h"
-
-static void sp_attribute_widget_class_init (SPAttributeWidgetClass *klass);
-static void sp_attribute_widget_init (SPAttributeWidget *widget);
-static void sp_attribute_widget_destroy (GtkObject *object);
-
-static void sp_attribute_widget_changed (GtkEditable *editable);
-
-static void sp_attribute_widget_object_modified ( SPObject *object,
-                                                  guint flags,
-                                                  SPAttributeWidget *spaw );
-static void sp_attribute_widget_object_release ( SPObject *object,
-                                                 SPAttributeWidget *spaw );
-
-static GtkEntryClass *parent_class;
-
-
-
-
-GType sp_attribute_widget_get_type(void)
-{
-    static GtkType type = 0;
-    if (!type) {
-        GTypeInfo info = {
-            sizeof(SPAttributeWidgetClass),
-            0, // base_init
-            0, // base_finalize
-            (GClassInitFunc)sp_attribute_widget_class_init,
-            0, // class_finalize
-            0, // class_data
-            sizeof(SPAttributeWidget),
-            0, // n_preallocs
-            (GInstanceInitFunc)sp_attribute_widget_init,
-            0 // value_table
-        };
-        type = g_type_register_static(GTK_TYPE_ENTRY, "SPAttributeWidget", &info, static_cast<GTypeFlags>(0));
-    }
-    return type;
-} // end of sp_attribute_widget_get_type()
-
-
-
-static void
-sp_attribute_widget_class_init (SPAttributeWidgetClass *klass)
-{
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-    GtkEditableClass *editable_class;
-
-    object_class = GTK_OBJECT_CLASS (klass);
-    widget_class = GTK_WIDGET_CLASS (klass);
-    editable_class = GTK_EDITABLE_CLASS (klass);
-
-    parent_class = (GtkEntryClass*)gtk_type_class (GTK_TYPE_ENTRY);
-
-    object_class->destroy = sp_attribute_widget_destroy;
-
-    editable_class->changed = sp_attribute_widget_changed;
-
-} // end of sp_attribute_widget_class_init()
-
-
-
-static void
-sp_attribute_widget_init (SPAttributeWidget *spaw)
-{
-    spaw->blocked = FALSE;
-    spaw->hasobj = FALSE;
-
-    spaw->src.object = NULL;
-
-    spaw->attribute = NULL;
-
-    new (&spaw->modified_connection) sigc::connection();
-    new (&spaw->release_connection) sigc::connection();
-}
-
-
-
-static void
-sp_attribute_widget_destroy (GtkObject *object)
-{
-
-    SPAttributeWidget *spaw;
-
-    spaw = SP_ATTRIBUTE_WIDGET (object);
-
-    if (spaw->attribute) {
-        g_free (spaw->attribute);
-        spaw->attribute = NULL;
-    }
-
-
-    if (spaw->hasobj) {
-
-        if (spaw->src.object) {
-            spaw->modified_connection.disconnect();
-            spaw->release_connection.disconnect();
-            spaw->src.object = NULL;
-        }
-    } else {
-
-        if (spaw->src.repr) {
-            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
-        }
-    } // end of if()
-
-    spaw->modified_connection.~connection();
-    spaw->release_connection.~connection();
-
-    ((GtkObjectClass *) parent_class)->destroy (object);
-
-}
-
-
-
-static void
-sp_attribute_widget_changed (GtkEditable *editable)
-{
-
-    SPAttributeWidget *spaw;
-
-    spaw = SP_ATTRIBUTE_WIDGET (editable);
-
-    if (!spaw->blocked) {
-
-        const gchar *text;
-        spaw->blocked = TRUE;
-        text = gtk_entry_get_text (GTK_ENTRY (spaw));
-        if (!*text)
-            text = NULL;
-
-        if (spaw->hasobj && spaw->src.object) {
-        
-            SP_OBJECT_REPR (spaw->src.object)->setAttribute(spaw->attribute, text, false);
-            sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object), SP_VERB_NONE,
-                              _("Set attribute"));
-
-        } else if (spaw->src.repr) {
-
-            spaw->src.repr->setAttribute(spaw->attribute, text, false);
-            /* TODO: Warning! Undo will not be flushed in given case */
-        }
-        spaw->blocked = FALSE;
-    }
-
-} // end of sp_attribute_widget_changed()
-
-
-
-GtkWidget *
-sp_attribute_widget_new ( SPObject *object, const gchar *attribute )
-{
-    SPAttributeWidget *spaw;
-
-    g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
-    g_return_val_if_fail (!object || attribute, NULL);
-
-    spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
-
-    sp_attribute_widget_set_object (spaw, object, attribute);
-
-    return GTK_WIDGET (spaw);
-
-} // end of sp_attribute_widget_new()
-
-
-
-GtkWidget *
-sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute )
-{
-    SPAttributeWidget *spaw;
-
-    spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
-
-    sp_attribute_widget_set_repr (spaw, repr, attribute);
-
-    return GTK_WIDGET (spaw);
-}
-
-
-
-void
-sp_attribute_widget_set_object ( SPAttributeWidget *spaw,
-                                 SPObject *object,
-                                 const gchar *attribute )
-{
-
-    g_return_if_fail (spaw != NULL);
-    g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
-    g_return_if_fail (!object || SP_IS_OBJECT (object));
-    g_return_if_fail (!object || attribute);
-    g_return_if_fail (attribute != NULL);
-
-    if (spaw->attribute) {
-        g_free (spaw->attribute);
-        spaw->attribute = NULL;
-    }
-
-    if (spaw->hasobj) {
-
-        if (spaw->src.object) {
-            spaw->modified_connection.disconnect();
-            spaw->release_connection.disconnect();
-            spaw->src.object = NULL;
-        }
-    } else {
-
-        if (spaw->src.repr) {
-            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
-        }
-    }
-
-    spaw->hasobj = TRUE;
-
-    if (object) {
-        const gchar *val;
-
-        spaw->blocked = TRUE;
-        spaw->src.object = object;
-
-        spaw->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_widget_object_modified), spaw));
-        spaw->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_widget_object_release), spaw));
-
-        spaw->attribute = g_strdup (attribute);
-
-        val = SP_OBJECT_REPR (object)->attribute(attribute);
-        gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
-        spaw->blocked = FALSE;
-    }
-
-    gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL));
-
-} // end of sp_attribute_widget_set_object()
-
-
-
-void
-sp_attribute_widget_set_repr ( SPAttributeWidget *spaw,
-                               Inkscape::XML::Node *repr,
-                               const gchar *attribute )
-{
-
-    g_return_if_fail (spaw != NULL);
-    g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
-    g_return_if_fail (attribute != NULL);
-
-    if (spaw->attribute) {
-        g_free (spaw->attribute);
-        spaw->attribute = NULL;
-    }
-
-    if (spaw->hasobj) {
-
-        if (spaw->src.object) {
-            spaw->modified_connection.disconnect();
-            spaw->release_connection.disconnect();
-            spaw->src.object = NULL;
-        }
-    } else {
-
-        if (spaw->src.repr) {
-            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
-        }
-    }
-
-    spaw->hasobj = FALSE;
-
-    if (repr) {
-        const gchar *val;
-
-        spaw->blocked = TRUE;
-        spaw->src.repr = Inkscape::GC::anchor(repr);
-        spaw->attribute = g_strdup (attribute);
-
-        val = repr->attribute(attribute);
-        gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
-        spaw->blocked = FALSE;
-    }
-
-    gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL));
-
-} // end of sp_attribute_widget_set_repr()
-
-
-
-static void
-sp_attribute_widget_object_modified ( SPObject */*object*/,
-                                      guint flags,
-                                      SPAttributeWidget *spaw )
-{
-
-    if (flags && SP_OBJECT_MODIFIED_FLAG) {
-
-        const gchar *val, *text;
-        val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
-        text = gtk_entry_get_text (GTK_ENTRY (spaw));
-
-        if (val || text) {
-
-            if (!val || !text || strcmp (val, text)) {
-                /* We are different */
-                spaw->blocked = TRUE;
-                gtk_entry_set_text ( GTK_ENTRY (spaw),
-                                     val ? val : (const gchar *) "");
-                spaw->blocked = FALSE;
-            } // end of if()
-
-        } // end of if()
-
-    } //end of if()
-
-} // end of sp_attribute_widget_object_modified()
-
-
-
-static void
-sp_attribute_widget_object_release ( SPObject */*object*/,
-                                     SPAttributeWidget *spaw )
-{
-    sp_attribute_widget_set_object (spaw, NULL, NULL);
-}
-
-
-
-/* SPAttributeTable */
-
-static void sp_attribute_table_class_init (SPAttributeTableClass *klass);
-static void sp_attribute_table_init (SPAttributeTable *widget);
-static void sp_attribute_table_destroy (GtkObject *object);
-
-static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw);
-static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw);
-static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat);
-
-static GtkVBoxClass *table_parent_class;
-
-
-
-
-GType sp_attribute_table_get_type(void)
-{
-    static GtkType type = 0;
-    if (!type) {
-        GTypeInfo info = {
-            sizeof(SPAttributeTableClass),
-            0, // base_init
-            0, // base_finalize
-            (GClassInitFunc)sp_attribute_table_class_init,
-            0, // class_finalize
-            0, // class_data
-            sizeof(SPAttributeTable),
-            0, // n_preallocs
-            (GInstanceInitFunc)sp_attribute_table_init,
-            0 // value_table
-        };
-        type = g_type_register_static(GTK_TYPE_VBOX, "SPAttributeTable", &info, static_cast<GTypeFlags>(0));
-    }
-    return type;
-} // end of sp_attribute_table_get_type()
-
-
-
-static void
-sp_attribute_table_class_init (SPAttributeTableClass *klass)
-{
-    GtkObjectClass *object_class;
-    GtkWidgetClass *widget_class;
-
-    object_class = GTK_OBJECT_CLASS (klass);
-    widget_class = GTK_WIDGET_CLASS (klass);
-
-    table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
-
-    object_class->destroy = sp_attribute_table_destroy;
-
-} // end of sp_attribute_table_class_init()
-
-
-
-static void
-sp_attribute_table_init ( SPAttributeTable *spat )
-{
-    spat->blocked = FALSE;
-    spat->hasobj = FALSE;
-    spat->table = NULL;
-    spat->src.object = NULL;
-    spat->num_attr = 0;
-    spat->attributes = NULL;
-    spat->entries = NULL;
-
-    new (&spat->modified_connection) sigc::connection();
-    new (&spat->release_connection) sigc::connection();
-}
-
-static void
-sp_attribute_table_destroy ( GtkObject *object )
-{
-    SPAttributeTable *spat;
-
-    spat = SP_ATTRIBUTE_TABLE (object);
-
-    if (spat->attributes) {
-        gint i;
-        for (i = 0; i < spat->num_attr; i++) {
-            g_free (spat->attributes[i]);
-        }
-        g_free (spat->attributes);
-        spat->attributes = NULL;
-    }
-
-    if (spat->hasobj) {
-
-        if (spat->src.object) {
-            spat->modified_connection.disconnect();
-            spat->release_connection.disconnect();
-            spat->src.object = NULL;
-        }
-    } else {
-        if (spat->src.repr) {
-            spat->src.repr = Inkscape::GC::release(spat->src.repr);
-        }
-    } // end of if()
-
-    spat->modified_connection.~connection();
-    spat->release_connection.~connection();
-
-    if (spat->entries) {
-        g_free (spat->entries);
-        spat->entries = NULL;
-    }
-
-    spat->table = NULL;
-
-    if (((GtkObjectClass *) table_parent_class)->destroy) {
-        (* ((GtkObjectClass *) table_parent_class)->destroy) (object);
-    }
-
-} // end of sp_attribute_table_destroy()
-
-
-GtkWidget *
-sp_attribute_table_new ( SPObject *object,
-                         gint num_attr,
-                         const gchar **labels,
-                         const gchar **attributes )
-{
-    SPAttributeTable *spat;
-
-    g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
-    g_return_val_if_fail (!object || (num_attr > 0), NULL);
-    g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
-
-    spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
-
-    sp_attribute_table_set_object (spat, object, num_attr, labels, attributes);
-
-    return GTK_WIDGET (spat);
-
-} // end of sp_attribute_table_new()
-
-
-
-GtkWidget *
-sp_attribute_table_new_repr ( Inkscape::XML::Node *repr,
-                              gint num_attr,
-                              const gchar **labels,
-                              const gchar **attributes )
-{
-    SPAttributeTable *spat;
-
-    g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
-
-    spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
-
-    sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes);
-
-    return GTK_WIDGET (spat);
-
-} // end of sp_attribute_table_new_repr()
-
-
-
-#define XPAD 4
-#define YPAD 0
-
-void
-sp_attribute_table_set_object ( SPAttributeTable *spat,
-                                SPObject *object,
-                                gint num_attr,
-                                const gchar **labels,
-                                const gchar **attributes )
-{
-
-    g_return_if_fail (spat != NULL);
-    g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
-    g_return_if_fail (!object || SP_IS_OBJECT (object));
-    g_return_if_fail (!object || (num_attr > 0));
-    g_return_if_fail (!num_attr || (labels && attributes));
-
-    if (spat->table) {
-        gtk_widget_destroy (spat->table);
-        spat->table = NULL;
-    }
-
-    if (spat->attributes) {
-        gint i;
-        for (i = 0; i < spat->num_attr; i++) {
-            g_free (spat->attributes[i]);
-        }
-        g_free (spat->attributes);
-        spat->attributes = NULL;
-    }
-
-    if (spat->entries) {
-        g_free (spat->entries);
-        spat->entries = NULL;
-    }
-
-    if (spat->hasobj) {
-        if (spat->src.object) {
-            spat->modified_connection.disconnect();
-            spat->release_connection.disconnect();
-            spat->src.object = NULL;
-        }
-    } else {
-        if (spat->src.repr) {
-            spat->src.repr = Inkscape::GC::release(spat->src.repr);
-        }
-    }
-
-    spat->hasobj = TRUE;
-
-    if (object) {
-        gint i;
-
-        spat->blocked = TRUE;
-
-        /* Set up object */
-        spat->src.object = object;
-        spat->num_attr = num_attr;
-
-        spat->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_table_object_modified), spat));
-        spat->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_table_object_release), spat));
-
-        /* Create table */
-        spat->table = gtk_table_new (num_attr, 2, FALSE);
-        gtk_container_add (GTK_CONTAINER (spat), spat->table);
-        /* Arrays */
-        spat->attributes = g_new0 (gchar *, num_attr);
-        spat->entries = g_new0 (GtkWidget *, num_attr);
-        /* Fill rows */
-        for (i = 0; i < num_attr; i++) {
-            GtkWidget *w;
-            const gchar *val;
-
-            spat->attributes[i] = g_strdup (attributes[i]);
-            w = gtk_label_new (_(labels[i]));
-            gtk_widget_show (w);
-            gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
-            gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
-                               GTK_FILL,
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               XPAD, YPAD );
-            w = gtk_entry_new ();
-            gtk_widget_show (w);
-            val = SP_OBJECT_REPR (object)->attribute(attributes[i]);
-            gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
-            gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               XPAD, YPAD );
-            spat->entries[i] = w;
-            g_signal_connect ( G_OBJECT (w), "changed",
-                               G_CALLBACK (sp_attribute_table_entry_changed),
-                               spat );
-        }
-        /* Show table */
-        gtk_widget_show (spat->table);
-
-        spat->blocked = FALSE;
-    }
-
-    gtk_widget_set_sensitive ( GTK_WIDGET (spat),
-                               (spat->src.object != NULL) );
-
-} // end of sp_attribute_table_set_object()
-
-
-
-void
-sp_attribute_table_set_repr ( SPAttributeTable *spat,
-                              Inkscape::XML::Node *repr,
-                              gint num_attr,
-                              const gchar **labels,
-                              const gchar **attributes )
-{
-    g_return_if_fail (spat != NULL);
-    g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
-    g_return_if_fail (!num_attr || (labels && attributes));
-
-    if (spat->table) {
-        gtk_widget_destroy (spat->table);
-        spat->table = NULL;
-    }
-
-    if (spat->attributes) {
-        gint i;
-        for (i = 0; i < spat->num_attr; i++) {
-            g_free (spat->attributes[i]);
-        }
-        g_free (spat->attributes);
-        spat->attributes = NULL;
-    }
-
-    if (spat->entries) {
-        g_free (spat->entries);
-        spat->entries = NULL;
-    }
-
-    if (spat->hasobj) {
-        if (spat->src.object) {
-            spat->modified_connection.disconnect();
-            spat->release_connection.disconnect();
-            spat->src.object = NULL;
-        }
-    } else {
-        if (spat->src.repr) {
-            spat->src.repr = Inkscape::GC::release(spat->src.repr);
-        }
-    }
-
-    spat->hasobj = FALSE;
-
-    if (repr) {
-        gint i;
-
-        spat->blocked = TRUE;
-
-        /* Set up repr */
-        spat->src.repr = Inkscape::GC::anchor(repr);
-        spat->num_attr = num_attr;
-        /* Create table */
-        spat->table = gtk_table_new (num_attr, 2, FALSE);
-        gtk_container_add (GTK_CONTAINER (spat), spat->table);
-        /* Arrays */
-        spat->attributes = g_new0 (gchar *, num_attr);
-        spat->entries = g_new0 (GtkWidget *, num_attr);
-
-        /* Fill rows */
-        for (i = 0; i < num_attr; i++) {
-            GtkWidget *w;
-            const gchar *val;
-
-            spat->attributes[i] = g_strdup (attributes[i]);
-            w = gtk_label_new (labels[i]);
-            gtk_widget_show (w);
-            gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
-            gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
-                               GTK_FILL,
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               XPAD, YPAD );
-            w = gtk_entry_new ();
-            gtk_widget_show (w);
-            val = repr->attribute(attributes[i]);
-            gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
-            gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
-                               XPAD, YPAD );
-            spat->entries[i] = w;
-            g_signal_connect ( G_OBJECT (w), "changed",
-                               G_CALLBACK (sp_attribute_table_entry_changed),
-                               spat );
-        }
-        /* Show table */
-        gtk_widget_show (spat->table);
-
-        spat->blocked = FALSE;
-    }
-
-    gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL));
-
-} // end of sp_attribute_table_set_repr()
-
-
-
-static void
-sp_attribute_table_object_modified ( SPObject */*object*/,
-                                     guint flags,
-                                     SPAttributeTable *spat )
-{
-    if (flags && SP_OBJECT_MODIFIED_FLAG)
-    {
-        gint i;
-        for (i = 0; i < spat->num_attr; i++) {
-            const gchar *val, *text;
-            val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
-            text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
-            if (val || text) {
-                if (!val || !text || strcmp (val, text)) {
-                    /* We are different */
-                    spat->blocked = TRUE;
-                    gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]),
-                                         val ? val : (const gchar *) "");
-                    spat->blocked = FALSE;
-                }
-            }
-        }
-    } // end of if()
-
-} // end of sp_attribute_table_object_modified()
-
-
-
-static void
-sp_attribute_table_object_release (SPObject */*object*/, SPAttributeTable *spat)
-{
-    sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL);
-}
-
-
-
-static void
-sp_attribute_table_entry_changed ( GtkEditable *editable,
-                                   SPAttributeTable *spat )
-{
-    if (!spat->blocked)
-    {
-        gint i;
-        for (i = 0; i < spat->num_attr; i++) {
-
-            if (GTK_WIDGET (editable) == spat->entries[i]) {
-                const gchar *text;
-                spat->blocked = TRUE;
-                text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
-
-                if (!*text)
-                    text = NULL;
-
-                if (spat->hasobj && spat->src.object) {
-                    SP_OBJECT_REPR (spat->src.object)->setAttribute(spat->attributes[i], text, false);
-                    sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object), SP_VERB_NONE,
-                                      _("Set attribute"));
-
-                } else if (spat->src.repr) {
-
-                    spat->src.repr->setAttribute(spat->attributes[i], text, false);
-                    /* TODO: Warning! Undo will not be flushed in given case */
-                }
-                spat->blocked = FALSE;
-                return;
-            }
-        }
-        g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__);
-    } // end of if()
-
-} // end of sp_attribute_table_entry_changed()
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/sp-attribute-widget.h b/src/dialogs/sp-attribute-widget.h
deleted file mode 100644 (file)
index 01da29b..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/** @file
- * @brief Widget that listens and modifies repr attributes
- */
-/* Authors:
- *  Lauris Kaplinski <lauris@kaplinski.com>
- *
- * Copyright (C) 2002 authors
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Licensed under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H
-#define SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H
-
-#include <glib.h>
-#include <sigc++/connection.h>
-
-#define SP_TYPE_ATTRIBUTE_WIDGET (sp_attribute_widget_get_type ())
-#define SP_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidget))
-#define SP_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidgetClass))
-#define SP_IS_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_WIDGET))
-#define SP_IS_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_WIDGET))
-
-#define SP_TYPE_ATTRIBUTE_TABLE (sp_attribute_table_get_type ())
-#define SP_ATTRIBUTE_TABLE(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTable))
-#define SP_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTableClass))
-#define SP_IS_ATTRIBUTE_TABLE(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_TABLE))
-#define SP_IS_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_TABLE))
-
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-
-struct SPAttributeWidget;
-struct SPAttributeWidgetClass;
-
-struct SPAttributeTable;
-struct SPAttributeTableClass;
-
-#include <gtk/gtkentry.h>
-#include <gtk/gtkvbox.h>
-
-#include <forward.h>
-
-struct SPAttributeWidget {
-    GtkEntry entry;
-    guint blocked : 1;
-    guint hasobj : 1;
-    union {
-        SPObject *object;
-        Inkscape::XML::Node *repr;
-    } src;
-    gchar *attribute;
-
-    sigc::connection modified_connection;
-    sigc::connection release_connection;
-};
-
-struct SPAttributeWidgetClass {
-    GtkEntryClass entry_class;
-};
-
-GtkType sp_attribute_widget_get_type (void);
-
-GtkWidget *sp_attribute_widget_new (SPObject *object, const gchar *attribute);
-GtkWidget *sp_attribute_widget_new_repr (Inkscape::XML::Node *repr, const gchar *attribute);
-
-void sp_attribute_widget_set_object ( SPAttributeWidget *spw, 
-                                      SPObject *object, 
-                                      const gchar *attribute );
-void sp_attribute_widget_set_repr ( SPAttributeWidget *spw, 
-                                    Inkscape::XML::Node *repr, 
-                                    const gchar *attribute );
-
-/* SPAttributeTable */
-
-struct SPAttributeTable {
-    GtkVBox vbox;
-    guint blocked : 1;
-    guint hasobj : 1;
-    GtkWidget *table;
-    union {
-        SPObject *object;
-        Inkscape::XML::Node *repr;
-    } src;
-    gint num_attr;
-    gchar **attributes;
-    GtkWidget **entries;
-
-    sigc::connection modified_connection;
-    sigc::connection release_connection;
-};
-
-struct SPAttributeTableClass {
-    GtkEntryClass entry_class;
-};
-
-GtkType sp_attribute_table_get_type (void);
-
-GtkWidget *sp_attribute_table_new ( SPObject *object, gint num_attr, 
-                                    const gchar **labels, 
-                                    const gchar **attributes );
-GtkWidget *sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, gint num_attr, 
-                                         const gchar **labels, 
-                                         const gchar **attributes );
-void sp_attribute_table_set_object ( SPAttributeTable *spw, 
-                                     SPObject *object, gint num_attr, 
-                                     const gchar **labels, 
-                                     const gchar **attrs );
-void sp_attribute_table_set_repr ( SPAttributeTable *spw, 
-                                   Inkscape::XML::Node *repr, gint num_attr, 
-                                   const gchar **labels, 
-                                   const gchar **attrs );
-
-#endif
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp
deleted file mode 100644 (file)
index 566ee51..0000000
+++ /dev/null
@@ -1,1838 +0,0 @@
-/** @file
- * @brief  Stroke style dialog
- */
-/* Authors:
- *   Lauris Kaplinski <lauris@kaplinski.com>
- *   Bryce Harrington <brycehar@bryceharrington.org>
- *   bulia byak <buliabyak@users.sf.net>
- *   Maximilian Albert <maximilian.albert@gmail.com>
- *   Josh Andler <scislac@users.sf.net>
- *
- * Copyright (C) 2001-2005 authors
- * Copyright (C) 2001 Ximian, Inc.
- * Copyright (C) 2004 John Cliff
- * Copyright (C) 2008 Maximilian Albert (gtkmm-ification)
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#define noSP_SS_VERBOSE
-
-#include <glib/gmem.h>
-#include <gtk/gtk.h>
-#include <glibmm/i18n.h>
-
-#include "desktop-handles.h"
-#include "desktop-style.h"
-#include "dialogs/dialog-events.h"
-#include "display/nr-arena.h"
-#include "display/nr-arena-item.h"
-#include "document-private.h"
-#include "gradient-chemistry.h"
-#include "helper/stock-items.h"
-#include "helper/unit-menu.h"
-#include "helper/units.h"
-#include "inkscape.h"
-#include "io/sys.h"
-#include "marker.h"
-#include "path-prefix.h"
-#include "selection.h"
-#include "sp-linear-gradient.h"
-#include "sp-namedview.h"
-#include "sp-pattern.h"
-#include "sp-radial-gradient.h"
-#include "sp-rect.h"
-#include "sp-text.h"
-#include "style.h"
-#include "svg/css-ostringstream.h"
-#include "ui/cache/svg_preview_cache.h"
-#include "ui/icon-names.h"
-#include "widgets/dash-selector.h"
-#include "widgets/icon.h"
-#include "widgets/paint-selector.h"
-#include "widgets/sp-widget.h"
-#include "widgets/spw-utilities.h"
-#include "xml/repr.h"
-
-#include "dialogs/stroke-style.h"
-
-
-/* Paint */
-
-static void sp_stroke_style_paint_selection_modified (SPWidget *spw, Inkscape::Selection *selection, guint flags, SPPaintSelector *psel);
-static void sp_stroke_style_paint_selection_changed (SPWidget *spw, Inkscape::Selection *selection, SPPaintSelector *psel);
-static void sp_stroke_style_paint_update(SPWidget *spw);
-
-static void sp_stroke_style_paint_mode_changed(SPPaintSelector *psel, SPPaintSelectorMode mode, SPWidget *spw);
-static void sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw);
-static void sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw);
-
-static void sp_stroke_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
-static void sp_stroke_style_widget_transientize_callback(Inkscape::Application *inkscape,
-                                                         SPDesktop *desktop,
-                                                         SPWidget *spw );
-
-/** Marker selection option menus */
-static Gtk::OptionMenu * marker_start_menu = NULL;
-static Gtk::OptionMenu * marker_mid_menu = NULL;
-static Gtk::OptionMenu * marker_end_menu = NULL;
-
-sigc::connection marker_start_menu_connection;
-sigc::connection marker_mid_menu_connection;
-sigc::connection marker_end_menu_connection;
-
-static SPObject *ink_extract_marker_name(gchar const *n, SPDocument *doc);
-static void      ink_markers_menu_update(Gtk::Container* spw, SPMarkerLoc const which);
-
-static Inkscape::UI::Cache::SvgPreview svg_preview_cache;
-
-/**
- * Create the stroke style widget, and hook up all the signals.
- */
-GtkWidget *
-sp_stroke_style_paint_widget_new(void)
-{
-    GtkWidget *spw, *psel;
-
-    spw = sp_widget_new_global(INKSCAPE);
-
-    psel = sp_paint_selector_new(false); // without fillrule selector
-    gtk_widget_show(psel);
-    gtk_container_add(GTK_CONTAINER(spw), psel);
-    gtk_object_set_data(GTK_OBJECT(spw), "paint-selector", psel);
-
-    gtk_signal_connect(GTK_OBJECT(spw), "modify_selection",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_modified),
-                       psel);
-    gtk_signal_connect(GTK_OBJECT(spw), "change_selection",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_changed),
-                       psel);
-
-    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_stroke_style_widget_change_subselection), spw);
-
-    g_signal_connect (G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK (sp_stroke_style_widget_transientize_callback), spw );
-
-    gtk_signal_connect(GTK_OBJECT(psel), "mode_changed",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_mode_changed),
-                       spw);
-    gtk_signal_connect(GTK_OBJECT(psel), "dragged",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_dragged),
-                       spw);
-    gtk_signal_connect(GTK_OBJECT(psel), "changed",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_changed),
-                       spw);
-
-    sp_stroke_style_paint_update (SP_WIDGET(spw));
-    return spw;
-}
-
-/**
- * On signal modified, invokes an update of the stroke style paint object.
- */
-static void
-sp_stroke_style_paint_selection_modified( SPWidget *spw,
-                                          Inkscape::Selection */*selection*/,
-                                          guint flags,
-                                          SPPaintSelector */*psel*/ )
-{
-    if (flags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG |
-                  SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
-        sp_stroke_style_paint_update(spw);
-    }
-}
-
-
-/**
- * On signal selection changed, invokes an update of the stroke style paint object.
- */
-static void
-sp_stroke_style_paint_selection_changed( SPWidget *spw,
-                                         Inkscape::Selection */*selection*/,
-                                         SPPaintSelector */*psel*/ )
-{
-    sp_stroke_style_paint_update (spw);
-}
-
-
-/**
- * On signal change subselection, invoke an update of the stroke style widget.
- */
-static void
-sp_stroke_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
-                                            SPDesktop */*desktop*/,
-                                            SPWidget *spw )
-{
-    sp_stroke_style_paint_update (spw);
-}
-
-/**
- * Gets the active stroke style property, then sets the appropriate color, alpha, gradient,
- * pattern, etc. for the paint-selector.
- */
-static void
-sp_stroke_style_paint_update (SPWidget *spw)
-{
-    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
-        return;
-    }
-
-    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
-
-    SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector"));
-
-    // create temporary style
-    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-    // query into it
-    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE);
-
-    switch (result) {
-        case QUERY_STYLE_NOTHING:
-        {
-            /* No paint at all */
-            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
-            break;
-        }
-
-        case QUERY_STYLE_SINGLE:
-        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
-        case QUERY_STYLE_MULTIPLE_SAME:
-        {
-            SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, false);
-            sp_paint_selector_set_mode (psel, pselmode);
-
-            if (query->stroke.set && query->stroke.isPaintserver()) {
-
-                SPPaintServer *server = SP_STYLE_STROKE_SERVER (query);
-
-                if (SP_IS_LINEARGRADIENT (server)) {
-                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
-                    sp_paint_selector_set_gradient_linear (psel, vector);
-
-                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
-                    sp_paint_selector_set_gradient_properties (psel,
-                                                       SP_GRADIENT_UNITS (lg),
-                                                       SP_GRADIENT_SPREAD (lg));
-                } else if (SP_IS_RADIALGRADIENT (server)) {
-                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
-                    sp_paint_selector_set_gradient_radial (psel, vector);
-
-                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
-                    sp_paint_selector_set_gradient_properties (psel,
-                                                       SP_GRADIENT_UNITS (rg),
-                                                       SP_GRADIENT_SPREAD (rg));
-                } else if (SP_IS_PATTERN (server)) {
-                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
-                    sp_update_pattern_list (psel, pat);
-                }
-            } else if (query->stroke.set && query->stroke.isColor()) {
-                sp_paint_selector_set_color_alpha (psel, &query->stroke.value.color, SP_SCALE24_TO_FLOAT (query->stroke_opacity.value));
-
-            }
-            break;
-        }
-
-        case QUERY_STYLE_MULTIPLE_DIFFERENT:
-        {
-            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
-            break;
-        }
-    }
-
-    sp_style_unref(query);
-
-    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
-}
-
-/**
- * When the mode is changed, invoke a regular changed handler.
- */
-static void
-sp_stroke_style_paint_mode_changed( SPPaintSelector *psel,
-                                    SPPaintSelectorMode /*mode*/,
-                                    SPWidget *spw )
-{
-    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
-        return;
-    }
-
-    /* TODO: Does this work?
-     * Not really, here we have to get old color back from object
-     * Instead of relying on paint widget having meaningful colors set
-     */
-    sp_stroke_style_paint_changed(psel, spw);
-}
-
-static gchar const *const undo_label_1 = "stroke:flatcolor:1";
-static gchar const *const undo_label_2 = "stroke:flatcolor:2";
-static gchar const *undo_label = undo_label_1;
-
-/**
- * When a drag callback occurs on a paint selector object, if it is a RGB or CMYK
- * color mode, then set the stroke opacity to psel's flat color.
- */
-static void
-sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw)
-{
-    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
-        return;
-    }
-
-    switch (psel->mode) {
-        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
-        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
-        {
-            sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "stroke", "stroke-opacity");
-            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE,
-                                    _("Set stroke color"));
-            break;
-        }
-
-        default:
-            g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
-                       __FILE__, __LINE__, psel->mode);
-            break;
-    }
-}
-
-/**
- * When the stroke style's paint settings change, this handler updates the
- * repr's stroke css style and applies the style to relevant drawing items.
- */
-static void
-sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw)
-{
-    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
-        return;
-    }
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
-
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    SPDocument *document = sp_desktop_document (desktop);
-    Inkscape::Selection *selection = sp_desktop_selection (desktop);
-
-    GSList const *items = selection->itemList();
-
-    switch (psel->mode) {
-        case SP_PAINT_SELECTOR_MODE_EMPTY:
-            // This should not happen.
-            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
-                        __FILE__, __LINE__, psel->mode);
-            break;
-        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
-            // This happens when you switch multiple objects with different gradients to flat color;
-            // nothing to do here.
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_NONE:
-        {
-            SPCSSAttr *css = sp_repr_css_attr_new();
-            sp_repr_css_set_property(css, "stroke", "none");
-
-            sp_desktop_set_style (desktop, css);
-
-            sp_repr_css_attr_unref(css);
-
-            sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
-                             _("Remove stroke"));
-            break;
-        }
-
-        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
-        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
-        {
-            sp_paint_selector_set_flat_color (psel, desktop, "stroke", "stroke-opacity");
-            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
-                                    _("Set stroke color"));
-
-            // on release, toggle undo_label so that the next drag will not be lumped with this one
-            if (undo_label == undo_label_1)
-                undo_label = undo_label_2;
-            else
-                undo_label = undo_label_1;
-
-            break;
-        }
-
-        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
-        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
-            if (items) {
-                SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
-                                                       ? SP_GRADIENT_TYPE_LINEAR
-                                                       : SP_GRADIENT_TYPE_RADIAL );
-                SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
-                if (!vector) {
-                    /* No vector in paint selector should mean that we just changed mode */
-
-                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-                    int result = objects_query_fillstroke ((GSList *) items, query, false);
-                    guint32 common_rgb = 0;
-                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
-                        if (!query->fill.isColor()) {
-                            common_rgb = sp_desktop_get_color(desktop, false);
-                        } else {
-                            common_rgb = query->stroke.value.color.toRGBA32( 0xff );
-                        }
-                        vector = sp_document_default_gradient_vector(document, common_rgb);
-                    }
-                    sp_style_unref(query);
-
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                        if (!vector) {
-                            sp_item_set_gradient(SP_ITEM(i->data),
-                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), false),
-                                                 gradient_type, false);
-                        } else {
-                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
-                        }
-                    }
-                } else {
-                    vector = sp_gradient_ensure_vector_normalized(vector);
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
-                        sp_gradient_selector_attrs_to_gradient(gr, psel);
-                    }
-                }
-
-                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
-                                 _("Set gradient on stroke"));
-            }
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_PATTERN:
-
-            if (items) {
-
-                SPPattern *pattern = sp_paint_selector_get_pattern (psel);
-                if (!pattern) {
-
-                    /* No Pattern in paint selector should mean that we just
-                     * changed mode - dont do jack.
-                     */
-
-                } else {
-                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
-                    SPCSSAttr *css = sp_repr_css_attr_new ();
-                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
-                    sp_repr_css_set_property (css, "stroke", urltext);
-
-                    for (GSList const *i = items; i != NULL; i = i->next) {
-                         Inkscape::XML::Node *selrepr = SP_OBJECT_REPR (i->data);
-                         SPObject *selobj = SP_OBJECT (i->data);
-                         if (!selrepr)
-                             continue;
-
-                         SPStyle *style = SP_OBJECT_STYLE (selobj);
-                         if (style && style->stroke.isPaintserver()) {
-                             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (selobj);
-                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
-                                 // only if this object's pattern is not rooted in our selected pattern, apply
-                                 continue;
-                         }
-
-                         sp_repr_css_change_recursive (selrepr, css, "style");
-                     }
-
-                    sp_repr_css_attr_unref (css);
-                    g_free (urltext);
-
-                } // end if
-
-                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
-                                  _("Set pattern on stroke"));
-            } // end if
-
-            break;
-
-        case SP_PAINT_SELECTOR_MODE_UNSET:
-            if (items) {
-                    SPCSSAttr *css = sp_repr_css_attr_new ();
-                    sp_repr_css_unset_property (css, "stroke");
-                    sp_repr_css_unset_property (css, "stroke-opacity");
-                    sp_repr_css_unset_property (css, "stroke-width");
-                    sp_repr_css_unset_property (css, "stroke-miterlimit");
-                    sp_repr_css_unset_property (css, "stroke-linejoin");
-                    sp_repr_css_unset_property (css, "stroke-linecap");
-                    sp_repr_css_unset_property (css, "stroke-dashoffset");
-                    sp_repr_css_unset_property (css, "stroke-dasharray");
-
-                    sp_desktop_set_style (desktop, css);
-                    sp_repr_css_attr_unref (css);
-
-                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
-                                      _("Unset stroke"));
-            }
-            break;
-
-        default:
-            g_warning( "file %s: line %d: Paint selector should not be in "
-                       "mode %d",
-                       __FILE__, __LINE__,
-                       psel->mode );
-            break;
-    }
-
-    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
-}
-
-
-
-
-
-/* Line */
-
-static void sp_stroke_style_line_selection_modified(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data);
-static void sp_stroke_style_line_selection_changed(SPWidget *spw, Inkscape::Selection *selection, gpointer data);
-
-static void sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel);
-
-static void sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active);
-
-static void sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active);
-
-static void sp_stroke_style_width_changed(Gtk::Container *spw);
-static void sp_stroke_style_miterlimit_changed(Gtk::Container *spw);
-static void sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw);
-static void sp_stroke_style_line_dash_changed(Gtk::Container *spw);
-
-static void sp_stroke_style_update_marker_menus(Gtk::Container *spw, GSList const *objects);
-
-
-/**
- * Helper function for creating radio buttons.  This should probably be re-thought out
- * when reimplementing this with Gtkmm.
- */
-static Gtk::RadioButton *
-sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon,
-                       Gtk::HBox *hb, Gtk::Container *spw,
-                       gchar const *key, gchar const *data)
-{
-    g_assert(icon != NULL);
-    g_assert(hb  != NULL);
-    g_assert(spw != NULL);
-
-    if (tb == NULL) {
-        tb = new Gtk::RadioButton();
-    } else {
-        Gtk::RadioButtonGroup grp = tb->get_group();
-        tb = new Gtk::RadioButton(grp);
-    }
-
-    tb->show();
-    tb->set_mode(false);
-    hb->pack_start(*tb, false, false, 0);
-    spw->set_data(icon, tb);
-    tb->set_data(key, (gpointer*)data);
-    tb->signal_toggled().connect(sigc::bind<Gtk::RadioButton *, Gtk::Container *>(
-                                     sigc::ptr_fun(&sp_stroke_style_any_toggled), tb, spw));
-    Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon)));
-    g_assert(px != NULL);
-    px->show();
-    tb->add(*px);
-
-    return tb;
-
-}
-
-static void
-sp_stroke_style_widget_transientize_callback(Inkscape::Application */*inkscape*/,
-                                             SPDesktop */*desktop*/,
-                                             SPWidget */*spw*/ )
-{
-// TODO:  Either of these will cause crashes sometimes
-//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
-//    ink_markers_menu_update(spw);
-}
-
-/**
- * Creates a copy of the marker named mname, determines its visible and renderable
- * area in menu_id's bounding box, and then renders it.  This allows us to fill in
- * preview images of each marker in the marker menu.
- */
-static Gtk::Image *
-sp_marker_prev_new(unsigned psize, gchar const *mname,
-                   SPDocument *source, SPDocument *sandbox,
-                   gchar const *menu_id, NRArena const */*arena*/, unsigned /*visionkey*/, NRArenaItem *root)
-{
-    // Retrieve the marker named 'mname' from the source SVG document
-    SPObject const *marker = source->getObjectById(mname);
-    if (marker == NULL)
-        return NULL;
-
-    // Create a copy repr of the marker with id="sample"
-    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(sandbox);
-    Inkscape::XML::Node *mrepr = SP_OBJECT_REPR (marker)->duplicate(xml_doc);
-    mrepr->setAttribute("id", "sample");
-
-    // Replace the old sample in the sandbox by the new one
-    Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (sandbox->getObjectById("defs"));
-    SPObject *oldmarker = sandbox->getObjectById("sample");
-    if (oldmarker)
-        oldmarker->deleteObject(false);
-    defsrepr->appendChild(mrepr);
-    Inkscape::GC::release(mrepr);
-
-// Uncomment this to get the sandbox documents saved (useful for debugging)
-    //FILE *fp = fopen (g_strconcat(menu_id, mname, ".svg", NULL), "w");
-    //sp_repr_save_stream (sp_document_repr_doc (sandbox), fp);
-    //fclose (fp);
-
-    // object to render; note that the id is the same as that of the menu we're building
-    SPObject *object = sandbox->getObjectById(menu_id);
-    sp_document_root (sandbox)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
-    sp_document_ensure_up_to_date(sandbox);
-
-    if (object == NULL || !SP_IS_ITEM(object))
-        return NULL; // sandbox broken?
-
-    // Find object's bbox in document
-    Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object)));
-    Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc);
-
-    if (!dbox) {
-        return NULL;
-    }
-
-    /* Update to renderable state */
-    double sf = 0.8;
-
-    gchar *cache_name = g_strconcat(menu_id, mname, NULL);
-    Glib::ustring key = svg_preview_cache.cache_key(source->uri, cache_name, psize);
-    g_free (cache_name);
-    // TODO: is this correct?
-    Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key));
-
-    if (!pixbuf) {
-        pixbuf = Glib::wrap(render_pixbuf(root, sf, *dbox, psize));
-        svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj());
-    }
-
-    // Create widget
-    Gtk::Image *pb = new Gtk::Image(pixbuf);
-
-    return pb;
-}
-
-/**
- *  Returns a list of markers in the defs of the given source document as a GSList object
- *  Returns NULL if there are no markers in the document.
- */
-GSList *
-ink_marker_list_get (SPDocument *source)
-{
-    if (source == NULL)
-        return NULL;
-
-    GSList *ml   = NULL;
-    SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS (source);
-    for ( SPObject *child = sp_object_first_child(SP_OBJECT(defs));
-          child != NULL;
-          child = SP_OBJECT_NEXT (child) )
-    {
-        if (SP_IS_MARKER(child)) {
-            ml = g_slist_prepend (ml, child);
-        }
-    }
-    return ml;
-}
-
-#define MARKER_ITEM_MARGIN 0
-
-/**
- * Adds previews of markers in marker_list to the given menu widget
- */
-static void
-sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPDocument *sandbox, gchar const *menu_id)
-{
-    // Do this here, outside of loop, to speed up preview generation:
-    NRArena const *arena = NRArena::create();
-    unsigned const visionkey = sp_item_display_key_new(1);
-    NRArenaItem *root =  sp_item_invoke_show(SP_ITEM(SP_DOCUMENT_ROOT (sandbox)), (NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY);
-
-    for (; marker_list != NULL; marker_list = marker_list->next) {
-        Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) marker_list->data);
-        Gtk::MenuItem *i = new Gtk::MenuItem();
-        i->show();
-
-        if (repr->attribute("inkscape:stockid"))
-            i->set_data("stockid", (void *) "true");
-        else
-            i->set_data("stockid", (void *) "false");
-
-        gchar const *markid = repr->attribute("id");
-        i->set_data("marker", (void *) markid);
-
-        Gtk::HBox *hb = new Gtk::HBox(false, MARKER_ITEM_MARGIN);
-        hb->show();
-
-        // generate preview
-
-        Gtk::Image *prv = sp_marker_prev_new (22, markid, source, sandbox, menu_id, arena, visionkey, root);
-        prv->show();
-        hb->pack_start(*prv, false, false, 6);
-
-        // create label
-        Gtk::Label *l = new Gtk::Label(repr->attribute("id"));
-        l->show();
-        l->set_alignment(0.0, 0.5);
-
-        hb->pack_start(*l, true, true, 0);
-
-        hb->show();
-        i->add(*hb);
-
-        m->append(*i);
-    }
-
-    sp_item_invoke_hide(SP_ITEM(sp_document_root(sandbox)), visionkey);
-    nr_object_unref((NRObject *) arena);
-}
-
-/**
- * sp_marker_list_from_doc()
- *
- * \brief Pick up all markers from source, except those that are in
- * current_doc (if non-NULL), and add items to the m menu
- *
- */
-static void
-sp_marker_list_from_doc (Gtk::Menu *m, SPDocument */*current_doc*/, SPDocument *source, SPDocument */*markers_doc*/, SPDocument *sandbox, gchar const *menu_id)
-{
-    GSList *ml = ink_marker_list_get(source);
-    GSList *clean_ml = NULL;
-
-    for (; ml != NULL; ml = ml->next) {
-        if (!SP_IS_MARKER(ml->data))
-            continue;
-
-        // Add to the list of markers we really do wish to show
-        clean_ml = g_slist_prepend (clean_ml, ml->data);
-    }
-    sp_marker_menu_build(m, clean_ml, source, sandbox, menu_id);
-
-    g_slist_free (ml);
-    g_slist_free (clean_ml);
-}
-
-/**
- * Returns a new document containing default start, mid, and end markers.
- */
-SPDocument *
-ink_markers_preview_doc ()
-{
-gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
-"  <defs id=\"defs\" />"
-
-"  <g id=\"marker-start\">"
-"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\""
-"       d=\"M 12.5,13 L 25,13\" id=\"path1\" />"
-"    <rect style=\"fill:none;stroke:none\" id=\"rect2\""
-"       width=\"25\" height=\"25\" x=\"0\" y=\"0\" />"
-"  </g>"
-
-"  <g id=\"marker-mid\">"
-"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\""
-"       d=\"M 0,113 L 12.5,113 L 25,113\" id=\"path11\" />"
-"    <rect style=\"fill:none;stroke:none\" id=\"rect22\""
-"       width=\"25\" height=\"25\" x=\"0\" y=\"100\" />"
-"  </g>"
-
-"  <g id=\"marker-end\">"
-"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\""
-"       d=\"M 0,213 L 12.5,213\" id=\"path111\" />"
-"    <rect style=\"fill:none;stroke:none\" id=\"rect222\""
-"       width=\"25\" height=\"25\" x=\"0\" y=\"200\" />"
-"  </g>"
-
-"</svg>";
-
-    return sp_document_new_from_mem (buffer, strlen(buffer), FALSE);
-}
-
-static void
-ink_marker_menu_create_menu(Gtk::Menu *m, gchar const *menu_id, SPDocument *doc, SPDocument *sandbox)
-{
-    static SPDocument *markers_doc = NULL;
-
-    // add "None"
-    Gtk::MenuItem *i = new Gtk::MenuItem();
-    i->show();
-
-    i->set_data("marker", (void *) "none");
-
-    Gtk::HBox *hb = new Gtk::HBox(false,  MARKER_ITEM_MARGIN);
-    hb->show();
-
-    Gtk::Label *l = new Gtk::Label( _("None") );
-    l->show();
-    l->set_alignment(0.0, 0.5);
-
-    hb->pack_start(*l, true, true, 0);
-
-    hb->show();
-    i->add(*hb);
-    m->append(*i);
-
-    // find and load markers.svg
-    if (markers_doc == NULL) {
-        char *markers_source = g_build_filename(INKSCAPE_MARKERSDIR, "markers.svg", NULL);
-        if (Inkscape::IO::file_test(markers_source, G_FILE_TEST_IS_REGULAR)) {
-            markers_doc = sp_document_new(markers_source, FALSE);
-        }
-        g_free(markers_source);
-    }
-
-    // suck in from current doc
-    sp_marker_list_from_doc(m, NULL, doc, markers_doc, sandbox, menu_id);
-
-    // add separator
-    {
-        //Gtk::Separator *i = gtk_separator_menu_item_new();
-        Gtk::SeparatorMenuItem *i = new Gtk::SeparatorMenuItem();
-        i->show();
-        m->append(*i);
-    }
-
-    // suck in from markers.svg
-    if (markers_doc) {
-        sp_document_ensure_up_to_date(doc);
-        sp_marker_list_from_doc(m, doc, markers_doc, NULL, sandbox, menu_id);
-    }
-
-}
-
-/**
- * Creates a menu widget to display markers from markers.svg
- */
-static Gtk::OptionMenu *
-ink_marker_menu(Gtk::Widget */*tbl*/, gchar const *menu_id, SPDocument *sandbox)
-{
-    SPDesktop *desktop = inkscape_active_desktop();
-    SPDocument *doc = sp_desktop_document(desktop);
-    Gtk::OptionMenu *mnu = new Gtk::OptionMenu();
-
-    /* Create new menu widget */
-    Gtk::Menu *m = new Gtk::Menu();
-    m->show();
-
-    mnu->set_data("updating", (gpointer) FALSE);
-
-    if (!doc) {
-        Gtk::MenuItem *i = new Gtk::MenuItem(_("No document selected"));
-        i->show();
-        m->append(*i);
-        mnu->set_sensitive(false);
-
-    } else {
-        ink_marker_menu_create_menu(m, menu_id, doc, sandbox);
-
-        mnu->set_sensitive(true);
-    }
-
-    mnu->set_data("menu_id", const_cast<gchar *>(menu_id));
-    mnu->set_menu(*m);
-
-    /* Set history */
-    mnu->set_history(0);
-
-    return mnu;
-}
-
-/**
- * Handles when user selects one of the markers from the marker menu.
- * Defines a uri string to refer to it, then applies it to all selected
- * items in the current desktop.
- */
-static void
-sp_marker_select(Gtk::OptionMenu *mnu, Gtk::Container *spw, SPMarkerLoc const which)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    SPDesktop *desktop = inkscape_active_desktop();
-    SPDocument *document = sp_desktop_document(desktop);
-    if (!document) {
-        return;
-    }
-
-    /* Get Marker */
-    if (!mnu->get_menu()->get_active()->get_data("marker"))
-    {
-        return;
-    }
-    gchar *markid = static_cast<gchar *>(mnu->get_menu()->get_active()->get_data("marker"));
-    gchar const *marker = "";
-    if (strcmp(markid, "none")) {
-       gchar *stockid = static_cast<gchar *>(mnu->get_menu()->get_active()->get_data("stockid"));
-
-       gchar *markurn = markid;
-       if (!strcmp(stockid,"true")) markurn = g_strconcat("urn:inkscape:marker:",markid,NULL);
-       SPObject *mark = get_stock_item(markurn);
-       if (mark) {
-            Inkscape::XML::Node *repr = SP_OBJECT_REPR(mark);
-            marker = g_strconcat("url(#", repr->attribute("id"), ")", NULL);
-        }
-    } else {
-        marker = markid;
-    }
-    SPCSSAttr *css = sp_repr_css_attr_new();
-    gchar const *menu_id = static_cast<gchar const *>(mnu->get_data("menu_id"));
-    sp_repr_css_set_property(css, menu_id, marker);
-
-    // Also update the marker dropdown menus, so the document's markers
-    // show up at the top of the menu
-//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
-    ink_markers_menu_update(spw, which);
-
-    Inkscape::Selection *selection = sp_desktop_selection(desktop);
-    GSList const *items = selection->itemList();
-    for (; items != NULL; items = items->next) {
-         SPItem *item = (SPItem *) items->data;
-         if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) // can't set marker to rect, until it's converted to using <path>
-             continue;
-         Inkscape::XML::Node *selrepr = SP_OBJECT_REPR((SPItem *) items->data);
-         if (selrepr) {
-             sp_repr_css_change_recursive(selrepr, css, "style");
-         }
-         SP_OBJECT(items->data)->requestModified(SP_OBJECT_MODIFIED_FLAG);
-         SP_OBJECT(items->data)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
-     }
-
-    sp_repr_css_attr_unref(css);
-
-    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
-                     _("Set markers"));
-
-};
-
-static unsigned int
-ink_marker_menu_get_pos(Gtk::Menu *mnu, gchar const *markname)
-{
-    if (markname == NULL)
-        markname = static_cast<gchar const *>(mnu->get_active()->get_data("marker"));
-
-    if (markname == NULL)
-        return 0;
-
-    std::vector<Gtk::Widget *> kids = mnu->get_children();
-    unsigned int i = 0;
-    for (; i < kids.size();) {
-        gchar const *mark = static_cast<gchar const *>(kids[i]->get_data("marker"));
-        if (mark && strcmp(mark, markname) == 0) {
-            break;
-        }
-        ++i;
-    }
-
-    return i;
-}
-
-static void
-ink_markers_menu_update(Gtk::Container* /*spw*/, SPMarkerLoc const which) {
-    SPDesktop  *desktop = inkscape_active_desktop();
-    SPDocument *document = sp_desktop_document(desktop);
-    SPDocument *sandbox = ink_markers_preview_doc ();
-    Gtk::Menu  *m;
-    int        pos;
-
-    // TODO: this code can be shortened by abstracting out marker_(start|mid|end)_...
-    switch (which) {
-        case SP_MARKER_LOC_START:
-            marker_start_menu_connection.block();
-            pos = ink_marker_menu_get_pos(marker_start_menu->get_menu(), NULL);
-            m = new Gtk::Menu();
-            m->show();
-            ink_marker_menu_create_menu(m, "marker-start", document, sandbox);
-            marker_start_menu->remove_menu();
-            marker_start_menu->set_menu(*m);
-            marker_start_menu->set_history(pos);
-            marker_start_menu_connection.unblock();
-            break;
-
-        case SP_MARKER_LOC_MID:
-            marker_mid_menu_connection.block();
-            pos = ink_marker_menu_get_pos(marker_mid_menu->get_menu(), NULL);
-            m = new Gtk::Menu();
-            m->show();
-            ink_marker_menu_create_menu(m, "marker-mid", document, sandbox);
-            marker_mid_menu->remove_menu();
-            marker_mid_menu->set_menu(*m);
-            marker_mid_menu->set_history(pos);
-            marker_mid_menu_connection.unblock();
-            break;
-
-        case SP_MARKER_LOC_END:
-            marker_end_menu_connection.block();
-            pos = ink_marker_menu_get_pos(marker_end_menu->get_menu(), NULL);
-            m = new Gtk::Menu();
-            m->show();
-            ink_marker_menu_create_menu(m, "marker-end", document, sandbox);
-            marker_end_menu->remove_menu();
-            marker_end_menu->set_menu(*m);
-            marker_end_menu->set_history(pos);
-            marker_end_menu_connection.unblock();
-            break;
-        default:
-            g_assert_not_reached();
-    }
-}
-
-/**
- * Sets the stroke width units for all selected items.
- * Also handles absolute and dimensionless units.
- */
-static gboolean stroke_width_set_unit(SPUnitSelector *,
-                                      SPUnit const *old,
-                                      SPUnit const *new_units,
-                                      Gtk::Container *spw)
-{
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
-    if (!desktop) {
-        return FALSE;
-    }
-
-    Inkscape::Selection *selection = sp_desktop_selection (desktop);
-
-    if (selection->isEmpty())
-        return FALSE;
-
-    GSList const *objects = selection->itemList();
-
-    if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE) &&
-       (new_units->base == SP_UNIT_DIMENSIONLESS)) {
-
-        /* Absolute to percentage */
-        spw->set_data ("update", GUINT_TO_POINTER (TRUE));
-
-        Gtk::Adjustment *a = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
-        float w = sp_units_get_pixels (a->get_value(), *old);
-
-        gdouble average = stroke_average_width (objects);
-
-        if (average == NR_HUGE || average == 0)
-            return FALSE;
-
-        a->set_value (100.0 * w / average);
-
-        spw->set_data ("update", GUINT_TO_POINTER (FALSE));
-        return TRUE;
-
-    } else if ((old->base == SP_UNIT_DIMENSIONLESS) &&
-              (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) {
-
-        /* Percentage to absolute */
-        spw->set_data ("update", GUINT_TO_POINTER (TRUE));
-
-        Gtk::Adjustment *a = static_cast<Gtk::Adjustment *>(spw->get_data ("width"));
-
-        gdouble average = stroke_average_width (objects);
-
-        a->set_value (sp_pixels_get_units (0.01 * a->get_value() * average, *new_units));
-
-        spw->set_data ("update", GUINT_TO_POINTER (FALSE));
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-
-/**
- * \brief  Creates a new widget for the line stroke style.
- *
- */
-Gtk::Container *
-sp_stroke_style_line_widget_new(void)
-{
-    Gtk::Widget *us;
-    SPDashSelector *ds;
-    GtkWidget *us_old, *spw_old;
-    Gtk::Container *spw;
-    Gtk::Table *t;
-    Gtk::Adjustment *a;
-    Gtk::SpinButton *sb;
-    Gtk::RadioButton *tb;
-    Gtk::HBox *f, *hb;
-
-    Gtk::Tooltips *tt = new Gtk::Tooltips();
-
-    spw_old = sp_widget_new_global(INKSCAPE);
-    spw = dynamic_cast<Gtk::Container *>(manage(Glib::wrap(spw_old)));
-
-    f = new Gtk::HBox(false, 0);
-    f->show();
-    spw->add(*f);
-
-    t = new Gtk::Table(3, 6, false);
-    t->show();
-    t->set_border_width(4);
-    t->set_row_spacings(4);
-    f->add(*t);
-    spw->set_data("stroke", t);
-
-    gint i = 0;
-
-    /* Stroke width */
-    spw_label(t, Q_("StrokeWidth|Width:"), 0, i);
-
-    hb = spw_hbox(t, 3, 1, i);
-
-// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate
-// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use
-// setHundredPercent to remember the aeraged width corresponding to 100%. Then the
-// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and
-// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that
-// function in desktop-style.
-
-    a = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 10.0);
-    spw->set_data("width", a);
-    sb = new Gtk::SpinButton(*a, 0.1, 3);
-    tt->set_tip(*sb, _("Stroke width"));
-    sb->show();
-
-    sp_dialog_defocus_on_enter_cpp(sb);
-
-    hb->pack_start(*sb, false, false, 0);
-    us_old = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
-    us = manage(Glib::wrap(us_old));
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    if (desktop)
-        sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us_old), sp_desktop_namedview(desktop)->doc_units);
-    sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us_old), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0);
-    g_signal_connect ( G_OBJECT (us_old), "set_unit", G_CALLBACK (stroke_width_set_unit), spw );
-    us->show();
-    sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT(a->gobj()) );
-    hb->pack_start(*us, FALSE, FALSE, 0);
-    spw->set_data("units", us_old);
-
-    a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw));
-    i++;
-
-    /* Join type */
-    // TRANSLATORS: The line join style specifies the shape to be used at the
-    //  corners of paths. It can be "miter", "round" or "bevel".
-    spw_label(t, _("Join:"), 0, i);
-
-    hb = spw_hbox(t, 3, 1, i);
-
-    tb = NULL;
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_MITER,
-                                hb, spw, "join", "miter");
-
-    // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner.
-    //  For an example, draw a triangle with a large stroke width and modify the
-    //  "Join" option (in the Fill and Stroke dialog).
-    tt->set_tip(*tb, _("Miter join"));
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_ROUND,
-                                hb, spw, "join", "round");
-
-    // TRANSLATORS: Round join: joining lines with a rounded corner.
-    //  For an example, draw a triangle with a large stroke width and modify the
-    //  "Join" option (in the Fill and Stroke dialog).
-    tt->set_tip(*tb, _("Round join"));
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_BEVEL,
-                                hb, spw, "join", "bevel");
-
-    // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner.
-    //  For an example, draw a triangle with a large stroke width and modify the
-    //  "Join" option (in the Fill and Stroke dialog).
-    tt->set_tip(*tb, _("Bevel join"));
-
-    i++;
-
-    /* Miterlimit  */
-    // TRANSLATORS: Miter limit: only for "miter join", this limits the length
-    //  of the sharp "spike" when the lines connect at too sharp an angle.
-    // When two line segments meet at a sharp angle, a miter join results in a
-    //  spike that extends well beyond the connection point. The purpose of the
-    //  miter limit is to cut off such spikes (i.e. convert them into bevels)
-    //  when they become too long.
-    spw_label(t, _("Miter limit:"), 0, i);
-
-    hb = spw_hbox(t, 3, 1, i);
-
-    a = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 10.0);
-    spw->set_data("miterlimit", a);
-
-    sb = new Gtk::SpinButton(*a, 0.1, 2);
-    tt->set_tip(*sb, _("Maximum length of the miter (in units of stroke width)"));
-    sb->show();
-    spw->set_data("miterlimit_sb", sb);
-    sp_dialog_defocus_on_enter_cpp(sb);
-
-    hb->pack_start(*sb, false, false, 0);
-
-    a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw));
-    i++;
-
-    /* Cap type */
-    // TRANSLATORS: cap type specifies the shape for the ends of lines
-    spw_label(t, _("Cap:"), 0, i);
-
-    hb = spw_hbox(t, 3, 1, i);
-
-    tb = NULL;
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_BUTT,
-                                hb, spw, "cap", "butt");
-
-    // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point
-    //  of the line; the ends of the line are square
-    tt->set_tip(*tb, _("Butt cap"));
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_ROUND,
-                                hb, spw, "cap", "round");
-
-    // TRANSLATORS: Round cap: the line shape extends beyond the end point of the
-    //  line; the ends of the line are rounded
-    tt->set_tip(*tb, _("Round cap"));
-
-    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_SQUARE,
-                                hb, spw, "cap", "square");
-
-    // TRANSLATORS: Square cap: the line shape extends beyond the end point of the
-    //  line; the ends of the line are square
-    tt->set_tip(*tb, _("Square cap"));
-
-    i++;
-
-
-    /* Dash */
-    spw_label(t, _("Dashes:"), 0, i);
-    ds = manage(new SPDashSelector);
-
-    ds->show();
-    t->attach(*ds, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
-    spw->set_data("dash", ds);
-    ds->changed_signal.connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_line_dash_changed), spw));
-    i++;
-
-    /* Drop down marker selectors*/
-    // TODO: this code can be shortened by iterating over the possible menus!
-
-    // doing this here once, instead of for each preview, to speed things up
-    SPDocument *sandbox = ink_markers_preview_doc ();
-
-    // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes
-    // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path.
-    spw_label(t, _("Start Markers:"), 0, i);
-    marker_start_menu = ink_marker_menu(spw ,"marker-start", sandbox);
-    tt->set_tip(*marker_start_menu, _("Start Markers are drawn on the first node of a path or shape"));
-    marker_start_menu_connection = marker_start_menu->signal_changed().connect(
-        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
-            sigc::ptr_fun(&sp_marker_select), marker_start_menu, spw, SP_MARKER_LOC_START));
-    marker_start_menu->show();
-    t->attach(*marker_start_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
-    spw->set_data("start_mark_menu", marker_start_menu);
-
-    i++;
-    spw_label(t, _("Mid Markers:"), 0, i);
-    marker_mid_menu = ink_marker_menu(spw ,"marker-mid", sandbox);
-    tt->set_tip(*marker_mid_menu, _("Mid Markers are drawn on every node of a path or shape except the first and last nodes"));
-    marker_mid_menu_connection = marker_mid_menu->signal_changed().connect(
-        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
-            sigc::ptr_fun(&sp_marker_select), marker_mid_menu,spw, SP_MARKER_LOC_MID));
-    marker_mid_menu->show();
-    t->attach(*marker_mid_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
-    spw->set_data("mid_mark_menu", marker_mid_menu);
-
-    i++;
-    spw_label(t, _("End Markers:"), 0, i);
-    marker_end_menu = ink_marker_menu(spw ,"marker-end", sandbox);
-    tt->set_tip(*marker_end_menu, _("End Markers are drawn on the last node of a path or shape"));
-    marker_end_menu_connection = marker_end_menu->signal_changed().connect(
-        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
-            sigc::ptr_fun(&sp_marker_select), marker_end_menu, spw, SP_MARKER_LOC_END));
-    marker_end_menu->show();
-    t->attach(*marker_end_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
-    spw->set_data("end_mark_menu", marker_end_menu);
-
-    i++;
-
-    // FIXME: we cheat and still use gtk+ signals
-
-    gtk_signal_connect(GTK_OBJECT(spw_old), "modify_selection",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_modified),
-                       spw);
-    gtk_signal_connect(GTK_OBJECT(spw_old), "change_selection",
-                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_changed),
-                       spw);
-
-    sp_stroke_style_line_update(spw, desktop ? sp_desktop_selection(desktop) : NULL);
-
-    return spw;
-}
-
-/**
- * Callback for when stroke style widget is modified.
- * Triggers update action.
- */
-static void
-sp_stroke_style_line_selection_modified(SPWidget *,
-                                        Inkscape::Selection *selection,
-                                        guint flags,
-                                        gpointer data)
-{
-    Gtk::Container *spw = static_cast<Gtk::Container *>(data);
-    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) {
-        sp_stroke_style_line_update(spw, selection);
-    }
-
-}
-
-/**
- * Callback for when stroke style widget is changed.
- * Triggers update action.
- */
-static void
-sp_stroke_style_line_selection_changed(SPWidget *,
-                                       Inkscape::Selection *selection,
-                                       gpointer data)
-{
-    Gtk::Container *spw = static_cast<Gtk::Container *>(data);
-    sp_stroke_style_line_update(spw, selection);
-}
-
-/**
- * Sets selector widgets' dash style from an SPStyle object.
- */
-static void
-sp_dash_selector_set_from_style(SPDashSelector *dsel, SPStyle *style)
-{
-    if (style->stroke_dash.n_dash > 0) {
-        double d[64];
-        int len = MIN(style->stroke_dash.n_dash, 64);
-        for (int i = 0; i < len; i++) {
-            if (style->stroke_width.computed != 0)
-                d[i] = style->stroke_dash.dash[i] / style->stroke_width.computed;
-            else
-                d[i] = style->stroke_dash.dash[i]; // is there a better thing to do for stroke_width==0?
-        }
-        dsel->set_dash(len, d, style->stroke_width.computed != 0 ?
-                       style->stroke_dash.offset / style->stroke_width.computed  :
-                       style->stroke_dash.offset);
-    } else {
-        dsel->set_dash(0, NULL, 0.0);
-    }
-}
-
-/**
- * Sets the join type for a line, and updates the stroke style widget's buttons
- */
-static void
-sp_jointype_set (Gtk::Container *spw, unsigned const jointype)
-{
-    Gtk::RadioButton *tb = NULL;
-    switch (jointype) {
-        case SP_STROKE_LINEJOIN_MITER:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_MITER));
-            break;
-        case SP_STROKE_LINEJOIN_ROUND:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_ROUND));
-            break;
-        case SP_STROKE_LINEJOIN_BEVEL:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_BEVEL));
-            break;
-        default:
-            break;
-    }
-    sp_stroke_style_set_join_buttons(spw, tb);
-}
-
-/**
- * Sets the cap type for a line, and updates the stroke style widget's buttons
- */
-static void
-sp_captype_set (Gtk::Container *spw, unsigned const captype)
-{
-    Gtk::RadioButton *tb = NULL;
-    switch (captype) {
-        case SP_STROKE_LINECAP_BUTT:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_BUTT));
-            break;
-        case SP_STROKE_LINECAP_ROUND:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_ROUND));
-            break;
-        case SP_STROKE_LINECAP_SQUARE:
-            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_SQUARE));
-            break;
-        default:
-            break;
-    }
-    sp_stroke_style_set_cap_buttons(spw, tb);
-}
-
-/**
- * Callback for when stroke style widget is updated, including markers, cap type,
- * join type, etc.
- */
-static void
-sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    spw->set_data("update", GINT_TO_POINTER(TRUE));
-
-    Gtk::Table *sset = static_cast<Gtk::Table *>(spw->get_data("stroke"));
-    Gtk::Adjustment *width = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
-    Gtk::Adjustment *ml = static_cast<Gtk::Adjustment *>(spw->get_data("miterlimit"));
-    SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units"));
-    SPDashSelector *dsel = static_cast<SPDashSelector *>(spw->get_data("dash"));
-
-    // create temporary style
-    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
-    // query into it
-    int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
-    int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT);
-    int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP);
-    int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
-
-    if (result_sw == QUERY_STYLE_NOTHING) {
-        /* No objects stroked, set insensitive */
-        sset->set_sensitive(false);
-
-        spw->set_data("update", GINT_TO_POINTER(FALSE));
-        return;
-    } else {
-        sset->set_sensitive(true);
-
-        SPUnit const *unit = sp_unit_selector_get_unit(us);
-
-        if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) {
-            sp_unit_selector_set_unit(us, &sp_unit_get_by_id(SP_UNIT_PERCENT));
-        } else {
-            // same width, or only one object; no sense to keep percent, switch to absolute
-            if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) {
-                sp_unit_selector_set_unit(us, sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units);
-            }
-        }
-
-        unit = sp_unit_selector_get_unit(us);
-
-        if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) {
-            double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit);
-            width->set_value(avgwidth);
-        } else {
-            width->set_value(100);
-        }
-    }
-
-    if (result_ml != QUERY_STYLE_NOTHING)
-        ml->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness?
-
-    if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) {
-        sp_jointype_set(spw, query->stroke_linejoin.value);
-    } else {
-        sp_stroke_style_set_join_buttons(spw, NULL);
-    }
-
-    if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) {
-        sp_captype_set (spw, query->stroke_linecap.value);
-    } else {
-        sp_stroke_style_set_cap_buttons(spw, NULL);
-    }
-
-    sp_style_unref(query);
-
-    if (!sel || sel->isEmpty())
-        return;
-
-    GSList const *objects = sel->itemList();
-    SPObject * const object = SP_OBJECT(objects->data);
-    SPStyle * const style = SP_OBJECT_STYLE(object);
-
-    /* Markers */
-    sp_stroke_style_update_marker_menus(spw, objects); // FIXME: make this desktop query too
-
-    /* Dash */
-    sp_dash_selector_set_from_style(dsel, style); // FIXME: make this desktop query too
-
-    sset->set_sensitive(true);
-
-    spw->set_data("update", GINT_TO_POINTER(FALSE));
-}
-
-/**
- * Sets a line's dash properties in a CSS style object.
- */
-static void
-sp_stroke_style_set_scaled_dash(SPCSSAttr *css,
-                                int ndash, double *dash, double offset,
-                                double scale)
-{
-    if (ndash > 0) {
-        Inkscape::CSSOStringStream osarray;
-        for (int i = 0; i < ndash; i++) {
-            osarray << dash[i] * scale;
-            if (i < (ndash - 1)) {
-                osarray << ",";
-            }
-        }
-        sp_repr_css_set_property(css, "stroke-dasharray", osarray.str().c_str());
-
-        Inkscape::CSSOStringStream osoffset;
-        osoffset << offset * scale;
-        sp_repr_css_set_property(css, "stroke-dashoffset", osoffset.str().c_str());
-    } else {
-        sp_repr_css_set_property(css, "stroke-dasharray", "none");
-        sp_repr_css_set_property(css, "stroke-dashoffset", NULL);
-    }
-}
-
-/**
- * Sets line properties like width, dashes, markers, etc. on all currently selected items.
- */
-static void
-sp_stroke_style_scale_line(Gtk::Container *spw)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    spw->set_data("update", GINT_TO_POINTER(TRUE));
-
-    Gtk::Adjustment *wadj = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
-    SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units"));
-    SPDashSelector *dsel = static_cast<SPDashSelector *>(spw->get_data("dash"));
-    Gtk::Adjustment *ml = static_cast<Gtk::Adjustment *>(spw->get_data("miterlimit"));
-
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    SPDocument *document = sp_desktop_document (desktop);
-    Inkscape::Selection *selection = sp_desktop_selection (desktop);
-
-    GSList const *items = selection->itemList();
-
-    /* TODO: Create some standardized method */
-    SPCSSAttr *css = sp_repr_css_attr_new();
-
-    if (items) {
-
-        double width_typed = wadj->get_value();
-        double const miterlimit = ml->get_value();
-
-        SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
-
-        double *dash, offset;
-        int ndash;
-        dsel->get_dash(&ndash, &dash, &offset);
-
-        for (GSList const *i = items; i != NULL; i = i->next) {
-            /* Set stroke width */
-            double width;
-            if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) {
-                width = sp_units_get_pixels (width_typed, *unit);
-            } else { // percentage
-                gdouble old_w = SP_OBJECT_STYLE (i->data)->stroke_width.computed;
-                width = old_w * width_typed / 100;
-            }
-
-            {
-                Inkscape::CSSOStringStream os_width;
-                os_width << width;
-                sp_repr_css_set_property(css, "stroke-width", os_width.str().c_str());
-            }
-
-            {
-                Inkscape::CSSOStringStream os_ml;
-                os_ml << miterlimit;
-                sp_repr_css_set_property(css, "stroke-miterlimit", os_ml.str().c_str());
-            }
-
-            /* Set dash */
-            sp_stroke_style_set_scaled_dash(css, ndash, dash, offset, width);
-
-            sp_desktop_apply_css_recursive (SP_OBJECT(i->data), css, true);
-        }
-
-        g_free(dash);
-
-        if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) {
-            // reset to 100 percent
-            wadj->set_value(100.0);
-        }
-
-    }
-
-    // we have already changed the items, so set style without changing selection
-    // FIXME: move the above stroke-setting stuff, including percentages, to desktop-style
-    sp_desktop_set_style (desktop, css, false);
-
-    sp_repr_css_attr_unref(css);
-
-    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
-                     _("Set stroke style"));
-
-    spw->set_data("update", GINT_TO_POINTER(FALSE));
-}
-
-/**
- * Callback for when the stroke style's width changes.
- * Causes all line styles to be applied to all selected items.
- */
-static void
-sp_stroke_style_width_changed(Gtk::Container *spw)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    sp_stroke_style_scale_line(spw);
-}
-
-/**
- * Callback for when the stroke style's miterlimit changes.
- * Causes all line styles to be applied to all selected items.
- */
-static void
-sp_stroke_style_miterlimit_changed(Gtk::Container *spw)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    sp_stroke_style_scale_line(spw);
-}
-
-/**
- * Callback for when the stroke style's dash changes.
- * Causes all line styles to be applied to all selected items.
- */
-
-static void
-sp_stroke_style_line_dash_changed(Gtk::Container *spw)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    sp_stroke_style_scale_line(spw);
-}
-
-/**
- * \brief  This routine handles toggle events for buttons in the stroke style
- *         dialog.
- * When activated, this routine gets the data for the various widgets, and then
- * calls the respective routines to update css properties, etc.
- *
- */
-static void
-sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw)
-{
-    if (spw->get_data("update")) {
-        return;
-    }
-
-    if (tb->get_active()) {
-
-        gchar const *join
-            = static_cast<gchar const *>(tb->get_data("join"));
-        gchar const *cap
-            = static_cast<gchar const *>(tb->get_data("cap"));
-
-        if (join) {
-            Gtk::SpinButton *ml = static_cast<Gtk::SpinButton *>(spw->get_data("miterlimit_sb"));
-            ml->set_sensitive(!strcmp(join, "miter"));
-        }
-
-        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
-        /* TODO: Create some standardized method */
-        SPCSSAttr *css = sp_repr_css_attr_new();
-
-        if (join) {
-            sp_repr_css_set_property(css, "stroke-linejoin", join);
-
-            sp_desktop_set_style (desktop, css);
-
-            sp_stroke_style_set_join_buttons(spw, tb);
-        } else if (cap) {
-            sp_repr_css_set_property(css, "stroke-linecap", cap);
-
-            sp_desktop_set_style (desktop, css);
-
-            sp_stroke_style_set_cap_buttons(spw, tb);
-        }
-
-        sp_repr_css_attr_unref(css);
-
-        sp_document_done(sp_desktop_document(desktop), SP_VERB_DIALOG_FILL_STROKE,
-                         _("Set stroke style"));
-    }
-}
-
-/**
- * Updates the join style toggle buttons
- */
-static void
-sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active)
-{
-    Gtk::RadioButton *tb;
-
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_MITER));
-    tb->set_active(active == tb);
-
-    Gtk::SpinButton *ml = static_cast<Gtk::SpinButton *>(spw->get_data("miterlimit_sb"));
-    ml->set_sensitive(active == tb);
-
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_ROUND));
-    tb->set_active(active == tb);
-
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_BEVEL));
-    tb->set_active(active == tb);
-}
-
-/**
- * Updates the cap style toggle buttons
- */
-static void
-sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active)
-{
-    Gtk::RadioButton *tb;
-
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_BUTT));
-    tb->set_active(active == tb);
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_ROUND));
-    tb->set_active(active == tb);
-    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_SQUARE));
-    tb->set_active(active == tb);
-}
-
-/**
- * Sets the current marker in the marker menu.
- */
-static void
-ink_marker_menu_set_current(SPObject *marker, Gtk::OptionMenu *mnu)
-{
-    mnu->set_data("update", GINT_TO_POINTER(TRUE));
-
-    Gtk::Menu *m = mnu->get_menu();
-    if (marker != NULL) {
-        bool mark_is_stock = false;
-        if (SP_OBJECT_REPR(marker)->attribute("inkscape:stockid"))
-            mark_is_stock = true;
-
-        gchar *markname;
-        if (mark_is_stock)
-            markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("inkscape:stockid"));
-        else
-            markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("id"));
-
-        int markpos = ink_marker_menu_get_pos(m, markname);
-        mnu->set_history(markpos);
-
-        g_free (markname);
-    }
-    else {
-        mnu->set_history(0);
-    }
-    mnu->set_data("update", GINT_TO_POINTER(FALSE));
-}
-
-/**
- * Updates the marker menus to highlight the appropriate marker and scroll to
- * that marker.
- */
-static void
-sp_stroke_style_update_marker_menus(Gtk::Container *spw, GSList const *objects)
-{
-    struct { char const *key; int loc; } const keyloc[] = {
-        { "start_mark_menu", SP_MARKER_LOC_START },
-        { "mid_mark_menu", SP_MARKER_LOC_MID },
-        { "end_mark_menu", SP_MARKER_LOC_END }
-    };
-
-    bool all_texts = true;
-    for (GSList *i = (GSList *) objects; i != NULL; i = i->next) {
-        if (!SP_IS_TEXT (i->data)) {
-            all_texts = false;
-        }
-    }
-
-    for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
-        Gtk::OptionMenu *mnu = static_cast<Gtk::OptionMenu *>(spw->get_data(keyloc[i].key));
-        // Per SVG spec, text objects cannot have markers; disable menus if only texts are selected
-        mnu->set_sensitive(!all_texts);
-    }
-
-    // We show markers of the first object in the list only
-    // FIXME: use the first in the list that has the marker of each type, if any
-    SPObject *object = SP_OBJECT(objects->data);
-
-    for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
-        // For all three marker types,
-
-        // find the corresponding menu
-        Gtk::OptionMenu *mnu = static_cast<Gtk::OptionMenu *>(spw->get_data(keyloc[i].key));
-
-        // Quit if we're in update state
-        if (mnu->get_data("update")) {
-            return;
-        }
-
-        if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) {
-            // If the object has this type of markers,
-
-            // Extract the name of the marker that the object uses
-            SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value, SP_OBJECT_DOCUMENT(object));
-            // Scroll the menu to that marker
-            ink_marker_menu_set_current(marker, mnu);
-
-        } else {
-            mnu->set_history(0);
-        }
-    }
-}
-
-
-/**
- * Extract the actual name of the link
- * e.g. get mTriangle from url(#mTriangle).
- * \return Buffer containing the actual name, allocated from GLib;
- * the caller should free the buffer when they no longer need it.
- */
-static SPObject*
-ink_extract_marker_name(gchar const *n, SPDocument *doc)
-{
-    gchar const *p = n;
-    while (*p != '\0' && *p != '#') {
-        p++;
-    }
-
-    if (*p == '\0' || p[1] == '\0') {
-        return NULL;
-    }
-
-    p++;
-    int c = 0;
-    while (p[c] != '\0' && p[c] != ')') {
-        c++;
-    }
-
-    if (p[c] == '\0') {
-        return NULL;
-    }
-
-    gchar* b = g_strdup(p);
-    b[c] = '\0';
-
-    // FIXME: get the document from the object and let the caller pass it in
-    SPObject *marker = doc->getObjectById(b);
-    return marker;
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/stroke-style.h b/src/dialogs/stroke-style.h
deleted file mode 100644 (file)
index b947209..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/** @file
- * @brief  Stroke style dialog
- */
-/* Author:
- *   Lauris Kaplinski <lauris@ximian.com>
- *
- * Copyright (C) 2001 Ximian, Inc.
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_DIALOGS_STROKE_STYLE_H
-#define SEEN_DIALOGS_STROKE_STYLE_H
-
-#include <glib.h>
-
-#include <gtk/gtkwidget.h>
-
-#include "forward.h"
-#include "display/canvas-bpath.h"
-
-GtkWidget *sp_stroke_style_paint_widget_new (void);
-Gtk::Container *sp_stroke_style_line_widget_new (void);
-
-#endif
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/swatches.cpp b/src/dialogs/swatches.cpp
deleted file mode 100644 (file)
index 4546efe..0000000
+++ /dev/null
@@ -1,1213 +0,0 @@
-/** @file
- * @brief Color swatches dialog
- */
-/* Authors:
- *   Jon A. Cruz
- *   John Bintz
- *
- * Copyright (C) 2005 Jon A. Cruz
- * Copyright (C) 2008 John Bintz
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <errno.h>
-
-#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
-#include <gtk/gtkdnd.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkseparatormenuitem.h>
-
-#include <glibmm/i18n.h>
-#include <gdkmm/pixbuf.h>
-#include "inkscape.h"
-#include "desktop.h"
-#include "message-context.h"
-#include "document.h"
-#include "desktop-handles.h"
-#include "extension/db.h"
-#include "inkscape.h"
-#include "svg/svg-color.h"
-#include "desktop-style.h"
-#include "io/sys.h"
-#include "path-prefix.h"
-#include "swatches.h"
-#include "sp-item.h"
-#include "preferences.h"
-
-#include "eek-preview.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-ColorItem::ColorItem() : _isRemove(true){};
-ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) :
-    def( r, g, b, name ),
-    _isRemove(false),
-    _isLive(false),
-    _linkIsTone(false),
-    _linkPercent(0),
-    _linkGray(0),
-    _linkSrc(0)
-{
-}
-
-ColorItem::~ColorItem()
-{
-}
-
-ColorItem::ColorItem(ColorItem const &other) :
-    Inkscape::UI::Previewable()
-{
-    if ( this != &other ) {
-        *this = other;
-    }
-}
-
-ColorItem &ColorItem::operator=(ColorItem const &other)
-{
-    if ( this != &other ) {
-        def = other.def;
-
-        // TODO - correct linkage
-        _linkSrc = other._linkSrc;
-        g_message("Erk!");
-    }
-    return *this;
-}
-
-
-class JustForNow
-{
-public:
-    JustForNow() : _prefWidth(0) {}
-
-    Glib::ustring _name;
-    int _prefWidth;
-    std::vector<ColorItem*> _colors;
-};
-
-static std::vector<JustForNow*> possible;
-
-
-
-typedef enum {
-    APP_X_INKY_COLOR_ID = 0,
-    APP_X_INKY_COLOR = 0,
-    APP_X_COLOR,
-    TEXT_DATA
-} colorFlavorType;
-
-//TODO: warning: deprecated conversion from string constant to â€˜gchar*’
-//
-//Turn out to be warnings that we should probably leave in place. The
-// pointers/types used need to be read-only. So until we correct the using
-// code, those warnings are actually desired. They say "Hey! Fix this". We
-// definitely don't want to hide/ignore them. --JonCruz
-static const GtkTargetEntry sourceColorEntries[] = {
-#if ENABLE_MAGIC_COLORS
-//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
-    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
-#endif // ENABLE_MAGIC_COLORS
-    {"application/x-color", 0, APP_X_COLOR},
-    {"text/plain", 0, TEXT_DATA},
-};
-
-void ColorItem::_dragGetColorData( GtkWidget *widget,
-                                   GdkDragContext *drag_context,
-                                   GtkSelectionData *data,
-                                   guint info,
-                                   guint time,
-                                   gpointer user_data)
-{
-    (void)widget;
-    (void)drag_context;
-    (void)time;
-    static GdkAtom typeXColor = gdk_atom_intern("application/x-color", FALSE);
-    static GdkAtom typeText = gdk_atom_intern("text/plain", FALSE);
-
-    ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-    if ( info == TEXT_DATA ) {
-        gchar* tmp = g_strdup_printf("#%02x%02x%02x", item->def.getR(), item->def.getG(), item->def.getB() );
-
-        gtk_selection_data_set( data,
-                                typeText,
-                                8, // format
-                                (guchar*)tmp,
-                                strlen((const char*)tmp) + 1);
-        g_free(tmp);
-        tmp = 0;
-    } else if ( info == APP_X_INKY_COLOR ) {
-        Glib::ustring paletteName;
-
-        // Find where this thing came from
-        bool found = false;
-        int index = 0;
-        for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end() && !found; ++it ) {
-            JustForNow* curr = *it;
-            index = 0;
-            for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
-                if ( item == *zz ) {
-                    found = true;
-                    paletteName = curr->_name;
-                    break;
-                } else {
-                    index++;
-                }
-            }
-        }
-
-//         if ( found ) {
-//             g_message("Found the color at entry %d in palette '%s'", index, paletteName.c_str() );
-//         } else {
-//             g_message("Unable to find the color");
-//         }
-        int itemCount = 4 + 2 + 1 + paletteName.length();
-
-        guint16* tmp = new guint16[itemCount];
-        tmp[0] = (item->def.getR() << 8) | item->def.getR();
-        tmp[1] = (item->def.getG() << 8) | item->def.getG();
-        tmp[2] = (item->def.getB() << 8) | item->def.getB();
-        tmp[3] = 0xffff;
-        tmp[4] = (item->_isLive || !item->_listeners.empty() || (item->_linkSrc != 0) ) ? 1 : 0;
-
-        tmp[5] = index;
-        tmp[6] = paletteName.length();
-        for ( unsigned int i = 0; i < paletteName.length(); i++ ) {
-            tmp[7 + i] = paletteName[i];
-        }
-        gtk_selection_data_set( data,
-                                typeXColor,
-                                16, // format
-                                reinterpret_cast<const guchar*>(tmp),
-                                itemCount * 2);
-        delete[] tmp;
-    } else {
-        guint16 tmp[4];
-        tmp[0] = (item->def.getR() << 8) | item->def.getR();
-        tmp[1] = (item->def.getG() << 8) | item->def.getG();
-        tmp[2] = (item->def.getB() << 8) | item->def.getB();
-        tmp[3] = 0xffff;
-        gtk_selection_data_set( data,
-                                typeXColor,
-                                16, // format
-                                reinterpret_cast<const guchar*>(tmp),
-                                (3+1) * 2);
-    }
-}
-
-static void dragBegin( GtkWidget *widget, GdkDragContext* dc, gpointer data )
-{
-    (void)widget;
-    ColorItem* item = reinterpret_cast<ColorItem*>(data);
-    if ( item )
-    {
-        if (item->isRemove()){
-            GError *error = NULL;
-            gchar *filepath = (gchar *) g_strdup_printf("%s/remove-color.png", INKSCAPE_PIXMAPDIR);
-            gsize bytesRead = 0;
-            gsize bytesWritten = 0;
-            gchar *localFilename = g_filename_from_utf8( filepath,
-                                                 -1,
-                                                 &bytesRead,
-                                                 &bytesWritten,
-                                                 &error);
-            GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, 32, 24, FALSE, &error);
-            g_free(localFilename);
-            g_free(filepath);
-            gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 );
-            return;
-        }
-
-        Glib::RefPtr<Gdk::Pixbuf> thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, 32, 24 );
-        guint32 fillWith = (0xff000000 & (item->def.getR() << 24))
-                         | (0x00ff0000 & (item->def.getG() << 16))
-                         | (0x0000ff00 & (item->def.getB() <<  8));
-        thumb->fill( fillWith );
-        gtk_drag_set_icon_pixbuf( dc, thumb->gobj(), 0, 0 );
-    }
-
-}
-
-//"drag-drop"
-// gboolean dragDropColorData( GtkWidget *widget,
-//                             GdkDragContext *drag_context,
-//                             gint x,
-//                             gint y,
-//                             guint time,
-//                             gpointer user_data)
-// {
-// // TODO finish
-
-//     return TRUE;
-// }
-
-static void handleClick( GtkWidget* widget, gpointer callback_data ) {
-    (void)widget;
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        item->buttonClicked(false);
-    }
-}
-
-static void handleSecondaryClick( GtkWidget* widget, gint arg1, gpointer callback_data ) {
-    (void)widget;
-    (void)arg1;
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        item->buttonClicked(true);
-    }
-}
-
-static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) {
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-        if ( desktop ) {
-            gchar* msg = g_strdup_printf(_("Color: <b>%s</b>; <b>Click</b> to set fill, <b>Shift+click</b> to set stroke"),
-                                         item->def.descr.c_str());
-            desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg);
-            g_free(msg);
-        }
-    }
-    return FALSE;
-}
-
-static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) {
-    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
-    if ( item ) {
-        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-        if ( desktop ) {
-            desktop->tipsMessageContext()->clear();
-        }
-    }
-    return FALSE;
-}
-
-static GtkWidget* popupMenu = 0;
-static ColorItem* bounceTarget = 0;
-
-static void redirClick( GtkMenuItem *menuitem, gpointer user_data )
-{
-    (void)user_data;
-    if ( bounceTarget ) {
-        handleClick( GTK_WIDGET(menuitem), bounceTarget );
-    }
-}
-
-static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer user_data )
-{
-    (void)user_data;
-    if ( bounceTarget ) {
-        handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget );
-    }
-}
-
-static gboolean handleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data)
-{
-    (void)widget;
-    gboolean handled = FALSE;
-
-    if ( (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) {
-        if ( !popupMenu ) {
-            popupMenu = gtk_menu_new();
-            GtkWidget* child = 0;
-
-            //TRANSLATORS: An item in context menu on a colour in the swatches
-            child = gtk_menu_item_new_with_label(_("Set fill"));
-            g_signal_connect( G_OBJECT(child),
-                              "activate",
-                              G_CALLBACK(redirClick),
-                              user_data);
-            gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
-
-            //TRANSLATORS: An item in context menu on a colour in the swatches
-            child = gtk_menu_item_new_with_label(_("Set stroke"));
-
-            g_signal_connect( G_OBJECT(child),
-                              "activate",
-                              G_CALLBACK(redirSecondaryClick),
-                              user_data);
-            gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
-
-            gtk_widget_show_all(popupMenu);
-        }
-
-        ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-        if ( item ) {
-            bounceTarget = item;
-            if ( popupMenu ) {
-                gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time);
-                handled = TRUE;
-            }
-        }
-    }
-
-    return handled;
-}
-
-static void dieDieDie( GtkObject *obj, gpointer user_data )
-{
-    g_message("die die die %p  %p", obj, user_data );
-}
-
-//TODO: warning: deprecated conversion from string constant to â€˜gchar*’
-//
-//Turn out to be warnings that we should probably leave in place. The
-// pointers/types used need to be read-only. So until we correct the using
-// code, those warnings are actually desired. They say "Hey! Fix this". We
-// definitely don't want to hide/ignore them. --JonCruz
-static const GtkTargetEntry destColorTargets[] = {
-#if ENABLE_MAGIC_COLORS
-//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
-    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
-#endif // ENABLE_MAGIC_COLORS
-    {"application/x-color", 0, APP_X_COLOR},
-};
-
-#include "color.h" // for SP_RGBA32_U_COMPOSE
-
-void ColorItem::_dropDataIn( GtkWidget *widget,
-                             GdkDragContext *drag_context,
-                             gint x, gint y,
-                             GtkSelectionData *data,
-                             guint info,
-                             guint event_time,
-                             gpointer user_data)
-{
-    (void)widget;
-    (void)drag_context;
-    (void)x;
-    (void)y;
-    (void)event_time;
-//     g_message("    droppy droppy   %d", info);
-     switch (info) {
-         case APP_X_INKY_COLOR:
-         {
-             if ( data->length >= 8 ) {
-                 // Careful about endian issues.
-                 guint16* dataVals = (guint16*)data->data;
-                 if ( user_data ) {
-                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-                     if ( item->def.isEditable() ) {
-                         // Shove on in the new value
-                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
-                     }
-                 }
-             }
-             break;
-         }
-         case APP_X_COLOR:
-         {
-             if ( data->length == 8 ) {
-                 // Careful about endian issues.
-                 guint16* dataVals = (guint16*)data->data;
-//                  {
-//                      gchar c[64] = {0};
-//                      sp_svg_write_color( c, 64,
-//                                          SP_RGBA32_U_COMPOSE(
-//                                              0x0ff & (dataVals[0] >> 8),
-//                                              0x0ff & (dataVals[1] >> 8),
-//                                              0x0ff & (dataVals[2] >> 8),
-//                                              0xff // can't have transparency in the color itself
-//                                              //0x0ff & (data->data[3] >> 8),
-//                                              ));
-//                  }
-                 if ( user_data ) {
-                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-                     if ( item->def.isEditable() ) {
-                         // Shove on in the new value
-                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
-                     }
-                 }
-             }
-             break;
-         }
-         default:
-             g_message("unknown drop type");
-     }
-
-}
-
-static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b )
-{
-    bool changed = false;
-
-    if ( node ) {
-        gchar const * val = node->attribute("inkscape:x-fill-tag");
-        if ( val  && (match == val) ) {
-            SPObject *obj = document->getObjectByRepr( node );
-
-            gchar c[64] = {0};
-            sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
-            SPCSSAttr *css = sp_repr_css_attr_new();
-            sp_repr_css_set_property( css, "fill", c );
-
-            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
-            ((SPItem*)obj)->updateRepr();
-
-            changed = true;
-        }
-
-        val = node->attribute("inkscape:x-stroke-tag");
-        if ( val  && (match == val) ) {
-            SPObject *obj = document->getObjectByRepr( node );
-
-            gchar c[64] = {0};
-            sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
-            SPCSSAttr *css = sp_repr_css_attr_new();
-            sp_repr_css_set_property( css, "stroke", c );
-
-            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
-            ((SPItem*)obj)->updateRepr();
-
-            changed = true;
-        }
-
-        Inkscape::XML::Node* first = node->firstChild();
-        changed |= bruteForce( document, first, match, r, g, b );
-
-        changed |= bruteForce( document, node->next(), match, r, g, b );
-    }
-
-    return changed;
-}
-
-void ColorItem::_colorDefChanged(void* data)
-{
-    ColorItem* item = reinterpret_cast<ColorItem*>(data);
-    if ( item ) {
-        for ( std::vector<Gtk::Widget*>::iterator it =  item->_previews.begin(); it != item->_previews.end(); ++it ) {
-            Gtk::Widget* widget = *it;
-            if ( IS_EEK_PREVIEW(widget->gobj()) ) {
-                EekPreview * preview = EEK_PREVIEW(widget->gobj());
-                eek_preview_set_color( preview,
-                                       (item->def.getR() << 8) | item->def.getR(),
-                                       (item->def.getG() << 8) | item->def.getG(),
-                                       (item->def.getB() << 8) | item->def.getB() );
-
-                eek_preview_set_linked( preview, (LinkType)((item->_linkSrc ? PREVIEW_LINK_IN:0)
-                                                            | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT)
-                                                            | (item->_isLive ? PREVIEW_LINK_OTHER:0)) );
-
-                widget->queue_draw();
-            }
-        }
-
-        for ( std::vector<ColorItem*>::iterator it = item->_listeners.begin(); it != item->_listeners.end(); ++it ) {
-            guint r = item->def.getR();
-            guint g = item->def.getG();
-            guint b = item->def.getB();
-
-            if ( (*it)->_linkIsTone ) {
-                r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100;
-                g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100;
-                b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100;
-            } else {
-                r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100;
-                g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100;
-                b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100;
-            }
-
-            (*it)->def.setRGB( r, g, b );
-        }
-
-
-        // Look for objects using this color
-        {
-            SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-            if ( desktop ) {
-                SPDocument* document = sp_desktop_document( desktop );
-                Inkscape::XML::Node *rroot =  sp_document_repr_root( document );
-                if ( rroot ) {
-
-                    // Find where this thing came from
-                    Glib::ustring paletteName;
-                    bool found = false;
-                    int index = 0;
-                    for ( std::vector<JustForNow*>::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) {
-                        JustForNow* curr = *it2;
-                        index = 0;
-                        for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
-                            if ( item == *zz ) {
-                                found = true;
-                                paletteName = curr->_name;
-                                break;
-                            } else {
-                                index++;
-                            }
-                        }
-                    }
-
-                    if ( !paletteName.empty() ) {
-                        gchar* str = g_strdup_printf("%d|", index);
-                        paletteName.insert( 0, str );
-                        g_free(str);
-                        str = 0;
-
-                        if ( bruteForce( document, rroot, paletteName, item->def.getR(), item->def.getG(), item->def.getB() ) ) {
-                            sp_document_done( document , SP_VERB_DIALOG_SWATCHES, 
-                                              _("Change color definition"));
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-
-Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio)
-{
-    Gtk::Widget* widget = 0;
-    if ( style == PREVIEW_STYLE_BLURB) {
-        Gtk::Label *lbl = new Gtk::Label(def.descr);
-        lbl->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
-        widget = lbl;
-    } else {
-//         Glib::ustring blank("          ");
-//         if ( size == Inkscape::ICON_SIZE_MENU || size == Inkscape::ICON_SIZE_DECORATION ) {
-//             blank = " ";
-//         }
-
-        GtkWidget* eekWidget = eek_preview_new();
-        EekPreview * preview = EEK_PREVIEW(eekWidget);
-        Gtk::Widget* newBlot = Glib::wrap(eekWidget);
-
-        eek_preview_set_color( preview, (def.getR() << 8) | def.getR(), (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB());
-        if ( _isRemove ) {
-            GError *error = NULL;
-            gchar *filepath = (gchar *) g_strdup_printf("%s/remove-color.png", INKSCAPE_PIXMAPDIR);
-            gsize bytesRead = 0;
-            gsize bytesWritten = 0;
-            gchar *localFilename = g_filename_from_utf8( filepath,
-                                                 -1,
-                                                 &bytesRead,
-                                                 &bytesWritten,
-                                                 &error);
-            GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error);
-            if (!pixbuf) {
-                g_warning("Null pixbuf for %p [%s]", localFilename, localFilename );
-            }
-            g_free(localFilename);
-            g_free(filepath);
-
-            eek_preview_set_pixbuf( preview, pixbuf );
-        }
-
-        eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::PreviewSize)size, ratio );
-        eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0)
-                                                    | (_listeners.empty() ? 0:PREVIEW_LINK_OUT)
-                                                    | (_isLive ? PREVIEW_LINK_OTHER:0)) );
-
-        def.addCallback( _colorDefChanged, this );
-
-        GValue val = {0, {{0}, {0}}};
-        g_value_init( &val, G_TYPE_BOOLEAN );
-        g_value_set_boolean( &val, FALSE );
-        g_object_set_property( G_OBJECT(preview), "focus-on-click", &val );
-
-/*
-        Gtk::Button *btn = new Gtk::Button(blank);
-        Gdk::Color color;
-        color.set_rgb((_r << 8)|_r, (_g << 8)|_g, (_b << 8)|_b);
-        btn->modify_bg(Gtk::STATE_NORMAL, color);
-        btn->modify_bg(Gtk::STATE_ACTIVE, color);
-        btn->modify_bg(Gtk::STATE_PRELIGHT, color);
-        btn->modify_bg(Gtk::STATE_SELECTED, color);
-
-        Gtk::Widget* newBlot = btn;
-*/
-
-        tips.set_tip((*newBlot), def.descr);
-
-/*
-        newBlot->signal_clicked().connect( sigc::mem_fun(*this, &ColorItem::buttonClicked) );
-
-        sigc::signal<void> type_signal_something;
-*/
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "clicked",
-                          G_CALLBACK(handleClick),
-                          this);
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "alt-clicked",
-                          G_CALLBACK(handleSecondaryClick),
-                          this);
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "button-press-event",
-                          G_CALLBACK(handleButtonPress),
-                          this);
-
-        gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()),
-                             GDK_BUTTON1_MASK,
-                             sourceColorEntries,
-                             G_N_ELEMENTS(sourceColorEntries),
-                             GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) );
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "drag-data-get",
-                          G_CALLBACK(ColorItem::_dragGetColorData),
-                          this);
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "drag-begin",
-                          G_CALLBACK(dragBegin),
-                          this );
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "enter-notify-event",
-                          G_CALLBACK(handleEnterNotify),
-                          this);
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "leave-notify-event",
-                          G_CALLBACK(handleLeaveNotify),
-                          this);
-
-//         g_signal_connect( G_OBJECT(newBlot->gobj()),
-//                           "drag-drop",
-//                           G_CALLBACK(dragDropColorData),
-//                           this);
-
-        if ( def.isEditable() )
-        {
-            gtk_drag_dest_set( GTK_WIDGET(newBlot->gobj()),
-                               GTK_DEST_DEFAULT_ALL,
-                               destColorTargets,
-                               G_N_ELEMENTS(destColorTargets),
-                               GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
-
-
-            g_signal_connect( G_OBJECT(newBlot->gobj()),
-                              "drag-data-received",
-                              G_CALLBACK(_dropDataIn),
-                              this );
-        }
-
-        g_signal_connect( G_OBJECT(newBlot->gobj()),
-                          "destroy",
-                          G_CALLBACK(dieDieDie),
-                          this);
-
-
-        widget = newBlot;
-    }
-
-    _previews.push_back( widget );
-
-    return widget;
-}
-
-void ColorItem::buttonClicked(bool secondary)
-{
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    if (!desktop) return;
-    char const * attrName = secondary ? "stroke" : "fill";
-
-    gchar c[64];
-    if (!_isRemove){
-        guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff;
-        sp_svg_write_color(c, sizeof(c), rgba);
-    }
-
-    SPCSSAttr *css = sp_repr_css_attr_new();
-    sp_repr_css_set_property( css, attrName, _isRemove ? "none" : c );
-    sp_desktop_set_style(desktop, css);
-    sp_repr_css_attr_unref(css);
-
-    if (_isRemove){
-        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
-                      secondary? _("Remove stroke color") : _("Remove fill color"));
-    } else {
-        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
-                      secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"));
-    }
-}
-
-static char* trim( char* str ) {
-    char* ret = str;
-    while ( *str && (*str == ' ' || *str == '\t') ) {
-        str++;
-    }
-    ret = str;
-    while ( *str ) {
-        str++;
-    }
-    str--;
-    while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) {
-        *str-- = 0;
-    }
-    return ret;
-}
-
-void skipWhitespace( char*& str ) {
-    while ( *str == ' ' || *str == '\t' ) {
-        str++;
-    }
-}
-
-bool parseNum( char*& str, int& val ) {
-    val = 0;
-    while ( '0' <= *str && *str <= '9' ) {
-        val = val * 10 + (*str - '0');
-        str++;
-    }
-    bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n');
-    return retval;
-}
-
-
-static bool getBlock( std::string& dst, guchar ch, std::string const str )
-{
-    bool good = false;
-    std::string::size_type pos = str.find(ch);
-    if ( pos != std::string::npos )
-    {
-        std::string::size_type pos2 = str.find( '(', pos );
-        if ( pos2 != std::string::npos ) {
-            std::string::size_type endPos = str.find( ')', pos2 );
-            if ( endPos != std::string::npos ) {
-                dst = str.substr( pos2 + 1, (endPos - pos2 - 1) );
-                good = true;
-            }
-        }
-    }
-    return good;
-}
-
-static bool popVal( guint64& numVal, std::string& str )
-{
-    bool good = false;
-    std::string::size_type endPos = str.find(',');
-    if ( endPos == std::string::npos ) {
-        endPos = str.length();
-    }
-
-    if ( endPos != std::string::npos && endPos > 0 ) {
-        std::string xxx = str.substr( 0, endPos );
-        const gchar* ptr = xxx.c_str();
-        gchar* endPtr = 0;
-        numVal = g_ascii_strtoull( ptr, &endPtr, 10 );
-        if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) {
-            // overflow
-        } else if ( (numVal == 0) && (endPtr == ptr) ) {
-            // failed conversion
-        } else {
-            good = true;
-            str.erase( 0, endPos + 1 );
-        }
-    }
-
-    return good;
-}
-
-void ColorItem::_wireMagicColors( void* p )
-{
-    JustForNow* onceMore = reinterpret_cast<JustForNow*>(p);
-    if ( onceMore )
-    {
-        for ( std::vector<ColorItem*>::iterator it = onceMore->_colors.begin(); it != onceMore->_colors.end(); ++it )
-        {
-            std::string::size_type pos = (*it)->def.descr.find("*{");
-            if ( pos != std::string::npos )
-            {
-                std::string subby = (*it)->def.descr.substr( pos + 2 );
-                std::string::size_type endPos = subby.find("}*");
-                if ( endPos != std::string::npos )
-                {
-                    subby.erase( endPos );
-                    //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str());
-                    //g_message("               '%s'", subby.c_str());
-
-                    if ( subby.find('E') != std::string::npos )
-                    {
-                        (*it)->def.setEditable( true );
-                    }
-
-                    if ( subby.find('L') != std::string::npos )
-                    {
-                        (*it)->_isLive = true;
-                    }
-
-                    std::string part;
-                    // Tint. index + 1 more val.
-                    if ( getBlock( part, 'T', subby ) ) {
-                        guint64 colorIndex = 0;
-                        if ( popVal( colorIndex, part ) ) {
-                            guint64 percent = 0;
-                            if ( popVal( percent, part ) ) {
-                                (*it)->_linkTint( *(onceMore->_colors[colorIndex]), percent );
-                            }
-                        }
-                    }
-
-                    // Shade/tone. index + 1 or 2 more val.
-                    if ( getBlock( part, 'S', subby ) ) {
-                        guint64 colorIndex = 0;
-                        if ( popVal( colorIndex, part ) ) {
-                            guint64 percent = 0;
-                            if ( popVal( percent, part ) ) {
-                                guint64 grayLevel = 0;
-                                if ( !popVal( grayLevel, part ) ) {
-                                    grayLevel = 0;
-                                }
-                                (*it)->_linkTone( *(onceMore->_colors[colorIndex]), percent, grayLevel );
-                            }
-                        }
-                    }
-
-                }
-            }
-        }
-    }
-}
-
-
-void ColorItem::_linkTint( ColorItem& other, int percent )
-{
-    if ( !_linkSrc )
-    {
-        other._listeners.push_back(this);
-        _linkIsTone = false;
-        _linkPercent = percent;
-        if ( _linkPercent > 100 )
-            _linkPercent = 100;
-        if ( _linkPercent < 0 )
-            _linkPercent = 0;
-        _linkGray = 0;
-        _linkSrc = &other;
-
-        ColorItem::_colorDefChanged(&other);
-    }
-}
-
-void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel )
-{
-    if ( !_linkSrc )
-    {
-        other._listeners.push_back(this);
-        _linkIsTone = true;
-        _linkPercent = percent;
-        if ( _linkPercent > 100 )
-            _linkPercent = 100;
-        if ( _linkPercent < 0 )
-            _linkPercent = 0;
-        _linkGray = grayLevel;
-        _linkSrc = &other;
-
-        ColorItem::_colorDefChanged(&other);
-    }
-}
-
-
-void _loadPaletteFile( gchar const *filename )
-{
-    char block[1024];
-    FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" );
-    if ( f ) {
-        char* result = fgets( block, sizeof(block), f );
-        if ( result ) {
-            if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) {
-                bool inHeader = true;
-                bool hasErr = false;
-
-                JustForNow *onceMore = new JustForNow();
-
-                do {
-                    result = fgets( block, sizeof(block), f );
-                    block[sizeof(block) - 1] = 0;
-                    if ( result ) {
-                        if ( block[0] == '#' ) {
-                            // ignore comment
-                        } else {
-                            char *ptr = block;
-                            // very simple check for header versus entry
-                            while ( *ptr == ' ' || *ptr == '\t' ) {
-                                ptr++;
-                            }
-                            if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) {
-                                // blank line. skip it.
-                            } else if ( '0' <= *ptr && *ptr <= '9' ) {
-                                // should be an entry link
-                                inHeader = false;
-                                ptr = block;
-                                Glib::ustring name("");
-                                int r = 0;
-                                int g = 0;
-                                int b = 0;
-                                skipWhitespace(ptr);
-                                if ( *ptr ) {
-                                    hasErr = parseNum(ptr, r);
-                                    if ( !hasErr ) {
-                                        skipWhitespace(ptr);
-                                        hasErr = parseNum(ptr, g);
-                                    }
-                                    if ( !hasErr ) {
-                                        skipWhitespace(ptr);
-                                        hasErr = parseNum(ptr, b);
-                                    }
-                                    if ( !hasErr && *ptr ) {
-                                        char* n = trim(ptr);
-                                        if (n != NULL) {
-                                            name = n;
-                                        }
-                                    }
-                                    if ( !hasErr ) {
-                                        // Add the entry now
-                                        Glib::ustring nameStr(name);
-                                        ColorItem* item = new ColorItem( r, g, b, nameStr );
-                                        onceMore->_colors.push_back(item);
-                                    }
-                                } else {
-                                    hasErr = true;
-                                }
-                            } else {
-                                if ( !inHeader ) {
-                                    // Hmmm... probably bad. Not quite the format we want?
-                                    hasErr = true;
-                                } else {
-                                    char* sep = strchr(result, ':');
-                                    if ( sep ) {
-                                        *sep = 0;
-                                        char* val = trim(sep + 1);
-                                        char* name = trim(result);
-                                        if ( *name ) {
-                                            if ( strcmp( "Name", name ) == 0 )
-                                            {
-                                                onceMore->_name = val;
-                                            }
-                                            else if ( strcmp( "Columns", name ) == 0 )
-                                            {
-                                                gchar* endPtr = 0;
-                                                guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 );
-                                                if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) {
-                                                    // overflow
-                                                } else if ( (numVal == 0) && (endPtr == val) ) {
-                                                    // failed conversion
-                                                } else {
-                                                    onceMore->_prefWidth = numVal;
-                                                }
-                                            }
-                                        } else {
-                                            // error
-                                            hasErr = true;
-                                        }
-                                    } else {
-                                        // error
-                                        hasErr = true;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } while ( result && !hasErr );
-                if ( !hasErr ) {
-                    possible.push_back(onceMore);
-#if ENABLE_MAGIC_COLORS
-                    ColorItem::_wireMagicColors( onceMore );
-#endif // ENABLE_MAGIC_COLORS
-                } else {
-                    delete onceMore;
-                }
-            }
-        }
-
-        fclose(f);
-    }
-}
-
-static void loadEmUp()
-{
-    static bool beenHere = false;
-    if ( !beenHere ) {
-        beenHere = true;
-
-        std::list<gchar *> sources;
-        sources.push_back( profile_path("palettes") );
-        sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) );
-        sources.push_back( g_strdup(CREATE_PALETTESDIR) );
-
-        // Use this loop to iterate through a list of possible document locations.
-        while (!sources.empty()) {
-            gchar *dirname = sources.front();
-
-            if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS )
-                && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) {
-                GError *err = 0;
-                GDir *directory = g_dir_open(dirname, 0, &err);
-                if (!directory) {
-                    gchar *safeDir = Inkscape::IO::sanitizeString(dirname);
-                    g_warning(_("Palettes directory (%s) is unavailable."), safeDir);
-                    g_free(safeDir);
-                } else {
-                    gchar *filename = 0;
-                    while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
-                        gchar* lower = g_ascii_strdown( filename, -1 );
-//                        if ( g_str_has_suffix(lower, ".gpl") ) {
-                            gchar* full = g_build_filename(dirname, filename, NULL);
-                            if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) {
-                                _loadPaletteFile(full);
-                            }
-                            g_free(full);
-//                      }
-                        g_free(lower);
-                    }
-                    g_dir_close(directory);
-                }
-            }
-
-            // toss the dirname
-            g_free(dirname);
-            sources.pop_front();
-        }
-    }
-}
-
-
-
-
-
-
-
-
-
-SwatchesPanel& SwatchesPanel::getInstance()
-{
-    return *new SwatchesPanel();
-}
-
-
-/**
- * Constructor
- */
-SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
-    Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true),
-    _holder(0)
-{
-    Gtk::RadioMenuItem* hotItem = 0;
-    _holder = new PreviewHolder();
-    _remove = new ColorItem();
-    loadEmUp();
-    if ( !possible.empty() ) {
-        JustForNow* first = 0;
-        Glib::ustring targetName;
-        if ( !_prefs_path.empty() ) {
-            Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-            targetName = prefs->getString(_prefs_path + "/palette");
-            if (!targetName.empty()) {
-                for ( std::vector<JustForNow*>::iterator iter = possible.begin(); iter != possible.end(); ++iter ) {
-                    if ( (*iter)->_name == targetName ) {
-                        first = *iter;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if ( !first ) {
-            first = possible.front();
-        }
-
-        if ( first->_prefWidth > 0 ) {
-            _holder->setColumnPref( first->_prefWidth );
-        }
-        _holder->freezeUpdates();
-        _holder->addPreview(_remove);
-        for ( std::vector<ColorItem*>::iterator it = first->_colors.begin(); it != first->_colors.end(); it++ ) {
-            _holder->addPreview(*it);
-        }
-        _holder->thawUpdates();
-
-        Gtk::RadioMenuItem::Group groupOne;
-
-        int i = 0;
-        for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end(); it++ ) {
-            JustForNow* curr = *it;
-            Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name));
-            if ( curr == first ) {
-                hotItem = single;
-            }
-            _regItem( single, 3, i );
-            i++;
-        }
-    }
-
-
-    _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET);
-    _setTargetFillable(_holder);
-
-    show_all_children();
-
-    restorePanelPrefs();
-    if ( hotItem ) {
-        hotItem->set_active();
-    }
-}
-
-SwatchesPanel::~SwatchesPanel()
-{
-    if (_remove) delete _remove;
-    if (_holder) delete _holder;
-}
-
-void SwatchesPanel::setOrientation( Gtk::AnchorType how )
-{
-    // Must call the parent class or bad things might happen
-    Inkscape::UI::Widget::Panel::setOrientation( how );
-
-    if ( _holder )
-    {
-        _holder->setOrientation( Gtk::ANCHOR_SOUTH );
-    }
-}
-
-void SwatchesPanel::_handleAction( int setId, int itemId )
-{
-    switch( setId ) {
-        case 3:
-        {
-            if ( itemId >= 0 && itemId < static_cast<int>(possible.size()) ) {
-                _holder->clear();
-                JustForNow* curr = possible[itemId];
-
-                if ( !_prefs_path.empty() ) {
-                    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-                    prefs->setString(_prefs_path + "/palette", curr->_name);
-                }
-
-                if ( curr->_prefWidth > 0 ) {
-                    _holder->setColumnPref( curr->_prefWidth );
-                }
-                _holder->freezeUpdates();
-                _holder->addPreview(_remove);
-                for ( std::vector<ColorItem*>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); it++ ) {
-                    _holder->addPreview(*it);
-                }
-                _holder->thawUpdates();
-            }
-        }
-        break;
-    }
-}
-
-} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/swatches.h b/src/dialogs/swatches.h
deleted file mode 100644 (file)
index 00c73ff..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/** @file
- * @brief Color swatches dialog
- */
-/* Authors:
- *   Jon A. Cruz
- *
- * Copyright (C) 2005 Jon A. Cruz
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-#ifndef SEEN_DIALOGS_SWATCHES_H
-#define SEEN_DIALOGS_SWATCHES_H
-
-#include <gtkmm/textview.h>
-#include <gtkmm/tooltips.h>
-
-#include "ui/widget/panel.h"
-#include "ui/previewholder.h"
-#include "dialogs/eek-color-def.h"
-
-using eek::ColorDef;
-
-namespace Inkscape {
-namespace UI {
-namespace Dialogs {
-
-
-void _loadPaletteFile( gchar const *filename );
-
-/**
- * The color swatch you see on screen as a clickable box.
- */
-class ColorItem : public Inkscape::UI::Previewable
-{
-    friend void _loadPaletteFile( gchar const *filename );
-public:
-    ColorItem();
-    ColorItem( unsigned int r, unsigned int g, unsigned int b,
-               Glib::ustring& name );
-    virtual ~ColorItem();
-    ColorItem(ColorItem const &other);
-    virtual ColorItem &operator=(ColorItem const &other);
-    virtual Gtk::Widget* getPreview(PreviewStyle style,
-                                    ViewType view,
-                                    ::PreviewSize size,
-                                    guint ratio);
-    void buttonClicked(bool secondary = false);
-    bool isRemove(){ return _isRemove; }
-    ColorDef def;
-
-private:
-    static void _dropDataIn( GtkWidget *widget,
-                             GdkDragContext *drag_context,
-                             gint x, gint y,
-                             GtkSelectionData *data,
-                             guint info,
-                             guint event_time,
-                             gpointer user_data);
-
-    static void _dragGetColorData( GtkWidget *widget,
-                                   GdkDragContext *drag_context,
-                                   GtkSelectionData *data,
-                                   guint info,
-                                   guint time,
-                                   gpointer user_data);
-
-    static void _wireMagicColors( void* p );
-    static void _colorDefChanged(void* data);
-
-    void _linkTint( ColorItem& other, int percent );
-    void _linkTone( ColorItem& other, int percent, int grayLevel );
-
-    Gtk::Tooltips tips;
-    std::vector<Gtk::Widget*> _previews;
-
-    bool _isRemove;
-    bool _isLive;
-    bool _linkIsTone;
-    int _linkPercent;
-    int _linkGray;
-    ColorItem* _linkSrc;
-    std::vector<ColorItem*> _listeners;
-};
-       
-class RemoveColorItem;
-
-/**
- * A panel that displays color swatches.
- */
-class SwatchesPanel : public Inkscape::UI::Widget::Panel
-{
-public:
-    SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches");
-    virtual ~SwatchesPanel();
-
-    static SwatchesPanel& getInstance();
-    virtual void setOrientation( Gtk::AnchorType how );
-
-protected:
-    virtual void _handleAction( int setId, int itemId );
-
-private:
-    SwatchesPanel(SwatchesPanel const &); // no copy
-    SwatchesPanel &operator=(SwatchesPanel const &); // no assign
-
-    static SwatchesPanel* instance;
-
-    PreviewHolder* _holder;
-    ColorItem* _remove;
-};
-
-} //namespace Dialogs
-} //namespace UI
-} //namespace Inkscape
-
-
-
-#endif // SEEN_SWATCHES_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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/unclump.cpp b/src/dialogs/unclump.cpp
deleted file mode 100644 (file)
index aebcfd9..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/** @file
- * @brief Unclumping objects
- */
-/* Authors:
- *   bulia byak
- *
- * Copyright (C) 2005 Authors
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <algorithm>
-#include <map>
-#include "sp-item.h"
-
-
-// Taking bbox of an item is an expensive operation, and we need to do it many times, so here we
-// cache the centers, widths, and heights of items
-
-//FIXME: make a class with these cashes as members instead of globals 
-std::map<const gchar *, Geom::Point> c_cache;
-std::map<const gchar *, Geom::Point> wh_cache;
-
-/**
-Center of bbox of item
-*/
-Geom::Point
-unclump_center (SPItem *item)
-{
-    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(item));
-    if ( i != c_cache.end() ) {
-        return i->second;
-    }
-
-    Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item));
-    if (r) {
-       Geom::Point const c = r->midpoint();
-       c_cache[SP_OBJECT_ID(item)] = c;
-        return c; 
-    } else {
-       // FIXME
-        return Geom::Point(0, 0);
-    }
-}
-
-Geom::Point
-unclump_wh (SPItem *item)
-{
-    Geom::Point wh;
-    std::map<const gchar *, Geom::Point>::iterator i = wh_cache.find(SP_OBJECT_ID(item));
-    if ( i != wh_cache.end() ) {
-        wh = i->second;
-    } else {
-        Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item));
-       if (r) {
-            wh = r->dimensions();
-            wh_cache[SP_OBJECT_ID(item)] = wh;
-        } else {
-           wh = Geom::Point(0, 0);
-        }
-    }
-
-    return wh;
-}
-
-/**
-Distance between "edges" of item1 and item2. An item is considered to be an ellipse inscribed into its w/h, 
-so its radius (distance from center to edge) depends on the w/h and the angle towards the other item.
-May be negative if the edge of item1 is between the center and the edge of item2.
-*/
-double
-unclump_dist (SPItem *item1, SPItem *item2)
-{
-       Geom::Point c1 = unclump_center (item1);
-       Geom::Point c2 = unclump_center (item2);
-
-       Geom::Point wh1 = unclump_wh (item1);
-       Geom::Point wh2 = unclump_wh (item2);
-
-       // angle from each item's center to the other's, unsqueezed by its w/h, normalized to 0..pi/2
-       double a1 = atan2 ((c2 - c1)[Geom::Y], (c2 - c1)[Geom::X] * wh1[Geom::Y]/wh1[Geom::X]);
-       a1 = fabs (a1);
-       if (a1 > M_PI/2) a1 = M_PI - a1;
-
-       double a2 = atan2 ((c1 - c2)[Geom::Y], (c1 - c2)[Geom::X] * wh2[Geom::Y]/wh2[Geom::X]);
-       a2 = fabs (a2);
-       if (a2 > M_PI/2) a2 = M_PI - a2;
-
-       // get the radius of each item for the given angle
-       double r1 = 0.5 * (wh1[Geom::X] + (wh1[Geom::Y] - wh1[Geom::X]) * (a1/(M_PI/2)));
-       double r2 = 0.5 * (wh2[Geom::X] + (wh2[Geom::Y] - wh2[Geom::X]) * (a2/(M_PI/2)));
-
-       // dist between centers minus angle-adjusted radii
-       double dist_r =  (Geom::L2 (c2 - c1) - r1 - r2);
-
-       double stretch1 = wh1[Geom::Y]/wh1[Geom::X];
-       double stretch2 = wh2[Geom::Y]/wh2[Geom::X];
-
-       if ((stretch1 > 1.5 || stretch1 < 0.66) && (stretch2 > 1.5 || stretch2 < 0.66)) {
-
-               std::vector<double> dists;
-               dists.push_back (dist_r);
-
-               // If both objects are not circle-like, find dists between four corners
-               std::vector<Geom::Point> c1_points(2);
-               {
-                       double y_closest;
-                       if (c2[Geom::Y] > c1[Geom::Y] + wh1[Geom::Y]/2) {
-                               y_closest = c1[Geom::Y] + wh1[Geom::Y]/2;
-                       } else if (c2[Geom::Y] < c1[Geom::Y] - wh1[Geom::Y]/2) {
-                               y_closest = c1[Geom::Y] - wh1[Geom::Y]/2;
-                       } else {
-                               y_closest = c2[Geom::Y];
-                       }
-                       c1_points[0] = Geom::Point (c1[Geom::X], y_closest);
-                       double x_closest;
-                       if (c2[Geom::X] > c1[Geom::X] + wh1[Geom::X]/2) {
-                               x_closest = c1[Geom::X] + wh1[Geom::X]/2;
-                       } else if (c2[Geom::X] < c1[Geom::X] - wh1[Geom::X]/2) {
-                               x_closest = c1[Geom::X] - wh1[Geom::X]/2;
-                       } else {
-                               x_closest = c2[Geom::X];
-                       }
-                       c1_points[1] = Geom::Point (x_closest, c1[Geom::Y]);
-               }
-
-
-               std::vector<Geom::Point> c2_points(2);
-               {
-                       double y_closest;
-                       if (c1[Geom::Y] > c2[Geom::Y] + wh2[Geom::Y]/2) {
-                               y_closest = c2[Geom::Y] + wh2[Geom::Y]/2;
-                       } else if (c1[Geom::Y] < c2[Geom::Y] - wh2[Geom::Y]/2) {
-                               y_closest = c2[Geom::Y] - wh2[Geom::Y]/2;
-                       } else {
-                               y_closest = c1[Geom::Y];
-                       }
-                       c2_points[0] = Geom::Point (c2[Geom::X], y_closest);
-                       double x_closest;
-                       if (c1[Geom::X] > c2[Geom::X] + wh2[Geom::X]/2) {
-                               x_closest = c2[Geom::X] + wh2[Geom::X]/2;
-                       } else if (c1[Geom::X] < c2[Geom::X] - wh2[Geom::X]/2) {
-                               x_closest = c2[Geom::X] - wh2[Geom::X]/2;
-                       } else {
-                               x_closest = c1[Geom::X];
-                       }
-                       c2_points[1] = Geom::Point (x_closest, c2[Geom::Y]);
-               }
-
-               for (int i = 0; i < 2; i ++) {
-                       for (int j = 0; j < 2; j ++) {
-                               dists.push_back (Geom::L2 (c1_points[i] - c2_points[j]));
-                       }
-               }
-
-               // return the minimum of all dists
-               return *std::min_element(dists.begin(), dists.end());
-       } else {
-               return dist_r;
-       }
-}
-
-/**
-Average unclump_dist from item to others
-*/
-double unclump_average (SPItem *item, GSList *others)
-{
-    int n = 0;
-    double sum = 0;
-
-    for (GSList *i = others; i != NULL; i = i->next) {
-        SPItem *other = SP_ITEM (i->data);
-
-        if (other == item)
-            continue;
-
-        n++;
-        sum += unclump_dist (item, other);
-    }
-
-    if (n != 0)
-        return sum/n;
-    else
-        return 0;
-}
-
-/**
-Closest to item among others
- */
-SPItem *unclump_closest (SPItem *item, GSList *others)
-{
-    double min = HUGE_VAL;
-    SPItem *closest = NULL;
-
-    for (GSList *i = others; i != NULL; i = i->next) {
-        SPItem *other = SP_ITEM (i->data);
-
-        if (other == item)
-            continue;
-
-        double dist = unclump_dist (item, other);
-        if (dist < min && fabs (dist) < 1e6) {
-            min = dist;
-            closest = other;
-        }
-    }
-
-    return closest;
-}
-
-/**
-Most distant from item among others
- */
-SPItem *unclump_farest (SPItem *item, GSList *others)
-{
-    double max = -HUGE_VAL;
-    SPItem *farest = NULL;
-
-    for (GSList *i = others; i != NULL; i = i->next) {
-        SPItem *other = SP_ITEM (i->data);
-
-        if (other == item)
-            continue;
-
-        double dist = unclump_dist (item, other);
-        if (dist > max && fabs (dist) < 1e6) {
-            max = dist;
-            farest = other;
-        }
-    }
-
-    return farest;
-}
-
-/**
-Removes from the \a rest list those items that are "behind" \a closest as seen from \a item,
-i.e. those on the other side of the line through \a closest perpendicular to the direction from \a
-item to \a closest. Returns a newly created list which must be freed.
- */
-GSList *
-unclump_remove_behind (SPItem *item, SPItem *closest, GSList *rest)
-{
-    Geom::Point it = unclump_center (item);
-    Geom::Point p1 = unclump_center (closest);
-
-    // perpendicular through closest to the direction to item:
-    Geom::Point perp = Geom::rot90(it - p1);
-    Geom::Point p2 = p1 + perp;
-
-    // get the standard Ax + By + C = 0 form for p1-p2:
-    double A = p1[Geom::Y] - p2[Geom::Y];
-    double B = p2[Geom::X] - p1[Geom::X];
-    double C = p2[Geom::Y] * p1[Geom::X] - p1[Geom::Y] * p2[Geom::X];
-
-    // substitute the item into it:
-    double val_item = A * it[Geom::X] + B * it[Geom::Y] + C;
-
-    GSList *out = NULL;
-
-    for (GSList *i = rest; i != NULL; i = i->next) {
-        SPItem *other = SP_ITEM (i->data);
-
-        if (other == item)
-            continue;
-
-        Geom::Point o = unclump_center (other);
-        double val_other = A * o[Geom::X] + B * o[Geom::Y] + C;
-
-        if (val_item * val_other <= 1e-6) {
-            // different signs, which means item and other are on the different sides of p1-p2 line; skip
-        } else {
-            out = g_slist_prepend (out, other);
-        }
-    }
-
-    return out;
-}
-
-/**
-Moves \a what away from \a from by \a dist
- */
-void
-unclump_push (SPItem *from, SPItem *what, double dist)
-{
-    Geom::Point it = unclump_center (what);
-    Geom::Point p = unclump_center (from);
-    Geom::Point by = dist * Geom::unit_vector (- (p - it));
-
-    Geom::Matrix move = Geom::Translate (by);
-
-    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(what));
-    if ( i != c_cache.end() ) {
-        i->second *= move;
-    }
-
-    //g_print ("push %s at %g,%g from %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[Geom::X],it[Geom::Y], p[Geom::X],p[Geom::Y], by[Geom::X],by[Geom::Y], dist);
-
-    sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move);
-    sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL);
-}
-
-/**
-Moves \a what towards \a to by \a dist
- */
-void
-unclump_pull (SPItem *to, SPItem *what, double dist)
-{
-    Geom::Point it = unclump_center (what);
-    Geom::Point p = unclump_center (to);
-    Geom::Point by = dist * Geom::unit_vector (p - it);
-
-    Geom::Matrix move = Geom::Translate (by);
-
-    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(what));
-    if ( i != c_cache.end() ) {
-        i->second *= move;
-    }
-
-    //g_print ("pull %s at %g,%g to %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[Geom::X],it[Geom::Y], p[Geom::X],p[Geom::Y], by[Geom::X],by[Geom::Y], dist);
-
-    sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move);
-    sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL);
-}
-
-
-/**
-Unclumps the items in \a items, reducing local unevenness in their distribution. Produces an effect
-similar to "engraver dots". The only distribution which is unchanged by unclumping is a hexagonal
-grid. May be called repeatedly for stronger effect. 
- */
-void
-unclump (GSList *items)
-{
-    c_cache.clear();
-    wh_cache.clear();
-
-    for (GSList *i = items; i != NULL; i = i->next) { //  for each original/clone x: 
-        SPItem *item = SP_ITEM (i->data);
-
-        GSList *nei = NULL;
-
-        GSList *rest = g_slist_copy (items);
-        rest = g_slist_remove (rest, item);
-
-        while (rest != NULL) {
-            SPItem *closest = unclump_closest (item, rest);
-            if (closest) {
-                nei = g_slist_prepend (nei, closest);
-                rest = g_slist_remove (rest, closest);
-                GSList *new_rest = unclump_remove_behind (item, closest, rest);
-                g_slist_free (rest);
-                rest = new_rest;
-            } else {
-                g_slist_free (rest);
-                break;
-            }
-        } 
-
-        if (g_slist_length (nei) >= 2) {
-            double ave = unclump_average (item, nei);
-
-            SPItem *closest = unclump_closest (item, nei);
-            SPItem *farest = unclump_farest (item, nei);
-
-            double dist_closest = unclump_dist (closest, item);
-            double dist_farest = unclump_dist (farest, item);
-
-            //g_print ("NEI %d for item %s    closest %s at %g  farest %s at %g  ave %g\n", g_slist_length(nei), SP_OBJECT_ID(item), SP_OBJECT_ID(closest), dist_closest, SP_OBJECT_ID(farest), dist_farest, ave);
-
-            if (fabs (ave) < 1e6 && fabs (dist_closest) < 1e6 && fabs (dist_farest) < 1e6) { // otherwise the items are bogus
-                // increase these coefficients to make unclumping more aggressive and less stable
-                // the pull coefficient is a bit bigger to counteract the long-term expansion trend
-                unclump_push (closest, item, 0.3 * (ave - dist_closest)); 
-                unclump_pull (farest, item, 0.35 * (dist_farest - ave));
-            }
-        }
-    }
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/dialogs/unclump.h b/src/dialogs/unclump.h
deleted file mode 100644 (file)
index c5a8bf7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
- * @brief Unclumping objects
- */
-/* Authors:
- *   bulia byak
- *
- * Copyright (C) 2005 Authors
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_DIALOGS_UNCLUMP_H
-#define SEEN_DIALOGS_UNCLUMP_H
-
-#include <glib/gslist.h>
-
-void unclump(GSList *items);
-
-#endif /* !UNCLUMP_H_SEEN */
-
-/*
-  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:encoding=utf-8:textwidth=99 :
index 65ae9a8a32c06253c095c8e3335e662d98f7360d..cf3599517b0318c44a9ade94a538ccb537bab0d4 100644 (file)
@@ -22,7 +22,6 @@
 #include "../document.h"
 #include "../event-context.h"
 #include "helper/window.h"
-#include "in-dt-coordsys.h"
 #include "../inkscape.h"
 #include "../interface.h"
 #include "macros.h"
@@ -142,6 +141,7 @@ static void cmd_set_attr(GtkObject *object, gpointer data);
 
 static gboolean sp_xml_tree_key_press(GtkWidget *widget, GdkEventKey *event);
 
+static bool in_dt_coordsys(SPObject const &item);
 
 /*
  * \brief Sets the XML status bar when the tree is selected.
@@ -1574,6 +1574,31 @@ void cmd_unindent_node(GtkObject */*object*/, gpointer /*data*/)
 
 } // end of cmd_unindent_node()
 
+/** Returns true iff \a item is suitable to be included in the selection, in particular
+    whether it has a bounding box in the desktop coordinate system for rendering resize handles.
+
+    Descendents of <defs> nodes (markers etc.) return false, for example.
+*/
+bool in_dt_coordsys(SPObject const &item)
+{
+    /* Definition based on sp_item_i2doc_affine. */
+    SPObject const *child = &item;
+    g_return_val_if_fail(child != NULL, false);
+    for(;;) {
+        if (!SP_IS_ITEM(child)) {
+            return false;
+        }
+        SPObject const * const parent = SP_OBJECT_PARENT(child);
+        if (parent == NULL) {
+            break;
+        }
+        child = parent;
+    }
+    g_assert(SP_IS_ROOT(child));
+    /* Relevance: Otherwise, I'm not sure whether to return true or false. */
+    return true;
+}
+
 
 /*
   Local Variables:
index 4f54870324b9232fc972ff3897f0ac0b50124826..fe6ce011b9590291894f9c04155bd53385af969d 100644 (file)
 #include <gtk/gtkmain.h>
 #include <string>
 #include <cstring>
+
 #include "application/application.h"
 #include "application/editor.h"
-#include "xml/repr.h"
+#include "desktop.h"
+#include "dir-util.h"
+#include "display/nr-arena-item.h"
+#include "document-private.h"
 #include "helper/units.h"
 #include "inkscape-private.h"
 #include "inkscape-version.h"
-#include "sp-object-repr.h"
-#include "sp-namedview.h"
-#include "desktop.h"
-#include "document-private.h"
-#include "dir-util.h"
-#include "unit-constants.h"
-#include "preferences.h"
 #include "libavoid/router.h"
-#include "sp-item-group.h"
-#include "profile-manager.h"
 #include "persp3d.h"
-
-#include "display/nr-arena-item.h"
-
-#include "dialogs/rdf.h"
-
+#include "preferences.h"
+#include "profile-manager.h"
+#include "rdf.h"
+#include "sp-item-group.h"
+#include "sp-namedview.h"
+#include "sp-object-repr.h"
 #include "transf_mat_3x4.h"
+#include "unit-constants.h"
+#include "xml/repr.h"
 
 #define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 1)
 
index 7e40522b36f77df193eed67f0b5044c9428549be..5a3f8dcd2030fe37f7dacf440d721cb309c046a1 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "inkscape.h"
 #include "preferences.h"
-#include "dialogs/extensions.h"
+#include "ui/dialog/extensions.h"
 #include "extension/extension.h"
 
 #include "error-file.h"
index 5c729eeeb65b1032a8c61cb0ca255d6bdbcad34a..396e9095f17b87673d3a12871cd2f1a54f741cd7 100644 (file)
@@ -1,9 +1,7 @@
-#define __SP_FILE_C__
-
-/*
- * File/Print operations
- *
- * Authors:
+/** @file
+ * @brief File/Print operations
+ */
+/* Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   Chema Celorio <chema@celorio.com>
  *   bulia byak <buliabyak@users.sf.net>
 
 #include <gtk/gtk.h>
 #include <glib/gmem.h>
+#include <glibmm/i18n.h>
 #include <libnr/nr-pixops.h>
 
-#include "document-private.h"
-#include "selection-chemistry.h"
-#include "ui/view/view-widget.h"
+#include "application/application.h"
+#include "application/editor.h"
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "dialogs/export.h"
 #include "dir-util.h"
+#include "document-private.h"
+#include "extension/db.h"
+#include "extension/input.h"
+#include "extension/output.h"
+#include "extension/system.h"
+#include "file.h"
 #include "helper/png-write.h"
-#include "dialogs/export.h"
-#include <glibmm/i18n.h>
+#include "id-clash.h"
+#include "inkscape.h"
 #include "inkscape.h"
-#include "desktop.h"
-#include "selection.h"
 #include "interface.h"
-#include "style.h"
-#include "print.h"
-#include "file.h"
+#include "io/sys.h"
 #include "message.h"
 #include "message-stack.h"
-#include "ui/dialog/filedialog.h"
-#include "ui/dialog/ocaldialogs.h"
-#include "preferences.h"
 #include "path-prefix.h"
-
+#include "preferences.h"
+#include "print.h"
+#include "rdf.h"
+#include "selection-chemistry.h"
+#include "selection.h"
 #include "sp-namedview.h"
-#include "desktop-handles.h"
-
-#include "extension/db.h"
-#include "extension/input.h"
-#include "extension/output.h"
-/* #include "extension/menu.h"  */
-#include "extension/system.h"
-
-#include "io/sys.h"
-#include "application/application.h"
-#include "application/editor.h"
-#include "inkscape.h"
+#include "style.h"
+#include "ui/dialog/filedialog.h"
+#include "ui/dialog/ocaldialogs.h"
+#include "ui/view/view-widget.h"
 #include "uri.h"
-#include "id-clash.h"
-#include "dialogs/rdf.h"
 
 #ifdef WITH_GNOME_VFS
 # include <libgnomevfs/gnome-vfs.h>
index 753b0df45ee1a684ad07e283663ee00cf9e93016..ee17e7079e639a724607ec37e2d45609f088a3c8 100644 (file)
@@ -31,7 +31,7 @@
 #include <sp-root.h>
 #include <sp-defs.h>
 #include "preferences.h"
-#include "dialogs/rdf.h"
+#include "rdf.h"
 
 /* This is an example of how to use libpng to read and write PNG files.
  * The file libpng.txt is much more verbose then this.  If you have not
diff --git a/src/rdf.cpp b/src/rdf.cpp
new file mode 100644 (file)
index 0000000..f0b1749
--- /dev/null
@@ -0,0 +1,1023 @@
+/** @file
+ * @brief  RDF manipulation functions
+ *
+ * @todo move these to xml/ instead of dialogs/
+ */
+/* Authors:
+ *   Kees Cook <kees@outflux.net>
+ *   Jon Phillips <jon@rejon.org>
+ *
+ * Copyright (C) 2004 Kees Cook <kees@outflux.net>
+ * Copyright (C) 2006 Jon Phillips <jon@rejon.org>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "xml/repr.h"
+#include "rdf.h"
+#include "sp-item-group.h"
+#include "inkscape.h"
+
+/*
+   Example RDF XML from various places...
+<rdf:RDF xmlns="http://creativecommons.org/ns#"
+    xmlns:dc="http://purl.org/dc/elements/1.1/"
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+<Work rdf:about="">
+   <dc:title>title of work</dc:title>
+   <dc:date>year</dc:date>
+   <dc:description>description of work</dc:description>
+   <dc:creator><Agent>
+      <dc:title>creator</dc:title>
+   </Agent></dc:creator>
+   <dc:rights><Agent>
+      <dc:title>holder</dc:title>
+   </Agent></dc:rights>
+   <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+   <dc:source rdf:resource="source"/>
+   <license rdf:resource="http://creativecommons.org/licenses/by/2.0/" 
+/>
+</Work>
+
+
+  <rdf:RDF xmlns="http://creativecommons.org/ns#"
+      xmlns:dc="http://purl.org/dc/elements/1.1/"
+      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+  <Work rdf:about="">
+     <dc:title>SVG Road Signs</dc:title>
+     <dc:rights><Agent>
+        <dc:title>John Cliff</dc:title>
+     </Agent></dc:rights>
+     <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+     <license rdf:resource="http://creativecommons.org/ns#PublicDomain" />
+  </Work>
+  
+  <License rdf:about="http://creativecommons.org/ns#PublicDomain">
+     <permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
+     <permits rdf:resource="http://creativecommons.org/ns#Distribution" />
+     <permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+  </License>
+  
+</rdf:RDF>
+
+
+Bag example:
+
+<dc:subject>
+<rdf:Bag>
+<rdf:li>open clip art logo</rdf:li>
+<rdf:li>images</rdf:li>
+<rdf:li>logo</rdf:li>
+<rdf:li>clip art</rdf:li>
+<rdf:li>ocal</rdf:li>
+<rdf:li>logotype</rdf:li>
+<rdf:li>filetype</rdf:li>
+</rdf:Bag>
+</dc:subject>
+*/
+
+struct rdf_double_t rdf_license_empty [] = {
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a_sa [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a_nd [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a_nc [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a_nc_sa [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_cc_a_nc_nd [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_pd [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_freeart [] = {
+    { "cc:permits", "http://creativecommons.org/ns#Reproduction", },
+    { "cc:permits", "http://creativecommons.org/ns#Distribution", },
+    { "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
+    { "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
+    { "cc:requires", "http://creativecommons.org/ns#Notice", },
+    { "cc:requires", "http://creativecommons.org/ns#Attribution", },
+    { NULL, NULL }
+};
+
+struct rdf_double_t rdf_license_ofl [] = {
+    { "cc:permits", "http://scripts.sil.org/pub/OFL/Reproduction", },
+    { "cc:permits", "http://scripts.sil.org/pub/OFL/Distribution", },
+    { "cc:permits", "http://scripts.sil.org/pub/OFL/Embedding", },
+    { "cc:permits", "http://scripts.sil.org/pub/OFL/DerivativeWorks", },
+    { "cc:requires", "http://scripts.sil.org/pub/OFL/Notice", },
+    { "cc:requires", "http://scripts.sil.org/pub/OFL/Attribution", },
+    { "cc:requires", "http://scripts.sil.org/pub/OFL/ShareAlike", },
+    { "cc:requires", "http://scripts.sil.org/pub/OFL/DerivativeRenaming", },
+    { "cc:requires", "http://scripts.sil.org/pub/OFL/BundlingWhenSelling", },
+    { NULL, NULL }
+};
+
+struct rdf_license_t rdf_licenses [] = {
+    { N_("CC Attribution"), 
+      "http://creativecommons.org/licenses/by/3.0/",
+      rdf_license_cc_a,
+    },
+
+    { N_("CC Attribution-ShareAlike"), 
+      "http://creativecommons.org/licenses/by-sa/3.0/",
+      rdf_license_cc_a_sa,
+    },
+
+    { N_("CC Attribution-NoDerivs"), 
+      "http://creativecommons.org/licenses/by-nd/3.0/",
+      rdf_license_cc_a_nd,
+    },
+
+    { N_("CC Attribution-NonCommercial"), 
+      "http://creativecommons.org/licenses/by-nc/3.0/",
+      rdf_license_cc_a_nc,
+    },
+
+    { N_("CC Attribution-NonCommercial-ShareAlike"), 
+      "http://creativecommons.org/licenses/by-nc-sa/3.0/",
+      rdf_license_cc_a_nc_sa,
+    },
+
+    { N_("CC Attribution-NonCommercial-NoDerivs"), 
+      "http://creativecommons.org/licenses/by-nc-nd/3.0/",
+      rdf_license_cc_a_nc_nd,
+    },
+
+    { N_("Public Domain"),
+      "http://creativecommons.org/licenses/publicdomain/",
+      rdf_license_pd,
+    },
+
+    { N_("FreeArt"),
+      "http://artlibre.org/licence.php/lalgb.html",
+      rdf_license_freeart,
+    },
+
+    { N_("Open Font License"),
+      "http://scripts.sil.org/OFL",
+      rdf_license_ofl,
+    },
+
+    { NULL, NULL, rdf_license_empty, }
+};
+
+#define XML_TAG_NAME_SVG      "svg:svg"
+#define XML_TAG_NAME_METADATA "svg:metadata"
+#define XML_TAG_NAME_RDF      "rdf:RDF"
+#define XML_TAG_NAME_WORK     "cc:Work"
+#define XML_TAG_NAME_LICENSE  "cc:License"
+
+// Remember when using the "title" and "tip" elements to pass them through
+// the localization functions when you use them!
+struct rdf_work_entity_t rdf_work_entities [] = {
+    { "title", N_("Title"), "dc:title", RDF_CONTENT,
+      N_("Name by which this document is formally known."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "date", N_("Date"), "dc:date", RDF_CONTENT,
+      N_("Date associated with the creation of this document (YYYY-MM-DD)."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "format", N_("Format"), "dc:format", RDF_CONTENT,
+      N_("The physical or digital manifestation of this document (MIME type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
+    },
+    { "type", N_("Type"), "dc:type", RDF_RESOURCE,
+      N_("Type of document (DCMI Type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
+    },
+
+    { "creator", N_("Creator"), "dc:creator", RDF_AGENT,
+      N_("Name of entity primarily responsible for making the content of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "rights", N_("Rights"), "dc:rights", RDF_AGENT,
+      N_("Name of entity with rights to the Intellectual Property of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "publisher", N_("Publisher"), "dc:publisher", RDF_AGENT,
+      N_("Name of entity responsible for making this document available."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+
+    { "identifier", N_("Identifier"), "dc:identifier", RDF_CONTENT,
+      N_("Unique URI to reference this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "source", N_("Source"), "dc:source", RDF_CONTENT,
+      N_("Unique URI to reference the source of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "relation", N_("Relation"), "dc:relation", RDF_CONTENT,
+      N_("Unique URI to a related document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "language", N_("Language"), "dc:language", RDF_CONTENT,
+      N_("Two-letter language tag with optional subtags for the language of this document.  (e.g. 'en-GB')"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    { "subject", N_("Keywords"), "dc:subject", RDF_BAG,
+      N_("The topic of this document as comma-separated key words, phrases, or classifications."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+    // TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content.
+    // For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/
+    { "coverage", N_("Coverage"), "dc:coverage", RDF_CONTENT,
+      N_("Extent or scope of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    },
+
+    { "description", N_("Description"), "dc:description", RDF_CONTENT,
+      N_("A short account of the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
+    },
+
+    // FIXME: need to handle 1 agent per line of input
+    { "contributor", N_("Contributors"), "dc:contributor", RDF_AGENT,
+      N_("Names of entities responsible for making contributions to the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
+    },
+
+    // TRANSLATORS: URL to a page that defines the license for the document
+    { "license_uri", N_("URI"), "cc:license", RDF_RESOURCE,
+      // TRANSLATORS: this is where you put a URL to a page that defines the license
+      N_("URI to this document's license's namespace definition."), RDF_FORMAT_LINE, RDF_EDIT_SPECIAL,
+    },
+
+      // TRANSLATORS: fragment of XML representing the license of the document
+    { "license_fragment", N_("Fragment"), "License", RDF_XML,
+      N_("XML fragment for the RDF 'License' section."), RDF_FORMAT_MULTILINE, RDF_EDIT_SPECIAL,
+    },
+    
+    { NULL, NULL, NULL, RDF_CONTENT,
+      NULL, RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
+    }
+};
+
+/**
+ *  \brief   Retrieves a known RDF/Work entity by name
+ *  \return  A pointer to an RDF/Work entity
+ *  \param   name  The desired RDF/Work entity
+ *  
+ */
+struct rdf_work_entity_t *
+rdf_find_entity(gchar const * name)
+{
+    struct rdf_work_entity_t *entity;
+    for (entity=rdf_work_entities; entity->name; entity++) {
+        if (strcmp(entity->name,name)==0) break;
+    }
+    if (entity->name) return entity;
+    return NULL;
+}
+
+/*
+ * Takes the inkscape rdf struct and spits out a static RDF, which is only
+ * useful for testing.  We must merge the rdf struct into the XML DOM for
+ * changes to be saved.
+ */
+/*
+
+   Since g_markup_printf_escaped doesn't exist for most people's glib
+   right now, this function will remain commented out since it's only
+   for generic debug anyway.  --Kees
+
+gchar *
+rdf_string(struct rdf_t * rdf)
+{
+    gulong overall=0;
+    gchar *string=NULL;
+
+    gchar *rdf_head="\
+<rdf:RDF xmlns=\"http://creativecommons.org/ns#\"\
+    xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\
+    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\
+";
+    gchar *work_head="\
+<Work rdf:about=\"\">\
+   <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\
+";
+    gchar *work_title=NULL;
+    gchar *work_date=NULL;
+    gchar *work_description=NULL;
+    gchar *work_creator=NULL;
+    gchar *work_owner=NULL;
+    gchar *work_source=NULL;
+    gchar *work_license=NULL;
+    gchar *license_head=NULL;
+    gchar *license=NULL;
+    gchar *license_end="</License>\n";
+    gchar *work_end="</Work>\n";
+    gchar *rdf_end="</rdf:RDF>\n";
+
+    if (rdf && rdf->work_title && rdf->work_title[0]) {
+        work_title=g_markup_printf_escaped("   <dc:title>%s</dc:title>\n",
+            rdf->work_title);
+    overall+=strlen(work_title);
+    }
+    if (rdf && rdf->work_date && rdf->work_date[0]) {
+        work_date=g_markup_printf_escaped("   <dc:date>%s</dc:date>\n",
+            rdf->work_date);
+    overall+=strlen(work_date);
+    }
+    if (rdf && rdf->work_description && rdf->work_description[0]) {
+        work_description=g_markup_printf_escaped("   <dc:description>%s</dc:description>\n",
+            rdf->work_description);
+    overall+=strlen(work_description);
+    }
+    if (rdf && rdf->work_creator && rdf->work_creator[0]) {
+        work_creator=g_markup_printf_escaped("   <dc:creator><Agent>\
+      <dc:title>%s</dc:title>\
+   </Agent></dc:creator>\n",
+            rdf->work_creator);
+    overall+=strlen(work_creator);
+    }
+    if (rdf && rdf->work_owner && rdf->work_owner[0]) {
+        work_owner=g_markup_printf_escaped("   <dc:rights><Agent>\
+      <dc:title>%s</dc:title>\
+   </Agent></dc:rights>\n",
+            rdf->work_owner);
+    overall+=strlen(work_owner);
+    }
+    if (rdf && rdf->work_source && rdf->work_source[0]) {
+        work_source=g_markup_printf_escaped("   <dc:source rdf:resource=\"%s\" />\n",
+            rdf->work_source);
+    overall+=strlen(work_source);
+    }
+    if (rdf && rdf->license && rdf->license->work_rdf && rdf->license->work_rdf[0]) {
+        work_license=g_markup_printf_escaped("   <license rdf:resource=\"%s\" />\n",
+            rdf->license->work_rdf);
+    overall+=strlen(work_license);
+
+    license_head=g_markup_printf_escaped("<License rdf:about=\"%s\">\n",
+            rdf->license->work_rdf);
+    overall+=strlen(license_head);
+    overall+=strlen(rdf->license->license_rdf);
+    overall+=strlen(license_end);
+    }
+
+    overall+=strlen(rdf_head)+strlen(rdf_end);
+    overall+=strlen(work_head)+strlen(work_end);
+
+    overall++; // NULL term
+
+    if (!(string=(gchar*)g_malloc(overall))) {
+        return NULL;
+    }
+
+    string[0]='\0';
+    strcat(string,rdf_head);
+    strcat(string,work_head);
+
+    if (work_title)       strcat(string,work_title);
+    if (work_date)        strcat(string,work_date);
+    if (work_description) strcat(string,work_description);
+    if (work_creator)     strcat(string,work_creator);
+    if (work_owner)       strcat(string,work_owner);
+    if (work_source)      strcat(string,work_source);
+    if (work_license)     strcat(string,work_license);
+
+    strcat(string,work_end);
+    if (license_head) {
+        strcat(string,license_head);
+    strcat(string,rdf->license->license_rdf);
+    strcat(string,license_end);
+    }
+    strcat(string,rdf_end);
+
+    return string;
+}
+*/
+
+
+/**
+ *  \brief   Pull the text out of an RDF entity, depends on how it's stored
+ *  \return  A pointer to the entity's static contents as a string
+ *  \param   repr    The XML element to extract from
+ *  \param   entity  The desired RDF/Work entity
+ *  
+ */
+const gchar *
+rdf_get_repr_text ( Inkscape::XML::Node * repr, struct rdf_work_entity_t * entity )
+{
+    g_return_val_if_fail (repr != NULL, NULL);
+    g_return_val_if_fail (entity != NULL, NULL);
+    static gchar * bag = NULL;
+    gchar * holder = NULL;
+
+    Inkscape::XML::Node * temp=NULL;
+    switch (entity->datatype) {
+        case RDF_CONTENT:
+            temp = sp_repr_children(repr);
+            if ( temp == NULL ) return NULL;
+            
+            return temp->content();
+
+        case RDF_AGENT:
+            temp = sp_repr_lookup_name ( repr, "cc:Agent", 1 );
+            if ( temp == NULL ) return NULL;
+
+            temp = sp_repr_lookup_name ( temp, "dc:title", 1 );
+            if ( temp == NULL ) return NULL;
+
+            temp = sp_repr_children(temp);
+            if ( temp == NULL ) return NULL;
+
+            return temp->content();
+
+        case RDF_RESOURCE:
+            return repr->attribute("rdf:resource");
+
+        case RDF_XML:
+            return "xml goes here";
+
+        case RDF_BAG:
+            /* clear the static string.  yucky. */
+            if (bag) g_free(bag);
+            bag = NULL;
+
+            temp = sp_repr_lookup_name ( repr, "rdf:Bag", 1 );
+            if ( temp == NULL ) {
+                /* backwards compatible: read contents */
+                temp = sp_repr_children(repr);
+                if ( temp == NULL ) return NULL;
+            
+                return temp->content();
+            }
+
+            for ( temp = sp_repr_children(temp) ;
+                  temp ;
+                  temp = sp_repr_next(temp) ) {
+                if (!strcmp(temp->name(),"rdf:li") &&
+                    temp->firstChild()) {
+                    const gchar * str = temp->firstChild()->content();
+                    if (bag) {
+                        holder = bag;
+                        bag = g_strconcat(holder, ", ", str, NULL);
+                        g_free(holder);
+                    }
+                    else {
+                        bag = g_strdup(str);
+                    }
+                }
+            }
+            return bag;
+
+        default:
+            break;
+    }
+    return NULL;
+}
+
+unsigned int
+rdf_set_repr_text ( Inkscape::XML::Node * repr,
+                    struct rdf_work_entity_t * entity,
+                    gchar const * text )
+{
+    g_return_val_if_fail ( repr != NULL, 0);
+    g_return_val_if_fail ( entity != NULL, 0);
+    g_return_val_if_fail ( text != NULL, 0);
+    gchar * str = NULL;
+    gchar** strlist = NULL;
+    int i;
+
+    Inkscape::XML::Node * temp=NULL;
+    Inkscape::XML::Node * child=NULL;
+    Inkscape::XML::Node * parent=repr;
+
+    Inkscape::XML::Document * xmldoc = parent->document();
+    g_return_val_if_fail (xmldoc != NULL, FALSE);
+
+    // set document's title element to the RDF title
+    if (!strcmp(entity->name, "title")) {
+        SPDocument *doc = SP_ACTIVE_DOCUMENT;
+        if(doc && doc->root) doc->root->setTitle(text);
+    }
+
+    switch (entity->datatype) {
+        case RDF_CONTENT:
+            temp = sp_repr_children(parent);
+            if ( temp == NULL ) {
+                temp = xmldoc->createTextNode( text );
+                g_return_val_if_fail (temp != NULL, FALSE);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+
+                return TRUE;
+            }
+            else {
+                temp->setContent(text);
+                return TRUE;
+            }
+
+        case RDF_AGENT:
+            temp = sp_repr_lookup_name ( parent, "cc:Agent", 1 );
+            if ( temp == NULL ) {
+                temp = xmldoc->createElement ( "cc:Agent" );
+                g_return_val_if_fail (temp != NULL, FALSE);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+            }
+            parent = temp;
+
+            temp = sp_repr_lookup_name ( parent, "dc:title", 1 );
+            if ( temp == NULL ) {
+                temp = xmldoc->createElement ( "dc:title" );
+                g_return_val_if_fail (temp != NULL, FALSE);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+            }
+            parent = temp;
+
+            temp = sp_repr_children(parent);
+            if ( temp == NULL ) {
+                temp = xmldoc->createTextNode( text );
+                g_return_val_if_fail (temp != NULL, FALSE);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+
+                return TRUE;
+            }
+            else {
+                temp->setContent(text);
+                               return TRUE;
+            }
+
+        case RDF_RESOURCE:
+            parent->setAttribute("rdf:resource", text );
+            return true;
+
+        case RDF_XML:
+            return 1;
+
+        case RDF_BAG:
+            /* find/create the rdf:Bag item */
+            temp = sp_repr_lookup_name ( parent, "rdf:Bag", 1 );
+            if ( temp == NULL ) {
+                /* backward compatibility: drop the dc:subject contents */
+                while ( (temp = sp_repr_children( parent )) ) {
+                    parent->removeChild(temp);
+                }
+
+                temp = xmldoc->createElement ( "rdf:Bag" );
+                g_return_val_if_fail (temp != NULL, FALSE);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+            }
+            parent = temp;
+
+            /* toss all the old list items */
+            while ( (temp = sp_repr_children( parent )) ) {
+                parent->removeChild(temp);
+            }
+
+            /* chop our list up on commas */
+            strlist = g_strsplit( text, ",", 0);
+
+            for (i = 0; (str = strlist[i]); i++) {
+                temp = xmldoc->createElement ( "rdf:li" );
+                g_return_val_if_fail (temp != NULL, 0);
+
+                parent->appendChild(temp);
+                Inkscape::GC::release(temp);
+
+                child = xmldoc->createTextNode( g_strstrip(str) );
+                g_return_val_if_fail (child != NULL, 0);
+
+                temp->appendChild(child);
+                Inkscape::GC::release(child);
+            }
+            g_strfreev( strlist );
+
+            return 1;
+
+        default:
+            break;
+    }
+    return 0;
+}
+
+Inkscape::XML::Node *
+rdf_get_rdf_root_repr ( SPDocument * doc, bool build )
+{
+    g_return_val_if_fail (doc        != NULL, NULL);
+    g_return_val_if_fail (doc->rroot != NULL, NULL);
+
+    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
+    g_return_val_if_fail (xmldoc != NULL, NULL);
+
+    Inkscape::XML::Node * rdf = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_RDF );
+
+    if (rdf == NULL) {
+        //printf("missing XML '%s'\n",XML_TAG_NAME_RDF);
+        if (!build) return NULL;
+
+        Inkscape::XML::Node * svg = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_SVG );
+        g_return_val_if_fail ( svg != NULL, NULL );
+
+        Inkscape::XML::Node * parent = sp_repr_lookup_name ( svg, XML_TAG_NAME_METADATA );
+        if ( parent == NULL ) {
+            parent = xmldoc->createElement( XML_TAG_NAME_METADATA );
+            g_return_val_if_fail ( parent != NULL, NULL);
+
+            svg->appendChild(parent);
+            Inkscape::GC::release(parent);
+        }
+
+        Inkscape::XML::Document * xmldoc = parent->document();
+        g_return_val_if_fail (xmldoc != NULL, FALSE);
+
+        rdf = xmldoc->createElement( XML_TAG_NAME_RDF );
+        g_return_val_if_fail (rdf != NULL, NULL);
+
+        parent->appendChild(rdf);
+        Inkscape::GC::release(rdf);
+    }
+
+    /*
+     * some implementations do not put RDF stuff inside <metadata>,
+     * so we need to check for it and add it if we don't see it
+     */
+    Inkscape::XML::Node * want_metadata = sp_repr_parent ( rdf );
+    g_return_val_if_fail (want_metadata != NULL, NULL);
+    if (strcmp( want_metadata->name(), XML_TAG_NAME_METADATA )) {
+            Inkscape::XML::Node * metadata = xmldoc->createElement( XML_TAG_NAME_METADATA );
+            g_return_val_if_fail (metadata != NULL, NULL);
+
+            /* attach the metadata node */
+            want_metadata->appendChild(metadata);
+            Inkscape::GC::release(metadata);
+
+            /* move the RDF into it */
+            Inkscape::GC::anchor(rdf);
+            sp_repr_unparent ( rdf );
+            metadata->appendChild(rdf);
+            Inkscape::GC::release(rdf);
+    }
+    
+    return rdf;
+}
+
+Inkscape::XML::Node *
+rdf_get_xml_repr( SPDocument * doc, gchar const * name, bool build )
+{
+    g_return_val_if_fail (name       != NULL, NULL);
+    g_return_val_if_fail (doc        != NULL, NULL);
+    g_return_val_if_fail (doc->rroot != NULL, NULL);
+
+    Inkscape::XML::Node * rdf = rdf_get_rdf_root_repr ( doc, build );
+    if (!rdf) return NULL;
+
+    Inkscape::XML::Node * xml = sp_repr_lookup_name ( rdf, name );
+    if (xml == NULL) {
+        //printf("missing XML '%s'\n",name);
+        if (!build) return NULL;
+
+        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
+        g_return_val_if_fail (xmldoc != NULL, NULL);
+
+        xml = xmldoc->createElement( name );
+        g_return_val_if_fail (xml != NULL, NULL);
+
+        xml->setAttribute("rdf:about", "" );
+
+        rdf->appendChild(xml);
+        Inkscape::GC::release(xml);
+    }
+
+    return xml;
+}
+
+Inkscape::XML::Node *
+rdf_get_work_repr( SPDocument * doc, gchar const * name, bool build )
+{
+    g_return_val_if_fail (name       != NULL, NULL);
+    g_return_val_if_fail (doc        != NULL, NULL);
+    g_return_val_if_fail (doc->rroot != NULL, NULL);
+
+    Inkscape::XML::Node * work = rdf_get_xml_repr ( doc, XML_TAG_NAME_WORK, build );
+    if (!work) return NULL;
+
+    Inkscape::XML::Node * item = sp_repr_lookup_name ( work, name, 1 );
+    if (item == NULL) {
+        //printf("missing XML '%s'\n",name);
+        if (!build) return NULL;
+
+        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
+        g_return_val_if_fail (xmldoc != NULL, NULL);
+
+        item = xmldoc->createElement( name );
+        g_return_val_if_fail (item != NULL, NULL);
+
+        work->appendChild(item);
+        Inkscape::GC::release(item);
+    }
+
+    return item;
+}
+
+
+
+/**
+ *  \brief   Retrieves a known RDF/Work entity's contents from the document XML by name
+ *  \return  A pointer to the entity's static contents as a string, or NULL if no entity exists
+ *  \param   entity  The desired RDF/Work entity
+ *  
+ */
+const gchar *
+rdf_get_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity)
+{
+    g_return_val_if_fail (doc    != NULL, NULL);
+    if ( entity == NULL ) return NULL;
+    //printf("want '%s'\n",entity->title);
+    bool bIsTitle = !strcmp(entity->name, "title");
+
+    Inkscape::XML::Node * item;
+    if ( entity->datatype == RDF_XML ) {
+        item = rdf_get_xml_repr ( doc, entity->tag, FALSE );
+    }
+    else {
+        item = rdf_get_work_repr( doc, entity->tag, bIsTitle ); // build title if necessary
+    }
+    if ( item == NULL ) return NULL;
+    const gchar * result = rdf_get_repr_text ( item, entity );
+    if(!result && bIsTitle && doc->root) {         // if RDF title not set
+        result = doc->root->title();               // get the document's <title>
+        rdf_set_work_entity(doc, entity, result);  // and set the RDF
+    }
+    //printf("found '%s' == '%s'\n", entity->title, result );
+    return result;
+}
+
+/**
+ *  \brief   Stores a string into a named RDF/Work entity in the document XML
+ *  \param   entity The desired RDF/Work entity to replace
+ *  \param   string The string to replace the entity contents with
+ *  
+ */
+unsigned int
+rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity,
+                    const gchar * text)
+{
+    g_return_val_if_fail ( entity != NULL, 0 );
+    if (text == NULL) {
+        // FIXME: on a "NULL" text, delete the entity.  For now, blank it.
+        text="";
+    }
+
+    /*
+    printf("changing '%s' (%s) to '%s'\n",
+        entity->title,
+        entity->tag,
+        text);
+    */
+
+    Inkscape::XML::Node * item = rdf_get_work_repr( doc, entity->tag, TRUE );
+    g_return_val_if_fail ( item != NULL, 0 );
+
+    return rdf_set_repr_text ( item, entity, text );
+}
+
+#undef DEBUG_MATCH
+
+static bool
+rdf_match_license(Inkscape::XML::Node const *repr, struct rdf_license_t const *license)
+{
+    g_assert ( repr != NULL );
+    g_assert ( license != NULL );
+
+    bool result=TRUE;
+#ifdef DEBUG_MATCH
+    printf("checking against '%s'\n",license->name);
+#endif
+
+    int count = 0;
+    for (struct rdf_double_t const *details = license->details;
+         details->name; details++ ) {
+        count++;
+    }
+    bool * matched = (bool*)calloc(count,sizeof(bool));
+
+    for (Inkscape::XML::Node const *current = sp_repr_children(repr);
+         current;
+         current = sp_repr_next ( current ) ) {
+
+        gchar const * attr = current->attribute("rdf:resource");
+        if ( attr == NULL ) continue;
+
+#ifdef DEBUG_MATCH
+        printf("\texamining '%s' => '%s'\n", current->name(), attr);
+#endif
+
+        bool found_match=FALSE;
+        for (int i=0; i<count; i++) {
+            // skip already matched items
+            if (matched[i]) continue;
+
+#ifdef DEBUG_MATCH
+            printf("\t\t'%s' vs '%s'\n", current->name(), license->details[i].name);
+            printf("\t\t'%s' vs '%s'\n", attr, license->details[i].resource);
+#endif
+
+            if (!strcmp( current->name(),
+                         license->details[i].name ) &&
+                !strcmp( attr,
+                         license->details[i].resource )) {
+                matched[i]=TRUE;
+                found_match=TRUE;
+#ifdef DEBUG_MATCH
+                printf("\t\tgood!\n");
+#endif
+                break;
+            }
+        }
+        if (!found_match) {
+            // if we checked each known item of the license
+            // and didn't find it, we must abort
+            result=FALSE;
+#ifdef DEBUG_MATCH
+            printf("\t\tno '%s' element matched XML (bong)!\n",license->name);
+#endif
+            break;
+        }
+    }
+#ifdef DEBUG_MATCH
+    if (result) printf("\t\tall XML found matching elements!\n");
+#endif
+    for (int i=0; result && i<count; i++) {
+        // scan looking for an unmatched item
+        if (matched[i]==0) {
+            result=FALSE;
+#ifdef DEBUG_MATCH
+            printf("\t\tnot all '%s' elements used to match (bong)!\n", license->name);
+#endif
+        }
+    }
+
+#ifdef DEBUG_MATCH
+    printf("\t\tall '%s' elements used to match!\n",license->name);
+#endif
+
+    free(matched);
+
+#ifdef DEBUG_MATCH
+    if (result) printf("matched '%s'\n",license->name);
+#endif
+    return result;
+}
+
+/**
+ *  \brief   Attempts to match and retrieve a known RDF/License from the document XML
+ *  \return  A pointer to the static RDF license structure
+ *  
+ */
+struct rdf_license_t *
+rdf_get_license(SPDocument * document)
+{
+    Inkscape::XML::Node const *repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, FALSE );
+    if (repr) {
+        for (struct rdf_license_t * license = rdf_licenses;
+             license->name; license++ ) {
+            if ( rdf_match_license ( repr, license ) ) return license;
+        }
+    }
+#ifdef DEBUG_MATCH
+    else {
+        printf("no license XML\n");
+    }
+#endif
+    return NULL;
+}
+
+/**
+ *  \brief   Stores an RDF/License XML in the document XML
+ *  \param   document  Which document to update
+ *  \param   license   The desired RDF/License structure to store; NULL drops old license, so can be used for proprietary license. 
+ *  
+ */
+void
+rdf_set_license(SPDocument * doc, struct rdf_license_t const * license)
+{
+    // drop old license section
+    Inkscape::XML::Node * repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, FALSE );
+    if (repr) sp_repr_unparent(repr);
+
+    if (!license) return;
+
+    // build new license section
+    repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, TRUE );
+    g_assert ( repr );
+
+    repr->setAttribute("rdf:about", license->uri );
+
+    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
+    g_return_if_fail (xmldoc != NULL);
+
+    for (struct rdf_double_t const * detail = license->details;
+         detail->name; detail++) {
+        Inkscape::XML::Node * child = xmldoc->createElement( detail->name );
+        g_assert ( child != NULL );
+
+        child->setAttribute("rdf:resource", detail->resource );
+        repr->appendChild(child);
+        Inkscape::GC::release(child);
+    }
+}
+
+struct rdf_entity_default_t {
+    gchar const * name;
+    gchar const * text;
+};
+struct rdf_entity_default_t rdf_defaults[] = {
+    { "format",      "image/svg+xml", },
+    { "type",        "http://purl.org/dc/dcmitype/StillImage", },
+    { NULL,          NULL, }
+};
+
+void
+rdf_set_defaults ( SPDocument * doc )
+{
+    g_assert ( doc != NULL );
+
+    // Create metadata node if it doesn't already exist
+    if (!sp_item_group_get_child_by_name ((SPGroup *) doc->root, NULL,
+                                          XML_TAG_NAME_METADATA)) {
+        // create repr
+        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
+        g_return_if_fail (xmldoc != NULL);
+        Inkscape::XML::Node * rnew = xmldoc->createElement (XML_TAG_NAME_METADATA);
+        // insert into the document
+        doc->rroot->addChild(rnew, NULL);
+        // clean up
+        Inkscape::GC::release(rnew);
+    }
+
+    /* install defaults */
+    for ( struct rdf_entity_default_t * rdf_default = rdf_defaults;
+          rdf_default->name;
+          rdf_default++) {
+        struct rdf_work_entity_t * entity = rdf_find_entity ( rdf_default->name );
+        g_assert ( entity != NULL );
+
+        if ( rdf_get_work_entity ( doc, entity ) == NULL ) {
+            rdf_set_work_entity ( doc, entity, rdf_default->text );
+        }
+    }
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/rdf.h b/src/rdf.h
new file mode 100644 (file)
index 0000000..a98f5a1
--- /dev/null
+++ b/src/rdf.h
@@ -0,0 +1,120 @@
+/** @file
+ * @brief headers for RDF types
+ */
+/* Authors:
+ *  Kees Cook <kees@outflux.net>
+ *
+ * Copyright (C) 2004 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifndef _RDF_H_
+#define _RDF_H_
+
+#include <glib.h>
+#include <glibmm/i18n.h>
+#include "document.h"
+
+// yeah, it's not a triple yet...
+/**
+ * \brief Holds license name/resource doubles for rdf_license_t entries
+ */
+struct rdf_double_t {
+    gchar const *name;
+    gchar const *resource;
+};
+
+/**
+ * \brief Holds license name and RDF information
+ */
+struct rdf_license_t {
+    gchar const *name;        /* localized name of this license */
+    gchar const *uri;         /* URL for the RDF/Work/license element */
+    struct rdf_double_t *details; /* the license details */
+//    gchar const *fragment;    /* XML contents for the RDF/License tag */
+};
+
+extern rdf_license_t rdf_licenses [];
+
+/**
+ * \brief Describes how a given RDF entity is stored in XML
+ */
+enum RDFType {
+    RDF_CONTENT,  // direct between-XML-tags content
+    RDF_AGENT,    // requires the "Agent" hierarchy before doing content
+    RDF_RESOURCE, // stored in "rdf:resource" element
+    RDF_XML,      // literal XML
+    RDF_BAG       // rdf:Bag resources
+};
+
+/**
+ * \brief Describes how a given RDF entity should be edited
+ */
+enum RDF_Format {
+    RDF_FORMAT_LINE,          // uses single line data (GtkEntry)
+    RDF_FORMAT_MULTILINE,     // uses multiline data (GtkTextView)
+    RDF_FORMAT_SPECIAL        // uses some other edit methods
+};
+
+enum RDF_Editable {
+    RDF_EDIT_GENERIC,       // editable via generic widgets
+    RDF_EDIT_SPECIAL,       // special widgets are needed
+    RDF_EDIT_HARDCODED      // isn't editable
+};
+
+/**
+ * \brief Holds known RDF/Work tags
+ */
+struct rdf_work_entity_t {
+    char const *name;       /* unique name of this entity for internal reference */
+    gchar const *title;      /* localized title of this entity for data entry */
+    gchar const *tag;        /* namespace tag for the RDF/Work element */
+    RDFType datatype;   /* how to extract/inject the RDF information */
+    gchar const *tip;        /* tool tip to explain the meaning of the entity */
+    RDF_Format format;  /* in what format is this data edited? */
+    RDF_Editable editable;/* in what way is the data editable? */
+};
+
+extern rdf_work_entity_t rdf_work_entities [];
+
+/**
+ * \brief Generic collection of RDF information for the RDF debug function
+ */
+struct rdf_t {
+    gchar*                work_title;
+    gchar*                work_date;
+    gchar*                work_creator;
+    gchar*                work_owner;
+    gchar*                work_publisher;
+    gchar*                work_type;
+    gchar*                work_source;
+    gchar*                work_subject;
+    gchar*                work_description;
+    struct rdf_license_t* license;
+};
+
+struct rdf_work_entity_t * rdf_find_entity(gchar const * name);
+
+const gchar * rdf_get_work_entity(SPDocument * doc,
+                                  struct rdf_work_entity_t * entity);
+unsigned int  rdf_set_work_entity(SPDocument * doc,
+                                  struct rdf_work_entity_t * entity,
+                                  const gchar * text);
+
+struct rdf_license_t * rdf_get_license(SPDocument * doc);
+void                   rdf_set_license(SPDocument * doc,
+                                       struct rdf_license_t const * license);
+
+void rdf_set_defaults ( SPDocument * doc );
+
+#endif // _RDF_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:encoding=utf-8:textwidth=99 :
index e91c22025a9dcf45bb3ff3019d40c57d5303f1c4..3eb6c6b13c93cb29745fd91d297687ccdfc38454 100644 (file)
@@ -1,9 +1,11 @@
 ## Makefile.am fragment sourced by src/Makefile.am.
 
 ink_common_sources +=          \
-       ui/clipboard.cpp \
-       ui/clipboard.h \
-       ui/icon-names.h \
+       ui/context-menu.cpp     \
+       ui/context-menu.h       \
+       ui/clipboard.cpp        \
+       ui/clipboard.h          \
+       ui/icon-names.h         \
        ui/previewable.h        \
        ui/previewfillable.h    \
        ui/previewholder.cpp    \
index bf3b6baeb2d17f5b0305acce5bf98650602d9f4d..6a9ebf61ffac8529deb89636700f887f584b8c06 100644 (file)
@@ -1,11 +1,23 @@
 ## Makefile.am fragment sourced by src/Makefile.am.
 
+if WITH_INKBOARD
+inkboard_dialogs = \
+       whiteboard-connect.cpp                  \
+       whiteboard-connect.h                    \
+       whiteboard-sharewithchat.cpp            \
+       whiteboard-sharewithchat.h              \
+       whiteboard-sharewithuser.cpp            \
+       whiteboard-sharewithuser.h
+endif
+
 ink_common_sources +=          \
        ui/dialog/aboutbox.cpp                  \
        ui/dialog/aboutbox.h                    \
        ui/dialog/align-and-distribute.cpp      \
        ui/dialog/align-and-distribute.h        \
        ui/dialog/behavior.h                    \
+       ui/dialog/calligraphic-profile-rename.h \
+       ui/dialog/calligraphic-profile-rename.cpp       \
        ui/dialog/debug.cpp                     \
        ui/dialog/debug.h                       \
        ui/dialog/dialog.cpp                    \
@@ -20,6 +32,8 @@ ink_common_sources +=         \
        ui/dialog/document-properties.h         \
        ui/dialog/extension-editor.cpp          \
        ui/dialog/extension-editor.h            \
+       ui/dialog/extensions.cpp                \
+       ui/dialog/extensions.h                  \
        ui/dialog/filedialog.cpp                \
        ui/dialog/filedialog.h                  \
        ui/dialog/filedialogimpl-gtkmm.cpp      \
@@ -34,10 +48,18 @@ ink_common_sources +=               \
        ui/dialog/find.h                        \
        ui/dialog/floating-behavior.cpp         \
        ui/dialog/floating-behavior.h           \
+       ui/dialog/guides.cpp                    \
+       ui/dialog/guides.h                      \
+       ui/dialog/icon-preview.cpp              \
+       ui/dialog/icon-preview.h                \
        ui/dialog/inkscape-preferences.cpp      \
        ui/dialog/inkscape-preferences.h        \
        ui/dialog/input.cpp                     \
        ui/dialog/input.h                       \
+       ui/dialog/layer-properties.cpp          \
+       ui/dialog/layer-properties.h            \
+       ui/dialog/layers.cpp                    \
+       ui/dialog/layers.h                      \
        ui/dialog/livepatheffect-editor.cpp     \
        ui/dialog/livepatheffect-editor.h       \
        ui/dialog/memory.cpp                    \
@@ -53,6 +75,8 @@ ink_common_sources +=         \
        ui/dialog/scriptdialog.h                \
        ui/dialog/svg-fonts-dialog.cpp          \
        ui/dialog/svg-fonts-dialog.h            \
+       ui/dialog/swatches.cpp                  \
+       ui/dialog/swatches.h                    \
        ui/dialog/tile.cpp                      \
        ui/dialog/tile.h                        \
        ui/dialog/tracedialog.cpp               \
index 0a59c004f3e0b4f181fa8e6ac0fa5a77e372beab..d8c4bc005606483457e09fdb8f8a6e8e42bb16df 100644 (file)
@@ -21,7 +21,7 @@
 #include <gtkmm/spinbutton.h>
 
 #include "desktop-handles.h"
-#include "dialogs/unclump.h"
+#include "unclump.h"
 #include "document.h"
 #include "enums.h"
 #include "graphlayout/graphlayout.h"
diff --git a/src/ui/dialog/calligraphic-profile-rename.cpp b/src/ui/dialog/calligraphic-profile-rename.cpp
new file mode 100644 (file)
index 0000000..888b327
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file
+ * @brief Dialog for naming calligraphic profiles
+ *
+ * @note This file is in the wrong directory because of link order issues - 
+ * it is required by widgets/toolbox.cpp, and libspwidgets.a comes after
+ * libinkdialogs.a in the current link order.
+ */
+/* Author:
+ *   Aubanel MONNIER 
+ *
+ * Copyright (C) 2007 Authors
+ * Released under GNU GPL.  Read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <glibmm/i18n.h>
+#include <gtkmm/stock.h>
+
+#include "desktop.h"
+#include "calligraphic-profile-rename.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+CalligraphicProfileRename::CalligraphicProfileRename() :
+    _applied(false)
+{
+    Gtk::VBox *mainVBox = get_vbox();
+    _layout_table.set_spacings(4);
+    _layout_table.resize (1, 2);
+
+    _profile_name_entry.set_activates_default(true);
+
+    _profile_name_label.set_label(_("Profile name:"));
+    _profile_name_label.set_alignment(1.0, 0.5);
+
+    _layout_table.attach(_profile_name_label,
+                  0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_profile_name_entry,
+                  1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+    mainVBox->pack_start(_layout_table, false, false, 4);
+    // Buttons
+    _close_button.set_use_stock(true);
+    _close_button.set_label(Gtk::Stock::CANCEL.id);
+    _close_button.set_flags(Gtk::CAN_DEFAULT);
+
+    _apply_button.set_use_underline(true);
+    _apply_button.set_label(_("Save"));
+    _apply_button.set_flags(Gtk::CAN_DEFAULT);
+
+    _close_button.signal_clicked()
+    .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_close));
+    _apply_button.signal_clicked()
+    .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_apply));
+
+    signal_delete_event().connect( sigc::bind_return(
+        sigc::hide(sigc::mem_fun(*this, &CalligraphicProfileRename::_close)), true ) );
+
+    add_action_widget(_close_button, Gtk::RESPONSE_CLOSE);
+    add_action_widget(_apply_button, Gtk::RESPONSE_APPLY);
+
+    _apply_button.grab_default();
+
+    show_all_children();
+}
+
+void CalligraphicProfileRename::_apply()
+{
+    _profile_name = _profile_name_entry.get_text();
+    _applied = true;
+    _close();
+}
+
+void CalligraphicProfileRename::_close()
+{
+    this->Gtk::Dialog::hide();
+}
+
+void CalligraphicProfileRename::show(SPDesktop *desktop)
+{
+    CalligraphicProfileRename &dial = instance();
+    dial._applied=false;
+    dial.set_modal(true);
+    desktop->setWindowTransient (dial.gobj());
+    dial.property_destroy_with_parent() = true;
+    //  dial.Gtk::Dialog::show();
+    //dial.present();
+    dial.run();
+}
+
+} // namespace Dialog
+} // 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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/calligraphic-profile-rename.h b/src/ui/dialog/calligraphic-profile-rename.h
new file mode 100644 (file)
index 0000000..53ce907
--- /dev/null
@@ -0,0 +1,75 @@
+/** @file
+ * @brief Dialog for naming calligraphic profiles
+ */
+/* Author:
+ *   Aubanel MONNIER 
+ *
+ * Copyright (C) 2007 Authors
+ * Released under GNU GPL.  Read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
+#define INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/label.h>
+#include <gtkmm/table.h>
+struct SPDesktop;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+      
+class CalligraphicProfileRename : public Gtk::Dialog {  
+public:
+    CalligraphicProfileRename();
+    virtual ~CalligraphicProfileRename() {}
+    Glib::ustring getName() const {
+        return "CalligraphicProfileRename";
+    }
+    
+    static void show(SPDesktop *desktop);
+    static bool applied() {
+        return instance()._applied;
+    }
+    static Glib::ustring getProfileName() {
+        return instance()._profile_name;
+    }
+
+protected:
+    void _close();
+    void _apply();
+
+    Gtk::Label        _profile_name_label;
+    Gtk::Entry        _profile_name_entry;
+    Gtk::Table        _layout_table;
+    Gtk::Button       _close_button;
+    Gtk::Button       _apply_button;
+    Glib::ustring _profile_name;
+    bool _applied;
+private:
+    static CalligraphicProfileRename &instance() {
+        static CalligraphicProfileRename instance_;
+        return instance_;
+    }
+    CalligraphicProfileRename(CalligraphicProfileRename const &); // no copy
+    CalligraphicProfileRename &operator=(CalligraphicProfileRename const &); // no assign
+};
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_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:encoding=utf-8:textwidth=99 :
index 7a8947adf7bc9315ee079b9baa9a92f897b11007..d1b818d236a781f6eacd8b1ca88b94bac2901367 100644 (file)
 #include "ui/dialog/memory.h"
 #include "ui/dialog/messages.h"
 #include "ui/dialog/scriptdialog.h"
-#ifdef ENABLE_SVG_FONTS
-#include "ui/dialog/svg-fonts-dialog.h"
-#endif // ENABLE_SVG_FONTS
 #include "ui/dialog/tile.h"
 #include "ui/dialog/tracedialog.h"
 #include "ui/dialog/transformation.h"
 #include "ui/dialog/undo-history.h"
 #include "ui/dialog/panel-dialog.h"
-
-#include "dialogs/layers-panel.h"
-#include "dialogs/iconpreview.h"
-
+#include "ui/dialog/layers.h"
+#include "ui/dialog/icon-preview.h"
 #include "ui/dialog/floating-behavior.h"
 #include "ui/dialog/dock-behavior.h"
 #include "preferences.h"
 
+#ifdef ENABLE_SVG_FONTS
+#include "ui/dialog/svg-fonts-dialog.h"
+#endif // ENABLE_SVG_FONTS
+
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
index 32838309a4d678a078ba8900ab17cbdb2c9efc09..96cad1fbe6074596d9edfde15ba8a1b44c4f8cae 100644 (file)
 # include <config.h>
 #endif
 
-
-
-#include "ui/widget/entity-entry.h"
-
-#include "xml/node-event-vector.h"
-#include "dialogs/rdf.h"
-
-#include "inkscape.h"
-#include "verbs.h"
-#include "desktop-handles.h"
 #include "desktop.h"
+#include "desktop-handles.h"
+#include "inkscape.h"
+#include "rdf.h"
 #include "sp-namedview.h"
+#include "ui/widget/entity-entry.h"
+#include "verbs.h"
+#include "xml/node-event-vector.h"
 
 #include "document-metadata.h"
 
diff --git a/src/ui/dialog/extensions.cpp b/src/ui/dialog/extensions.cpp
new file mode 100644 (file)
index 0000000..f168da3
--- /dev/null
@@ -0,0 +1,129 @@
+/** @file
+ * @brief A simple dialog with information about extensions
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2005 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
+#include <gtkmm/scrolledwindow.h>
+
+#include "extension/db.h"
+#include "extensions.h"
+
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+using Inkscape::Extension::Extension;
+
+ExtensionsPanel &ExtensionsPanel::getInstance()
+{
+    ExtensionsPanel &instance = *new ExtensionsPanel();
+
+    instance.rescan();
+
+    return instance;
+}
+
+
+
+/**
+ * Constructor
+ */
+ExtensionsPanel::ExtensionsPanel() :
+        _showAll(false)
+{
+    Gtk::ScrolledWindow* scroller = new Gtk::ScrolledWindow();
+
+    _view.set_editable(false);
+
+    scroller->add(_view);
+    add(*scroller);
+
+    rescan();
+
+    show_all_children();
+}
+
+void ExtensionsPanel::set_full(bool full)
+{
+    if ( full != _showAll ) {
+        _showAll = full;
+        rescan();
+    }
+}
+
+void ExtensionsPanel::listCB( Inkscape::Extension::Extension * in_plug, gpointer in_data )
+{
+    ExtensionsPanel * self = (ExtensionsPanel*)in_data;
+
+    const char* stateStr;
+    Extension::state_t state = in_plug->get_state();
+    switch ( state ) {
+        case Extension::STATE_LOADED:
+        {
+            stateStr = "loaded";
+        }
+        break;
+        case Extension::STATE_UNLOADED:
+        {
+            stateStr = "unloaded";
+        }
+        break;
+        case Extension::STATE_DEACTIVATED:
+        {
+            stateStr = "deactivated";
+        }
+        break;
+        default:
+            stateStr = "unknown";
+    }
+
+    if ( self->_showAll || in_plug->deactivated() ) {
+//         gchar* line = g_strdup_printf( " extension   %c %c  %s   |%s|%s|",
+//                                        (in_plug->loaded() ? 'X' : '-'),
+//                                        (in_plug->deactivated() ? 'X' : '-'),
+//                                        stateStr, in_plug->get_id(),
+//                                        in_plug->get_name() );
+        gchar* line = g_strdup_printf( "%s   %s\n        \"%s\"", stateStr, in_plug->get_name(), in_plug->get_id() );
+
+        self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), line );
+        self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), "\n" );
+        //g_message( "%s", line );
+    }
+
+
+
+    return;
+}
+
+void ExtensionsPanel::rescan()
+{
+    _view.get_buffer()->set_text("Extensions:\n");
+//     g_message("/------------------");
+
+    Inkscape::Extension::db.foreach(listCB, (gpointer)this);
+
+//     g_message("\\------------------");
+}
+
+} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/extensions.h b/src/ui/dialog/extensions.h
new file mode 100644 (file)
index 0000000..8b0fc27
--- /dev/null
@@ -0,0 +1,56 @@
+/** @file
+ * A simple dialog with information about extensions
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2005 The Inkscape Organization
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifndef SEEN_EXTENSIONS_H
+#define SEEN_EXTENSIONS_H
+
+#include <gtkmm/textview.h>
+#include "ui/widget/panel.h"
+
+namespace Inkscape {
+namespace Extension {
+class Extension;
+}
+}
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+
+/**
+ * A panel that displays information about extensions.
+ */
+class ExtensionsPanel : public Inkscape::UI::Widget::Panel
+{
+public:
+    ExtensionsPanel();
+
+    static ExtensionsPanel &getInstance();
+
+    void set_full(bool full);
+
+private:
+    ExtensionsPanel(ExtensionsPanel const &); // no copy
+    ExtensionsPanel &operator=(ExtensionsPanel const &); // no assign
+
+    static void listCB(Inkscape::Extension::Extension *in_plug, gpointer in_data);
+
+    void rescan();
+
+    bool _showAll;
+    Gtk::TextView _view;
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+#endif // SEEN_EXTENSIONS_H
index d28dc7955b20d03086f49cdeb344366f9adf1f5e..fe63c6e24e6fd9f15e4e2ff172d019bca906e5cc 100644 (file)
 #include "selection.h"
 #include "style.h"
 #include "svg/css-ostringstream.h"
+#include "ui/icon-names.h"
 #include "verbs.h"
-#include "xml/repr.h"
+#include "widgets/fill-style.h"
 #include "widgets/icon.h"
-#include "ui/icon-names.h"
-
-#include "dialogs/fill-style.h"
-#include "dialogs/stroke-style.h"
-
-#include <widgets/paint-selector.h>
+#include "widgets/paint-selector.h"
+#include "widgets/stroke-style.h"
+#include "xml/repr.h"
 
 namespace Inkscape {
 namespace UI {
diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp
new file mode 100644 (file)
index 0000000..c5d2ae4
--- /dev/null
@@ -0,0 +1,285 @@
+/** @file
+ * @brief Simple guideline dialog
+ */
+/* Authors:
+ *   Lauris Kaplinski <lauris@kaplinski.com>
+ *   Andrius R. <knutux@gmail.com>
+ *   Johan Engelen
+ *
+ * Copyright (C) 1999-2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "display/guideline.h"
+#include "helper/unit-menu.h"
+#include "helper/units.h"
+#include "desktop.h"
+#include "document.h"
+#include "sp-guide.h"
+#include "sp-namedview.h"
+#include "desktop-handles.h"
+#include "event-context.h"
+#include "widgets/desktop-widget.h"
+#include "sp-metrics.h"
+#include <glibmm/i18n.h>
+#include "dialogs/dialog-events.h"
+#include "message-context.h"
+#include "xml/repr.h"
+#include <2geom/point.h>
+#include <2geom/angle.h>
+#include "guides.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop)
+: _desktop(desktop), _guide(guide),
+  _label_units(_("Unit:")),
+  _label_X(_("X:")),
+  _label_Y(_("Y:")),
+  _label_degrees(_("Angle (degrees):")),
+  _relative_toggle(_("Rela_tive change"), _("Move and/or rotate the guide relative to current settings")),
+  _adjustment_x(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
+  _adjustment_y(0.0, -1e6, 1e6, 1.0, 10.0, 10.0),  
+  _adj_angle(0.0, -360, 360, 1.0, 10.0, 10.0),  
+  _unit_selector(NULL), _mode(true), _oldpos(0.,0.), _oldangle(0.0)
+{
+}
+
+GuidelinePropertiesDialog::~GuidelinePropertiesDialog() {
+}
+
+void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) {
+    GuidelinePropertiesDialog dialog(guide, desktop);
+    dialog._setup();
+    dialog.run();
+}
+
+void GuidelinePropertiesDialog::_modeChanged()
+{
+    _mode = !_relative_toggle.get_active();
+    if (!_mode) {
+        // relative
+        _spin_angle.set_value(0);
+
+        _spin_button_y.set_value(0);
+        _spin_button_x.set_value(0);
+    } else {
+        // absolute
+        _spin_angle.set_value(_oldangle);
+
+        SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
+        gdouble const val_y = sp_pixels_get_units(_oldpos[Geom::Y], unit);
+        _spin_button_y.set_value(val_y);
+        gdouble const val_x = sp_pixels_get_units(_oldpos[Geom::X], unit);
+        _spin_button_x.set_value(val_x);
+    }
+}
+
+void GuidelinePropertiesDialog::_onApply()
+{
+    double deg_angle = _spin_angle.get_value();
+    if (!_mode)
+        deg_angle += _oldangle;
+    Geom::Point normal;
+    if ( deg_angle == 90. || deg_angle == 270. || deg_angle == -90. || deg_angle == -270.) {
+        normal = Geom::Point(1.,0.);
+    } else if ( deg_angle == 0. || deg_angle == 180. || deg_angle == -180.) {
+        normal = Geom::Point(0.,1.);
+    } else {
+        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);
+
+    SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(_unit_selector->gobj()));
+    gdouble const raw_dist_x = _spin_button_x.get_value();
+    gdouble const points_x = sp_units_get_pixels(raw_dist_x, unit);
+    gdouble const raw_dist_y = _spin_button_y.get_value();
+    gdouble const points_y = sp_units_get_pixels(raw_dist_y, unit);
+    Geom::Point newpos(points_x, points_y);
+    if (!_mode)
+        newpos += _oldpos;
+
+    sp_guide_moveto(*_guide, newpos, true);
+
+    sp_document_done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, 
+                     _("Set guide properties"));
+}
+
+void GuidelinePropertiesDialog::_onOK()
+{
+    _onApply();
+}
+
+void GuidelinePropertiesDialog::_onDelete()
+{
+    SPDocument *doc = SP_OBJECT_DOCUMENT(_guide);
+    sp_guide_remove(_guide);
+    sp_document_done(doc, SP_VERB_NONE, 
+                     _("Delete guide"));
+}
+
+void GuidelinePropertiesDialog::_response(gint response)
+{
+    switch (response) {
+       case Gtk::RESPONSE_OK:
+            _onOK();
+            break;
+       case -12:
+            _onDelete();
+            break;
+       case Gtk::RESPONSE_CANCEL:
+            break;
+       case Gtk::RESPONSE_DELETE_EVENT:
+            break;
+/*     case GTK_RESPONSE_APPLY:
+        _onApply();
+        break;
+*/
+       default:
+            g_assert_not_reached();
+    }
+}
+
+void GuidelinePropertiesDialog::_setup() {
+    set_title(_("Guideline"));
+    add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
+    add_button(Gtk::Stock::DELETE, -12);
+    add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+
+    Gtk::VBox *mainVBox = get_vbox();
+
+    _layout_table.set_spacings(4);
+    _layout_table.resize (3, 4);
+
+    mainVBox->pack_start(_layout_table, false, false, 0);
+
+    _label_name.set_label("foo0");
+    _layout_table.attach(_label_name,
+                         0, 3, 0, 1, Gtk::FILL, Gtk::FILL);
+    _label_name.set_alignment(0, 0.5);
+
+    _label_descr.set_label("foo1");
+    _layout_table.attach(_label_descr,
+                         0, 3, 1, 2, Gtk::FILL, Gtk::FILL);
+    _label_descr.set_alignment(0, 0.5);
+
+    // indent
+    _layout_table.attach(*manage(new Gtk::Label(" ")),
+                         0, 1, 2, 3, Gtk::FILL, Gtk::FILL, 10);
+
+    // mode radio button
+    _layout_table.attach(_relative_toggle,
+                         1, 3, 9, 10, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _relative_toggle.signal_toggled().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_modeChanged));
+
+    // unitmenu
+    /* fixme: We should allow percents here too, as percents of the canvas size */
+    GtkWidget *unit_selector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
+    sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unit_selector), _desktop->namedview->doc_units);
+    _unit_selector = Gtk::manage(Glib::wrap(unit_selector));
+
+    // position spinbuttons
+    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_x.gobj()));
+    sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(unit_selector), GTK_ADJUSTMENT(_adjustment_y.gobj()));
+    _spin_button_x.configure(_adjustment_x, 1.0 , 3);
+    _spin_button_x.set_numeric();
+    _spin_button_y.configure(_adjustment_y, 1.0 , 3);
+    _spin_button_y.set_numeric();
+    _layout_table.attach(_label_X,
+                         1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_button_x,
+                         2, 3, 4, 5, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_label_Y,
+                         1, 2, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_button_y,
+                         2, 3, 5, 6, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    gtk_signal_connect_object(GTK_OBJECT(_spin_button_x.gobj()), "activate",
+                              GTK_SIGNAL_FUNC(gtk_window_activate_default),
+                              gobj());
+
+    _layout_table.attach(_label_units,
+                         1, 2, 6, 7, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(*_unit_selector,
+                         2, 3, 6, 7, Gtk::FILL, Gtk::FILL);
+
+    // angle spinbutton
+    _spin_angle.configure(_adj_angle, 5.0 , 3);
+    _spin_angle.set_numeric();
+    _spin_angle.show();
+    _layout_table.attach(_label_degrees,
+                         1, 2, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_spin_angle,
+                         2, 3, 8, 9, Gtk::EXPAND | Gtk::FILL, Gtk::FILL);
+
+
+    // dialog
+    set_default_response(Gtk::RESPONSE_OK);
+    signal_response().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_response));
+
+    // initialize dialog
+    _oldpos = _guide->point_on_line;
+    if (_guide->is_vertical()) {
+        _oldangle = 90;
+    } else if (_guide->is_horizontal()) {
+        _oldangle = 0;
+    } else {
+        _oldangle = Geom::rad_to_deg( std::atan2( - _guide->normal_to_line[Geom::X], _guide->normal_to_line[Geom::Y] ) );
+    }
+
+    {
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR (_guide);
+        const gchar *guide_id = repr->attribute("id");
+        gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id);
+        _label_name.set_label(label);
+        g_free(label);
+    }
+    {
+        gchar *guide_description = sp_guide_description(_guide);
+        gchar *label = g_strdup_printf(_("Current: %s"), guide_description);
+        g_free(guide_description);
+        _label_descr.set_markup(label);
+        g_free(label);
+    }
+
+    _modeChanged(); // sets values of spinboxes.
+
+    if ( _oldangle == 90. || _oldangle == 270. || _oldangle == -90. || _oldangle == -270.) {
+        _spin_button_x.grab_focus();
+        _spin_button_x.select_region(0, 20);
+    } else if ( _oldangle == 0. || _oldangle == 180. || _oldangle == -180.) {
+        _spin_button_y.grab_focus();
+        _spin_button_y.select_region(0, 20);
+    } else {
+        _spin_angle.grab_focus();
+        _spin_angle.select_region(0, 20);
+    }
+
+    set_position(Gtk::WIN_POS_MOUSE);
+
+    show_all_children();
+    set_modal(true);
+    _desktop->setWindowTransient (gobj());
+    property_destroy_with_parent() = true;
+}
+
+}
+}
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h
new file mode 100644 (file)
index 0000000..49f94de
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ *
+ * \brief  Dialog for modifying guidelines
+ *
+ * Author:
+ *   Andrius R. <knutux@gmail.com>
+ *   Johan Engelen
+ *
+ * Copyright (C) 2006-2007 Authors
+ *
+ * Released under GNU GPL.  Read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_DIALOG_GUIDELINE_H
+#define INKSCAPE_DIALOG_GUIDELINE_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/table.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/label.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/adjustment.h>
+#include "ui/widget/button.h"
+#include <2geom/point.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+class GuidelinePropertiesDialog : public Gtk::Dialog {
+public:
+    GuidelinePropertiesDialog(SPGuide *guide, SPDesktop *desktop);
+    virtual ~GuidelinePropertiesDialog();
+
+    Glib::ustring     getName() const { return "GuidelinePropertiesDialog"; }
+
+    static void showDialog(SPGuide *guide, SPDesktop *desktop);
+
+protected:
+    void _setup();
+
+    void _onApply();
+    void _onOK();
+    void _onDelete();
+
+    void _response(gint response);
+    void _modeChanged();
+
+private:
+    GuidelinePropertiesDialog(GuidelinePropertiesDialog const &); // no copy
+    GuidelinePropertiesDialog &operator=(GuidelinePropertiesDialog const &); // no assign
+
+    SPDesktop *_desktop;
+    SPGuide *_guide;
+    Gtk::Table  _layout_table;
+    Gtk::Label  _label_name;
+    Gtk::Label  _label_descr;
+    Gtk::Label  _label_units;
+    Gtk::Label  _label_X;
+    Gtk::Label  _label_Y;
+    Gtk::Label  _label_degrees;
+    Inkscape::UI::Widget::CheckButton _relative_toggle;
+    Gtk::Adjustment _adjustment_x;
+    Gtk::SpinButton _spin_button_x;
+    Gtk::Adjustment _adjustment_y;
+    Gtk::SpinButton _spin_button_y;
+
+    Gtk::Adjustment _adj_angle;
+    Gtk::SpinButton _spin_angle;
+
+    Gtk::Widget *_unit_selector;
+    bool _mode;
+    Geom::Point _oldpos;
+    gdouble _oldangle;
+};
+
+} // namespace
+} // namespace
+} // namespace
+
+
+#endif // INKSCAPE_DIALOG_GUIDELINE_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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp
new file mode 100644 (file)
index 0000000..336afc3
--- /dev/null
@@ -0,0 +1,307 @@
+/** @file
+ * @brief A simple dialog for previewing icon representation.
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *   Bob Jamison
+ *   Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004 Bob Jamison
+ * Copyright (C) 2005 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gmem.h>
+#include <glibmm/i18n.h>
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/stock.h>
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "display/nr-arena.h"
+#include "document.h"
+#include "inkscape.h"
+#include "preferences.h"
+#include "selection.h"
+#include "sp-root.h"
+#include "xml/repr.h"
+
+#include "icon-preview.h"
+
+extern "C" {
+// takes doc, root, icon, and icon name to produce pixels
+guchar *
+sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root,
+                  const gchar *name, unsigned int psize );
+}
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+
+IconPreviewPanel&
+IconPreviewPanel::getInstance()
+{
+    static IconPreviewPanel &instance = *new IconPreviewPanel();
+
+    instance.refreshPreview();
+
+    return instance;
+}
+
+//#########################################################################
+//## E V E N T S
+//#########################################################################
+
+void IconPreviewPanel::on_button_clicked(int which)
+{
+    if ( hot != which ) {
+        buttons[hot]->set_active( false );
+
+        hot = which;
+        updateMagnify();
+        _getContents()->queue_draw();
+    }
+}
+
+
+
+
+//#########################################################################
+//## C O N S T R U C T O R    /    D E S T R U C T O R
+//#########################################################################
+/**
+ * Constructor
+ */
+IconPreviewPanel::IconPreviewPanel() :
+    UI::Widget::Panel("", "/dialogs/iconpreview", SP_VERB_VIEW_ICON_PREVIEW),
+    hot(1),
+    refreshButton(0),
+    selectionButton(0)
+{
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    numEntries = 0;
+
+    std::vector<Glib::ustring> pref_sizes = prefs->getAllDirs("/iconpreview/sizes/default");
+    std::vector<int> rawSizes;
+    
+    for (std::vector<Glib::ustring>::iterator i = pref_sizes.begin(); i != pref_sizes.end(); ++i) {
+        if (prefs->getBool(*i + "/show", true)) {
+            int sizeVal = prefs->getInt(*i + "/value", -1);
+            if (sizeVal > 0) {
+                rawSizes.push_back(sizeVal);
+            }
+        }
+    }
+
+    if ( !rawSizes.empty() ) {
+        numEntries = rawSizes.size();
+        sizes = new int[numEntries];
+        int i = 0;
+        for ( std::vector<int>::iterator it = rawSizes.begin(); it != rawSizes.end(); ++it, ++i ) {
+            sizes[i] = *it;
+        }
+    }
+
+    if ( numEntries < 1 )
+    {
+        numEntries = 5;
+        sizes = new int[numEntries];
+        sizes[0] = 16;
+        sizes[1] = 24;
+        sizes[2] = 32;
+        sizes[3] = 48;
+        sizes[4] = 128;
+    }
+
+    pixMem = new guchar*[numEntries];
+    images = new Gtk::Image*[numEntries];
+    labels = new Glib::ustring*[numEntries];
+    buttons = new Gtk::ToggleToolButton*[numEntries];
+
+
+    for ( int i = 0; i < numEntries; i++ ) {
+        char *label = g_strdup_printf(_("%d x %d"), sizes[i], sizes[i]);
+        labels[i] = new Glib::ustring(label);
+        g_free(label);
+        pixMem[i] = 0;
+        images[i] = 0;
+    }
+
+
+    magLabel.set_label( *labels[hot] );
+
+    Gtk::VBox* magBox = new Gtk::VBox();
+
+    magBox->pack_start( magnified );
+    magBox->pack_start( magLabel, Gtk::PACK_SHRINK );
+
+
+    Gtk::VBox * verts = new Gtk::VBox();
+    for ( int i = 0; i < numEntries; i++ ) {
+        pixMem[i] = new guchar[4 * sizes[i] * sizes[i]];
+        memset( pixMem[i], 0x00, 4 *  sizes[i] * sizes[i] );
+
+        GdkPixbuf *pb = gdk_pixbuf_new_from_data( pixMem[i], GDK_COLORSPACE_RGB, TRUE, 8, sizes[i], sizes[i], sizes[i] * 4, /*(GdkPixbufDestroyNotify)g_free*/NULL, NULL );
+        GtkImage* img = GTK_IMAGE( gtk_image_new_from_pixbuf( pb ) );
+        images[i] = Glib::wrap(img);
+        Glib::ustring label(*labels[i]);
+        buttons[i] = new Gtk::ToggleToolButton(label);
+        buttons[i]->set_active( i == hot );
+        buttons[i]->set_icon_widget(*images[i]);
+
+        tips.set_tip((*buttons[i]), label);
+
+        buttons[i]->signal_clicked().connect( sigc::bind<int>( sigc::mem_fun(*this, &IconPreviewPanel::on_button_clicked), i) );
+
+
+        verts->add(*buttons[i]);
+    }
+
+    iconBox.pack_start(splitter);
+    splitter.pack1( *magBox, true, true );
+    splitter.pack2( *verts, false, false );
+
+
+    //## The Refresh button
+
+
+    Gtk::HButtonBox* holder = new Gtk::HButtonBox( Gtk::BUTTONBOX_END );
+    _getContents()->pack_end(*holder, false, false);
+
+    selectionButton = new Gtk::ToggleButton(_("Selection")); // , GTK_RESPONSE_APPLY
+    holder->pack_start( *selectionButton, false, false );
+    tips.set_tip((*selectionButton), _("Selection only or whole document"));
+    selectionButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::modeToggled) );
+
+    gint val = prefs->getBool("/iconpreview/selectionOnly");
+    selectionButton->set_active( val != 0 );
+
+    refreshButton = new Gtk::Button(Gtk::Stock::REFRESH); // , GTK_RESPONSE_APPLY
+    holder->pack_end( *refreshButton, false, false );
+    tips.set_tip((*refreshButton), _("Refresh the icons"));
+    refreshButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::refreshPreview) );
+
+
+    _getContents()->pack_start(iconBox, Gtk::PACK_EXPAND_WIDGET);
+
+    show_all_children();
+}
+
+//#########################################################################
+//## M E T H O D S
+//#########################################################################
+
+
+void IconPreviewPanel::refreshPreview()
+{
+    SPDesktop *desktop = getDesktop();
+    if ( desktop ) {
+
+        if ( selectionButton && selectionButton->get_active() )
+        {
+            Inkscape::Selection * sel = sp_desktop_selection(desktop);
+            if ( sel ) {
+                //g_message("found a selection to play with");
+
+                GSList const *items = sel->itemList();
+                SPObject *target = 0;
+                while ( items && !target ) {
+                    SPItem* item = SP_ITEM( items->data );
+                    SPObject * obj = SP_OBJECT(item);
+                    gchar const *id = SP_OBJECT_ID( obj );
+                    if ( id ) {
+                        target = obj;
+                    }
+
+                    items = g_slist_next(items);
+                }
+                if ( target ) {
+                    renderPreview(target);
+                }
+            }
+        }
+        else
+        {
+            SPObject *target = desktop->currentRoot();
+            if ( target ) {
+                renderPreview(target);
+            }
+        }
+    }
+}
+
+void IconPreviewPanel::modeToggled()
+{
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setBool("/iconpreview/selectionOnly", (selectionButton && selectionButton->get_active()));
+
+    refreshPreview();
+}
+
+void IconPreviewPanel::renderPreview( SPObject* obj )
+{
+    SPDocument * doc = SP_OBJECT_DOCUMENT(obj);
+    gchar * id = SP_OBJECT_ID(obj);
+
+//    g_message(" setting up to render '%s' as the icon", id );
+
+    NRArenaItem *root = NULL;
+
+    /* Create new arena */
+    NRArena *arena = NRArena::create();
+
+    /* Create ArenaItem and set transform */
+    unsigned int visionkey = sp_item_display_key_new(1);
+
+    root = sp_item_invoke_show ( SP_ITEM( SP_DOCUMENT_ROOT(doc) ),
+                                 arena, visionkey, SP_ITEM_SHOW_DISPLAY );
+
+    for ( int i = 0; i < numEntries; i++ ) {
+        guchar * px = sp_icon_doc_icon( doc, root, id, sizes[i] );
+//         g_message( " size %d %s", sizes[i], (px ? "worked" : "failed") );
+        if ( px ) {
+            memcpy( pixMem[i], px, sizes[i] * sizes[i] * 4 );
+            g_free( px );
+            px = 0;
+        } else {
+            memset( pixMem[i], 0, sizes[i] * sizes[i] * 4 );
+        }
+        images[i]->queue_draw();
+    }
+    updateMagnify();
+
+    sp_item_invoke_hide(SP_ITEM(sp_document_root(doc)), visionkey);
+    nr_object_unref((NRObject *) arena);
+}
+
+void IconPreviewPanel::updateMagnify()
+{
+    Glib::RefPtr<Gdk::Pixbuf> buf = images[hot]->get_pixbuf()->scale_simple( 128, 128, Gdk::INTERP_NEAREST );
+    magLabel.set_label( *labels[hot] );
+    magnified.set( buf );
+    magnified.queue_draw();
+    magnified.get_parent()->queue_draw();
+}
+
+
+} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/icon-preview.h b/src/ui/dialog/icon-preview.h
new file mode 100644 (file)
index 0000000..8f14372
--- /dev/null
@@ -0,0 +1,84 @@
+/** @file
+ * @brief A simple dialog for previewing icon representation.
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *   Bob Jamison
+ *   Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004,2005 The Inkscape Organization
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_ICON_PREVIEW_H
+#define SEEN_ICON_PREVIEW_H
+
+#include <gtkmm/box.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/image.h>
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/toggletoolbutton.h>
+
+#include "ui/widget/panel.h"
+
+struct SPObject;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+
+/**
+ * A panel that displays an icon preview
+ */
+class IconPreviewPanel : public UI::Widget::Panel
+{
+public:
+    IconPreviewPanel();
+    //IconPreviewPanel(Glib::ustring const &label);
+
+    static IconPreviewPanel& getInstance();
+
+    void refreshPreview();
+    void modeToggled();
+
+private:
+    IconPreviewPanel(IconPreviewPanel const &); // no copy
+    IconPreviewPanel &operator=(IconPreviewPanel const &); // no assign
+
+
+    void on_button_clicked(int which);
+    void renderPreview( SPObject* obj );
+    void updateMagnify();
+
+    Gtk::Tooltips   tips;
+
+    Gtk::VBox       iconBox;
+    Gtk::HPaned     splitter;
+
+    int hot;
+    int numEntries;
+    int* sizes;
+
+    Gtk::Image      magnified;
+    Gtk::Label      magLabel;
+
+    Gtk::Button           *refreshButton;
+    Gtk::ToggleButton     *selectionButton;
+
+    guchar** pixMem;
+    Gtk::Image** images;
+    Glib::ustring** labels;
+    Gtk::ToggleToolButton** buttons;
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+
+#endif // SEEN_ICON_PREVIEW_H
diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp
new file mode 100644 (file)
index 0000000..ccd91fa
--- /dev/null
@@ -0,0 +1,256 @@
+/** @file
+ * @brief Dialog for renaming layers
+ */
+/* Author:
+ *   Bryce W. Harrington <bryce@bryceharrington.com>
+ *   Andrius R. <knutux@gmail.com>
+ *
+ * Copyright (C) 2004 Bryce Harrington
+ * Copyright (C) 2006 Andrius R.
+ *
+ * Released under GNU GPL.  Read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/stock.h>
+#include <glibmm/i18n.h>
+#include "inkscape.h"
+#include "desktop.h"
+#include "document.h"
+#include "layer-manager.h"
+#include "message-stack.h"
+#include "desktop-handles.h"
+#include "sp-object.h"
+#include "sp-item.h"
+
+#include "layer-properties.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+LayerPropertiesDialog::LayerPropertiesDialog()
+: _strategy(NULL), _desktop(NULL), _layer(NULL), _position_visible(false)
+{
+    Gtk::VBox *mainVBox = get_vbox();
+
+    _layout_table.set_spacings(4);
+    _layout_table.resize (1, 2);
+
+    // Layer name widgets
+    _layer_name_entry.set_activates_default(true);
+    _layer_name_label.set_label(_("Layer name:"));
+    _layer_name_label.set_alignment(1.0, 0.5);
+
+    _layout_table.attach(_layer_name_label,
+                         0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
+    _layout_table.attach(_layer_name_entry,
+                         1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+    mainVBox->pack_start(_layout_table, false, false, 4);
+
+    // Buttons
+    _close_button.set_use_stock(true);
+    _close_button.set_label(Gtk::Stock::CANCEL.id);
+    _close_button.set_flags(Gtk::CAN_DEFAULT);
+
+    _apply_button.set_use_underline(true);
+    _apply_button.set_flags(Gtk::CAN_DEFAULT);
+
+    _close_button.signal_clicked()
+        .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_close));
+    _apply_button.signal_clicked()
+        .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_apply));
+
+    signal_delete_event().connect(
+        sigc::bind_return(
+            sigc::hide(sigc::mem_fun(*this, &LayerPropertiesDialog::_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();
+}
+
+LayerPropertiesDialog::~LayerPropertiesDialog() {
+    _setDesktop(NULL);
+    _setLayer(NULL);
+}
+
+void LayerPropertiesDialog::_showDialog(LayerPropertiesDialog::Strategy &strategy,
+                                        SPDesktop *desktop, SPObject *layer)
+{
+    LayerPropertiesDialog *dialog = new LayerPropertiesDialog();
+
+    dialog->_strategy = &strategy;
+    dialog->_setDesktop(desktop);
+    dialog->_setLayer(layer);
+
+    dialog->_strategy->setup(*dialog);
+
+    dialog->set_modal(true);
+    desktop->setWindowTransient (dialog->gobj());
+    dialog->property_destroy_with_parent() = true;
+
+    dialog->show();
+    dialog->present();
+}
+
+void
+LayerPropertiesDialog::_apply()
+{
+    g_assert(_strategy != NULL);
+
+    _strategy->perform(*this);
+    sp_document_done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_NONE,
+                     _("Add layer"));
+
+    _close();
+}
+
+void
+LayerPropertiesDialog::_close()
+{
+    _setLayer(NULL);
+    _setDesktop(NULL);
+    destroy_();
+    Glib::signal_idle().connect(
+        sigc::bind_return(
+            sigc::bind(sigc::ptr_fun(&::operator delete), this),
+            false 
+        )
+    );
+}
+
+void
+LayerPropertiesDialog::_setup_position_controls() {
+    if ( NULL == _layer || _desktop->currentRoot() == _layer ) {
+        // no layers yet, so option above/below/sublayer is useless
+        return;
+    }
+
+    _position_visible = true;
+    _dropdown_list = Gtk::ListStore::create(_dropdown_columns);
+    _layer_position_combo.set_model(_dropdown_list);
+    _layer_position_combo.pack_start(_label_renderer);
+    _layer_position_combo.set_cell_data_func(_label_renderer,
+                                             sigc::mem_fun(*this, &LayerPropertiesDialog::_prepareLabelRenderer));
+
+    _layout_table.resize (2, 2);
+
+    Gtk::ListStore::iterator row;
+    row = _dropdown_list->append();
+    row->set_value(_dropdown_columns.position, LPOS_ABOVE);
+    row->set_value(_dropdown_columns.name, Glib::ustring(_("Above current")));
+    _layer_position_combo.set_active(row);
+    row = _dropdown_list->append();
+    row->set_value(_dropdown_columns.position, LPOS_BELOW);
+    row->set_value(_dropdown_columns.name, Glib::ustring(_("Below current")));
+    row = _dropdown_list->append();
+    row->set_value(_dropdown_columns.position, LPOS_CHILD);
+    row->set_value(_dropdown_columns.name, Glib::ustring(_("As sublayer of current")));
+
+    _layout_table.attach(_layer_position_combo,
+                         1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
+    _layer_position_label.set_label(_("Position:"));
+    _layer_position_label.set_alignment(1.0, 0.5);
+    _layout_table.attach(_layer_position_label,
+                         0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
+    show_all_children();
+}
+
+/** Formats the label for a given layer row 
+ */
+void LayerPropertiesDialog::_prepareLabelRenderer(
+    Gtk::TreeModel::const_iterator const &row
+) {
+    Glib::ustring name=(*row)[_dropdown_columns.name];
+    _label_renderer.property_markup() = name.c_str();
+}
+
+void LayerPropertiesDialog::Rename::setup(LayerPropertiesDialog &dialog) {
+    SPDesktop *desktop=dialog._desktop;
+    dialog.set_title(_("Rename Layer"));
+    gchar const *name = desktop->currentLayer()->label();
+    dialog._layer_name_entry.set_text(( name ? name : "" ));
+    dialog._apply_button.set_label(_("_Rename"));
+}
+
+void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) {
+    SPDesktop *desktop=dialog._desktop;
+    Glib::ustring name(dialog._layer_name_entry.get_text());
+    desktop->layer_manager->renameLayer( desktop->currentLayer(),
+                                         ( name.empty() ? NULL : (gchar *)name.c_str() )
+    );
+    sp_document_done(sp_desktop_document(desktop), SP_VERB_NONE, 
+                     _("Rename layer"));
+    // TRANSLATORS: This means "The layer has been renamed"
+    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Renamed layer"));
+}
+
+void LayerPropertiesDialog::Create::setup(LayerPropertiesDialog &dialog) {
+    dialog.set_title(_("Add Layer"));
+    dialog._layer_name_entry.set_text("");
+    dialog._apply_button.set_label(_("_Add"));
+    dialog._setup_position_controls();
+}
+
+void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) {
+    SPDesktop *desktop=dialog._desktop;
+
+    LayerRelativePosition position = LPOS_ABOVE;
+    
+    if (dialog._position_visible) {
+        Gtk::ListStore::iterator activeRow(dialog._layer_position_combo.get_active());
+        position = activeRow->get_value(dialog._dropdown_columns.position);
+    }
+
+    SPObject *new_layer=Inkscape::create_layer(desktop->currentRoot(), dialog._layer, position);
+    
+    Glib::ustring name(dialog._layer_name_entry.get_text());
+    if (!name.empty()) {
+        desktop->layer_manager->renameLayer( new_layer, (gchar *)name.c_str() );
+    }
+    sp_desktop_selection(desktop)->clear();
+    desktop->setCurrentLayer(new_layer);
+    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created."));
+}
+
+void LayerPropertiesDialog::_setDesktop(SPDesktop *desktop) {
+    if (desktop) {
+        Inkscape::GC::anchor (desktop);
+    }
+    if (_desktop) {
+        Inkscape::GC::release (_desktop);
+    }
+    _desktop = desktop;
+}
+
+void LayerPropertiesDialog::_setLayer(SPObject *layer) {
+    if (layer) {
+        sp_object_ref(layer, NULL);
+    }
+    if (_layer) {
+        sp_object_unref(_layer, NULL);
+    }
+    _layer = layer;
+}
+
+} // 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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h
new file mode 100644 (file)
index 0000000..807967e
--- /dev/null
@@ -0,0 +1,132 @@
+/** @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_LAYER_PROPERTIES_H
+#define INKSCAPE_DIALOG_LAYER_PROPERTIES_H
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/separator.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/label.h>
+#include <gtkmm/table.h>
+#include <gtkmm/combobox.h>
+#include <gtkmm/liststore.h>
+
+#include "selection.h"
+#include "layer-fns.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+class LayerPropertiesDialog : public Gtk::Dialog {
+ public:
+    LayerPropertiesDialog();
+    virtual ~LayerPropertiesDialog();
+
+    Glib::ustring     getName() const { return "LayerPropertiesDialog"; }
+
+    static void showRename(SPDesktop *desktop, SPObject *layer) {
+        _showDialog(Rename::instance(), desktop, layer);
+    }
+    static void showCreate(SPDesktop *desktop, SPObject *layer) {
+        _showDialog(Create::instance(), desktop, layer);
+    }
+
+protected:
+    struct Strategy {
+        virtual ~Strategy() {}
+        virtual void setup(LayerPropertiesDialog &)=0;
+        virtual void perform(LayerPropertiesDialog &)=0;
+    };
+    struct Rename : public Strategy {
+        static Rename &instance() { static Rename instance; return instance; }
+        void setup(LayerPropertiesDialog &dialog);
+        void perform(LayerPropertiesDialog &dialog);
+    };
+    struct Create : public Strategy {
+        static Create &instance() { static Create instance; return instance; }
+        void setup(LayerPropertiesDialog &dialog);
+        void perform(LayerPropertiesDialog &dialog);
+    };
+
+    friend class Rename;
+    friend class Create;
+
+    Strategy *_strategy;
+    SPDesktop *_desktop;
+    SPObject *_layer;
+
+    class PositionDropdownColumns : public Gtk::TreeModel::ColumnRecord {
+    public:
+        Gtk::TreeModelColumn<LayerRelativePosition> position;
+        Gtk::TreeModelColumn<Glib::ustring> name;
+
+        PositionDropdownColumns() {
+            add(position); add(name);
+        }
+    };
+
+    Gtk::Label        _layer_name_label;
+    Gtk::Entry        _layer_name_entry;
+    Gtk::Label        _layer_position_label;
+    Gtk::ComboBox     _layer_position_combo;
+    Gtk::Table        _layout_table;
+    bool              _position_visible;
+
+    PositionDropdownColumns _dropdown_columns;
+    Gtk::CellRendererText _label_renderer;
+    Glib::RefPtr<Gtk::ListStore> _dropdown_list;
+
+    Gtk::Button       _close_button;
+    Gtk::Button       _apply_button;
+
+    sigc::connection    _destroy_connection;
+
+    static LayerPropertiesDialog &_instance() {
+        static LayerPropertiesDialog instance;
+        return instance;
+    }
+
+    void _setDesktop(SPDesktop *desktop);
+    void _setLayer(SPObject *layer);
+
+    static void _showDialog(Strategy &strategy, SPDesktop *desktop, SPObject *layer);
+    void _apply();
+    void _close();
+
+    void _setup_position_controls();
+    void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
+
+private:
+    LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy
+    LayerPropertiesDialog &operator=(LayerPropertiesDialog 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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp
new file mode 100644 (file)
index 0000000..0e75401
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+ * A simple panel for layers
+ *
+ * Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2006 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtkstock.h>
+#include <gtk/gtkmain.h>
+#include <gtkmm/widget.h>
+#include <gtkmm/icontheme.h>
+#include <glibmm/i18n.h>
+
+#include "desktop.h"
+#include "desktop-style.h"
+#include "document.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 "svg/css-ostringstream.h"
+#include "ui/icon-names.h"
+#include "ui/widget/imagetoggler.h"
+#include "verbs.h"
+#include "widgets/icon.h"
+#include "xml/repr.h"
+
+#include "layers.h"
+
+//#define DUMP_LAYERS 1
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+LayersPanel&
+LayersPanel::getInstance()
+{
+    return *new LayersPanel();
+}
+
+enum {
+    COL_VISIBLE = 1,
+    COL_LOCKED
+};
+
+enum {
+    BUTTON_NEW = 0,
+    BUTTON_RENAME,
+    BUTTON_TOP,
+    BUTTON_BOTTOM,
+    BUTTON_UP,
+    BUTTON_DOWN,
+    BUTTON_DUPLICATE,
+    BUTTON_DELETE,
+    BUTTON_SOLO
+};
+
+class LayersPanel::InternalUIBounce
+{
+public:
+    int _actionCode;
+    SPObject* _target;
+};
+
+static gboolean layers_panel_activated( GtkObject */*object*/, GdkEvent * /*event*/, gpointer data )
+{
+    if ( data )
+    {
+        LayersPanel* panel = reinterpret_cast<LayersPanel*>(data);
+        panel->setDesktop(panel->getDesktop());
+    }
+
+    return FALSE;
+}
+
+static gboolean layers_panel_deactivated( GtkObject */*object*/, GdkEvent * /*event*/, gpointer data )
+{
+    if ( data )
+    {
+        LayersPanel* panel = reinterpret_cast<LayersPanel*>(data);
+        panel->setDesktop(NULL);
+    }
+
+    return FALSE;
+}
+
+
+void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback )
+{
+    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)) );
+        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;
+            }
+
+            if ( action && action->tip ) {
+                _tips.set_tip( btn, action->tip );
+            }
+        }
+    }
+
+    if ( !set && fallback ) {
+        btn.set_label( fallback );
+    }
+}
+
+
+Gtk::MenuItem& LayersPanel::_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::Menu::MenuList& menulist = _popupMenu.items();
+
+    if ( wrapped ) {
+        menulist.push_back( Gtk::Menu_Helpers::ImageMenuElem( label, *wrapped, sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), id)) );
+    } else {
+        menulist.push_back( Gtk::Menu_Helpers::MenuElem( label, sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), id)) );
+    }
+    return menulist.back();
+}
+
+void LayersPanel::_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 );
+//             } else {
+//                 g_message("no action");
+            }
+//         } else {
+//             g_message("no verb for %u", code);
+        }
+//     } else {
+//         g_message("no active desktop");
+    }
+}
+
+//     SP_VERB_LAYER_NEXT,
+//     SP_VERB_LAYER_PREV,
+void LayersPanel::_takeAction( int val )
+{
+    if ( !_pending ) {
+        _pending = new InternalUIBounce();
+        _pending->_actionCode = val;
+        _pending->_target = _selectedLayer();
+        Glib::signal_timeout().connect( sigc::mem_fun(*this, &LayersPanel::_executeAction), 0 );
+    }
+}
+
+bool LayersPanel::_executeAction()
+{
+    // Make sure selected layer hasn't changed since the action was triggered
+    if ( _pending
+         && (
+             (_pending->_actionCode == BUTTON_NEW)
+             || !( (_desktop && _desktop->currentLayer())
+                   && (_desktop->currentLayer() != _pending->_target)
+                 )
+             )
+        ) {
+        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:
+            {
+                _fireAction( SP_VERB_LAYER_TO_TOP );
+            }
+            break;
+            case BUTTON_BOTTOM:
+            {
+                _fireAction( SP_VERB_LAYER_TO_BOTTOM );
+            }
+            break;
+            case BUTTON_UP:
+            {
+                _fireAction( SP_VERB_LAYER_RAISE );
+            }
+            break;
+            case BUTTON_DOWN:
+            {
+                _fireAction( SP_VERB_LAYER_LOWER );
+            }
+            break;
+            case BUTTON_DUPLICATE:
+            {
+                _fireAction( SP_VERB_LAYER_DUPLICATE );
+            }
+            break;
+            case BUTTON_DELETE:
+            {
+                _fireAction( SP_VERB_LAYER_DELETE );
+            }
+            case BUTTON_SOLO:
+            {
+                _fireAction( SP_VERB_LAYER_SOLO );
+            }
+            break;
+        }
+
+        delete _pending;
+        _pending = 0;
+    }
+
+    return false;
+}
+
+class LayersPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+
+    ModelColumns()
+    {
+        add(_colObject);
+        add(_colVisible);
+        add(_colLocked);
+        add(_colLabel);
+    }
+    virtual ~ModelColumns() {}
+
+    Gtk::TreeModelColumn<SPObject*> _colObject;
+    Gtk::TreeModelColumn<Glib::ustring> _colLabel;
+    Gtk::TreeModelColumn<bool> _colVisible;
+    Gtk::TreeModelColumn<bool> _colLocked;
+};
+
+void LayersPanel::_updateLayer( SPObject *layer ) {
+    _store->foreach( sigc::bind<SPObject*>(sigc::mem_fun(*this, &LayersPanel::_checkForUpdated), layer) );
+}
+
+bool LayersPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* layer)
+{
+    bool stopGoing = false;
+    Gtk::TreeModel::Row row = *iter;
+    Glib::ustring tmp = row[_model->_colLabel];
+    if ( layer == row[_model->_colObject] )
+    {
+        row[_model->_colLabel] = layer->label() ? layer->label() : SP_OBJECT_ID(layer);
+        row[_model->_colVisible] = SP_IS_ITEM(layer) ? !SP_ITEM(layer)->isHidden() : false;
+        row[_model->_colLocked] = SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false;
+
+        stopGoing = true;
+    }
+
+    return stopGoing;
+}
+
+void LayersPanel::_selectLayer( SPObject *layer ) {
+    if ( !layer || (_desktop && _desktop->doc() && (layer == _desktop->doc()->root)) ) {
+        if ( _tree.get_selection()->count_selected_rows() != 0 ) {
+            _tree.get_selection()->unselect_all();
+        }
+    } else {
+        _store->foreach( sigc::bind<SPObject*>(sigc::mem_fun(*this, &LayersPanel::_checkForSelected), layer) );
+    }
+
+    _checkTreeSelection();
+}
+
+bool LayersPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* layer)
+{
+    bool stopGoing = false;
+
+    Gtk::TreeModel::Row row = *iter;
+    if ( layer == row[_model->_colObject] )
+    {
+        _tree.expand_to_path( path );
+
+        Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
+
+        select->select(iter);
+
+        stopGoing = true;
+    }
+
+    return stopGoing;
+}
+
+void LayersPanel::_layersChanged()
+{
+//    g_message("_layersChanged()");
+    SPDocument* document = _desktop->doc();
+    SPObject* root = document->root;
+    if ( root ) {
+        _selectedConnection.block();
+        if ( _mgr && _mgr->includes( root ) ) {
+            SPObject* target = _desktop->currentLayer();
+            _store->clear();
+
+#if DUMP_LAYERS
+            g_message("root:%p  {%s}   [%s]", root, root->id, root->label() );
+#endif // DUMP_LAYERS
+            _addLayer( document, root, 0, target, 0 );
+        }
+        _selectedConnection.unblock();
+    }
+}
+
+void LayersPanel::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level )
+{
+    if ( layer && (level < _maxNestDepth) ) {
+        unsigned int counter = _mgr->childCount(layer);
+        for ( unsigned int i = 0; i < counter; i++ ) {
+            SPObject *child = _mgr->nthChildOf(layer, i);
+            if ( child ) {
+#if DUMP_LAYERS
+                g_message(" %3d    layer:%p  {%s}   [%s]", level, child, child->id, child->label() );
+#endif // DUMP_LAYERS
+
+                Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend();
+                Gtk::TreeModel::Row row = *iter;
+                row[_model->_colObject] = child;
+                row[_model->_colLabel] = child->label() ? child->label() : SP_OBJECT_ID(child);
+                row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false;
+                row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false;
+
+                if ( target && child == target ) {
+                    _tree.expand_to_path( _store->get_path(iter) );
+
+                    Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
+                    select->select(iter);
+
+                    _checkTreeSelection();
+                }
+
+                _addLayer( doc, child, &row, target, level + 1 );
+            }
+        }
+    }
+}
+
+SPObject* LayersPanel::_selectedLayer()
+{
+    SPObject* obj = 0;
+
+    Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
+    if ( iter ) {
+        Gtk::TreeModel::Row row = *iter;
+        obj = row[_model->_colObject];
+    }
+
+    return obj;
+}
+
+void LayersPanel::_pushTreeSelectionToCurrent()
+{
+    SPObject* inTree = _selectedLayer();
+    // TODO hunt down the possible API abuse in getting NULL
+    if ( _desktop->currentRoot() ) {
+        if ( inTree ) {
+            SPObject* curr = _desktop->currentLayer();
+            if ( curr != inTree ) {
+                _mgr->setCurrentLayer( inTree );
+            }
+        } else {
+            _mgr->setCurrentLayer( _desktop->doc()->root );
+        }
+    }
+}
+
+void LayersPanel::_checkTreeSelection()
+{
+    bool sensitive = false;
+    bool sensitiveNonTop = false;
+    bool sensitiveNonBottom = false;
+    if ( _tree.get_selection()->count_selected_rows() > 0 ) {
+        sensitive = true;
+
+        SPObject* inTree = _selectedLayer();
+        if ( inTree ) {
+
+            sensitiveNonTop = (Inkscape::next_layer(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 );
+    }
+}
+
+void LayersPanel::_preToggle( GdkEvent const *event )
+{
+    if ( _toggleEvent ) {
+        gdk_event_free(_toggleEvent);
+        _toggleEvent = 0;
+    }
+
+    if ( event && (event->type == GDK_BUTTON_PRESS) ) {
+        // Make a copy so we can keep it around.
+        _toggleEvent = gdk_event_copy(const_cast<GdkEvent*>(event));
+    }
+}
+
+void LayersPanel::_toggled( Glib::ustring const& str, int targetCol )
+{
+    Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(str);
+    Gtk::TreeModel::Row row = *iter;
+
+    Glib::ustring tmp = row[_model->_colLabel];
+
+    SPObject* obj = row[_model->_colObject];
+    SPItem* item = ( obj && SP_IS_ITEM(obj) ) ? SP_ITEM(obj) : 0;
+    if ( item ) {
+        switch ( targetCol ) {
+            case COL_VISIBLE:
+            {
+                bool newValue = !row[_model->_colVisible];
+                row[_model->_colVisible] = newValue;
+                item->setHidden( !newValue  );
+                item->updateRepr();
+                sp_document_done( _desktop->doc() , SP_VERB_DIALOG_LAYERS,
+                                  newValue? _("Unhide layer") : _("Hide layer"));
+            }
+            break;
+
+            case COL_LOCKED:
+            {
+                bool newValue = !row[_model->_colLocked];
+                row[_model->_colLocked] = newValue;
+                item->setLocked( newValue );
+                item->updateRepr();
+                sp_document_done( _desktop->doc() , SP_VERB_DIALOG_LAYERS,
+                                  newValue? _("Lock layer") : _("Unlock layer"));
+            }
+            break;
+        }
+    }
+}
+
+void LayersPanel::_handleButtonEvent(GdkEventButton* evt)
+{
+    // TODO - fix to a better is-popup function
+    if ( (evt->type == GDK_BUTTON_PRESS) && (evt->button == 3) ) {
+
+
+        {
+            Gtk::TreeModel::Path path;
+            Gtk::TreeViewColumn* col = 0;
+            int x = static_cast<int>(evt->x);
+            int y = static_cast<int>(evt->y);
+            int x2 = 0;
+            int y2 = 0;
+            if ( _tree.get_path_at_pos( x, y,
+                                        path, col,
+                                        x2, y2 ) ) {
+                _checkTreeSelection();
+                _popupMenu.popup(evt->button, evt->time);
+            }
+        }
+
+    }
+}
+
+void LayersPanel::_handleRowChange( Gtk::TreeModel::Path const& /*path*/, Gtk::TreeModel::iterator const& iter )
+{
+    Gtk::TreeModel::Row row = *iter;
+    if ( row ) {
+        SPObject* obj = row[_model->_colObject];
+        if ( obj ) {
+            gchar const* oldLabel = obj->label();
+            Glib::ustring tmp = row[_model->_colLabel];
+            if ( oldLabel && oldLabel[0] && !tmp.empty() && (tmp != oldLabel) ) {
+                _mgr->renameLayer( obj, tmp.c_str() );
+                row[_model->_colLabel] = obj->label();
+            }
+        }
+    }
+}
+
+bool LayersPanel::_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;
+}
+
+/**
+ * Constructor
+ */
+LayersPanel::LayersPanel() :
+    UI::Widget::Panel("", "/dialogs/layers", SP_VERB_DIALOG_LAYERS),
+    _maxNestDepth(20),
+    _mgr(0),
+    _desktop(0),
+    _model(0),
+    _pending(0),
+    _toggleEvent(0),
+    _compositeSettings(SP_VERB_DIALOG_LAYERS, "layers", UI::Widget::SimpleFilterModifier::BLEND)
+{
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    _maxNestDepth = prefs->getIntLimited("/dialogs/layers/maxDepth", 20, 1, 1000);
+
+    ModelColumns *zoop = new ModelColumns();
+    _model = zoop;
+
+    _store = Gtk::TreeStore::create( *zoop );
+
+    _tree.set_model( _store );
+    _tree.set_headers_visible(false);
+
+    Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler(
+        INKSCAPE_ICON_OBJECT_VISIBLE, INKSCAPE_ICON_OBJECT_HIDDEN) );
+    int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1;
+    eyeRenderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) );
+    eyeRenderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_toggled), (int)COL_VISIBLE) );
+    eyeRenderer->property_activatable() = true;
+    Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum);
+    if ( col ) {
+        col->add_attribute( eyeRenderer->property_active(), _model->_colVisible );
+    }
+
+    Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler(
+        INKSCAPE_ICON_OBJECT_LOCKED, INKSCAPE_ICON_OBJECT_UNLOCKED) );
+    int lockedColNum = _tree.append_column("lock", *renderer) - 1;
+    renderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) );
+    renderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_toggled), (int)COL_LOCKED) );
+    renderer->property_activatable() = true;
+    col = _tree.get_column(lockedColNum);
+    if ( col ) {
+        col->add_attribute( renderer->property_active(), _model->_colLocked );
+    }
+
+    int nameColNum = _tree.append_column_editable("Name", _model->_colLabel) - 1;
+
+    _tree.set_expander_column( *_tree.get_column(nameColNum) );
+
+    _compositeSettings.setSubject(&_subject);
+
+    _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &LayersPanel::_pushTreeSelectionToCurrent) );
+    _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &LayersPanel::_rowSelectFunction) );
+
+    _tree.get_model()->signal_row_changed().connect( sigc::mem_fun(*this, &LayersPanel::_handleRowChange) );
+    _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayersPanel::_handleButtonEvent) );
+
+    _scroller.add( _tree );
+    _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
+    _scroller.set_shadow_type(Gtk::SHADOW_IN);
+
+    _watching.push_back( &_compositeSettings );
+
+    _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET );
+    _layersPage.pack_end(_compositeSettings, Gtk::PACK_SHRINK);
+    _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK);
+
+    _notebook.append_page(_layersPage, _("Layers"));
+
+    _getContents()->pack_start(_notebook, Gtk::PACK_EXPAND_WIDGET);
+
+    SPDesktop* targetDesktop = getDesktop();
+
+    _buttonsRow.set_child_min_width( 16 );
+
+    Gtk::Button* btn = manage( new Gtk::Button() );
+    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("New") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) );
+    _buttonsRow.add( *btn );
+
+    btn = manage( new Gtk::Button() );
+    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, GTK_STOCK_GOTO_TOP, _("Top") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) );
+    _watchingNonTop.push_back( btn );
+    _buttonsRow.add( *btn );
+
+    btn = manage( new Gtk::Button() );
+    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, _("Up") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) );
+    _watchingNonTop.push_back( btn );
+    _buttonsRow.add( *btn );
+
+    btn = manage( new Gtk::Button() );
+    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, _("Dn") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) );
+    _watchingNonBottom.push_back( btn );
+    _buttonsRow.add( *btn );
+
+    btn = manage( new Gtk::Button() );
+    _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, GTK_STOCK_GOTO_BOTTOM, _("Bot") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) );
+    _watchingNonBottom.push_back( btn );
+    _buttonsRow.add( *btn );
+
+//     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, _("X") );
+    btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) );
+    _watching.push_back( btn );
+    _buttonsRow.add( *btn );
+
+
+
+
+    // -------------------------------------------------------
+    {
+        _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_SOLO, 0, "Solo", (int)BUTTON_SOLO ) );
+
+         _popupMenu.items().push_back( Gtk::Menu_Helpers::SeparatorElem() );
+
+        _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) );
+        _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) );
+
+        _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 );
+    }
+
+    g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( layers_panel_activated ), this );
+    g_signal_connect( G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK( layers_panel_deactivated ), this );
+    setDesktop( targetDesktop );
+
+    show_all_children();
+
+    // restorePanelPrefs();
+}
+
+LayersPanel::~LayersPanel()
+{
+    setDesktop(NULL);
+
+    _compositeSettings.setSubject(NULL);
+
+    if ( _model )
+    {
+        delete _model;
+    }
+
+    if ( _toggleEvent )
+    {
+        gdk_event_free( _toggleEvent );
+        _toggleEvent = 0;
+    }
+}
+
+
+void LayersPanel::setDesktop( SPDesktop* desktop )
+{
+    Panel::setDesktop(desktop);
+
+    if ( desktop != _desktop ) {
+        _layerChangedConnection.disconnect();
+        _layerUpdatedConnection.disconnect();
+        _changedConnection.disconnect();
+        if ( _mgr ) {
+            _mgr = 0;
+        }
+        if ( _desktop ) {
+            _desktop = 0;
+        }
+
+        _desktop = getDesktop();
+        if ( _desktop ) {
+            //setLabel( _desktop->doc()->name );
+
+            _mgr = _desktop->layer_manager;
+            if ( _mgr ) {
+                _layerChangedConnection = _mgr->connectCurrentLayerChanged( sigc::mem_fun(*this, &LayersPanel::_selectLayer) );
+                _layerUpdatedConnection = _mgr->connectLayerDetailsChanged( sigc::mem_fun(*this, &LayersPanel::_updateLayer) );
+                _changedConnection = _mgr->connectChanged( sigc::mem_fun(*this, &LayersPanel::_layersChanged) );
+            }
+
+            _layersChanged();
+        }
+    }
+/*
+    GSList const *layers=sp_document_get_resource_list( _desktop->doc(), "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() );
+    }
+*/
+}
+
+
+
+} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/layers.h b/src/ui/dialog/layers.h
new file mode 100644 (file)
index 0000000..1f593b9
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * A simple dialog for layer UI.
+ *
+ * Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2006 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_LAYERS_PANEL_H
+#define SEEN_LAYERS_PANEL_H
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/box.h>
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/notebook.h>
+
+//#include "ui/previewholder.h"
+#include "ui/widget/panel.h"
+#include "ui/widget/object-composite-settings.h"
+
+class SPObject;
+
+namespace Inkscape {
+
+class LayerManager;
+
+namespace UI {
+namespace Dialogs {
+
+
+/**
+ * A panel that displays layers.
+ */
+class LayersPanel : public UI::Widget::Panel
+{
+public:
+    LayersPanel();
+    virtual ~LayersPanel();
+
+    //virtual void setOrientation( Gtk::AnchorType how );
+    
+    static LayersPanel& getInstance();
+
+    void setDesktop( SPDesktop* desktop );
+
+protected:
+    //virtual void _handleAction( int setId, int itemId );
+
+private:
+    class ModelColumns;
+    class InternalUIBounce;
+
+    LayersPanel(LayersPanel const &); // no copy
+    LayersPanel &operator=(LayersPanel const &); // no assign
+
+    void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback );
+    void _fireAction( unsigned int code );
+    Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id );
+
+    void _preToggle( GdkEvent const *event );
+    void _toggled( Glib::ustring const& str, int targetCol );
+
+    void _handleButtonEvent(GdkEventButton* evt);
+    void _handleRowChange( Gtk::TreeModel::Path const& path, Gtk::TreeModel::iterator const& iter );
+
+    void _pushTreeSelectionToCurrent();
+    void _checkTreeSelection();
+
+    void _takeAction( int val );
+    bool _executeAction();
+
+    bool _rowSelectFunction( Glib::RefPtr<Gtk::TreeModel> const & model, Gtk::TreeModel::Path const & path, bool b );
+
+    void _updateLayer(SPObject *layer);
+    bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* layer);
+
+    void _selectLayer(SPObject *layer);
+    bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer);
+
+    void _layersChanged();
+    void _addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level );
+
+    SPObject* _selectedLayer();
+
+    // Hooked to the layer manager:
+    sigc::connection _layerChangedConnection;
+    sigc::connection _layerUpdatedConnection;
+    sigc::connection _changedConnection;
+    sigc::connection _addedConnection;
+    sigc::connection _removedConnection;
+
+    // Internal
+    sigc::connection _selectedConnection;
+
+    int _maxNestDepth;
+    Inkscape::LayerManager* _mgr;
+    SPDesktop* _desktop;
+    ModelColumns* _model;
+    InternalUIBounce* _pending;
+    GdkEvent* _toggleEvent;
+    Glib::RefPtr<Gtk::TreeStore> _store;
+    std::vector<Gtk::Widget*> _watching;
+    std::vector<Gtk::Widget*> _watchingNonTop;
+    std::vector<Gtk::Widget*> _watchingNonBottom;
+
+    Gtk::Tooltips _tips;
+    Gtk::TreeView _tree;
+    Gtk::HButtonBox _buttonsRow;
+    Gtk::ScrolledWindow _scroller;
+    Gtk::Menu _popupMenu;
+    Gtk::SpinButton _spinBtn;
+    Gtk::Notebook _notebook;
+    Gtk::VBox _layersPage;
+
+    UI::Widget::StyleSubject::CurrentLayer _subject;
+    UI::Widget::ObjectCompositeSettings _compositeSettings;
+};
+
+
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+
+#endif // SEEN_LAYERS_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:encoding=utf-8:textwidth=99 :
index f087f40e49ea6ceb4a2e2565732c817a88669347..7dbb6dd4ac25477142a8deafc18809fc1df09360 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "verbs.h"
 #include "dialog.h"
-#include "dialogs/swatches.h"
+#include "ui/dialog/swatches.h"
 #include "ui/dialog/floating-behavior.h"
 #include "ui/dialog/dock-behavior.h"
 #include "preferences.h"
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
new file mode 100644 (file)
index 0000000..dfb60c0
--- /dev/null
@@ -0,0 +1,1212 @@
+/** @file
+ * @brief Color swatches dialog
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *   John Bintz
+ *
+ * Copyright (C) 2005 Jon A. Cruz
+ * Copyright (C) 2008 John Bintz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <errno.h>
+
+#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
+#include <gtk/gtkdnd.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkseparatormenuitem.h>
+#include <glibmm/i18n.h>
+#include <gdkmm/pixbuf.h>
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "desktop-style.h"
+#include "document.h"
+#include "extension/db.h"
+#include "inkscape.h"
+#include "inkscape.h"
+#include "io/sys.h"
+#include "message-context.h"
+#include "path-prefix.h"
+#include "preferences.h"
+#include "sp-item.h"
+#include "svg/svg-color.h"
+#include "swatches.h"
+#include "widgets/eek-preview.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+ColorItem::ColorItem() : _isRemove(true){};
+ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) :
+    def( r, g, b, name ),
+    _isRemove(false),
+    _isLive(false),
+    _linkIsTone(false),
+    _linkPercent(0),
+    _linkGray(0),
+    _linkSrc(0)
+{
+}
+
+ColorItem::~ColorItem()
+{
+}
+
+ColorItem::ColorItem(ColorItem const &other) :
+    Inkscape::UI::Previewable()
+{
+    if ( this != &other ) {
+        *this = other;
+    }
+}
+
+ColorItem &ColorItem::operator=(ColorItem const &other)
+{
+    if ( this != &other ) {
+        def = other.def;
+
+        // TODO - correct linkage
+        _linkSrc = other._linkSrc;
+        g_message("Erk!");
+    }
+    return *this;
+}
+
+
+class JustForNow
+{
+public:
+    JustForNow() : _prefWidth(0) {}
+
+    Glib::ustring _name;
+    int _prefWidth;
+    std::vector<ColorItem*> _colors;
+};
+
+static std::vector<JustForNow*> possible;
+
+
+
+typedef enum {
+    APP_X_INKY_COLOR_ID = 0,
+    APP_X_INKY_COLOR = 0,
+    APP_X_COLOR,
+    TEXT_DATA
+} colorFlavorType;
+
+//TODO: warning: deprecated conversion from string constant to â€˜gchar*’
+//
+//Turn out to be warnings that we should probably leave in place. The
+// pointers/types used need to be read-only. So until we correct the using
+// code, those warnings are actually desired. They say "Hey! Fix this". We
+// definitely don't want to hide/ignore them. --JonCruz
+static const GtkTargetEntry sourceColorEntries[] = {
+#if ENABLE_MAGIC_COLORS
+//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
+    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
+#endif // ENABLE_MAGIC_COLORS
+    {"application/x-color", 0, APP_X_COLOR},
+    {"text/plain", 0, TEXT_DATA},
+};
+
+void ColorItem::_dragGetColorData( GtkWidget *widget,
+                                   GdkDragContext *drag_context,
+                                   GtkSelectionData *data,
+                                   guint info,
+                                   guint time,
+                                   gpointer user_data)
+{
+    (void)widget;
+    (void)drag_context;
+    (void)time;
+    static GdkAtom typeXColor = gdk_atom_intern("application/x-color", FALSE);
+    static GdkAtom typeText = gdk_atom_intern("text/plain", FALSE);
+
+    ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
+    if ( info == TEXT_DATA ) {
+        gchar* tmp = g_strdup_printf("#%02x%02x%02x", item->def.getR(), item->def.getG(), item->def.getB() );
+
+        gtk_selection_data_set( data,
+                                typeText,
+                                8, // format
+                                (guchar*)tmp,
+                                strlen((const char*)tmp) + 1);
+        g_free(tmp);
+        tmp = 0;
+    } else if ( info == APP_X_INKY_COLOR ) {
+        Glib::ustring paletteName;
+
+        // Find where this thing came from
+        bool found = false;
+        int index = 0;
+        for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end() && !found; ++it ) {
+            JustForNow* curr = *it;
+            index = 0;
+            for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
+                if ( item == *zz ) {
+                    found = true;
+                    paletteName = curr->_name;
+                    break;
+                } else {
+                    index++;
+                }
+            }
+        }
+
+//         if ( found ) {
+//             g_message("Found the color at entry %d in palette '%s'", index, paletteName.c_str() );
+//         } else {
+//             g_message("Unable to find the color");
+//         }
+        int itemCount = 4 + 2 + 1 + paletteName.length();
+
+        guint16* tmp = new guint16[itemCount];
+        tmp[0] = (item->def.getR() << 8) | item->def.getR();
+        tmp[1] = (item->def.getG() << 8) | item->def.getG();
+        tmp[2] = (item->def.getB() << 8) | item->def.getB();
+        tmp[3] = 0xffff;
+        tmp[4] = (item->_isLive || !item->_listeners.empty() || (item->_linkSrc != 0) ) ? 1 : 0;
+
+        tmp[5] = index;
+        tmp[6] = paletteName.length();
+        for ( unsigned int i = 0; i < paletteName.length(); i++ ) {
+            tmp[7 + i] = paletteName[i];
+        }
+        gtk_selection_data_set( data,
+                                typeXColor,
+                                16, // format
+                                reinterpret_cast<const guchar*>(tmp),
+                                itemCount * 2);
+        delete[] tmp;
+    } else {
+        guint16 tmp[4];
+        tmp[0] = (item->def.getR() << 8) | item->def.getR();
+        tmp[1] = (item->def.getG() << 8) | item->def.getG();
+        tmp[2] = (item->def.getB() << 8) | item->def.getB();
+        tmp[3] = 0xffff;
+        gtk_selection_data_set( data,
+                                typeXColor,
+                                16, // format
+                                reinterpret_cast<const guchar*>(tmp),
+                                (3+1) * 2);
+    }
+}
+
+static void dragBegin( GtkWidget *widget, GdkDragContext* dc, gpointer data )
+{
+    (void)widget;
+    ColorItem* item = reinterpret_cast<ColorItem*>(data);
+    if ( item )
+    {
+        if (item->isRemove()){
+            GError *error = NULL;
+            gchar *filepath = (gchar *) g_strdup_printf("%s/remove-color.png", INKSCAPE_PIXMAPDIR);
+            gsize bytesRead = 0;
+            gsize bytesWritten = 0;
+            gchar *localFilename = g_filename_from_utf8( filepath,
+                                                 -1,
+                                                 &bytesRead,
+                                                 &bytesWritten,
+                                                 &error);
+            GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, 32, 24, FALSE, &error);
+            g_free(localFilename);
+            g_free(filepath);
+            gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 );
+            return;
+        }
+
+        Glib::RefPtr<Gdk::Pixbuf> thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, 32, 24 );
+        guint32 fillWith = (0xff000000 & (item->def.getR() << 24))
+                         | (0x00ff0000 & (item->def.getG() << 16))
+                         | (0x0000ff00 & (item->def.getB() <<  8));
+        thumb->fill( fillWith );
+        gtk_drag_set_icon_pixbuf( dc, thumb->gobj(), 0, 0 );
+    }
+
+}
+
+//"drag-drop"
+// gboolean dragDropColorData( GtkWidget *widget,
+//                             GdkDragContext *drag_context,
+//                             gint x,
+//                             gint y,
+//                             guint time,
+//                             gpointer user_data)
+// {
+// // TODO finish
+
+//     return TRUE;
+// }
+
+static void handleClick( GtkWidget* widget, gpointer callback_data ) {
+    (void)widget;
+    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
+    if ( item ) {
+        item->buttonClicked(false);
+    }
+}
+
+static void handleSecondaryClick( GtkWidget* widget, gint arg1, gpointer callback_data ) {
+    (void)widget;
+    (void)arg1;
+    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
+    if ( item ) {
+        item->buttonClicked(true);
+    }
+}
+
+static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) {
+    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
+    if ( item ) {
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+        if ( desktop ) {
+            gchar* msg = g_strdup_printf(_("Color: <b>%s</b>; <b>Click</b> to set fill, <b>Shift+click</b> to set stroke"),
+                                         item->def.descr.c_str());
+            desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg);
+            g_free(msg);
+        }
+    }
+    return FALSE;
+}
+
+static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) {
+    ColorItem* item = reinterpret_cast<ColorItem*>(callback_data);
+    if ( item ) {
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+        if ( desktop ) {
+            desktop->tipsMessageContext()->clear();
+        }
+    }
+    return FALSE;
+}
+
+static GtkWidget* popupMenu = 0;
+static ColorItem* bounceTarget = 0;
+
+static void redirClick( GtkMenuItem *menuitem, gpointer user_data )
+{
+    (void)user_data;
+    if ( bounceTarget ) {
+        handleClick( GTK_WIDGET(menuitem), bounceTarget );
+    }
+}
+
+static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer user_data )
+{
+    (void)user_data;
+    if ( bounceTarget ) {
+        handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget );
+    }
+}
+
+static gboolean handleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data)
+{
+    (void)widget;
+    gboolean handled = FALSE;
+
+    if ( (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) {
+        if ( !popupMenu ) {
+            popupMenu = gtk_menu_new();
+            GtkWidget* child = 0;
+
+            //TRANSLATORS: An item in context menu on a colour in the swatches
+            child = gtk_menu_item_new_with_label(_("Set fill"));
+            g_signal_connect( G_OBJECT(child),
+                              "activate",
+                              G_CALLBACK(redirClick),
+                              user_data);
+            gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
+
+            //TRANSLATORS: An item in context menu on a colour in the swatches
+            child = gtk_menu_item_new_with_label(_("Set stroke"));
+
+            g_signal_connect( G_OBJECT(child),
+                              "activate",
+                              G_CALLBACK(redirSecondaryClick),
+                              user_data);
+            gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child);
+
+            gtk_widget_show_all(popupMenu);
+        }
+
+        ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
+        if ( item ) {
+            bounceTarget = item;
+            if ( popupMenu ) {
+                gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time);
+                handled = TRUE;
+            }
+        }
+    }
+
+    return handled;
+}
+
+static void dieDieDie( GtkObject *obj, gpointer user_data )
+{
+    g_message("die die die %p  %p", obj, user_data );
+}
+
+//TODO: warning: deprecated conversion from string constant to â€˜gchar*’
+//
+//Turn out to be warnings that we should probably leave in place. The
+// pointers/types used need to be read-only. So until we correct the using
+// code, those warnings are actually desired. They say "Hey! Fix this". We
+// definitely don't want to hide/ignore them. --JonCruz
+static const GtkTargetEntry destColorTargets[] = {
+#if ENABLE_MAGIC_COLORS
+//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
+    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
+#endif // ENABLE_MAGIC_COLORS
+    {"application/x-color", 0, APP_X_COLOR},
+};
+
+#include "color.h" // for SP_RGBA32_U_COMPOSE
+
+void ColorItem::_dropDataIn( GtkWidget *widget,
+                             GdkDragContext *drag_context,
+                             gint x, gint y,
+                             GtkSelectionData *data,
+                             guint info,
+                             guint event_time,
+                             gpointer user_data)
+{
+    (void)widget;
+    (void)drag_context;
+    (void)x;
+    (void)y;
+    (void)event_time;
+//     g_message("    droppy droppy   %d", info);
+     switch (info) {
+         case APP_X_INKY_COLOR:
+         {
+             if ( data->length >= 8 ) {
+                 // Careful about endian issues.
+                 guint16* dataVals = (guint16*)data->data;
+                 if ( user_data ) {
+                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
+                     if ( item->def.isEditable() ) {
+                         // Shove on in the new value
+                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
+                     }
+                 }
+             }
+             break;
+         }
+         case APP_X_COLOR:
+         {
+             if ( data->length == 8 ) {
+                 // Careful about endian issues.
+                 guint16* dataVals = (guint16*)data->data;
+//                  {
+//                      gchar c[64] = {0};
+//                      sp_svg_write_color( c, 64,
+//                                          SP_RGBA32_U_COMPOSE(
+//                                              0x0ff & (dataVals[0] >> 8),
+//                                              0x0ff & (dataVals[1] >> 8),
+//                                              0x0ff & (dataVals[2] >> 8),
+//                                              0xff // can't have transparency in the color itself
+//                                              //0x0ff & (data->data[3] >> 8),
+//                                              ));
+//                  }
+                 if ( user_data ) {
+                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
+                     if ( item->def.isEditable() ) {
+                         // Shove on in the new value
+                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
+                     }
+                 }
+             }
+             break;
+         }
+         default:
+             g_message("unknown drop type");
+     }
+
+}
+
+static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b )
+{
+    bool changed = false;
+
+    if ( node ) {
+        gchar const * val = node->attribute("inkscape:x-fill-tag");
+        if ( val  && (match == val) ) {
+            SPObject *obj = document->getObjectByRepr( node );
+
+            gchar c[64] = {0};
+            sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
+            SPCSSAttr *css = sp_repr_css_attr_new();
+            sp_repr_css_set_property( css, "fill", c );
+
+            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
+            ((SPItem*)obj)->updateRepr();
+
+            changed = true;
+        }
+
+        val = node->attribute("inkscape:x-stroke-tag");
+        if ( val  && (match == val) ) {
+            SPObject *obj = document->getObjectByRepr( node );
+
+            gchar c[64] = {0};
+            sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
+            SPCSSAttr *css = sp_repr_css_attr_new();
+            sp_repr_css_set_property( css, "stroke", c );
+
+            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
+            ((SPItem*)obj)->updateRepr();
+
+            changed = true;
+        }
+
+        Inkscape::XML::Node* first = node->firstChild();
+        changed |= bruteForce( document, first, match, r, g, b );
+
+        changed |= bruteForce( document, node->next(), match, r, g, b );
+    }
+
+    return changed;
+}
+
+void ColorItem::_colorDefChanged(void* data)
+{
+    ColorItem* item = reinterpret_cast<ColorItem*>(data);
+    if ( item ) {
+        for ( std::vector<Gtk::Widget*>::iterator it =  item->_previews.begin(); it != item->_previews.end(); ++it ) {
+            Gtk::Widget* widget = *it;
+            if ( IS_EEK_PREVIEW(widget->gobj()) ) {
+                EekPreview * preview = EEK_PREVIEW(widget->gobj());
+                eek_preview_set_color( preview,
+                                       (item->def.getR() << 8) | item->def.getR(),
+                                       (item->def.getG() << 8) | item->def.getG(),
+                                       (item->def.getB() << 8) | item->def.getB() );
+
+                eek_preview_set_linked( preview, (LinkType)((item->_linkSrc ? PREVIEW_LINK_IN:0)
+                                                            | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT)
+                                                            | (item->_isLive ? PREVIEW_LINK_OTHER:0)) );
+
+                widget->queue_draw();
+            }
+        }
+
+        for ( std::vector<ColorItem*>::iterator it = item->_listeners.begin(); it != item->_listeners.end(); ++it ) {
+            guint r = item->def.getR();
+            guint g = item->def.getG();
+            guint b = item->def.getB();
+
+            if ( (*it)->_linkIsTone ) {
+                r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100;
+                g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100;
+                b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100;
+            } else {
+                r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100;
+                g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100;
+                b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100;
+            }
+
+            (*it)->def.setRGB( r, g, b );
+        }
+
+
+        // Look for objects using this color
+        {
+            SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+            if ( desktop ) {
+                SPDocument* document = sp_desktop_document( desktop );
+                Inkscape::XML::Node *rroot =  sp_document_repr_root( document );
+                if ( rroot ) {
+
+                    // Find where this thing came from
+                    Glib::ustring paletteName;
+                    bool found = false;
+                    int index = 0;
+                    for ( std::vector<JustForNow*>::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) {
+                        JustForNow* curr = *it2;
+                        index = 0;
+                        for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
+                            if ( item == *zz ) {
+                                found = true;
+                                paletteName = curr->_name;
+                                break;
+                            } else {
+                                index++;
+                            }
+                        }
+                    }
+
+                    if ( !paletteName.empty() ) {
+                        gchar* str = g_strdup_printf("%d|", index);
+                        paletteName.insert( 0, str );
+                        g_free(str);
+                        str = 0;
+
+                        if ( bruteForce( document, rroot, paletteName, item->def.getR(), item->def.getG(), item->def.getB() ) ) {
+                            sp_document_done( document , SP_VERB_DIALOG_SWATCHES, 
+                                              _("Change color definition"));
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio)
+{
+    Gtk::Widget* widget = 0;
+    if ( style == PREVIEW_STYLE_BLURB) {
+        Gtk::Label *lbl = new Gtk::Label(def.descr);
+        lbl->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+        widget = lbl;
+    } else {
+//         Glib::ustring blank("          ");
+//         if ( size == Inkscape::ICON_SIZE_MENU || size == Inkscape::ICON_SIZE_DECORATION ) {
+//             blank = " ";
+//         }
+
+        GtkWidget* eekWidget = eek_preview_new();
+        EekPreview * preview = EEK_PREVIEW(eekWidget);
+        Gtk::Widget* newBlot = Glib::wrap(eekWidget);
+
+        eek_preview_set_color( preview, (def.getR() << 8) | def.getR(), (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB());
+        if ( _isRemove ) {
+            GError *error = NULL;
+            gchar *filepath = (gchar *) g_strdup_printf("%s/remove-color.png", INKSCAPE_PIXMAPDIR);
+            gsize bytesRead = 0;
+            gsize bytesWritten = 0;
+            gchar *localFilename = g_filename_from_utf8( filepath,
+                                                 -1,
+                                                 &bytesRead,
+                                                 &bytesWritten,
+                                                 &error);
+            GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error);
+            if (!pixbuf) {
+                g_warning("Null pixbuf for %p [%s]", localFilename, localFilename );
+            }
+            g_free(localFilename);
+            g_free(filepath);
+
+            eek_preview_set_pixbuf( preview, pixbuf );
+        }
+
+        eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::PreviewSize)size, ratio );
+        eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0)
+                                                    | (_listeners.empty() ? 0:PREVIEW_LINK_OUT)
+                                                    | (_isLive ? PREVIEW_LINK_OTHER:0)) );
+
+        def.addCallback( _colorDefChanged, this );
+
+        GValue val = {0, {{0}, {0}}};
+        g_value_init( &val, G_TYPE_BOOLEAN );
+        g_value_set_boolean( &val, FALSE );
+        g_object_set_property( G_OBJECT(preview), "focus-on-click", &val );
+
+/*
+        Gtk::Button *btn = new Gtk::Button(blank);
+        Gdk::Color color;
+        color.set_rgb((_r << 8)|_r, (_g << 8)|_g, (_b << 8)|_b);
+        btn->modify_bg(Gtk::STATE_NORMAL, color);
+        btn->modify_bg(Gtk::STATE_ACTIVE, color);
+        btn->modify_bg(Gtk::STATE_PRELIGHT, color);
+        btn->modify_bg(Gtk::STATE_SELECTED, color);
+
+        Gtk::Widget* newBlot = btn;
+*/
+
+        tips.set_tip((*newBlot), def.descr);
+
+/*
+        newBlot->signal_clicked().connect( sigc::mem_fun(*this, &ColorItem::buttonClicked) );
+
+        sigc::signal<void> type_signal_something;
+*/
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "clicked",
+                          G_CALLBACK(handleClick),
+                          this);
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "alt-clicked",
+                          G_CALLBACK(handleSecondaryClick),
+                          this);
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "button-press-event",
+                          G_CALLBACK(handleButtonPress),
+                          this);
+
+        gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()),
+                             GDK_BUTTON1_MASK,
+                             sourceColorEntries,
+                             G_N_ELEMENTS(sourceColorEntries),
+                             GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) );
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "drag-data-get",
+                          G_CALLBACK(ColorItem::_dragGetColorData),
+                          this);
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "drag-begin",
+                          G_CALLBACK(dragBegin),
+                          this );
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "enter-notify-event",
+                          G_CALLBACK(handleEnterNotify),
+                          this);
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "leave-notify-event",
+                          G_CALLBACK(handleLeaveNotify),
+                          this);
+
+//         g_signal_connect( G_OBJECT(newBlot->gobj()),
+//                           "drag-drop",
+//                           G_CALLBACK(dragDropColorData),
+//                           this);
+
+        if ( def.isEditable() )
+        {
+            gtk_drag_dest_set( GTK_WIDGET(newBlot->gobj()),
+                               GTK_DEST_DEFAULT_ALL,
+                               destColorTargets,
+                               G_N_ELEMENTS(destColorTargets),
+                               GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
+
+
+            g_signal_connect( G_OBJECT(newBlot->gobj()),
+                              "drag-data-received",
+                              G_CALLBACK(_dropDataIn),
+                              this );
+        }
+
+        g_signal_connect( G_OBJECT(newBlot->gobj()),
+                          "destroy",
+                          G_CALLBACK(dieDieDie),
+                          this);
+
+
+        widget = newBlot;
+    }
+
+    _previews.push_back( widget );
+
+    return widget;
+}
+
+void ColorItem::buttonClicked(bool secondary)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (!desktop) return;
+    char const * attrName = secondary ? "stroke" : "fill";
+
+    gchar c[64];
+    if (!_isRemove){
+        guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff;
+        sp_svg_write_color(c, sizeof(c), rgba);
+    }
+
+    SPCSSAttr *css = sp_repr_css_attr_new();
+    sp_repr_css_set_property( css, attrName, _isRemove ? "none" : c );
+    sp_desktop_set_style(desktop, css);
+    sp_repr_css_attr_unref(css);
+
+    if (_isRemove){
+        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
+                      secondary? _("Remove stroke color") : _("Remove fill color"));
+    } else {
+        sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_SWATCHES, 
+                      secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"));
+    }
+}
+
+static char* trim( char* str ) {
+    char* ret = str;
+    while ( *str && (*str == ' ' || *str == '\t') ) {
+        str++;
+    }
+    ret = str;
+    while ( *str ) {
+        str++;
+    }
+    str--;
+    while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) {
+        *str-- = 0;
+    }
+    return ret;
+}
+
+void skipWhitespace( char*& str ) {
+    while ( *str == ' ' || *str == '\t' ) {
+        str++;
+    }
+}
+
+bool parseNum( char*& str, int& val ) {
+    val = 0;
+    while ( '0' <= *str && *str <= '9' ) {
+        val = val * 10 + (*str - '0');
+        str++;
+    }
+    bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n');
+    return retval;
+}
+
+
+static bool getBlock( std::string& dst, guchar ch, std::string const str )
+{
+    bool good = false;
+    std::string::size_type pos = str.find(ch);
+    if ( pos != std::string::npos )
+    {
+        std::string::size_type pos2 = str.find( '(', pos );
+        if ( pos2 != std::string::npos ) {
+            std::string::size_type endPos = str.find( ')', pos2 );
+            if ( endPos != std::string::npos ) {
+                dst = str.substr( pos2 + 1, (endPos - pos2 - 1) );
+                good = true;
+            }
+        }
+    }
+    return good;
+}
+
+static bool popVal( guint64& numVal, std::string& str )
+{
+    bool good = false;
+    std::string::size_type endPos = str.find(',');
+    if ( endPos == std::string::npos ) {
+        endPos = str.length();
+    }
+
+    if ( endPos != std::string::npos && endPos > 0 ) {
+        std::string xxx = str.substr( 0, endPos );
+        const gchar* ptr = xxx.c_str();
+        gchar* endPtr = 0;
+        numVal = g_ascii_strtoull( ptr, &endPtr, 10 );
+        if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) {
+            // overflow
+        } else if ( (numVal == 0) && (endPtr == ptr) ) {
+            // failed conversion
+        } else {
+            good = true;
+            str.erase( 0, endPos + 1 );
+        }
+    }
+
+    return good;
+}
+
+void ColorItem::_wireMagicColors( void* p )
+{
+    JustForNow* onceMore = reinterpret_cast<JustForNow*>(p);
+    if ( onceMore )
+    {
+        for ( std::vector<ColorItem*>::iterator it = onceMore->_colors.begin(); it != onceMore->_colors.end(); ++it )
+        {
+            std::string::size_type pos = (*it)->def.descr.find("*{");
+            if ( pos != std::string::npos )
+            {
+                std::string subby = (*it)->def.descr.substr( pos + 2 );
+                std::string::size_type endPos = subby.find("}*");
+                if ( endPos != std::string::npos )
+                {
+                    subby.erase( endPos );
+                    //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str());
+                    //g_message("               '%s'", subby.c_str());
+
+                    if ( subby.find('E') != std::string::npos )
+                    {
+                        (*it)->def.setEditable( true );
+                    }
+
+                    if ( subby.find('L') != std::string::npos )
+                    {
+                        (*it)->_isLive = true;
+                    }
+
+                    std::string part;
+                    // Tint. index + 1 more val.
+                    if ( getBlock( part, 'T', subby ) ) {
+                        guint64 colorIndex = 0;
+                        if ( popVal( colorIndex, part ) ) {
+                            guint64 percent = 0;
+                            if ( popVal( percent, part ) ) {
+                                (*it)->_linkTint( *(onceMore->_colors[colorIndex]), percent );
+                            }
+                        }
+                    }
+
+                    // Shade/tone. index + 1 or 2 more val.
+                    if ( getBlock( part, 'S', subby ) ) {
+                        guint64 colorIndex = 0;
+                        if ( popVal( colorIndex, part ) ) {
+                            guint64 percent = 0;
+                            if ( popVal( percent, part ) ) {
+                                guint64 grayLevel = 0;
+                                if ( !popVal( grayLevel, part ) ) {
+                                    grayLevel = 0;
+                                }
+                                (*it)->_linkTone( *(onceMore->_colors[colorIndex]), percent, grayLevel );
+                            }
+                        }
+                    }
+
+                }
+            }
+        }
+    }
+}
+
+
+void ColorItem::_linkTint( ColorItem& other, int percent )
+{
+    if ( !_linkSrc )
+    {
+        other._listeners.push_back(this);
+        _linkIsTone = false;
+        _linkPercent = percent;
+        if ( _linkPercent > 100 )
+            _linkPercent = 100;
+        if ( _linkPercent < 0 )
+            _linkPercent = 0;
+        _linkGray = 0;
+        _linkSrc = &other;
+
+        ColorItem::_colorDefChanged(&other);
+    }
+}
+
+void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel )
+{
+    if ( !_linkSrc )
+    {
+        other._listeners.push_back(this);
+        _linkIsTone = true;
+        _linkPercent = percent;
+        if ( _linkPercent > 100 )
+            _linkPercent = 100;
+        if ( _linkPercent < 0 )
+            _linkPercent = 0;
+        _linkGray = grayLevel;
+        _linkSrc = &other;
+
+        ColorItem::_colorDefChanged(&other);
+    }
+}
+
+
+void _loadPaletteFile( gchar const *filename )
+{
+    char block[1024];
+    FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" );
+    if ( f ) {
+        char* result = fgets( block, sizeof(block), f );
+        if ( result ) {
+            if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) {
+                bool inHeader = true;
+                bool hasErr = false;
+
+                JustForNow *onceMore = new JustForNow();
+
+                do {
+                    result = fgets( block, sizeof(block), f );
+                    block[sizeof(block) - 1] = 0;
+                    if ( result ) {
+                        if ( block[0] == '#' ) {
+                            // ignore comment
+                        } else {
+                            char *ptr = block;
+                            // very simple check for header versus entry
+                            while ( *ptr == ' ' || *ptr == '\t' ) {
+                                ptr++;
+                            }
+                            if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) {
+                                // blank line. skip it.
+                            } else if ( '0' <= *ptr && *ptr <= '9' ) {
+                                // should be an entry link
+                                inHeader = false;
+                                ptr = block;
+                                Glib::ustring name("");
+                                int r = 0;
+                                int g = 0;
+                                int b = 0;
+                                skipWhitespace(ptr);
+                                if ( *ptr ) {
+                                    hasErr = parseNum(ptr, r);
+                                    if ( !hasErr ) {
+                                        skipWhitespace(ptr);
+                                        hasErr = parseNum(ptr, g);
+                                    }
+                                    if ( !hasErr ) {
+                                        skipWhitespace(ptr);
+                                        hasErr = parseNum(ptr, b);
+                                    }
+                                    if ( !hasErr && *ptr ) {
+                                        char* n = trim(ptr);
+                                        if (n != NULL) {
+                                            name = n;
+                                        }
+                                    }
+                                    if ( !hasErr ) {
+                                        // Add the entry now
+                                        Glib::ustring nameStr(name);
+                                        ColorItem* item = new ColorItem( r, g, b, nameStr );
+                                        onceMore->_colors.push_back(item);
+                                    }
+                                } else {
+                                    hasErr = true;
+                                }
+                            } else {
+                                if ( !inHeader ) {
+                                    // Hmmm... probably bad. Not quite the format we want?
+                                    hasErr = true;
+                                } else {
+                                    char* sep = strchr(result, ':');
+                                    if ( sep ) {
+                                        *sep = 0;
+                                        char* val = trim(sep + 1);
+                                        char* name = trim(result);
+                                        if ( *name ) {
+                                            if ( strcmp( "Name", name ) == 0 )
+                                            {
+                                                onceMore->_name = val;
+                                            }
+                                            else if ( strcmp( "Columns", name ) == 0 )
+                                            {
+                                                gchar* endPtr = 0;
+                                                guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 );
+                                                if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) {
+                                                    // overflow
+                                                } else if ( (numVal == 0) && (endPtr == val) ) {
+                                                    // failed conversion
+                                                } else {
+                                                    onceMore->_prefWidth = numVal;
+                                                }
+                                            }
+                                        } else {
+                                            // error
+                                            hasErr = true;
+                                        }
+                                    } else {
+                                        // error
+                                        hasErr = true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } while ( result && !hasErr );
+                if ( !hasErr ) {
+                    possible.push_back(onceMore);
+#if ENABLE_MAGIC_COLORS
+                    ColorItem::_wireMagicColors( onceMore );
+#endif // ENABLE_MAGIC_COLORS
+                } else {
+                    delete onceMore;
+                }
+            }
+        }
+
+        fclose(f);
+    }
+}
+
+static void loadEmUp()
+{
+    static bool beenHere = false;
+    if ( !beenHere ) {
+        beenHere = true;
+
+        std::list<gchar *> sources;
+        sources.push_back( profile_path("palettes") );
+        sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) );
+        sources.push_back( g_strdup(CREATE_PALETTESDIR) );
+
+        // Use this loop to iterate through a list of possible document locations.
+        while (!sources.empty()) {
+            gchar *dirname = sources.front();
+
+            if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS )
+                && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) {
+                GError *err = 0;
+                GDir *directory = g_dir_open(dirname, 0, &err);
+                if (!directory) {
+                    gchar *safeDir = Inkscape::IO::sanitizeString(dirname);
+                    g_warning(_("Palettes directory (%s) is unavailable."), safeDir);
+                    g_free(safeDir);
+                } else {
+                    gchar *filename = 0;
+                    while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
+                        gchar* lower = g_ascii_strdown( filename, -1 );
+//                        if ( g_str_has_suffix(lower, ".gpl") ) {
+                            gchar* full = g_build_filename(dirname, filename, NULL);
+                            if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) {
+                                _loadPaletteFile(full);
+                            }
+                            g_free(full);
+//                      }
+                        g_free(lower);
+                    }
+                    g_dir_close(directory);
+                }
+            }
+
+            // toss the dirname
+            g_free(dirname);
+            sources.pop_front();
+        }
+    }
+}
+
+
+
+
+
+
+
+
+
+SwatchesPanel& SwatchesPanel::getInstance()
+{
+    return *new SwatchesPanel();
+}
+
+
+/**
+ * Constructor
+ */
+SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
+    Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true),
+    _holder(0)
+{
+    Gtk::RadioMenuItem* hotItem = 0;
+    _holder = new PreviewHolder();
+    _remove = new ColorItem();
+    loadEmUp();
+    if ( !possible.empty() ) {
+        JustForNow* first = 0;
+        Glib::ustring targetName;
+        if ( !_prefs_path.empty() ) {
+            Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+            targetName = prefs->getString(_prefs_path + "/palette");
+            if (!targetName.empty()) {
+                for ( std::vector<JustForNow*>::iterator iter = possible.begin(); iter != possible.end(); ++iter ) {
+                    if ( (*iter)->_name == targetName ) {
+                        first = *iter;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if ( !first ) {
+            first = possible.front();
+        }
+
+        if ( first->_prefWidth > 0 ) {
+            _holder->setColumnPref( first->_prefWidth );
+        }
+        _holder->freezeUpdates();
+        _holder->addPreview(_remove);
+        for ( std::vector<ColorItem*>::iterator it = first->_colors.begin(); it != first->_colors.end(); it++ ) {
+            _holder->addPreview(*it);
+        }
+        _holder->thawUpdates();
+
+        Gtk::RadioMenuItem::Group groupOne;
+
+        int i = 0;
+        for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end(); it++ ) {
+            JustForNow* curr = *it;
+            Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name));
+            if ( curr == first ) {
+                hotItem = single;
+            }
+            _regItem( single, 3, i );
+            i++;
+        }
+    }
+
+
+    _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET);
+    _setTargetFillable(_holder);
+
+    show_all_children();
+
+    restorePanelPrefs();
+    if ( hotItem ) {
+        hotItem->set_active();
+    }
+}
+
+SwatchesPanel::~SwatchesPanel()
+{
+    if (_remove) delete _remove;
+    if (_holder) delete _holder;
+}
+
+void SwatchesPanel::setOrientation( Gtk::AnchorType how )
+{
+    // Must call the parent class or bad things might happen
+    Inkscape::UI::Widget::Panel::setOrientation( how );
+
+    if ( _holder )
+    {
+        _holder->setOrientation( Gtk::ANCHOR_SOUTH );
+    }
+}
+
+void SwatchesPanel::_handleAction( int setId, int itemId )
+{
+    switch( setId ) {
+        case 3:
+        {
+            if ( itemId >= 0 && itemId < static_cast<int>(possible.size()) ) {
+                _holder->clear();
+                JustForNow* curr = possible[itemId];
+
+                if ( !_prefs_path.empty() ) {
+                    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+                    prefs->setString(_prefs_path + "/palette", curr->_name);
+                }
+
+                if ( curr->_prefWidth > 0 ) {
+                    _holder->setColumnPref( curr->_prefWidth );
+                }
+                _holder->freezeUpdates();
+                _holder->addPreview(_remove);
+                for ( std::vector<ColorItem*>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); it++ ) {
+                    _holder->addPreview(*it);
+                }
+                _holder->thawUpdates();
+            }
+        }
+        break;
+    }
+}
+
+} //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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h
new file mode 100644 (file)
index 0000000..08fc9f7
--- /dev/null
@@ -0,0 +1,128 @@
+/** @file
+ * @brief Color swatches dialog
+ */
+/* Authors:
+ *   Jon A. Cruz
+ *
+ * Copyright (C) 2005 Jon A. Cruz
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifndef SEEN_DIALOGS_SWATCHES_H
+#define SEEN_DIALOGS_SWATCHES_H
+
+#include <gtkmm/textview.h>
+#include <gtkmm/tooltips.h>
+
+#include "ui/widget/panel.h"
+#include "ui/previewholder.h"
+#include "widgets/eek-color-def.h"
+
+using eek::ColorDef;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialogs {
+
+
+void _loadPaletteFile( gchar const *filename );
+
+/**
+ * The color swatch you see on screen as a clickable box.
+ */
+class ColorItem : public Inkscape::UI::Previewable
+{
+    friend void _loadPaletteFile( gchar const *filename );
+public:
+    ColorItem();
+    ColorItem( unsigned int r, unsigned int g, unsigned int b,
+               Glib::ustring& name );
+    virtual ~ColorItem();
+    ColorItem(ColorItem const &other);
+    virtual ColorItem &operator=(ColorItem const &other);
+    virtual Gtk::Widget* getPreview(PreviewStyle style,
+                                    ViewType view,
+                                    ::PreviewSize size,
+                                    guint ratio);
+    void buttonClicked(bool secondary = false);
+    bool isRemove(){ return _isRemove; }
+    ColorDef def;
+
+private:
+    static void _dropDataIn( GtkWidget *widget,
+                             GdkDragContext *drag_context,
+                             gint x, gint y,
+                             GtkSelectionData *data,
+                             guint info,
+                             guint event_time,
+                             gpointer user_data);
+
+    static void _dragGetColorData( GtkWidget *widget,
+                                   GdkDragContext *drag_context,
+                                   GtkSelectionData *data,
+                                   guint info,
+                                   guint time,
+                                   gpointer user_data);
+
+    static void _wireMagicColors( void* p );
+    static void _colorDefChanged(void* data);
+
+    void _linkTint( ColorItem& other, int percent );
+    void _linkTone( ColorItem& other, int percent, int grayLevel );
+
+    Gtk::Tooltips tips;
+    std::vector<Gtk::Widget*> _previews;
+
+    bool _isRemove;
+    bool _isLive;
+    bool _linkIsTone;
+    int _linkPercent;
+    int _linkGray;
+    ColorItem* _linkSrc;
+    std::vector<ColorItem*> _listeners;
+};
+       
+class RemoveColorItem;
+
+/**
+ * A panel that displays color swatches.
+ */
+class SwatchesPanel : public Inkscape::UI::Widget::Panel
+{
+public:
+    SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches");
+    virtual ~SwatchesPanel();
+
+    static SwatchesPanel& getInstance();
+    virtual void setOrientation( Gtk::AnchorType how );
+
+protected:
+    virtual void _handleAction( int setId, int itemId );
+
+private:
+    SwatchesPanel(SwatchesPanel const &); // no copy
+    SwatchesPanel &operator=(SwatchesPanel const &); // no assign
+
+    static SwatchesPanel* instance;
+
+    PreviewHolder* _holder;
+    ColorItem* _remove;
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+
+
+#endif // SEEN_SWATCHES_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:encoding=utf-8:textwidth=99 :
index c517e4f28d1540443d34b0a9b47e4c87afaf9812..ef1ca3ce256898728e78cca7819e9e6e6f826cc5 100644 (file)
@@ -14,7 +14,7 @@
 
 
 #include <gtkmm/widget.h>
-#include "../dialogs/eek-preview.h"
+#include "../widgets/eek-preview.h"
 
 namespace Inkscape {
 namespace UI {
index 6f02b60a8235b5a42aaf52acc1bfee7f776eaede..f863af121969bf5a3d7752d69a3d0b78866c7363 100644 (file)
@@ -14,7 +14,7 @@
 
 
 #include "previewable.h"
-#include "../dialogs/eek-preview.h"
+#include "../widgets/eek-preview.h"
 
 namespace Inkscape {
 namespace UI {
index 812d4b27d0259d77008f3e50c47e11f20cfeef80..3c1a161955e9c5ef2a9916fbb12965a8a48d75dd 100644 (file)
@@ -17,7 +17,7 @@
 #include <gtkmm/bin.h>
 #include <gtkmm/table.h>
 #include "previewfillable.h"
-#include "../dialogs/eek-preview.h"
+#include "../widgets/eek-preview.h"
 
 namespace Inkscape {
 namespace UI {
index ea32056966bbb99f0743ebb36b049ac3128a68cb..2bb7083054f817c459662620a6338d42f0b32dc8 100644 (file)
 #include "ui/dialog/dialog-manager.h"
 #include "ui/view/edit-widget-interface.h"
 #include "ui/widget/dock.h"
-#include "ui/widget/selected-style.h"
+#include "ui/widget/layer-selector.h"
 #include "ui/widget/ruler.h"
-#include "ui/widget/toolbox.h"
+#include "ui/widget/selected-style.h"
 #include "ui/widget/svg-canvas.h"
+#include "ui/widget/toolbox.h"
 #include "ui/widget/zoom-status.h"
-#include "widgets/layer-selector.h"
 
 struct SPDesktop;
 struct SPDocument;
index 9b4048ea927b56ab347bef6d434679e07b64684b..b6069631bc4164371f004784d00dbe5e07af56bf 100644 (file)
@@ -31,6 +31,8 @@ ink_common_sources += \
        ui/widget/imagetoggler.h                \
        ui/widget/labelled.cpp          \
        ui/widget/labelled.h            \
+       ui/widget/layer-selector.cpp    \
+       ui/widget/layer-selector.h      \
        ui/widget/licensor.cpp          \
        ui/widget/licensor.h            \
        ui/widget/notebook-page.cpp     \
index 980d225b289151f7a614968dc350b2a392c85abd..e9f09f574c9deb5109f7967d3dd5cdcd05d06f81 100644 (file)
 #include <gtkmm/scrolledwindow.h>
 #include <gtkmm/entry.h>
 
-#include "ui/widget/registry.h"
-
-#include "dialogs/rdf.h"
-
 #include "inkscape.h"
+#include "rdf.h"
+#include "ui/widget/registry.h"
 
 #include "entity-entry.h"
 
diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp
new file mode 100644 (file)
index 0000000..51084b1
--- /dev/null
@@ -0,0 +1,608 @@
+/*
+ * Inkscape::Widgets::LayerSelector - layer selector widget
+ *
+ * Authors:
+ *   MenTaLguY <mental@rydia.net>
+ *
+ * Copyright (C) 2004 MenTaLguY
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <cstring>
+#include <string>
+#include <glibmm/i18n.h>
+
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "document.h"
+#include "layer-manager.h"
+#include "sp-item.h"
+#include "ui/dialog/layer-properties.h"
+#include "ui/widget/layer-selector.h"
+#include "util/filter-list.h"
+#include "util/reverse-list.h"
+#include "verbs.h"
+#include "widgets/icon.h"
+#include "widgets/shrink-wrap-button.h"
+#include "xml/node-event-vector.h"
+
+namespace Inkscape {
+namespace Widgets {
+
+namespace {
+
+class AlternateIcons : public Gtk::HBox {
+public:
+    AlternateIcons(Inkscape::IconSize size, gchar const *a, gchar const *b)
+    : _a(NULL), _b(NULL)
+    {
+        if (a) {
+            _a = Gtk::manage(sp_icon_get_icon(a, size));
+            _a->set_no_show_all(true);
+            add(*_a);
+        }
+        if (b) {
+            _b = Gtk::manage(sp_icon_get_icon(b, size));
+            _b->set_no_show_all(true);
+            add(*_b);
+        }
+        setState(false);
+    }
+
+    bool state() const { return _state; }
+    void setState(bool state) {
+        _state = state;
+        if (_state) {
+            if (_a) {
+                _a->hide();
+            }
+            if (_b) {
+                _b->show();
+            }
+        } else {
+            if (_a) {
+                _a->show();
+            }
+            if (_b) {
+                _b->hide();
+            }
+        }
+    }
+
+private:
+    Gtk::Widget *_a;
+    Gtk::Widget *_b;
+    bool _state;
+};
+
+}
+
+/** LayerSelector constructor.  Creates lock and hide buttons,
+ *  initalizes the layer dropdown selector with a label renderer,
+ *  and hooks up signal for setting the desktop layer when the
+ *  selector is changed.
+ */
+LayerSelector::LayerSelector(SPDesktop *desktop)
+: _desktop(NULL), _layer(NULL)
+{
+    AlternateIcons *label;
+
+    label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "visible", "hidden"));
+    _visibility_toggle.add(*label);
+    _visibility_toggle.signal_toggled().connect(
+        sigc::compose(
+            sigc::mem_fun(*label, &AlternateIcons::setState),
+            sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active)
+        )
+    );
+    _visibility_toggled_connection = _visibility_toggle.signal_toggled().connect(
+        sigc::compose(
+            sigc::mem_fun(*this, &LayerSelector::_hideLayer),
+            sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active)
+        )
+    );
+
+    _visibility_toggle.set_relief(Gtk::RELIEF_NONE);
+    shrink_wrap_button(_visibility_toggle);
+    _tooltips.set_tip(_visibility_toggle, _("Toggle current layer visibility"));
+    pack_start(_visibility_toggle, Gtk::PACK_EXPAND_PADDING);
+
+    label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "lock_unlocked", "width_height_lock"));
+    _lock_toggle.add(*label);
+    _lock_toggle.signal_toggled().connect(
+        sigc::compose(
+            sigc::mem_fun(*label, &AlternateIcons::setState),
+            sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active)
+        )
+    );
+    _lock_toggled_connection = _lock_toggle.signal_toggled().connect(
+        sigc::compose(
+            sigc::mem_fun(*this, &LayerSelector::_lockLayer),
+            sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active)
+        )
+    );
+
+    _lock_toggle.set_relief(Gtk::RELIEF_NONE);
+    shrink_wrap_button(_lock_toggle);
+    _tooltips.set_tip(_lock_toggle, _("Lock or unlock current layer"));
+    pack_start(_lock_toggle, Gtk::PACK_EXPAND_PADDING);
+
+    _tooltips.set_tip(_selector, _("Current layer"));
+    pack_start(_selector, Gtk::PACK_EXPAND_WIDGET);
+
+    _layer_model = Gtk::ListStore::create(_model_columns);
+    _selector.set_model(_layer_model);
+    _selector.pack_start(_label_renderer);
+    _selector.set_cell_data_func(
+        _label_renderer,
+        sigc::mem_fun(*this, &LayerSelector::_prepareLabelRenderer)
+    );
+
+    _selection_changed_connection = _selector.signal_changed().connect(
+        sigc::mem_fun(*this, &LayerSelector::_setDesktopLayer)
+    );
+    setDesktop(desktop);
+}
+
+/**  Destructor - disconnects signal handler
+ */
+LayerSelector::~LayerSelector() {
+    setDesktop(NULL);
+    _selection_changed_connection.disconnect();
+}
+
+namespace {
+
+/** Helper function - detaches desktop from selector
+ */
+bool detach(LayerSelector *selector) {
+    selector->setDesktop(NULL);
+    return FALSE;
+}
+
+}
+
+/** Sets the desktop for the widget.  First disconnects signals
+ *  for the current desktop, then stores the pointer to the
+ *  given \a desktop, and attaches its signals to this one.
+ *  Then it selects the current layer for the desktop.
+ */
+void LayerSelector::setDesktop(SPDesktop *desktop) {
+    if ( desktop == _desktop ) {
+        return;
+    }
+
+    if (_desktop) {
+//        _desktop_shutdown_connection.disconnect();
+        _layer_changed_connection.disconnect();
+//        g_signal_handlers_disconnect_by_func(_desktop, (gpointer)&detach, this);
+    }
+    _desktop = desktop;
+    if (_desktop) {
+        // TODO we need a different signal for this, really..s
+//        _desktop_shutdown_connection = _desktop->connectShutdown(
+//          sigc::bind (sigc::ptr_fun (detach), this));
+//        g_signal_connect_after(_desktop, "shutdown", GCallback(detach), this);
+
+        _layer_changed_connection = _desktop->connectCurrentLayerChanged(
+            sigc::mem_fun(*this, &LayerSelector::_selectLayer)
+        );
+        _selectLayer(_desktop->currentLayer());
+    }
+}
+
+namespace {
+
+class is_layer {
+public:
+    is_layer(SPDesktop *desktop) : _desktop(desktop) {}
+    bool operator()(SPObject &object) const {
+        return _desktop->isLayer(&object);
+    }
+private:
+    SPDesktop *_desktop;
+};
+
+class column_matches_object {
+public:
+    column_matches_object(Gtk::TreeModelColumn<SPObject *> const &column,
+                          SPObject &object)
+    : _column(column), _object(object) {}
+    bool operator()(Gtk::TreeModel::const_iterator const &iter) const {
+        SPObject *current=(*iter)[_column];
+        return current == &_object;
+    }
+private:
+    Gtk::TreeModelColumn<SPObject *> const &_column;
+    SPObject &_object;
+};
+
+}
+
+/** Selects the given layer in the dropdown selector.
+ */
+void LayerSelector::_selectLayer(SPObject *layer) {
+    using Inkscape::Util::List;
+    using Inkscape::Util::cons;
+    using Inkscape::Util::reverse_list;
+
+    _selection_changed_connection.block();
+
+    while (!_layer_model->children().empty()) {
+        Gtk::ListStore::iterator first_row(_layer_model->children().begin());
+        _destroyEntry(first_row);
+        _layer_model->erase(first_row);
+    }
+
+    SPObject *root=_desktop->currentRoot();
+
+    if (_layer) {
+        sp_object_unref(_layer, NULL);
+        _layer = NULL;
+    }
+
+    if (layer) {
+        List<SPObject &> hierarchy=reverse_list<SPObject::ParentIterator>(layer, root);
+        if ( layer == root ) {
+            _buildEntries(0, cons(*root, hierarchy));
+        } else if (hierarchy) {
+            _buildSiblingEntries(0, *root, hierarchy);
+        }
+
+        Gtk::TreeIter row(
+            std::find_if(
+                _layer_model->children().begin(),
+                _layer_model->children().end(),
+                column_matches_object(_model_columns.object, *layer)
+            )
+        );
+        if ( row != _layer_model->children().end() ) {
+            _selector.set_active(row);
+        }
+
+        _layer = layer;
+        sp_object_ref(_layer, NULL);
+    }
+
+    if ( !layer || layer == root ) {
+        _visibility_toggle.set_sensitive(false);
+        _visibility_toggle.set_active(false);
+        _lock_toggle.set_sensitive(false);
+        _lock_toggle.set_active(false);
+    } else {
+        _visibility_toggle.set_sensitive(true);
+        _visibility_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false ));
+        _lock_toggle.set_sensitive(true);
+        _lock_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false ));
+    }
+
+    _selection_changed_connection.unblock();
+}
+
+/** Sets the current desktop layer to the actively selected layer.
+ */
+void LayerSelector::_setDesktopLayer() {
+    Gtk::ListStore::iterator selected(_selector.get_active());
+    SPObject *layer=_selector.get_active()->get_value(_model_columns.object);
+    if ( _desktop && layer ) {
+        _layer_changed_connection.block();
+
+        _desktop->layer_manager->setCurrentLayer(layer);
+
+        _layer_changed_connection.unblock();
+
+        _selectLayer(_desktop->currentLayer());
+    }
+    if (_desktop && _desktop->canvas) {
+        gtk_widget_grab_focus (GTK_WIDGET(_desktop->canvas));
+    }
+}
+
+/** Creates rows in the _layer_model data structure for each item
+ *  in \a hierarchy, to a given \a depth.
+ */
+void LayerSelector::_buildEntries(unsigned depth,
+                                  Inkscape::Util::List<SPObject &> hierarchy)
+{
+    using Inkscape::Util::List;
+    using Inkscape::Util::rest;
+
+    _buildEntry(depth, *hierarchy);
+
+    List<SPObject &> remainder=rest(hierarchy);
+    if (remainder) {
+        _buildEntries(depth+1, remainder);
+    } else {
+        _buildSiblingEntries(depth+1, *hierarchy, remainder);
+    }
+}
+
+/** Creates entries in the _layer_model data structure for
+ *  all siblings of the first child in \a parent.
+ */
+void LayerSelector::_buildSiblingEntries(
+    unsigned depth, SPObject &parent,
+    Inkscape::Util::List<SPObject &> hierarchy
+) {
+    using Inkscape::Util::List;
+    using Inkscape::Util::rest;
+    using Inkscape::Util::reverse_list_in_place;
+    using Inkscape::Util::filter_list;
+
+    Inkscape::Util::List<SPObject &> siblings(
+        reverse_list_in_place(
+            filter_list<SPObject::SiblingIterator>(
+                is_layer(_desktop), parent.firstChild(), NULL
+            )
+        )
+    );
+
+    SPObject *layer( hierarchy ? &*hierarchy : NULL );
+
+    while (siblings) {
+        _buildEntry(depth, *siblings);
+        if ( &*siblings == layer ) {
+            _buildSiblingEntries(depth+1, *layer, rest(hierarchy));
+        }
+        ++siblings;
+    }
+}
+
+namespace {
+
+struct Callbacks {
+    sigc::slot<void> update_row;
+    sigc::slot<void> update_list;
+};
+
+void attribute_changed(Inkscape::XML::Node */*repr*/, gchar const *name,
+                       gchar const */*old_value*/, gchar const */*new_value*/,
+                       bool /*is_interactive*/, void *data)
+{
+    if ( !std::strcmp(name, "inkscape:groupmode") ) {
+        reinterpret_cast<Callbacks *>(data)->update_list();
+    } else {
+        reinterpret_cast<Callbacks *>(data)->update_row();
+    }
+}
+
+void node_added(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) {
+    gchar const *mode=child->attribute("inkscape:groupmode");
+    if ( mode && !std::strcmp(mode, "layer") ) {
+        reinterpret_cast<Callbacks *>(data)->update_list();
+    }
+}
+
+void node_removed(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) {
+    gchar const *mode=child->attribute("inkscape:groupmode");
+    if ( mode && !std::strcmp(mode, "layer") ) {
+        reinterpret_cast<Callbacks *>(data)->update_list();
+    }
+}
+
+void node_reordered(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child,
+                    Inkscape::XML::Node */*old_ref*/, Inkscape::XML::Node */*new_ref*/,
+                    void *data)
+{
+    gchar const *mode=child->attribute("inkscape:groupmode");
+    if ( mode && !std::strcmp(mode, "layer") ) {
+        reinterpret_cast<Callbacks *>(data)->update_list();
+    }
+}
+
+void update_row_for_object(SPObject *object,
+                           Gtk::TreeModelColumn<SPObject *> const &column,
+                           Glib::RefPtr<Gtk::ListStore> const &model)
+{
+    Gtk::TreeIter row(
+        std::find_if(
+            model->children().begin(),
+            model->children().end(),
+            column_matches_object(column, *object)
+        )
+    );
+    if ( row != model->children().end() ) {
+        model->row_changed(model->get_path(row), row);
+    }
+}
+
+void rebuild_all_rows(sigc::slot<void, SPObject *> rebuild, SPDesktop *desktop)
+{
+    rebuild(desktop->currentLayer());
+}
+
+}
+
+void LayerSelector::_protectUpdate(sigc::slot<void> slot) {
+    bool visibility_blocked=_visibility_toggled_connection.blocked();
+    bool lock_blocked=_lock_toggled_connection.blocked();
+    _visibility_toggled_connection.block(true);
+    _lock_toggled_connection.block(true);
+    slot();
+
+    SPObject *layer = _desktop ? _desktop->currentLayer() : 0;
+    if ( layer ) {
+        bool wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false );
+        if ( _lock_toggle.get_active() != wantedValue ) {
+            _lock_toggle.set_active( wantedValue );
+        }
+        wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false );
+        if ( _visibility_toggle.get_active() != wantedValue ) {
+            _visibility_toggle.set_active( wantedValue );
+        }
+    }
+    _visibility_toggled_connection.block(visibility_blocked);
+    _lock_toggled_connection.block(lock_blocked);
+}
+
+/** Builds and appends a row in the layer model object.
+ */
+void LayerSelector::_buildEntry(unsigned depth, SPObject &object) {
+    Inkscape::XML::NodeEventVector *vector;
+
+    Callbacks *callbacks=new Callbacks();
+
+    callbacks->update_row = sigc::bind(
+        sigc::mem_fun(*this, &LayerSelector::_protectUpdate),
+        sigc::bind(
+            sigc::ptr_fun(&update_row_for_object),
+            &object, _model_columns.object, _layer_model
+        )
+    );
+
+    SPObject *layer=_desktop->currentLayer();
+    if ( &object == layer || &object == SP_OBJECT_PARENT(layer) ) {
+        callbacks->update_list = sigc::bind(
+            sigc::mem_fun(*this, &LayerSelector::_protectUpdate),
+            sigc::bind(
+                sigc::ptr_fun(&rebuild_all_rows),
+                sigc::mem_fun(*this, &LayerSelector::_selectLayer),
+                _desktop
+            )
+        );
+
+        Inkscape::XML::NodeEventVector events = {
+            &node_added,
+            &node_removed,
+            &attribute_changed,
+            NULL,
+            &node_reordered
+        };
+
+        vector = new Inkscape::XML::NodeEventVector(events);
+    } else {
+        Inkscape::XML::NodeEventVector events = {
+            NULL,
+            NULL,
+            &attribute_changed,
+            NULL,
+            NULL
+        };
+
+        vector = new Inkscape::XML::NodeEventVector(events);
+    }
+
+    Gtk::ListStore::iterator row(_layer_model->append());
+
+    row->set_value(_model_columns.depth, depth);
+
+    sp_object_ref(&object, NULL);
+    row->set_value(_model_columns.object, &object);
+
+    Inkscape::GC::anchor(SP_OBJECT_REPR(&object));
+    row->set_value(_model_columns.repr, SP_OBJECT_REPR(&object));
+
+    row->set_value(_model_columns.callbacks, reinterpret_cast<void *>(callbacks));
+
+    sp_repr_add_listener(SP_OBJECT_REPR(&object), vector, callbacks);
+}
+
+/** Removes a row from the _model_columns object, disconnecting listeners
+ *  on the slot.
+ */
+void LayerSelector::_destroyEntry(Gtk::ListStore::iterator const &row) {
+    Callbacks *callbacks=reinterpret_cast<Callbacks *>(row->get_value(_model_columns.callbacks));
+    SPObject *object=row->get_value(_model_columns.object);
+    if (object) {
+        sp_object_unref(object, NULL);
+    }
+    Inkscape::XML::Node *repr=row->get_value(_model_columns.repr);
+    if (repr) {
+        sp_repr_remove_listener_by_data(repr, callbacks);
+        Inkscape::GC::release(repr);
+    }
+    delete callbacks;
+}
+
+/** Formats the label for a given layer row
+ */
+void LayerSelector::_prepareLabelRenderer(
+    Gtk::TreeModel::const_iterator const &row
+) {
+    unsigned depth=(*row)[_model_columns.depth];
+    SPObject *object=(*row)[_model_columns.object];
+    bool label_defaulted(false);
+
+    // TODO: when the currently selected row is removed,
+    //       (or before one has been selected) something appears to
+    //       "invent" an iterator with null data and try to render it;
+    //       where does it come from, and how can we avoid it?
+    if ( object && SP_OBJECT_REPR(object) ) {
+        SPObject *layer=( _desktop ? _desktop->currentLayer() : NULL );
+        SPObject *root=( _desktop ? _desktop->currentRoot() : NULL );
+
+        bool isancestor = !( (layer && (SP_OBJECT_PARENT(object) == SP_OBJECT_PARENT(layer))) || ((layer == root) && (SP_OBJECT_PARENT(object) == root)));
+
+        bool iscurrent = ( object == layer && object != root );
+
+        gchar *format = g_strdup_printf (
+            "<span size=\"smaller\" %s><tt>%*s%s</tt>%s%s%s%%s%s%s%s</span>",
+            ( _desktop && _desktop->itemIsHidden (SP_ITEM(object)) ? "foreground=\"gray50\"" : "" ),
+            depth, "", ( iscurrent ? "&#8226;" : " " ),
+            ( iscurrent ? "<b>" : "" ),
+            ( SP_ITEM(object)->isLocked() ? "[" : "" ),
+            ( isancestor ? "<small>" : "" ),
+            ( isancestor ? "</small>" : "" ),
+            ( SP_ITEM(object)->isLocked() ? "]" : "" ),
+            ( iscurrent ? "</b>" : "" )
+            );
+
+        gchar const *label;
+        if ( object != root ) {
+            label = object->label();
+            if (!label) {
+                label = object->defaultLabel();
+                label_defaulted = true;
+            }
+        } else {
+            label = _("(root)");
+        }
+
+        gchar *text = g_markup_printf_escaped(format, label);
+        _label_renderer.property_markup() = text;
+        g_free(text);
+        g_free(format);
+    } else {
+        _label_renderer.property_markup() = "<small> </small>";
+    }
+
+    _label_renderer.property_ypad() = 1;
+    _label_renderer.property_style() = ( label_defaulted ?
+                                         Pango::STYLE_ITALIC :
+                                         Pango::STYLE_NORMAL );
+}
+
+void LayerSelector::_lockLayer(bool lock) {
+    if ( _layer && SP_IS_ITEM(_layer) ) {
+        SP_ITEM(_layer)->setLocked(lock);
+        sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE,
+                         lock? _("Lock layer") : _("Unlock layer"));
+    }
+}
+
+void LayerSelector::_hideLayer(bool hide) {
+    if ( _layer && SP_IS_ITEM(_layer) ) {
+        SP_ITEM(_layer)->setHidden(hide);
+        sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE,
+                         hide? _("Hide layer") : _("Unhide layer"));
+    }
+}
+
+}
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/layer-selector.h b/src/ui/widget/layer-selector.h
new file mode 100644 (file)
index 0000000..0b53002
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Inkscape::Widgets::LayerSelector - layer selector widget
+ *
+ * Authors:
+ *   MenTaLguY <mental@rydia.net>
+ *
+ * Copyright (C) 2004 MenTaLguY
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_WIDGETS_LAYER_SELECTOR
+#define SEEN_INKSCAPE_WIDGETS_LAYER_SELECTOR
+
+#include <gtkmm/box.h>
+#include <gtkmm/combobox.h>
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/cellrenderertext.h>
+#include <gtkmm/treemodel.h>
+#include <gtkmm/liststore.h>
+#include <sigc++/slot.h>
+#include "util/list.h"
+
+class SPDesktop;
+class SPDocument;
+class SPObject;
+namespace Inkscape {
+namespace XML {
+class Node;
+}
+}
+
+
+namespace Inkscape {
+namespace Widgets {
+
+class DocumentTreeModel;
+
+class LayerSelector : public Gtk::HBox {
+public:
+    LayerSelector(SPDesktop *desktop = NULL);
+    ~LayerSelector();
+
+    SPDesktop *desktop() { return _desktop; }
+    void setDesktop(SPDesktop *desktop);
+
+private:
+    class LayerModelColumns : public Gtk::TreeModel::ColumnRecord {
+    public:
+        Gtk::TreeModelColumn<unsigned> depth;
+        Gtk::TreeModelColumn<SPObject *> object;
+        Gtk::TreeModelColumn<Inkscape::XML::Node *> repr;
+        Gtk::TreeModelColumn<void *> callbacks;
+
+        LayerModelColumns() {
+            add(depth); add(object); add(repr); add(callbacks);
+        }
+    };
+
+    SPDesktop *_desktop;
+
+    Gtk::Tooltips _tooltips;
+    Gtk::ComboBox _selector;
+    Gtk::ToggleButton _visibility_toggle;
+    Gtk::ToggleButton _lock_toggle;
+
+    LayerModelColumns _model_columns;
+    Gtk::CellRendererText _label_renderer;
+    Glib::RefPtr<Gtk::ListStore> _layer_model;
+
+//    sigc::connection _desktop_shutdown_connection;
+    sigc::connection _layer_changed_connection;
+    sigc::connection _selection_changed_connection;
+    sigc::connection _visibility_toggled_connection;
+    sigc::connection _lock_toggled_connection;
+
+    SPObject *_layer;
+
+    void _selectLayer(SPObject *layer);
+    void _setDesktopLayer();
+
+    void _buildEntry(unsigned depth, SPObject &object);
+    void _buildEntries(unsigned depth,
+                       Inkscape::Util::List<SPObject &> hierarchy);
+    void _buildSiblingEntries(unsigned depth,
+                              SPObject &parent,
+                              Inkscape::Util::List<SPObject &> hierarchy);
+    void _protectUpdate(sigc::slot<void> slot);
+    void _destroyEntry(Gtk::ListStore::iterator const &row);
+    void _hideLayer(bool hide);
+    void _lockLayer(bool lock);
+
+    void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
+};
+
+}
+}
+
+#endif
+/*
+  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:encoding=utf-8:textwidth=99 :
index 24bd5595f54fd583a67f4fcbc9ecfb4f243e2054..05f00edfca11dbe9f5e291bb795225db04afddab 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "ui/widget/entity-entry.h"
 #include "ui/widget/registry.h"
-#include "dialogs/rdf.h"
+#include "rdf.h"
 #include "inkscape.h"
 
 #include "licensor.h"
index 9811cc89c638fa16969a051471f5d5a1e5675243..82f75c3ff43810ced7cf17e2fac02b6a1bd915a1 100644 (file)
@@ -29,7 +29,7 @@
 #include "preferences.h"
 #include "desktop-handles.h"
 #include "inkscape.h"
-#include "dialogs/eek-preview.h"
+#include "widgets/eek-preview.h"
 
 namespace Inkscape {
 namespace UI {
diff --git a/src/unclump.cpp b/src/unclump.cpp
new file mode 100644 (file)
index 0000000..aebcfd9
--- /dev/null
@@ -0,0 +1,388 @@
+/** @file
+ * @brief Unclumping objects
+ */
+/* Authors:
+ *   bulia byak
+ *
+ * Copyright (C) 2005 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <algorithm>
+#include <map>
+#include "sp-item.h"
+
+
+// Taking bbox of an item is an expensive operation, and we need to do it many times, so here we
+// cache the centers, widths, and heights of items
+
+//FIXME: make a class with these cashes as members instead of globals 
+std::map<const gchar *, Geom::Point> c_cache;
+std::map<const gchar *, Geom::Point> wh_cache;
+
+/**
+Center of bbox of item
+*/
+Geom::Point
+unclump_center (SPItem *item)
+{
+    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(item));
+    if ( i != c_cache.end() ) {
+        return i->second;
+    }
+
+    Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item));
+    if (r) {
+       Geom::Point const c = r->midpoint();
+       c_cache[SP_OBJECT_ID(item)] = c;
+        return c; 
+    } else {
+       // FIXME
+        return Geom::Point(0, 0);
+    }
+}
+
+Geom::Point
+unclump_wh (SPItem *item)
+{
+    Geom::Point wh;
+    std::map<const gchar *, Geom::Point>::iterator i = wh_cache.find(SP_OBJECT_ID(item));
+    if ( i != wh_cache.end() ) {
+        wh = i->second;
+    } else {
+        Geom::OptRect r = item->getBounds(sp_item_i2d_affine(item));
+       if (r) {
+            wh = r->dimensions();
+            wh_cache[SP_OBJECT_ID(item)] = wh;
+        } else {
+           wh = Geom::Point(0, 0);
+        }
+    }
+
+    return wh;
+}
+
+/**
+Distance between "edges" of item1 and item2. An item is considered to be an ellipse inscribed into its w/h, 
+so its radius (distance from center to edge) depends on the w/h and the angle towards the other item.
+May be negative if the edge of item1 is between the center and the edge of item2.
+*/
+double
+unclump_dist (SPItem *item1, SPItem *item2)
+{
+       Geom::Point c1 = unclump_center (item1);
+       Geom::Point c2 = unclump_center (item2);
+
+       Geom::Point wh1 = unclump_wh (item1);
+       Geom::Point wh2 = unclump_wh (item2);
+
+       // angle from each item's center to the other's, unsqueezed by its w/h, normalized to 0..pi/2
+       double a1 = atan2 ((c2 - c1)[Geom::Y], (c2 - c1)[Geom::X] * wh1[Geom::Y]/wh1[Geom::X]);
+       a1 = fabs (a1);
+       if (a1 > M_PI/2) a1 = M_PI - a1;
+
+       double a2 = atan2 ((c1 - c2)[Geom::Y], (c1 - c2)[Geom::X] * wh2[Geom::Y]/wh2[Geom::X]);
+       a2 = fabs (a2);
+       if (a2 > M_PI/2) a2 = M_PI - a2;
+
+       // get the radius of each item for the given angle
+       double r1 = 0.5 * (wh1[Geom::X] + (wh1[Geom::Y] - wh1[Geom::X]) * (a1/(M_PI/2)));
+       double r2 = 0.5 * (wh2[Geom::X] + (wh2[Geom::Y] - wh2[Geom::X]) * (a2/(M_PI/2)));
+
+       // dist between centers minus angle-adjusted radii
+       double dist_r =  (Geom::L2 (c2 - c1) - r1 - r2);
+
+       double stretch1 = wh1[Geom::Y]/wh1[Geom::X];
+       double stretch2 = wh2[Geom::Y]/wh2[Geom::X];
+
+       if ((stretch1 > 1.5 || stretch1 < 0.66) && (stretch2 > 1.5 || stretch2 < 0.66)) {
+
+               std::vector<double> dists;
+               dists.push_back (dist_r);
+
+               // If both objects are not circle-like, find dists between four corners
+               std::vector<Geom::Point> c1_points(2);
+               {
+                       double y_closest;
+                       if (c2[Geom::Y] > c1[Geom::Y] + wh1[Geom::Y]/2) {
+                               y_closest = c1[Geom::Y] + wh1[Geom::Y]/2;
+                       } else if (c2[Geom::Y] < c1[Geom::Y] - wh1[Geom::Y]/2) {
+                               y_closest = c1[Geom::Y] - wh1[Geom::Y]/2;
+                       } else {
+                               y_closest = c2[Geom::Y];
+                       }
+                       c1_points[0] = Geom::Point (c1[Geom::X], y_closest);
+                       double x_closest;
+                       if (c2[Geom::X] > c1[Geom::X] + wh1[Geom::X]/2) {
+                               x_closest = c1[Geom::X] + wh1[Geom::X]/2;
+                       } else if (c2[Geom::X] < c1[Geom::X] - wh1[Geom::X]/2) {
+                               x_closest = c1[Geom::X] - wh1[Geom::X]/2;
+                       } else {
+                               x_closest = c2[Geom::X];
+                       }
+                       c1_points[1] = Geom::Point (x_closest, c1[Geom::Y]);
+               }
+
+
+               std::vector<Geom::Point> c2_points(2);
+               {
+                       double y_closest;
+                       if (c1[Geom::Y] > c2[Geom::Y] + wh2[Geom::Y]/2) {
+                               y_closest = c2[Geom::Y] + wh2[Geom::Y]/2;
+                       } else if (c1[Geom::Y] < c2[Geom::Y] - wh2[Geom::Y]/2) {
+                               y_closest = c2[Geom::Y] - wh2[Geom::Y]/2;
+                       } else {
+                               y_closest = c1[Geom::Y];
+                       }
+                       c2_points[0] = Geom::Point (c2[Geom::X], y_closest);
+                       double x_closest;
+                       if (c1[Geom::X] > c2[Geom::X] + wh2[Geom::X]/2) {
+                               x_closest = c2[Geom::X] + wh2[Geom::X]/2;
+                       } else if (c1[Geom::X] < c2[Geom::X] - wh2[Geom::X]/2) {
+                               x_closest = c2[Geom::X] - wh2[Geom::X]/2;
+                       } else {
+                               x_closest = c1[Geom::X];
+                       }
+                       c2_points[1] = Geom::Point (x_closest, c2[Geom::Y]);
+               }
+
+               for (int i = 0; i < 2; i ++) {
+                       for (int j = 0; j < 2; j ++) {
+                               dists.push_back (Geom::L2 (c1_points[i] - c2_points[j]));
+                       }
+               }
+
+               // return the minimum of all dists
+               return *std::min_element(dists.begin(), dists.end());
+       } else {
+               return dist_r;
+       }
+}
+
+/**
+Average unclump_dist from item to others
+*/
+double unclump_average (SPItem *item, GSList *others)
+{
+    int n = 0;
+    double sum = 0;
+
+    for (GSList *i = others; i != NULL; i = i->next) {
+        SPItem *other = SP_ITEM (i->data);
+
+        if (other == item)
+            continue;
+
+        n++;
+        sum += unclump_dist (item, other);
+    }
+
+    if (n != 0)
+        return sum/n;
+    else
+        return 0;
+}
+
+/**
+Closest to item among others
+ */
+SPItem *unclump_closest (SPItem *item, GSList *others)
+{
+    double min = HUGE_VAL;
+    SPItem *closest = NULL;
+
+    for (GSList *i = others; i != NULL; i = i->next) {
+        SPItem *other = SP_ITEM (i->data);
+
+        if (other == item)
+            continue;
+
+        double dist = unclump_dist (item, other);
+        if (dist < min && fabs (dist) < 1e6) {
+            min = dist;
+            closest = other;
+        }
+    }
+
+    return closest;
+}
+
+/**
+Most distant from item among others
+ */
+SPItem *unclump_farest (SPItem *item, GSList *others)
+{
+    double max = -HUGE_VAL;
+    SPItem *farest = NULL;
+
+    for (GSList *i = others; i != NULL; i = i->next) {
+        SPItem *other = SP_ITEM (i->data);
+
+        if (other == item)
+            continue;
+
+        double dist = unclump_dist (item, other);
+        if (dist > max && fabs (dist) < 1e6) {
+            max = dist;
+            farest = other;
+        }
+    }
+
+    return farest;
+}
+
+/**
+Removes from the \a rest list those items that are "behind" \a closest as seen from \a item,
+i.e. those on the other side of the line through \a closest perpendicular to the direction from \a
+item to \a closest. Returns a newly created list which must be freed.
+ */
+GSList *
+unclump_remove_behind (SPItem *item, SPItem *closest, GSList *rest)
+{
+    Geom::Point it = unclump_center (item);
+    Geom::Point p1 = unclump_center (closest);
+
+    // perpendicular through closest to the direction to item:
+    Geom::Point perp = Geom::rot90(it - p1);
+    Geom::Point p2 = p1 + perp;
+
+    // get the standard Ax + By + C = 0 form for p1-p2:
+    double A = p1[Geom::Y] - p2[Geom::Y];
+    double B = p2[Geom::X] - p1[Geom::X];
+    double C = p2[Geom::Y] * p1[Geom::X] - p1[Geom::Y] * p2[Geom::X];
+
+    // substitute the item into it:
+    double val_item = A * it[Geom::X] + B * it[Geom::Y] + C;
+
+    GSList *out = NULL;
+
+    for (GSList *i = rest; i != NULL; i = i->next) {
+        SPItem *other = SP_ITEM (i->data);
+
+        if (other == item)
+            continue;
+
+        Geom::Point o = unclump_center (other);
+        double val_other = A * o[Geom::X] + B * o[Geom::Y] + C;
+
+        if (val_item * val_other <= 1e-6) {
+            // different signs, which means item and other are on the different sides of p1-p2 line; skip
+        } else {
+            out = g_slist_prepend (out, other);
+        }
+    }
+
+    return out;
+}
+
+/**
+Moves \a what away from \a from by \a dist
+ */
+void
+unclump_push (SPItem *from, SPItem *what, double dist)
+{
+    Geom::Point it = unclump_center (what);
+    Geom::Point p = unclump_center (from);
+    Geom::Point by = dist * Geom::unit_vector (- (p - it));
+
+    Geom::Matrix move = Geom::Translate (by);
+
+    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(what));
+    if ( i != c_cache.end() ) {
+        i->second *= move;
+    }
+
+    //g_print ("push %s at %g,%g from %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[Geom::X],it[Geom::Y], p[Geom::X],p[Geom::Y], by[Geom::X],by[Geom::Y], dist);
+
+    sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move);
+    sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL);
+}
+
+/**
+Moves \a what towards \a to by \a dist
+ */
+void
+unclump_pull (SPItem *to, SPItem *what, double dist)
+{
+    Geom::Point it = unclump_center (what);
+    Geom::Point p = unclump_center (to);
+    Geom::Point by = dist * Geom::unit_vector (p - it);
+
+    Geom::Matrix move = Geom::Translate (by);
+
+    std::map<const gchar *, Geom::Point>::iterator i = c_cache.find(SP_OBJECT_ID(what));
+    if ( i != c_cache.end() ) {
+        i->second *= move;
+    }
+
+    //g_print ("pull %s at %g,%g to %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[Geom::X],it[Geom::Y], p[Geom::X],p[Geom::Y], by[Geom::X],by[Geom::Y], dist);
+
+    sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move);
+    sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL);
+}
+
+
+/**
+Unclumps the items in \a items, reducing local unevenness in their distribution. Produces an effect
+similar to "engraver dots". The only distribution which is unchanged by unclumping is a hexagonal
+grid. May be called repeatedly for stronger effect. 
+ */
+void
+unclump (GSList *items)
+{
+    c_cache.clear();
+    wh_cache.clear();
+
+    for (GSList *i = items; i != NULL; i = i->next) { //  for each original/clone x: 
+        SPItem *item = SP_ITEM (i->data);
+
+        GSList *nei = NULL;
+
+        GSList *rest = g_slist_copy (items);
+        rest = g_slist_remove (rest, item);
+
+        while (rest != NULL) {
+            SPItem *closest = unclump_closest (item, rest);
+            if (closest) {
+                nei = g_slist_prepend (nei, closest);
+                rest = g_slist_remove (rest, closest);
+                GSList *new_rest = unclump_remove_behind (item, closest, rest);
+                g_slist_free (rest);
+                rest = new_rest;
+            } else {
+                g_slist_free (rest);
+                break;
+            }
+        } 
+
+        if (g_slist_length (nei) >= 2) {
+            double ave = unclump_average (item, nei);
+
+            SPItem *closest = unclump_closest (item, nei);
+            SPItem *farest = unclump_farest (item, nei);
+
+            double dist_closest = unclump_dist (closest, item);
+            double dist_farest = unclump_dist (farest, item);
+
+            //g_print ("NEI %d for item %s    closest %s at %g  farest %s at %g  ave %g\n", g_slist_length(nei), SP_OBJECT_ID(item), SP_OBJECT_ID(closest), dist_closest, SP_OBJECT_ID(farest), dist_farest, ave);
+
+            if (fabs (ave) < 1e6 && fabs (dist_closest) < 1e6 && fabs (dist_farest) < 1e6) { // otherwise the items are bogus
+                // increase these coefficients to make unclumping more aggressive and less stable
+                // the pull coefficient is a bit bigger to counteract the long-term expansion trend
+                unclump_push (closest, item, 0.3 * (ave - dist_closest)); 
+                unclump_pull (farest, item, 0.35 * (dist_farest - ave));
+            }
+        }
+    }
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/unclump.h b/src/unclump.h
new file mode 100644 (file)
index 0000000..c5a8bf7
--- /dev/null
@@ -0,0 +1,29 @@
+/** @file
+ * @brief Unclumping objects
+ */
+/* Authors:
+ *   bulia byak
+ *
+ * Copyright (C) 2005 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_DIALOGS_UNCLUMP_H
+#define SEEN_DIALOGS_UNCLUMP_H
+
+#include <glib/gslist.h>
+
+void unclump(GSList *items);
+
+#endif /* !UNCLUMP_H_SEEN */
+
+/*
+  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:encoding=utf-8:textwidth=99 :
index ce624b14c2fd8aea2b9380d8da4fb369151d669e..834e1511d4bae4382fc481bba7027ca6a362f227 100644 (file)
 #include "desktop.h"
 #include "desktop-handles.h"
 #include "dialogs/clonetiler.h"
-#include "dialogs/extensions.h"
 #include "dialogs/find.h"
-#include "dialogs/iconpreview.h"
 #include "dialogs/input.h"
 #include "dialogs/item-properties.h"
-#include "dialogs/layer-properties.h"
-#include "dialogs/layers-panel.h"
 #include "dialogs/spellcheck.h"
-#include "dialogs/swatches.h"
 #include "dialogs/text-edit.h"
 #include "dialogs/xml-tree.h"
 #include "display/curve.h"
 #include "tools-switch.h"
 #include "ui/dialog/dialog-manager.h"
 #include "ui/dialog/document-properties.h"
+#include "ui/dialog/extensions.h"
+#include "ui/dialog/icon-preview.h"
 #include "ui/dialog/inkscape-preferences.h"
+#include "ui/dialog/layer-properties.h"
+#include "ui/dialog/layers.h"
+#include "ui/dialog/swatches.h"
 #include "ui/icon-names.h"
 
 #ifdef WITH_INKBOARD
index 32a8a71e5310acd2d0746424cf9995eb2fe5eb0c..13f2b33eb56c3e37e09d75e42b52405007f97125 100644 (file)
@@ -3,12 +3,16 @@
 ink_common_sources +=  \
        widgets/button.cpp              \
        widgets/button.h                \
-       widgets/calligraphic-profile-rename.cpp \
-       widgets/calligraphic-profile-rename.h   \
        widgets/dash-selector.cpp       \
        widgets/dash-selector.h         \
        widgets/desktop-widget.cpp      \
        widgets/desktop-widget.h        \
+       widgets/eek-color-def.cpp       \
+       widgets/eek-color-def.h         \
+       widgets/eek-preview.cpp         \
+       widgets/eek-preview.h           \
+       widgets/fill-style.cpp          \
+       widgets/fill-style.h            \
        widgets/font-selector.cpp       \
        widgets/font-selector.h         \
        widgets/gradient-image.cpp      \
@@ -21,8 +25,6 @@ ink_common_sources += \
        widgets/gradient-vector.h       \
        widgets/icon.cpp                \
        widgets/icon.h                  \
-       widgets/layer-selector.cpp      \
-       widgets/layer-selector.h        \
        widgets/paint-selector.cpp      \
        widgets/paint-selector.h        \
        widgets/ruler.cpp               \
@@ -31,6 +33,8 @@ ink_common_sources += \
        widgets/select-toolbar.h        \
        widgets/shrink-wrap-button.cpp  \
        widgets/shrink-wrap-button.h    \
+       widgets/sp-attribute-widget.cpp \
+       widgets/sp-attribute-widget.h   \
        widgets/sp-color-gtkselector.cpp        \
        widgets/sp-color-gtkselector.h  \
        widgets/sp-color-icc-selector.cpp       \
@@ -61,6 +65,8 @@ ink_common_sources += \
        widgets/sp-xmlview-content.h    \
        widgets/sp-xmlview-tree.cpp     \
        widgets/sp-xmlview-tree.h       \
+       widgets/stroke-style.cpp        \
+       widgets/stroke-style.h          \
        widgets/toolbox.cpp             \
        widgets/toolbox.h               \
        widgets/widget-sizes.h
diff --git a/src/widgets/calligraphic-profile-rename.cpp b/src/widgets/calligraphic-profile-rename.cpp
deleted file mode 100644 (file)
index 888b327..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/** @file
- * @brief Dialog for naming calligraphic profiles
- *
- * @note This file is in the wrong directory because of link order issues - 
- * it is required by widgets/toolbox.cpp, and libspwidgets.a comes after
- * libinkdialogs.a in the current link order.
- */
-/* Author:
- *   Aubanel MONNIER 
- *
- * Copyright (C) 2007 Authors
- * Released under GNU GPL.  Read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <glibmm/i18n.h>
-#include <gtkmm/stock.h>
-
-#include "desktop.h"
-#include "calligraphic-profile-rename.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Dialog {
-
-CalligraphicProfileRename::CalligraphicProfileRename() :
-    _applied(false)
-{
-    Gtk::VBox *mainVBox = get_vbox();
-    _layout_table.set_spacings(4);
-    _layout_table.resize (1, 2);
-
-    _profile_name_entry.set_activates_default(true);
-
-    _profile_name_label.set_label(_("Profile name:"));
-    _profile_name_label.set_alignment(1.0, 0.5);
-
-    _layout_table.attach(_profile_name_label,
-                  0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
-    _layout_table.attach(_profile_name_entry,
-                  1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
-    mainVBox->pack_start(_layout_table, false, false, 4);
-    // Buttons
-    _close_button.set_use_stock(true);
-    _close_button.set_label(Gtk::Stock::CANCEL.id);
-    _close_button.set_flags(Gtk::CAN_DEFAULT);
-
-    _apply_button.set_use_underline(true);
-    _apply_button.set_label(_("Save"));
-    _apply_button.set_flags(Gtk::CAN_DEFAULT);
-
-    _close_button.signal_clicked()
-    .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_close));
-    _apply_button.signal_clicked()
-    .connect(sigc::mem_fun(*this, &CalligraphicProfileRename::_apply));
-
-    signal_delete_event().connect( sigc::bind_return(
-        sigc::hide(sigc::mem_fun(*this, &CalligraphicProfileRename::_close)), true ) );
-
-    add_action_widget(_close_button, Gtk::RESPONSE_CLOSE);
-    add_action_widget(_apply_button, Gtk::RESPONSE_APPLY);
-
-    _apply_button.grab_default();
-
-    show_all_children();
-}
-
-void CalligraphicProfileRename::_apply()
-{
-    _profile_name = _profile_name_entry.get_text();
-    _applied = true;
-    _close();
-}
-
-void CalligraphicProfileRename::_close()
-{
-    this->Gtk::Dialog::hide();
-}
-
-void CalligraphicProfileRename::show(SPDesktop *desktop)
-{
-    CalligraphicProfileRename &dial = instance();
-    dial._applied=false;
-    dial.set_modal(true);
-    desktop->setWindowTransient (dial.gobj());
-    dial.property_destroy_with_parent() = true;
-    //  dial.Gtk::Dialog::show();
-    //dial.present();
-    dial.run();
-}
-
-} // namespace Dialog
-} // 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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/calligraphic-profile-rename.h b/src/widgets/calligraphic-profile-rename.h
deleted file mode 100644 (file)
index 53ce907..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/** @file
- * @brief Dialog for naming calligraphic profiles
- */
-/* Author:
- *   Aubanel MONNIER 
- *
- * Copyright (C) 2007 Authors
- * Released under GNU GPL.  Read the file 'COPYING' for more information
- */
-
-#ifndef INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
-#define INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_H
-
-#include <gtkmm/dialog.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/label.h>
-#include <gtkmm/table.h>
-struct SPDesktop;
-
-namespace Inkscape {
-namespace UI {
-namespace Dialog {
-      
-class CalligraphicProfileRename : public Gtk::Dialog {  
-public:
-    CalligraphicProfileRename();
-    virtual ~CalligraphicProfileRename() {}
-    Glib::ustring getName() const {
-        return "CalligraphicProfileRename";
-    }
-    
-    static void show(SPDesktop *desktop);
-    static bool applied() {
-        return instance()._applied;
-    }
-    static Glib::ustring getProfileName() {
-        return instance()._profile_name;
-    }
-
-protected:
-    void _close();
-    void _apply();
-
-    Gtk::Label        _profile_name_label;
-    Gtk::Entry        _profile_name_entry;
-    Gtk::Table        _layout_table;
-    Gtk::Button       _close_button;
-    Gtk::Button       _apply_button;
-    Glib::ustring _profile_name;
-    bool _applied;
-private:
-    static CalligraphicProfileRename &instance() {
-        static CalligraphicProfileRename instance_;
-        return instance_;
-    }
-    CalligraphicProfileRename(CalligraphicProfileRename const &); // no copy
-    CalligraphicProfileRename &operator=(CalligraphicProfileRename const &); // no assign
-};
-} // namespace Dialog
-} // namespace UI
-} // namespace Inkscape
-
-#endif // INKSCAPE_DIALOG_CALLIGRAPHIC_PROFILE_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:encoding=utf-8:textwidth=99 :
index 324e5b0087d1401b55198368d89f4efcedf91582..356a09418de9439c8661762afcec391cfb44d1d4 100644 (file)
 #include <gtkmm/paned.h>
 #include <gtk/gtk.h>
 
-#include "macros.h"
-#include "inkscape-private.h"
-#include "desktop-handles.h"
+#include "box3d-context.h"
+#include "color-profile-fns.h"
+#include "conn-avoid-ref.h"
 #include "desktop-events.h"
-#include "document.h"
+#include "desktop-handles.h"
 #include "desktop-widget.h"
-#include "sp-namedview.h"
-#include "interface.h"
-#include "toolbox.h"
-#include "preferences.h"
-#include "file.h"
 #include "display/canvas-arena.h"
 #include "display/nr-arena.h"
+#include "document.h"
+#include "ege-color-prof-tracker.h"
+#include "ege-select-one-action.h"
 #include <extension/db.h>
+#include "file.h"
 #include "helper/units.h"
+#include "inkscape-private.h"
+#include "interface.h"
+#include "macros.h"
+#include "preferences.h"
+#include "sp-image.h"
+#include "sp-item.h"
+#include "sp-namedview.h"
+#include "toolbox.h"
+#include "ui/dialog/dialog-manager.h"
+#include "ui/dialog/swatches.h"
+#include "ui/widget/dock.h"
+#include "ui/widget/layer-selector.h"
+#include "ui/widget/selected-style.h"
 #include "widgets/button.h"
 #include "widgets/ruler.h"
-#include "widgets/widget-sizes.h"
-#include "widgets/spw-utilities.h"
 #include "widgets/spinbutton-events.h"
-#include "widgets/layer-selector.h"
+#include "widgets/spw-utilities.h"
 #include "widgets/toolbox.h"
-#include "ui/dialog/dialog-manager.h"
-#include "ui/widget/dock.h"
-#include "ui/widget/selected-style.h"
-#include "sp-item.h"
-#include "dialogs/swatches.h"
-#include "conn-avoid-ref.h"
-#include "ege-select-one-action.h"
-#include "ege-color-prof-tracker.h"
-#include "color-profile-fns.h"
-#include "box3d-context.h"
-#include "sp-image.h"
+#include "widgets/widget-sizes.h"
 
 #if defined (SOLARIS) && (SOLARIS == 8)
 #include "round.h"
diff --git a/src/widgets/eek-color-def.cpp b/src/widgets/eek-color-def.cpp
new file mode 100644 (file)
index 0000000..85b00b2
--- /dev/null
@@ -0,0 +1,147 @@
+/** @file
+ * @brief EEK color definition
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Eek Color Definition.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "config.h"
+
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
+#if !defined(_)
+#define _(s) gettext(s)
+#endif // !defined(_)
+
+#include "eek-color-def.h"
+
+namespace eek
+{
+
+ColorDef::ColorDef() :
+    descr(_("none")),
+    r(0),
+    g(0),
+    b(0),
+    none(true),
+    editable(false)
+{
+}
+
+ColorDef::ColorDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description ) :
+    descr(description),
+    r(r),
+    g(g),
+    b(b),
+    none(false),
+    editable(false)
+{
+}
+
+ColorDef::~ColorDef()
+{
+}
+
+ColorDef::ColorDef( ColorDef const &other )
+{
+    if ( this != &other ) {
+        *this = other;
+    }
+}
+
+ColorDef& ColorDef::operator=( ColorDef const &other )
+{
+    if ( this != & other )
+    {
+        r = other.r;
+        g = other.g;
+        b = other.b;
+        descr = other.descr;
+        none = other.none;
+        editable = other.editable;
+    }
+    return *this;
+}
+
+class ColorDef::HookData {
+public:
+    HookData( ColorCallback cb, void* data ) {_cb = cb; _data = data;}
+    ColorCallback _cb;
+    void* _data;
+};
+
+void ColorDef::setRGB( unsigned int r, unsigned int g, unsigned int b )
+{
+    if ( r != this->r || g != this->g || b != this->b ) {
+        this->r = r;
+        this->g = g;
+        this->b = b;
+
+        // beware of callbacks changing things
+        for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
+        {
+            if ( (*it)->_cb )
+            {
+                (*it)->_cb( (*it)->_data );
+            }
+        }
+    }
+}
+
+void ColorDef::addCallback( ColorCallback cb, void* data )
+{
+    _listeners.push_back( new HookData(cb, data) );
+}
+
+void ColorDef::removeCallback( ColorCallback cb, void* data )
+{
+    (void)cb;
+    (void)data;
+}
+
+} // namespace eek
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/eek-color-def.h b/src/widgets/eek-color-def.h
new file mode 100644 (file)
index 0000000..63cd096
--- /dev/null
@@ -0,0 +1,102 @@
+/** @file
+ * @brief EEK color definition
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Eek Color Definition.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef SEEN_EEK_COLOR_DEF_H
+#define SEEN_EEK_COLOR_DEF_H
+
+#include <string>
+#include <vector>
+
+namespace eek
+{
+
+typedef void (*ColorCallback)( void* data );
+
+
+class ColorDef
+{
+public:
+    ColorDef();
+    ColorDef( unsigned int r, unsigned int g, unsigned int b, const std::string& description );
+    virtual ~ColorDef();
+
+    ColorDef( ColorDef const &other );
+    virtual ColorDef& operator=( ColorDef const &other );
+
+    void setRGB( unsigned int r, unsigned int g, unsigned int b );
+    unsigned int getR() const { return r; }
+    unsigned int getG() const { return g; }
+    unsigned int getB() const { return b; }
+
+    void addCallback( ColorCallback cb, void* data );
+    void removeCallback( ColorCallback cb, void* data );
+
+    bool isEditable() const { return editable; }
+    void setEditable( bool edit ) { editable = edit; }
+
+    std::string descr;
+
+protected:
+    unsigned int r;
+    unsigned int g;
+    unsigned int b;
+    bool none;
+    bool editable;
+
+private:
+    class HookData;
+
+    std::vector<HookData*> _listeners;
+};
+
+
+} // namespace eek
+
+#endif // SEEN_EEK_COLOR_DEF_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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/eek-preview.cpp b/src/widgets/eek-preview.cpp
new file mode 100644 (file)
index 0000000..1c1adf5
--- /dev/null
@@ -0,0 +1,736 @@
+/** @file
+ * @brief EEK preview stuff
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Eek Preview Stuffs.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include "eek-preview.h"
+
+#define PRIME_BUTTON_MAGIC_NUMBER 1
+
+#define FOCUS_PROP_ID 1
+
+/* Keep in sycn with last value in eek-preview.h */
+#define PREVIEW_SIZE_LAST PREVIEW_SIZE_HUGE
+#define PREVIEW_SIZE_NEXTFREE (PREVIEW_SIZE_HUGE + 1)
+
+#define PREVIEW_MAX_RATIO 500
+
+static void eek_preview_class_init( EekPreviewClass *klass );
+static void eek_preview_init( EekPreview *preview );
+
+static GtkWidgetClass* parent_class = 0;
+
+void eek_preview_set_color( EekPreview* preview, int r, int g, int b )
+{
+    preview->_r = r;
+    preview->_g = g;
+    preview->_b = b;
+
+    gtk_widget_queue_draw(GTK_WIDGET(preview));
+}
+
+
+void eek_preview_set_pixbuf( EekPreview* preview, GdkPixbuf* pixbuf )
+{
+    preview->_previewPixbuf = pixbuf;
+
+    gtk_widget_queue_draw(GTK_WIDGET(preview));
+
+    if (preview->_scaled) {
+        g_object_unref(preview->_scaled);
+        preview->_scaled = 0;
+    }
+    preview->_scaledW = gdk_pixbuf_get_width(preview->_previewPixbuf);
+    preview->_scaledH = gdk_pixbuf_get_height(preview->_previewPixbuf);
+}
+
+
+GType eek_preview_get_type(void)
+{
+    static GType preview_type = 0;
+
+    if (!preview_type) {
+      static const GTypeInfo preview_info = {
+          sizeof( EekPreviewClass ),
+          NULL, /* base_init */
+          NULL, /* base_finalize */
+          (GClassInitFunc)eek_preview_class_init,
+          NULL, /* class_finalize */
+          NULL, /* class_data */
+          sizeof( EekPreview ),
+          0,    /* n_preallocs */
+          (GInstanceInitFunc)eek_preview_init,
+          NULL /* value_table */
+      };
+
+
+      preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 );
+    }
+
+    return preview_type;
+}
+
+static gboolean setupDone = FALSE;
+static GtkRequisition sizeThings[PREVIEW_SIZE_NEXTFREE];
+
+void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes )
+{
+    gint width = 0;
+    gint height = 0;
+    gint smallest = 512;
+    gint largest = 0;
+    guint i = 0;
+    guint delta = 0;
+
+    for ( i = 0; i < count; ++i ) {
+        gboolean worked = gtk_icon_size_lookup( sizes[i], &width, &height );
+        if ( worked ) {
+            if ( width < smallest ) {
+                smallest = width;
+            }
+            if ( width > largest ) {
+                largest = width;
+            }
+        }
+    }
+
+    smallest = (smallest * 3) / 4;
+
+    delta = largest - smallest;
+
+    for ( i = 0; i < G_N_ELEMENTS(sizeThings); ++i ) {
+        guint val = smallest + ( (i * delta) / (G_N_ELEMENTS(sizeThings) - 1) );
+        sizeThings[i].width = val;
+        sizeThings[i].height = val;
+    }
+
+    setupDone = TRUE;
+}
+
+static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req )
+{
+    gint width = 0;
+    gint height = 0;
+    EekPreview* preview = EEK_PREVIEW(widget);
+
+    if ( !setupDone ) {
+        GtkIconSize sizes[] = {
+            GTK_ICON_SIZE_MENU,
+            GTK_ICON_SIZE_SMALL_TOOLBAR,
+            GTK_ICON_SIZE_LARGE_TOOLBAR,
+            GTK_ICON_SIZE_BUTTON,
+            GTK_ICON_SIZE_DIALOG
+        };
+        eek_preview_set_size_mappings( G_N_ELEMENTS(sizes), sizes );
+    }
+
+    width = sizeThings[preview->_size].width;
+    height = sizeThings[preview->_size].height;
+
+    if ( preview->_view == VIEW_TYPE_LIST ) {
+        width *= 3;
+    }
+
+    if ( preview->_ratio != 100 ) {
+        width = (width * preview->_ratio) / 100;
+        if ( width < 0 ) {
+            width = 1;
+        }
+    }
+
+    req->width = width;
+    req->height = height;
+}
+
+enum {
+  CLICKED_SIGNAL,
+  ALTCLICKED_SIGNAL,
+  LAST_SIGNAL
+};
+
+
+static guint eek_preview_signals[LAST_SIGNAL] = { 0 };
+
+
+gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event )
+{
+/*     g_message("Exposed!!!   %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */
+    gint insetX = 0;
+    gint insetY = 0;
+
+    (void)event;
+/*
+    gint lower = widget->allocation.width;
+    lower = (widget->allocation.height < lower) ? widget->allocation.height : lower;
+    if ( lower > 16 ) {
+        insetX++;
+        if ( lower > 18 ) {
+            insetX++;
+            if ( lower > 22 ) {
+                insetX++;
+                if ( lower > 24 ) {
+                    insetX++;
+                    if ( lower > 32 ) {
+                        insetX++;
+                    }
+                }
+            }
+        }
+        insetY = insetX;
+    }
+*/
+
+    if ( GTK_WIDGET_DRAWABLE( widget ) ) {
+        GtkStyle* style = gtk_widget_get_style( widget );
+
+        if ( insetX > 0 || insetY > 0 ) {
+            gtk_paint_flat_box( style,
+                                widget->window,
+                                (GtkStateType)GTK_WIDGET_STATE(widget),
+                                GTK_SHADOW_NONE,
+                                NULL,
+                                widget,
+                                NULL,
+                                0, 0,
+                                widget->allocation.width, widget->allocation.height);
+        }
+
+        GdkGC *gc = gdk_gc_new( widget->window );
+        EekPreview* preview = EEK_PREVIEW(widget);
+        GdkColor fg = {0, preview->_r, preview->_g, preview->_b};
+
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE );
+
+        gdk_gc_set_foreground( gc, &fg );
+
+        gdk_draw_rectangle( widget->window,
+                            gc,
+                            TRUE,
+                            insetX, insetY,
+                            widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) );
+
+        if ( preview->_linked ) {
+            /* Draw arrow */
+            GdkRectangle possible = {insetX, insetY, (widget->allocation.width - (insetX * 2)), (widget->allocation.height - (insetY * 2)) };
+            GdkRectangle area = {possible.x, possible.y, possible.width / 2, possible.height / 2 };
+
+            /* Make it square */
+            if ( area.width > area.height )
+                area.width = area.height;
+            if ( area.height > area.width )
+                area.height = area.width;
+
+            /* Center it horizontally */
+            if ( area.width < possible.width ) {
+                int diff = (possible.width - area.width) / 2;
+                area.x += diff;
+            }
+
+
+            if ( preview->_linked & PREVIEW_LINK_IN ) {
+                gtk_paint_arrow( style,
+                                 widget->window,
+                                 (GtkStateType)widget->state,
+                                 GTK_SHADOW_ETCHED_IN,
+                                 NULL, /* clip area.  &area, */
+                                 widget, /* may be NULL */
+                                 NULL, /* detail */
+                                 GTK_ARROW_DOWN,
+                                 FALSE,
+                                 area.x, area.y,
+                                 area.width, area.height
+                                 );
+            }
+
+            if ( preview->_linked & PREVIEW_LINK_OUT ) {
+                GdkRectangle otherArea = {area.x, area.y, area.width, area.height};
+                if ( otherArea.height < possible.height ) {
+                    otherArea.y = possible.y + (possible.height - otherArea.height);
+                }
+
+                gtk_paint_arrow( style,
+                                 widget->window,
+                                 (GtkStateType)widget->state,
+                                 GTK_SHADOW_ETCHED_OUT,
+                                 NULL, /* clip area.  &area, */
+                                 widget, /* may be NULL */
+                                 NULL, /* detail */
+                                 GTK_ARROW_UP,
+                                 FALSE,
+                                 otherArea.x, otherArea.y,
+                                 otherArea.width, otherArea.height
+                                 );
+            }
+
+            if ( preview->_linked & PREVIEW_LINK_OTHER ) {
+                GdkRectangle otherArea = {insetX, area.y, area.width, area.height};
+                if ( otherArea.height < possible.height ) {
+                    otherArea.y = possible.y + (possible.height - otherArea.height) / 2;
+                }
+
+                gtk_paint_arrow( style,
+                                 widget->window,
+                                 (GtkStateType)widget->state,
+                                 GTK_SHADOW_ETCHED_OUT,
+                                 NULL, /* clip area.  &area, */
+                                 widget, /* may be NULL */
+                                 NULL, /* detail */
+                                 GTK_ARROW_LEFT,
+                                 FALSE,
+                                 otherArea.x, otherArea.y,
+                                 otherArea.width, otherArea.height
+                                 );
+            }
+        }
+
+        if ( preview->_previewPixbuf ) {
+            GtkDrawingArea* da = &(preview->drawing);
+            GdkDrawable* drawable = (GdkDrawable*) (((GtkWidget*)da)->window);
+            gint w = 0;
+            gint h = 0;
+            gdk_drawable_get_size(drawable, &w, &h);
+            if ((w != preview->_scaledW) || (h != preview->_scaledH)) {
+                if (preview->_scaled) {
+                    g_object_unref(preview->_scaled);
+                }
+                preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR);
+                preview->_scaledW = w;
+                preview->_scaledH = h;
+            }
+
+            GdkPixbuf* pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf;
+            gdk_draw_pixbuf( drawable, 0, pix, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0 );
+        }
+
+
+        if ( GTK_WIDGET_HAS_FOCUS(widget) ) {
+            gtk_paint_focus( style,
+                             widget->window,
+                             GTK_STATE_NORMAL,
+                             NULL, /* GdkRectangle *area, */
+                             widget,
+                             NULL,
+                             0 + 1, 0 + 1,
+                             widget->allocation.width - 2, widget->allocation.height - 2 );
+        }
+    }
+
+
+    return FALSE;
+}
+
+
+static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event )
+{
+    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
+        EekPreview* preview = EEK_PREVIEW(widget);
+        preview->_within = TRUE;
+        gtk_widget_set_state( widget, preview->_hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT );
+    }
+    return FALSE;
+}
+
+static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event )
+{
+    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
+        EekPreview* preview = EEK_PREVIEW(widget);
+        preview->_within = FALSE;
+        gtk_widget_set_state( widget, GTK_STATE_NORMAL );
+    }
+    return FALSE;
+}
+
+/*
+static gboolean eek_preview_focus_in_event( GtkWidget* widget, GdkEventFocus* event )
+{
+    g_message("focus IN");
+    gboolean blip = parent_class->focus_in_event ? parent_class->focus_in_event(widget, event) : FALSE;
+    return blip;
+}
+
+static gboolean eek_preview_focus_out_event( GtkWidget* widget, GdkEventFocus* event )
+{
+    g_message("focus OUT");
+    gboolean blip = parent_class->focus_out_event ? parent_class->focus_out_event(widget, event) : FALSE;
+    return blip;
+}
+*/
+
+static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* event )
+{
+    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
+        EekPreview* preview = EEK_PREVIEW(widget);
+
+        if ( preview->_takesFocus && !GTK_WIDGET_HAS_FOCUS(widget) ) {
+            gtk_widget_grab_focus(widget);
+        }
+
+        if ( event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
+            preview->_hot = TRUE;
+            if ( preview->_within ) {
+                gtk_widget_set_state( widget, GTK_STATE_ACTIVE );
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton* event )
+{
+    if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) {
+        EekPreview* preview = EEK_PREVIEW(widget);
+        preview->_hot = FALSE;
+        gtk_widget_set_state( widget, GTK_STATE_NORMAL );
+        if ( preview->_within && event->button == PRIME_BUTTON_MAGIC_NUMBER ) {
+            gboolean isAlt = (event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
+
+            if ( isAlt ) {
+                g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 );
+            } else {
+                g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 );
+            }
+        }
+    }
+    return FALSE;
+}
+
+gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event)
+{
+    (void)widget;
+    (void)event;
+    g_message("TICK");
+    return FALSE;
+}
+
+gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event)
+{
+    (void)widget;
+    (void)event;
+    g_message("tock");
+    return FALSE;
+}
+
+static void eek_preview_get_property( GObject *object,
+                                      guint property_id,
+                                      GValue *value,
+                                      GParamSpec *pspec)
+{
+    GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
+    switch ( property_id ) {
+        case FOCUS_PROP_ID:
+        {
+            EekPreview* preview = EEK_PREVIEW( object );
+            g_value_set_boolean( value, preview->_takesFocus );
+        }
+        break;
+        default:
+        {
+            if ( gobjClass->get_property ) {
+                gobjClass->get_property( object, property_id, value, pspec );
+            }
+        }
+    }
+}
+
+static void eek_preview_set_property( GObject *object,
+                                      guint property_id,
+                                      const GValue *value,
+                                      GParamSpec *pspec)
+{
+    GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class);
+    switch ( property_id ) {
+        case FOCUS_PROP_ID:
+        {
+            EekPreview* preview = EEK_PREVIEW( object );
+            gboolean val = g_value_get_boolean( value );
+            if ( val != preview->_takesFocus ) {
+                preview->_takesFocus = val;
+            }
+        }
+        break;
+        default:
+        {
+            if ( gobjClass->set_property ) {
+                gobjClass->set_property( object, property_id, value, pspec );
+            }
+        }
+    }
+}
+
+
+static gboolean eek_preview_popup_menu( GtkWidget* widget )
+{
+/*     g_message("Do the popup!"); */
+    gboolean blip = parent_class->popup_menu ? parent_class->popup_menu(widget) : FALSE;
+    return blip;
+}
+
+
+static void eek_preview_class_init( EekPreviewClass *klass )
+{
+    GObjectClass* gobjClass = G_OBJECT_CLASS(klass);
+    /*GtkObjectClass* objectClass = (GtkObjectClass*)klass;*/
+    GtkWidgetClass* widgetClass = (GtkWidgetClass*)klass;
+
+    gobjClass->set_property = eek_preview_set_property;
+    gobjClass->get_property = eek_preview_get_property;
+
+    /*objectClass->destroy = eek_preview_destroy;*/
+
+    parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass );
+
+    /*widgetClass->map = ;*/
+    /*widgetClass->unmap = ;*/
+    /*widgetClass->realize = ;*/
+    /*widgetClass->unrealize = ;*/
+    widgetClass->size_request = eek_preview_size_request;
+    /*widgetClass->size_allocate = ;*/
+    /*widgetClass->state_changed = ;*/
+    /*widgetClass->style_set = ;*/
+    /*widgetClass->grab_notify = ;*/
+
+    widgetClass->button_press_event = eek_preview_button_press_cb;
+    widgetClass->button_release_event = eek_preview_button_release_cb;
+    /*widgetClass->delete_event = ;*/
+    /*widgetClass->destroy_event = ;*/
+    widgetClass->expose_event = eek_preview_expose_event;
+/*     widgetClass->key_press_event = eek_preview_key_press_event; */
+/*     widgetClass->key_release_event = eek_preview_key_release_event; */
+    widgetClass->enter_notify_event = eek_preview_enter_cb;
+    widgetClass->leave_notify_event = eek_preview_leave_cb;
+    /*widgetClass->configure_event = ;*/
+    /*widgetClass->focus_in_event = eek_preview_focus_in_event;*/
+    /*widgetClass->focus_out_event = eek_preview_focus_out_event;*/
+
+    /* selection */
+    /*widgetClass->selection_get = ;*/
+    /*widgetClass->selection_received = ;*/
+
+
+    /* drag source: */
+    /*widgetClass->drag_begin = ;*/
+    /*widgetClass->drag_end = ;*/
+    /*widgetClass->drag_data_get = ;*/
+    /*widgetClass->drag_data_delete = ;*/
+
+    /* drag target: */
+    /*widgetClass->drag_leave = ;*/
+    /*widgetClass->drag_motion = ;*/
+    /*widgetClass->drag_drop = ;*/
+    /*widgetClass->drag_data_received = ;*/
+
+    /* For keybindings: */
+    widgetClass->popup_menu = eek_preview_popup_menu;
+    /*widgetClass->show_help = ;*/
+
+    /* Accessibility support: */
+    /*widgetClass->get_accessible = ;*/
+    /*widgetClass->screen_changed = ;*/
+    /*widgetClass->can_activate_accel = ;*/
+
+
+    eek_preview_signals[CLICKED_SIGNAL] =
+        g_signal_new( "clicked",
+                      G_TYPE_FROM_CLASS( klass ),
+                      (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+                      G_STRUCT_OFFSET( EekPreviewClass, clicked ),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 );
+
+    eek_preview_signals[ALTCLICKED_SIGNAL] =
+        g_signal_new( "alt-clicked",
+                      G_TYPE_FROM_CLASS( klass ),
+                      (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
+                      G_STRUCT_OFFSET( EekPreviewClass, clicked ),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
+                      1, G_TYPE_INT );
+
+
+    g_object_class_install_property( gobjClass,
+                                     FOCUS_PROP_ID,
+                                     g_param_spec_boolean(
+                                         "focus-on-click",
+                                         NULL,
+                                         "flag to grab focus when clicked",
+                                         TRUE,
+                                         (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT)
+                                         )
+        );
+}
+
+void eek_preview_set_linked( EekPreview* splat, LinkType link )
+{
+    link = (LinkType)(link & PREVIEW_LINK_ALL);
+    if ( link != (LinkType)splat->_linked ) {
+        splat->_linked = link;
+
+        gtk_widget_queue_draw( GTK_WIDGET(splat) );
+    }
+}
+
+LinkType eek_preview_get_linked( EekPreview* splat )
+{
+    return (LinkType)splat->_linked;
+}
+
+gboolean eek_preview_get_focus_on_click( EekPreview* preview )
+{
+    return preview->_takesFocus;
+}
+
+void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click )
+{
+    if ( focus_on_click != preview->_takesFocus ) {
+        preview->_takesFocus = focus_on_click;
+    }
+}
+
+void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio )
+{
+    preview->_prevstyle = prevstyle;
+    preview->_view = view;
+
+    if ( size > PREVIEW_SIZE_LAST ) {
+        size = PREVIEW_SIZE_LAST;
+    }
+    preview->_size = size;
+
+    if ( ratio > PREVIEW_MAX_RATIO ) {
+        ratio = PREVIEW_MAX_RATIO;
+    }
+    preview->_ratio = ratio;
+
+    gtk_widget_queue_draw(GTK_WIDGET(preview));
+}
+
+static void eek_preview_init( EekPreview *preview )
+{
+    GtkWidget* widg = GTK_WIDGET(preview);
+    GTK_WIDGET_SET_FLAGS( widg, GTK_CAN_FOCUS );
+    GTK_WIDGET_SET_FLAGS( widg, GTK_RECEIVES_DEFAULT );
+
+    gtk_widget_set_sensitive( widg, TRUE );
+
+    gtk_widget_add_events(widg, GDK_BUTTON_PRESS_MASK
+                          | GDK_BUTTON_RELEASE_MASK
+                          | GDK_KEY_PRESS_MASK
+                          | GDK_KEY_RELEASE_MASK
+                          | GDK_FOCUS_CHANGE_MASK
+                          | GDK_ENTER_NOTIFY_MASK
+                          | GDK_LEAVE_NOTIFY_MASK );
+
+/*    gtk_widget_add_events( widg, GDK_ALL_EVENTS_MASK );*/
+
+    preview->_r = 0x80;
+    preview->_g = 0x80;
+    preview->_b = 0xcc;
+    preview->_scaledW = 0;
+    preview->_scaledH = 0;
+
+    preview->_hot = FALSE;
+    preview->_within = FALSE;
+    preview->_takesFocus = FALSE;
+
+    preview->_prevstyle = PREVIEW_STYLE_ICON;
+    preview->_view = VIEW_TYPE_LIST;
+    preview->_size = PREVIEW_SIZE_SMALL;
+    preview->_ratio = 100;
+
+    preview->_previewPixbuf = 0;
+    preview->_scaled = 0;
+
+/*
+    GdkColor color = {0};
+    color.red = (255 << 8) | 255;
+
+    GdkColor whack = {0};
+    whack.green = (255 << 8) | 255;
+
+    gtk_widget_modify_bg( widg, GTK_STATE_NORMAL, &color );
+    gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &whack );
+*/
+
+/*   GTK_STATE_ACTIVE, */
+/*   GTK_STATE_PRELIGHT, */
+/*   GTK_STATE_SELECTED, */
+/*   GTK_STATE_INSENSITIVE */
+
+    if ( 0 ) {
+        GdkColor color = {0,0,0,0};
+
+        color.red = 0xffff;
+        color.green = 0;
+        color.blue = 0xffff;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color);
+
+        color.red = 0;
+        color.green = 0xffff;
+        color.blue = 0;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color);
+
+        color.red = 0xffff;
+        color.green = 0;
+        color.blue = 0;
+        gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE );
+        gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color );
+    }
+}
+
+
+GtkWidget* eek_preview_new(void)
+{
+    return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) );
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/eek-preview.h b/src/widgets/eek-preview.h
new file mode 100644 (file)
index 0000000..6eb5c89
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file
+ * @brief EEK preview stuff
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Eek Preview Stuffs.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2005-2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef SEEN_EEK_PREVIEW_H
+#define SEEN_EEK_PREVIEW_H
+
+#include <gdk/gdkpixbuf.h>
+#include <gtk/gtkdrawingarea.h>
+
+G_BEGIN_DECLS
+
+
+#define EEK_PREVIEW_TYPE            (eek_preview_get_type())
+#define EEK_PREVIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST( (obj), EEK_PREVIEW_TYPE, EekPreview))
+#define EEK_PREVIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST( (klass), EEK_PREVIEW_TYPE, EekPreviewClass))
+#define IS_EEK_PREVIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE( (obj), EEK_PREVIEW_TYPE))
+#define IS_EEK_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE( (klass), EEK_PREVIEW_TYPE))
+#define EEK_PREVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS( (obj), EEK_PREVIEW_TYPE, EekPreviewClass))
+
+typedef enum {
+    PREVIEW_STYLE_ICON = 0,
+    PREVIEW_STYLE_PREVIEW,
+    PREVIEW_STYLE_NAME,
+    PREVIEW_STYLE_BLURB,
+    PREVIEW_STYLE_ICON_NAME,
+    PREVIEW_STYLE_ICON_BLURB,
+    PREVIEW_STYLE_PREVIEW_NAME,
+    PREVIEW_STYLE_PREVIEW_BLURB
+} PreviewStyle;
+
+typedef enum {
+    VIEW_TYPE_LIST = 0,
+    VIEW_TYPE_GRID
+} ViewType;
+
+typedef enum {
+    PREVIEW_SIZE_TINY = 0,
+    PREVIEW_SIZE_SMALL,
+    PREVIEW_SIZE_MEDIUM,
+    PREVIEW_SIZE_BIG,
+    PREVIEW_SIZE_BIGGER,
+    PREVIEW_SIZE_HUGE
+} PreviewSize;
+
+typedef enum {
+  PREVIEW_LINK_NONE = 0,
+  PREVIEW_LINK_IN = 1,
+  PREVIEW_LINK_OUT = 2,
+  PREVIEW_LINK_OTHER = 4,
+  PREVIEW_LINK_ALL = 7
+} LinkType;
+
+typedef struct _EekPreview       EekPreview;
+typedef struct _EekPreviewClass  EekPreviewClass;
+
+
+struct _EekPreview
+{
+    GtkDrawingArea drawing;
+
+    int _r;
+    int _g;
+    int _b;
+    int _scaledW;
+    int _scaledH;
+
+    gboolean _hot;
+    gboolean _within;
+    gboolean _takesFocus;
+
+    PreviewStyle _prevstyle;
+    ViewType _view;
+    PreviewSize _size;
+    guint _ratio;
+    guint _linked;
+    GdkPixbuf* _previewPixbuf;
+    GdkPixbuf* _scaled;
+};
+
+struct _EekPreviewClass
+{
+    GtkDrawingAreaClass parent_class;
+
+    void (*clicked) (EekPreview* splat);
+};
+
+
+GType      eek_preview_get_type(void) G_GNUC_CONST;
+GtkWidget* eek_preview_new(void);
+
+void eek_preview_set_details( EekPreview* splat, PreviewStyle prevstyle, ViewType view, PreviewSize size, guint ratio );
+void eek_preview_set_color( EekPreview* splat, int r, int g, int b );
+void eek_preview_set_pixbuf( EekPreview* splat, GdkPixbuf* pixbuf );
+
+void eek_preview_set_linked( EekPreview* splat, LinkType link );
+LinkType eek_preview_get_linked( EekPreview* splat );
+
+gboolean eek_preview_get_focus_on_click( EekPreview* preview );
+void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click );
+
+void eek_preview_set_size_mappings( guint count, GtkIconSize const* sizes );
+
+G_END_DECLS
+
+#endif /* SEEN_EEK_PREVIEW_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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp
new file mode 100644 (file)
index 0000000..5e9d30b
--- /dev/null
@@ -0,0 +1,552 @@
+/** @file
+ * @brief  Fill style widget
+ */
+/* Authors:
+ *   Lauris Kaplinski <lauris@kaplinski.com>
+ *   Frank Felfe <innerspace@iname.com>
+ *   bulia byak <buliabyak@users.sf.net>
+ *
+ * Copyright (C) 1999-2005 authors
+ * Copyright (C) 2001-2002 Ximian, Inc.
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#define noSP_FS_VERBOSE
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glibmm/i18n.h>
+
+#include "desktop-handles.h"
+#include "desktop-style.h"
+#include "display/sp-canvas.h"
+#include "document-private.h"
+#include "gradient-chemistry.h"
+#include "inkscape.h"
+#include "selection.h"
+#include "sp-linear-gradient.h"
+#include "sp-pattern.h"
+#include "sp-radial-gradient.h"
+#include "style.h"
+#include "widgets/paint-selector.h"
+#include "widgets/sp-widget.h"
+#include "xml/repr.h"
+
+#include "widgets/fill-style.h"
+
+
+// These can be deleted once we sort out the libart dependence.
+
+#define ART_WIND_RULE_NONZERO 0
+
+static void sp_fill_style_widget_construct          ( SPWidget *spw,
+                                                      SPPaintSelector *psel );
+
+static void sp_fill_style_widget_modify_selection   ( SPWidget *spw,
+                                                      Inkscape::Selection *selection,
+                                                      guint flags,
+                                                      SPPaintSelector *psel );
+
+static void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
+
+static void sp_fill_style_widget_change_selection   ( SPWidget *spw,
+                                                      Inkscape::Selection *selection,
+                                                      SPPaintSelector *psel );
+
+static void sp_fill_style_widget_update (SPWidget *spw);
+
+static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
+                                                      SPPaintSelectorMode mode,
+                                                      SPWidget *spw );
+static void sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel,
+                                          SPPaintSelectorFillRule mode,
+                                                    SPWidget *spw );
+
+static void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw );
+static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw );
+
+GtkWidget *
+sp_fill_style_widget_new (void)
+{
+    GtkWidget *spw = sp_widget_new_global (INKSCAPE);
+
+    GtkWidget *vb = gtk_vbox_new (FALSE, 0);
+    gtk_widget_show (vb);
+    gtk_container_add (GTK_CONTAINER (spw), vb);
+
+    GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector
+    gtk_widget_show (psel);
+    gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
+    g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
+
+    g_signal_connect ( G_OBJECT (psel), "mode_changed",
+                       G_CALLBACK (sp_fill_style_widget_paint_mode_changed),
+                       spw );
+
+    g_signal_connect ( G_OBJECT (psel), "dragged",
+                       G_CALLBACK (sp_fill_style_widget_paint_dragged),
+                       spw );
+
+    g_signal_connect ( G_OBJECT (psel), "changed",
+                       G_CALLBACK (sp_fill_style_widget_paint_changed),
+                       spw );
+
+    g_signal_connect ( G_OBJECT (psel), "fillrule_changed",
+                       G_CALLBACK (sp_fill_style_widget_fillrule_changed),
+                       spw );
+
+
+    g_signal_connect ( G_OBJECT (spw), "construct",
+                       G_CALLBACK (sp_fill_style_widget_construct), psel);
+
+//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
+//those anyway; then eliminate spw
+    g_signal_connect ( G_OBJECT (spw), "modify_selection",
+                       G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
+
+    g_signal_connect ( G_OBJECT (spw), "change_selection",
+                       G_CALLBACK (sp_fill_style_widget_change_selection), psel);
+
+    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw);
+
+    sp_fill_style_widget_update (SP_WIDGET (spw));
+
+    return spw;
+
+} // end of sp_fill_style_widget_new()
+
+
+
+static void
+sp_fill_style_widget_construct( SPWidget *spw, SPPaintSelector */*psel*/ )
+{
+#ifdef SP_FS_VERBOSE
+    g_print ( "Fill style widget constructed: inkscape %p repr %p\n",
+              spw->inkscape, spw->repr );
+#endif
+    if (spw->inkscape) {
+        sp_fill_style_widget_update (spw);
+    }
+
+} // end of sp_fill_style_widget_construct()
+
+static void
+sp_fill_style_widget_modify_selection( SPWidget *spw,
+                                       Inkscape::Selection */*selection*/,
+                                       guint flags,
+                                       SPPaintSelector */*psel*/ )
+{
+    if (flags & ( SP_OBJECT_MODIFIED_FLAG |
+                  SP_OBJECT_PARENT_MODIFIED_FLAG |
+                  SP_OBJECT_STYLE_MODIFIED_FLAG) )
+    {
+        sp_fill_style_widget_update (spw);
+    }
+}
+
+static void
+sp_fill_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
+                                          SPDesktop */*desktop*/,
+                                          SPWidget *spw )
+{
+    sp_fill_style_widget_update (spw);
+}
+
+static void
+sp_fill_style_widget_change_selection( SPWidget *spw,
+                                       Inkscape::Selection */*selection*/,
+                                       SPPaintSelector */*psel*/ )
+{
+    sp_fill_style_widget_update (spw);
+}
+
+/**
+* \param sel Selection to use, or NULL.
+*/
+static void
+sp_fill_style_widget_update (SPWidget *spw)
+{
+    if (g_object_get_data (G_OBJECT (spw), "update"))
+        return;
+
+    if (g_object_get_data (G_OBJECT (spw), "local")) {
+        g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag
+        return;
+    }
+
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
+
+    SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
+
+    // create temporary style
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
+    // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
+    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); 
+
+    switch (result) {
+        case QUERY_STYLE_NOTHING:
+        {
+            /* No paint at all */
+            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
+            break;
+        }
+
+        case QUERY_STYLE_SINGLE:
+        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
+        case QUERY_STYLE_MULTIPLE_SAME: 
+        {
+            SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, true);
+            sp_paint_selector_set_mode (psel, pselmode);
+
+            sp_paint_selector_set_fillrule (psel, query->fill_rule.computed == ART_WIND_RULE_NONZERO? 
+                                     SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD);
+
+            if (query->fill.set && query->fill.isColor()) {
+                sp_paint_selector_set_color_alpha (psel, &query->fill.value.color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
+            } else if (query->fill.set && query->fill.isPaintserver()) {
+
+                SPPaintServer *server = SP_STYLE_FILL_SERVER (query);
+
+                if (SP_IS_LINEARGRADIENT (server)) {
+                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
+                    sp_paint_selector_set_gradient_linear (psel, vector);
+
+                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
+                    sp_paint_selector_set_gradient_properties (psel,
+                                                       SP_GRADIENT_UNITS (lg),
+                                                       SP_GRADIENT_SPREAD (lg));
+                } else if (SP_IS_RADIALGRADIENT (server)) {
+                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
+                    sp_paint_selector_set_gradient_radial (psel, vector);
+
+                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
+                    sp_paint_selector_set_gradient_properties (psel,
+                                                       SP_GRADIENT_UNITS (rg),
+                                                       SP_GRADIENT_SPREAD (rg));
+                } else if (SP_IS_PATTERN (server)) {
+                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
+                    sp_update_pattern_list (psel, pat);
+                }
+            }
+            break;
+        }
+
+        case QUERY_STYLE_MULTIPLE_DIFFERENT:
+        {
+            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
+            break;
+        }
+    }
+
+    sp_style_unref(query);
+
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
+
+}
+
+
+static void
+sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
+                                          SPPaintSelectorMode /*mode*/,
+                                          SPWidget *spw )
+{
+    if (g_object_get_data (G_OBJECT (spw), "update"))
+        return;
+
+    /* TODO: Does this work? */
+    /* TODO: Not really, here we have to get old color back from object */
+    /* Instead of relying on paint widget having meaningful colors set */
+    sp_fill_style_widget_paint_changed (psel, spw);
+}
+
+static void
+sp_fill_style_widget_fillrule_changed ( SPPaintSelector */*psel*/,
+                                          SPPaintSelectorFillRule mode,
+                                          SPWidget *spw )
+{
+    if (g_object_get_data (G_OBJECT (spw), "update"))
+        return;
+
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+
+    SPCSSAttr *css = sp_repr_css_attr_new ();
+    sp_repr_css_set_property (css, "fill-rule", mode == SP_PAINT_SELECTOR_FILLRULE_EVENODD? "evenodd":"nonzero");
+
+    sp_desktop_set_style (desktop, css);
+
+    sp_repr_css_attr_unref (css);
+
+    sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, 
+                      _("Change fill rule"));
+}
+
+static gchar const *undo_label_1 = "fill:flatcolor:1";
+static gchar const *undo_label_2 = "fill:flatcolor:2";
+static gchar const *undo_label = undo_label_1;
+
+/**
+This is called repeatedly while you are dragging a color slider, only for flat color
+modes. Previously it set the color in style but did not update the repr for efficiency, however
+this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
+lumps all its changes for undo.
+ */
+static void
+sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
+{
+    if (!spw->inkscape) {
+        return;
+    }
+
+    if (g_object_get_data (G_OBJECT (spw), "update")) {
+        return;
+    }
+
+    if (g_object_get_data (G_OBJECT (spw), "local")) {
+        // previous local flag not cleared yet; 
+        // this means dragged events come too fast, so we better skip this one to speed up display 
+        // (it's safe to do this in any case)
+        return;
+    }
+
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
+
+    switch (psel->mode) {
+
+        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
+        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
+        {
+            sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "fill", "fill-opacity");
+            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE, 
+                                    _("Set fill color"));
+            g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection
+            break;
+        }
+
+        default:
+            g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
+                        __FILE__, __LINE__, psel->mode );
+            break;
+
+    }
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
+}
+
+
+/**
+This is called (at least) when:
+1  paint selector mode is switched (e.g. flat color -> gradient)
+2  you finished dragging a gradient node and released mouse
+3  you changed a gradient selector parameter (e.g. spread)
+Must update repr.
+ */
+static void
+sp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
+                                     SPWidget *spw )
+{
+    if (g_object_get_data (G_OBJECT (spw), "update")) {
+        return;
+    }
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
+
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (!desktop) {
+        return;
+    }
+    SPDocument *document = sp_desktop_document (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+    GSList const *items = selection->itemList();
+
+    switch (psel->mode) {
+
+        case SP_PAINT_SELECTOR_MODE_EMPTY:
+            // This should not happen.
+            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
+                        __FILE__, __LINE__, psel->mode);
+            break;
+        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
+            // This happens when you switch multiple objects with different gradients to flat color;
+            // nothing to do here.
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_NONE:
+        {
+            SPCSSAttr *css = sp_repr_css_attr_new ();
+            sp_repr_css_set_property (css, "fill", "none");
+
+            sp_desktop_set_style (desktop, css);
+
+            sp_repr_css_attr_unref (css);
+
+            sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
+                              _("Remove fill"));
+            break;
+        }
+
+        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
+        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
+        {
+            // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
+            sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
+
+            sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity");
+            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
+                                    _("Set fill color"));
+            // resume interruptibility
+            sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
+
+            // on release, toggle undo_label so that the next drag will not be lumped with this one
+            if (undo_label == undo_label_1)
+                undo_label = undo_label_2;
+            else
+                undo_label = undo_label_1;
+
+            break;
+        }
+
+        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
+        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
+            if (items) {
+                SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
+                                                       ? SP_GRADIENT_TYPE_LINEAR
+                                                       : SP_GRADIENT_TYPE_RADIAL );
+
+                // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
+                SPCSSAttr *css = sp_repr_css_attr_new();
+                sp_repr_css_set_property(css, "fill-opacity", "1.0");
+
+                SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
+                if (!vector) {
+                    /* No vector in paint selector should mean that we just changed mode */
+
+                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
+                    int result = objects_query_fillstroke ((GSList *) items, query, true);
+                    guint32 common_rgb = 0;
+                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
+                        if (!query->fill.isColor()) {
+                            common_rgb = sp_desktop_get_color(desktop, true);
+                        } else {
+                            common_rgb = query->fill.value.color.toRGBA32( 0xff );
+                        }
+                        vector = sp_document_default_gradient_vector(document, common_rgb);
+                    }
+                    sp_style_unref(query);
+
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                        //FIXME: see above
+                        sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
+
+                        if (!vector) {
+                            sp_item_set_gradient(SP_ITEM(i->data),
+                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true),
+                                                 gradient_type, true);
+                        } else {
+                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
+                        }
+                    }
+                } else {
+                    /* We have changed from another gradient type, or modified spread/units within
+                     * this gradient type. */
+                    vector = sp_gradient_ensure_vector_normalized (vector);
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                        //FIXME: see above
+                        sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style");
+
+                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
+                        sp_gradient_selector_attrs_to_gradient (gr, psel);
+                    }
+                }
+
+                sp_repr_css_attr_unref (css);
+
+                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
+                                  _("Set gradient on fill"));
+            }
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_PATTERN:
+
+            if (items) {
+
+                SPPattern *pattern = sp_paint_selector_get_pattern (psel);
+                if (!pattern) {
+
+                    /* No Pattern in paint selector should mean that we just
+                     * changed mode - dont do jack.
+                     */
+
+                } else {
+                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
+                    SPCSSAttr *css = sp_repr_css_attr_new ();
+                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
+                    sp_repr_css_set_property (css, "fill", urltext);
+
+                    // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
+                    sp_repr_css_set_property(css, "fill-opacity", "1.0");
+
+                    // cannot just call sp_desktop_set_style, because we don't want to touch those
+                    // objects who already have the same root pattern but through a different href
+                    // chain. FIXME: move this to a sp_item_set_pattern
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                         SPObject *selobj = SP_OBJECT (i->data);
+
+                         SPStyle *style = SP_OBJECT_STYLE (selobj);
+                         if (style && style->fill.isPaintserver()) {
+                             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj);
+                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
+                                // only if this object's pattern is not rooted in our selected pattern, apply
+                                 continue;
+                         }
+
+                         sp_desktop_apply_css_recursive (selobj, css, true);
+                     }
+
+                    sp_repr_css_attr_unref (css);
+                    g_free (urltext);
+
+                } // end if
+
+                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
+                                  _("Set pattern on fill"));
+
+            } // end if
+
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_UNSET:
+            if (items) {
+                    SPCSSAttr *css = sp_repr_css_attr_new ();
+                    sp_repr_css_unset_property (css, "fill");
+
+                    sp_desktop_set_style (desktop, css);
+                    sp_repr_css_attr_unref (css);
+
+                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
+                                      _("Unset fill"));
+            }
+            break;
+
+        default:
+            g_warning ( "file %s: line %d: Paint selector should not be in "
+                        "mode %d",
+                        __FILE__, __LINE__, psel->mode );
+            break;
+    }
+
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
+}
+
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/fill-style.h b/src/widgets/fill-style.h
new file mode 100644 (file)
index 0000000..3924412
--- /dev/null
@@ -0,0 +1,33 @@
+/** @file
+ * @brief  Fill style configuration
+ */
+/* Authors:
+ *   Lauris Kaplinski <lauris@kaplinski.com>
+ *
+ * Copyright (C) 2002 Lauris Kaplinski
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_DIALOGS_SP_FILL_STYLE_H
+#define SEEN_DIALOGS_SP_FILL_STYLE_H
+
+#include <glib.h>
+#include <gtk/gtkwidget.h>
+#include "forward.h"
+
+
+GtkWidget *sp_fill_style_widget_new (void);
+
+#endif
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/layer-selector.cpp b/src/widgets/layer-selector.cpp
deleted file mode 100644 (file)
index d51b31e..0000000
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * Inkscape::Widgets::LayerSelector - layer selector widget
- *
- * Authors:
- *   MenTaLguY <mental@rydia.net>
- *
- * Copyright (C) 2004 MenTaLguY
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <cstring>
-#include <string>
-#include <glibmm/i18n.h>
-
-#include "desktop-handles.h"
-
-#include "widgets/layer-selector.h"
-#include "widgets/shrink-wrap-button.h"
-#include "widgets/icon.h"
-
-#include "util/reverse-list.h"
-#include "util/filter-list.h"
-
-#include "sp-item.h"
-#include "desktop.h"
-#include "document.h"
-#include "dialogs/layer-properties.h"
-#include "layer-manager.h"
-#include "xml/node-event-vector.h"
-#include "verbs.h"
-
-namespace Inkscape {
-namespace Widgets {
-
-namespace {
-
-class AlternateIcons : public Gtk::HBox {
-public:
-    AlternateIcons(Inkscape::IconSize size, gchar const *a, gchar const *b)
-    : _a(NULL), _b(NULL)
-    {
-        if (a) {
-            _a = Gtk::manage(sp_icon_get_icon(a, size));
-            _a->set_no_show_all(true);
-            add(*_a);
-        }
-        if (b) {
-            _b = Gtk::manage(sp_icon_get_icon(b, size));
-            _b->set_no_show_all(true);
-            add(*_b);
-        }
-        setState(false);
-    }
-
-    bool state() const { return _state; }
-    void setState(bool state) {
-        _state = state;
-        if (_state) {
-            if (_a) {
-                _a->hide();
-            }
-            if (_b) {
-                _b->show();
-            }
-        } else {
-            if (_a) {
-                _a->show();
-            }
-            if (_b) {
-                _b->hide();
-            }
-        }
-    }
-
-private:
-    Gtk::Widget *_a;
-    Gtk::Widget *_b;
-    bool _state;
-};
-
-}
-
-/** LayerSelector constructor.  Creates lock and hide buttons,
- *  initalizes the layer dropdown selector with a label renderer,
- *  and hooks up signal for setting the desktop layer when the
- *  selector is changed.
- */
-LayerSelector::LayerSelector(SPDesktop *desktop)
-: _desktop(NULL), _layer(NULL)
-{
-    AlternateIcons *label;
-
-    label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "visible", "hidden"));
-    _visibility_toggle.add(*label);
-    _visibility_toggle.signal_toggled().connect(
-        sigc::compose(
-            sigc::mem_fun(*label, &AlternateIcons::setState),
-            sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active)
-        )
-    );
-    _visibility_toggled_connection = _visibility_toggle.signal_toggled().connect(
-        sigc::compose(
-            sigc::mem_fun(*this, &LayerSelector::_hideLayer),
-            sigc::mem_fun(_visibility_toggle, &Gtk::ToggleButton::get_active)
-        )
-    );
-
-    _visibility_toggle.set_relief(Gtk::RELIEF_NONE);
-    shrink_wrap_button(_visibility_toggle);
-    _tooltips.set_tip(_visibility_toggle, _("Toggle current layer visibility"));
-    pack_start(_visibility_toggle, Gtk::PACK_EXPAND_PADDING);
-
-    label = Gtk::manage(new AlternateIcons(Inkscape::ICON_SIZE_DECORATION, "lock_unlocked", "width_height_lock"));
-    _lock_toggle.add(*label);
-    _lock_toggle.signal_toggled().connect(
-        sigc::compose(
-            sigc::mem_fun(*label, &AlternateIcons::setState),
-            sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active)
-        )
-    );
-    _lock_toggled_connection = _lock_toggle.signal_toggled().connect(
-        sigc::compose(
-            sigc::mem_fun(*this, &LayerSelector::_lockLayer),
-            sigc::mem_fun(_lock_toggle, &Gtk::ToggleButton::get_active)
-        )
-    );
-
-    _lock_toggle.set_relief(Gtk::RELIEF_NONE);
-    shrink_wrap_button(_lock_toggle);
-    _tooltips.set_tip(_lock_toggle, _("Lock or unlock current layer"));
-    pack_start(_lock_toggle, Gtk::PACK_EXPAND_PADDING);
-
-    _tooltips.set_tip(_selector, _("Current layer"));
-    pack_start(_selector, Gtk::PACK_EXPAND_WIDGET);
-
-    _layer_model = Gtk::ListStore::create(_model_columns);
-    _selector.set_model(_layer_model);
-    _selector.pack_start(_label_renderer);
-    _selector.set_cell_data_func(
-        _label_renderer,
-        sigc::mem_fun(*this, &LayerSelector::_prepareLabelRenderer)
-    );
-
-    _selection_changed_connection = _selector.signal_changed().connect(
-        sigc::mem_fun(*this, &LayerSelector::_setDesktopLayer)
-    );
-    setDesktop(desktop);
-}
-
-/**  Destructor - disconnects signal handler
- */
-LayerSelector::~LayerSelector() {
-    setDesktop(NULL);
-    _selection_changed_connection.disconnect();
-}
-
-namespace {
-
-/** Helper function - detaches desktop from selector
- */
-bool detach(LayerSelector *selector) {
-    selector->setDesktop(NULL);
-    return FALSE;
-}
-
-}
-
-/** Sets the desktop for the widget.  First disconnects signals
- *  for the current desktop, then stores the pointer to the
- *  given \a desktop, and attaches its signals to this one.
- *  Then it selects the current layer for the desktop.
- */
-void LayerSelector::setDesktop(SPDesktop *desktop) {
-    if ( desktop == _desktop ) {
-        return;
-    }
-
-    if (_desktop) {
-//        _desktop_shutdown_connection.disconnect();
-        _layer_changed_connection.disconnect();
-//        g_signal_handlers_disconnect_by_func(_desktop, (gpointer)&detach, this);
-    }
-    _desktop = desktop;
-    if (_desktop) {
-        // TODO we need a different signal for this, really..s
-//        _desktop_shutdown_connection = _desktop->connectShutdown(
-//          sigc::bind (sigc::ptr_fun (detach), this));
-//        g_signal_connect_after(_desktop, "shutdown", GCallback(detach), this);
-
-        _layer_changed_connection = _desktop->connectCurrentLayerChanged(
-            sigc::mem_fun(*this, &LayerSelector::_selectLayer)
-        );
-        _selectLayer(_desktop->currentLayer());
-    }
-}
-
-namespace {
-
-class is_layer {
-public:
-    is_layer(SPDesktop *desktop) : _desktop(desktop) {}
-    bool operator()(SPObject &object) const {
-        return _desktop->isLayer(&object);
-    }
-private:
-    SPDesktop *_desktop;
-};
-
-class column_matches_object {
-public:
-    column_matches_object(Gtk::TreeModelColumn<SPObject *> const &column,
-                          SPObject &object)
-    : _column(column), _object(object) {}
-    bool operator()(Gtk::TreeModel::const_iterator const &iter) const {
-        SPObject *current=(*iter)[_column];
-        return current == &_object;
-    }
-private:
-    Gtk::TreeModelColumn<SPObject *> const &_column;
-    SPObject &_object;
-};
-
-}
-
-/** Selects the given layer in the dropdown selector.
- */
-void LayerSelector::_selectLayer(SPObject *layer) {
-    using Inkscape::Util::List;
-    using Inkscape::Util::cons;
-    using Inkscape::Util::reverse_list;
-
-    _selection_changed_connection.block();
-
-    while (!_layer_model->children().empty()) {
-        Gtk::ListStore::iterator first_row(_layer_model->children().begin());
-        _destroyEntry(first_row);
-        _layer_model->erase(first_row);
-    }
-
-    SPObject *root=_desktop->currentRoot();
-
-    if (_layer) {
-        sp_object_unref(_layer, NULL);
-        _layer = NULL;
-    }
-
-    if (layer) {
-        List<SPObject &> hierarchy=reverse_list<SPObject::ParentIterator>(layer, root);
-        if ( layer == root ) {
-            _buildEntries(0, cons(*root, hierarchy));
-        } else if (hierarchy) {
-            _buildSiblingEntries(0, *root, hierarchy);
-        }
-
-        Gtk::TreeIter row(
-            std::find_if(
-                _layer_model->children().begin(),
-                _layer_model->children().end(),
-                column_matches_object(_model_columns.object, *layer)
-            )
-        );
-        if ( row != _layer_model->children().end() ) {
-            _selector.set_active(row);
-        }
-
-        _layer = layer;
-        sp_object_ref(_layer, NULL);
-    }
-
-    if ( !layer || layer == root ) {
-        _visibility_toggle.set_sensitive(false);
-        _visibility_toggle.set_active(false);
-        _lock_toggle.set_sensitive(false);
-        _lock_toggle.set_active(false);
-    } else {
-        _visibility_toggle.set_sensitive(true);
-        _visibility_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false ));
-        _lock_toggle.set_sensitive(true);
-        _lock_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false ));
-    }
-
-    _selection_changed_connection.unblock();
-}
-
-/** Sets the current desktop layer to the actively selected layer.
- */
-void LayerSelector::_setDesktopLayer() {
-    Gtk::ListStore::iterator selected(_selector.get_active());
-    SPObject *layer=_selector.get_active()->get_value(_model_columns.object);
-    if ( _desktop && layer ) {
-        _layer_changed_connection.block();
-
-        _desktop->layer_manager->setCurrentLayer(layer);
-
-        _layer_changed_connection.unblock();
-
-        _selectLayer(_desktop->currentLayer());
-    }
-    if (_desktop && _desktop->canvas) {
-        gtk_widget_grab_focus (GTK_WIDGET(_desktop->canvas));
-    }
-}
-
-/** Creates rows in the _layer_model data structure for each item
- *  in \a hierarchy, to a given \a depth.
- */
-void LayerSelector::_buildEntries(unsigned depth,
-                                  Inkscape::Util::List<SPObject &> hierarchy)
-{
-    using Inkscape::Util::List;
-    using Inkscape::Util::rest;
-
-    _buildEntry(depth, *hierarchy);
-
-    List<SPObject &> remainder=rest(hierarchy);
-    if (remainder) {
-        _buildEntries(depth+1, remainder);
-    } else {
-        _buildSiblingEntries(depth+1, *hierarchy, remainder);
-    }
-}
-
-/** Creates entries in the _layer_model data structure for
- *  all siblings of the first child in \a parent.
- */
-void LayerSelector::_buildSiblingEntries(
-    unsigned depth, SPObject &parent,
-    Inkscape::Util::List<SPObject &> hierarchy
-) {
-    using Inkscape::Util::List;
-    using Inkscape::Util::rest;
-    using Inkscape::Util::reverse_list_in_place;
-    using Inkscape::Util::filter_list;
-
-    Inkscape::Util::List<SPObject &> siblings(
-        reverse_list_in_place(
-            filter_list<SPObject::SiblingIterator>(
-                is_layer(_desktop), parent.firstChild(), NULL
-            )
-        )
-    );
-
-    SPObject *layer( hierarchy ? &*hierarchy : NULL );
-
-    while (siblings) {
-        _buildEntry(depth, *siblings);
-        if ( &*siblings == layer ) {
-            _buildSiblingEntries(depth+1, *layer, rest(hierarchy));
-        }
-        ++siblings;
-    }
-}
-
-namespace {
-
-struct Callbacks {
-    sigc::slot<void> update_row;
-    sigc::slot<void> update_list;
-};
-
-void attribute_changed(Inkscape::XML::Node */*repr*/, gchar const *name,
-                       gchar const */*old_value*/, gchar const */*new_value*/,
-                       bool /*is_interactive*/, void *data)
-{
-    if ( !std::strcmp(name, "inkscape:groupmode") ) {
-        reinterpret_cast<Callbacks *>(data)->update_list();
-    } else {
-        reinterpret_cast<Callbacks *>(data)->update_row();
-    }
-}
-
-void node_added(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) {
-    gchar const *mode=child->attribute("inkscape:groupmode");
-    if ( mode && !std::strcmp(mode, "layer") ) {
-        reinterpret_cast<Callbacks *>(data)->update_list();
-    }
-}
-
-void node_removed(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child, Inkscape::XML::Node */*ref*/, void *data) {
-    gchar const *mode=child->attribute("inkscape:groupmode");
-    if ( mode && !std::strcmp(mode, "layer") ) {
-        reinterpret_cast<Callbacks *>(data)->update_list();
-    }
-}
-
-void node_reordered(Inkscape::XML::Node */*parent*/, Inkscape::XML::Node *child,
-                    Inkscape::XML::Node */*old_ref*/, Inkscape::XML::Node */*new_ref*/,
-                    void *data)
-{
-    gchar const *mode=child->attribute("inkscape:groupmode");
-    if ( mode && !std::strcmp(mode, "layer") ) {
-        reinterpret_cast<Callbacks *>(data)->update_list();
-    }
-}
-
-void update_row_for_object(SPObject *object,
-                           Gtk::TreeModelColumn<SPObject *> const &column,
-                           Glib::RefPtr<Gtk::ListStore> const &model)
-{
-    Gtk::TreeIter row(
-        std::find_if(
-            model->children().begin(),
-            model->children().end(),
-            column_matches_object(column, *object)
-        )
-    );
-    if ( row != model->children().end() ) {
-        model->row_changed(model->get_path(row), row);
-    }
-}
-
-void rebuild_all_rows(sigc::slot<void, SPObject *> rebuild, SPDesktop *desktop)
-{
-    rebuild(desktop->currentLayer());
-}
-
-}
-
-void LayerSelector::_protectUpdate(sigc::slot<void> slot) {
-    bool visibility_blocked=_visibility_toggled_connection.blocked();
-    bool lock_blocked=_lock_toggled_connection.blocked();
-    _visibility_toggled_connection.block(true);
-    _lock_toggled_connection.block(true);
-    slot();
-
-    SPObject *layer = _desktop ? _desktop->currentLayer() : 0;
-    if ( layer ) {
-        bool wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false );
-        if ( _lock_toggle.get_active() != wantedValue ) {
-            _lock_toggle.set_active( wantedValue );
-        }
-        wantedValue = ( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isHidden() : false );
-        if ( _visibility_toggle.get_active() != wantedValue ) {
-            _visibility_toggle.set_active( wantedValue );
-        }
-    }
-    _visibility_toggled_connection.block(visibility_blocked);
-    _lock_toggled_connection.block(lock_blocked);
-}
-
-/** Builds and appends a row in the layer model object.
- */
-void LayerSelector::_buildEntry(unsigned depth, SPObject &object) {
-    Inkscape::XML::NodeEventVector *vector;
-
-    Callbacks *callbacks=new Callbacks();
-
-    callbacks->update_row = sigc::bind(
-        sigc::mem_fun(*this, &LayerSelector::_protectUpdate),
-        sigc::bind(
-            sigc::ptr_fun(&update_row_for_object),
-            &object, _model_columns.object, _layer_model
-        )
-    );
-
-    SPObject *layer=_desktop->currentLayer();
-    if ( &object == layer || &object == SP_OBJECT_PARENT(layer) ) {
-        callbacks->update_list = sigc::bind(
-            sigc::mem_fun(*this, &LayerSelector::_protectUpdate),
-            sigc::bind(
-                sigc::ptr_fun(&rebuild_all_rows),
-                sigc::mem_fun(*this, &LayerSelector::_selectLayer),
-                _desktop
-            )
-        );
-
-        Inkscape::XML::NodeEventVector events = {
-            &node_added,
-            &node_removed,
-            &attribute_changed,
-            NULL,
-            &node_reordered
-        };
-
-        vector = new Inkscape::XML::NodeEventVector(events);
-    } else {
-        Inkscape::XML::NodeEventVector events = {
-            NULL,
-            NULL,
-            &attribute_changed,
-            NULL,
-            NULL
-        };
-
-        vector = new Inkscape::XML::NodeEventVector(events);
-    }
-
-    Gtk::ListStore::iterator row(_layer_model->append());
-
-    row->set_value(_model_columns.depth, depth);
-
-    sp_object_ref(&object, NULL);
-    row->set_value(_model_columns.object, &object);
-
-    Inkscape::GC::anchor(SP_OBJECT_REPR(&object));
-    row->set_value(_model_columns.repr, SP_OBJECT_REPR(&object));
-
-    row->set_value(_model_columns.callbacks, reinterpret_cast<void *>(callbacks));
-
-    sp_repr_add_listener(SP_OBJECT_REPR(&object), vector, callbacks);
-}
-
-/** Removes a row from the _model_columns object, disconnecting listeners
- *  on the slot.
- */
-void LayerSelector::_destroyEntry(Gtk::ListStore::iterator const &row) {
-    Callbacks *callbacks=reinterpret_cast<Callbacks *>(row->get_value(_model_columns.callbacks));
-    SPObject *object=row->get_value(_model_columns.object);
-    if (object) {
-        sp_object_unref(object, NULL);
-    }
-    Inkscape::XML::Node *repr=row->get_value(_model_columns.repr);
-    if (repr) {
-        sp_repr_remove_listener_by_data(repr, callbacks);
-        Inkscape::GC::release(repr);
-    }
-    delete callbacks;
-}
-
-/** Formats the label for a given layer row
- */
-void LayerSelector::_prepareLabelRenderer(
-    Gtk::TreeModel::const_iterator const &row
-) {
-    unsigned depth=(*row)[_model_columns.depth];
-    SPObject *object=(*row)[_model_columns.object];
-    bool label_defaulted(false);
-
-    // TODO: when the currently selected row is removed,
-    //       (or before one has been selected) something appears to
-    //       "invent" an iterator with null data and try to render it;
-    //       where does it come from, and how can we avoid it?
-    if ( object && SP_OBJECT_REPR(object) ) {
-        SPObject *layer=( _desktop ? _desktop->currentLayer() : NULL );
-        SPObject *root=( _desktop ? _desktop->currentRoot() : NULL );
-
-        bool isancestor = !( (layer && (SP_OBJECT_PARENT(object) == SP_OBJECT_PARENT(layer))) || ((layer == root) && (SP_OBJECT_PARENT(object) == root)));
-
-        bool iscurrent = ( object == layer && object != root );
-
-        gchar *format = g_strdup_printf (
-            "<span size=\"smaller\" %s><tt>%*s%s</tt>%s%s%s%%s%s%s%s</span>",
-            ( _desktop && _desktop->itemIsHidden (SP_ITEM(object)) ? "foreground=\"gray50\"" : "" ),
-            depth, "", ( iscurrent ? "&#8226;" : " " ),
-            ( iscurrent ? "<b>" : "" ),
-            ( SP_ITEM(object)->isLocked() ? "[" : "" ),
-            ( isancestor ? "<small>" : "" ),
-            ( isancestor ? "</small>" : "" ),
-            ( SP_ITEM(object)->isLocked() ? "]" : "" ),
-            ( iscurrent ? "</b>" : "" )
-            );
-
-        gchar const *label;
-        if ( object != root ) {
-            label = object->label();
-            if (!label) {
-                label = object->defaultLabel();
-                label_defaulted = true;
-            }
-        } else {
-            label = _("(root)");
-        }
-
-        gchar *text = g_markup_printf_escaped(format, label);
-        _label_renderer.property_markup() = text;
-        g_free(text);
-        g_free(format);
-    } else {
-        _label_renderer.property_markup() = "<small> </small>";
-    }
-
-    _label_renderer.property_ypad() = 1;
-    _label_renderer.property_style() = ( label_defaulted ?
-                                         Pango::STYLE_ITALIC :
-                                         Pango::STYLE_NORMAL );
-}
-
-void LayerSelector::_lockLayer(bool lock) {
-    if ( _layer && SP_IS_ITEM(_layer) ) {
-        SP_ITEM(_layer)->setLocked(lock);
-        sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE,
-                         lock? _("Lock layer") : _("Unlock layer"));
-    }
-}
-
-void LayerSelector::_hideLayer(bool hide) {
-    if ( _layer && SP_IS_ITEM(_layer) ) {
-        SP_ITEM(_layer)->setHidden(hide);
-        sp_document_done(sp_desktop_document(_desktop), SP_VERB_NONE,
-                         hide? _("Hide layer") : _("Unhide layer"));
-    }
-}
-
-}
-}
-
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/layer-selector.h b/src/widgets/layer-selector.h
deleted file mode 100644 (file)
index 0b53002..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Inkscape::Widgets::LayerSelector - layer selector widget
- *
- * Authors:
- *   MenTaLguY <mental@rydia.net>
- *
- * Copyright (C) 2004 MenTaLguY
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifndef SEEN_INKSCAPE_WIDGETS_LAYER_SELECTOR
-#define SEEN_INKSCAPE_WIDGETS_LAYER_SELECTOR
-
-#include <gtkmm/box.h>
-#include <gtkmm/combobox.h>
-#include <gtkmm/togglebutton.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/cellrenderertext.h>
-#include <gtkmm/treemodel.h>
-#include <gtkmm/liststore.h>
-#include <sigc++/slot.h>
-#include "util/list.h"
-
-class SPDesktop;
-class SPDocument;
-class SPObject;
-namespace Inkscape {
-namespace XML {
-class Node;
-}
-}
-
-
-namespace Inkscape {
-namespace Widgets {
-
-class DocumentTreeModel;
-
-class LayerSelector : public Gtk::HBox {
-public:
-    LayerSelector(SPDesktop *desktop = NULL);
-    ~LayerSelector();
-
-    SPDesktop *desktop() { return _desktop; }
-    void setDesktop(SPDesktop *desktop);
-
-private:
-    class LayerModelColumns : public Gtk::TreeModel::ColumnRecord {
-    public:
-        Gtk::TreeModelColumn<unsigned> depth;
-        Gtk::TreeModelColumn<SPObject *> object;
-        Gtk::TreeModelColumn<Inkscape::XML::Node *> repr;
-        Gtk::TreeModelColumn<void *> callbacks;
-
-        LayerModelColumns() {
-            add(depth); add(object); add(repr); add(callbacks);
-        }
-    };
-
-    SPDesktop *_desktop;
-
-    Gtk::Tooltips _tooltips;
-    Gtk::ComboBox _selector;
-    Gtk::ToggleButton _visibility_toggle;
-    Gtk::ToggleButton _lock_toggle;
-
-    LayerModelColumns _model_columns;
-    Gtk::CellRendererText _label_renderer;
-    Glib::RefPtr<Gtk::ListStore> _layer_model;
-
-//    sigc::connection _desktop_shutdown_connection;
-    sigc::connection _layer_changed_connection;
-    sigc::connection _selection_changed_connection;
-    sigc::connection _visibility_toggled_connection;
-    sigc::connection _lock_toggled_connection;
-
-    SPObject *_layer;
-
-    void _selectLayer(SPObject *layer);
-    void _setDesktopLayer();
-
-    void _buildEntry(unsigned depth, SPObject &object);
-    void _buildEntries(unsigned depth,
-                       Inkscape::Util::List<SPObject &> hierarchy);
-    void _buildSiblingEntries(unsigned depth,
-                              SPObject &parent,
-                              Inkscape::Util::List<SPObject &> hierarchy);
-    void _protectUpdate(sigc::slot<void> slot);
-    void _destroyEntry(Gtk::ListStore::iterator const &row);
-    void _hideLayer(bool hide);
-    void _lockLayer(bool lock);
-
-    void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row);
-};
-
-}
-}
-
-#endif
-/*
-  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-attribute-widget.cpp b/src/widgets/sp-attribute-widget.cpp
new file mode 100644 (file)
index 0000000..de14fc1
--- /dev/null
@@ -0,0 +1,790 @@
+/** @file
+ * @brief Widget that listens and modifies repr attributes
+ */
+/* Authors:
+ *  Lauris Kaplinski <lauris@ximian.com>
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtk/gtktable.h>
+#include <gtk/gtklabel.h>
+#include "xml/repr.h"
+#include "macros.h"
+#include "document.h"
+#include "sp-object.h"
+#include <glibmm/i18n.h>
+
+#include <sigc++/functors/ptr_fun.h>
+#include <sigc++/adaptors/bind.h>
+
+#include "sp-attribute-widget.h"
+
+static void sp_attribute_widget_class_init (SPAttributeWidgetClass *klass);
+static void sp_attribute_widget_init (SPAttributeWidget *widget);
+static void sp_attribute_widget_destroy (GtkObject *object);
+
+static void sp_attribute_widget_changed (GtkEditable *editable);
+
+static void sp_attribute_widget_object_modified ( SPObject *object,
+                                                  guint flags,
+                                                  SPAttributeWidget *spaw );
+static void sp_attribute_widget_object_release ( SPObject *object,
+                                                 SPAttributeWidget *spaw );
+
+static GtkEntryClass *parent_class;
+
+
+
+
+GType sp_attribute_widget_get_type(void)
+{
+    static GtkType type = 0;
+    if (!type) {
+        GTypeInfo info = {
+            sizeof(SPAttributeWidgetClass),
+            0, // base_init
+            0, // base_finalize
+            (GClassInitFunc)sp_attribute_widget_class_init,
+            0, // class_finalize
+            0, // class_data
+            sizeof(SPAttributeWidget),
+            0, // n_preallocs
+            (GInstanceInitFunc)sp_attribute_widget_init,
+            0 // value_table
+        };
+        type = g_type_register_static(GTK_TYPE_ENTRY, "SPAttributeWidget", &info, static_cast<GTypeFlags>(0));
+    }
+    return type;
+} // end of sp_attribute_widget_get_type()
+
+
+
+static void
+sp_attribute_widget_class_init (SPAttributeWidgetClass *klass)
+{
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+    GtkEditableClass *editable_class;
+
+    object_class = GTK_OBJECT_CLASS (klass);
+    widget_class = GTK_WIDGET_CLASS (klass);
+    editable_class = GTK_EDITABLE_CLASS (klass);
+
+    parent_class = (GtkEntryClass*)gtk_type_class (GTK_TYPE_ENTRY);
+
+    object_class->destroy = sp_attribute_widget_destroy;
+
+    editable_class->changed = sp_attribute_widget_changed;
+
+} // end of sp_attribute_widget_class_init()
+
+
+
+static void
+sp_attribute_widget_init (SPAttributeWidget *spaw)
+{
+    spaw->blocked = FALSE;
+    spaw->hasobj = FALSE;
+
+    spaw->src.object = NULL;
+
+    spaw->attribute = NULL;
+
+    new (&spaw->modified_connection) sigc::connection();
+    new (&spaw->release_connection) sigc::connection();
+}
+
+
+
+static void
+sp_attribute_widget_destroy (GtkObject *object)
+{
+
+    SPAttributeWidget *spaw;
+
+    spaw = SP_ATTRIBUTE_WIDGET (object);
+
+    if (spaw->attribute) {
+        g_free (spaw->attribute);
+        spaw->attribute = NULL;
+    }
+
+
+    if (spaw->hasobj) {
+
+        if (spaw->src.object) {
+            spaw->modified_connection.disconnect();
+            spaw->release_connection.disconnect();
+            spaw->src.object = NULL;
+        }
+    } else {
+
+        if (spaw->src.repr) {
+            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
+        }
+    } // end of if()
+
+    spaw->modified_connection.~connection();
+    spaw->release_connection.~connection();
+
+    ((GtkObjectClass *) parent_class)->destroy (object);
+
+}
+
+
+
+static void
+sp_attribute_widget_changed (GtkEditable *editable)
+{
+
+    SPAttributeWidget *spaw;
+
+    spaw = SP_ATTRIBUTE_WIDGET (editable);
+
+    if (!spaw->blocked) {
+
+        const gchar *text;
+        spaw->blocked = TRUE;
+        text = gtk_entry_get_text (GTK_ENTRY (spaw));
+        if (!*text)
+            text = NULL;
+
+        if (spaw->hasobj && spaw->src.object) {
+        
+            SP_OBJECT_REPR (spaw->src.object)->setAttribute(spaw->attribute, text, false);
+            sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object), SP_VERB_NONE,
+                              _("Set attribute"));
+
+        } else if (spaw->src.repr) {
+
+            spaw->src.repr->setAttribute(spaw->attribute, text, false);
+            /* TODO: Warning! Undo will not be flushed in given case */
+        }
+        spaw->blocked = FALSE;
+    }
+
+} // end of sp_attribute_widget_changed()
+
+
+
+GtkWidget *
+sp_attribute_widget_new ( SPObject *object, const gchar *attribute )
+{
+    SPAttributeWidget *spaw;
+
+    g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
+    g_return_val_if_fail (!object || attribute, NULL);
+
+    spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
+
+    sp_attribute_widget_set_object (spaw, object, attribute);
+
+    return GTK_WIDGET (spaw);
+
+} // end of sp_attribute_widget_new()
+
+
+
+GtkWidget *
+sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute )
+{
+    SPAttributeWidget *spaw;
+
+    spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET);
+
+    sp_attribute_widget_set_repr (spaw, repr, attribute);
+
+    return GTK_WIDGET (spaw);
+}
+
+
+
+void
+sp_attribute_widget_set_object ( SPAttributeWidget *spaw,
+                                 SPObject *object,
+                                 const gchar *attribute )
+{
+
+    g_return_if_fail (spaw != NULL);
+    g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
+    g_return_if_fail (!object || SP_IS_OBJECT (object));
+    g_return_if_fail (!object || attribute);
+    g_return_if_fail (attribute != NULL);
+
+    if (spaw->attribute) {
+        g_free (spaw->attribute);
+        spaw->attribute = NULL;
+    }
+
+    if (spaw->hasobj) {
+
+        if (spaw->src.object) {
+            spaw->modified_connection.disconnect();
+            spaw->release_connection.disconnect();
+            spaw->src.object = NULL;
+        }
+    } else {
+
+        if (spaw->src.repr) {
+            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
+        }
+    }
+
+    spaw->hasobj = TRUE;
+
+    if (object) {
+        const gchar *val;
+
+        spaw->blocked = TRUE;
+        spaw->src.object = object;
+
+        spaw->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_widget_object_modified), spaw));
+        spaw->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_widget_object_release), spaw));
+
+        spaw->attribute = g_strdup (attribute);
+
+        val = SP_OBJECT_REPR (object)->attribute(attribute);
+        gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
+        spaw->blocked = FALSE;
+    }
+
+    gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL));
+
+} // end of sp_attribute_widget_set_object()
+
+
+
+void
+sp_attribute_widget_set_repr ( SPAttributeWidget *spaw,
+                               Inkscape::XML::Node *repr,
+                               const gchar *attribute )
+{
+
+    g_return_if_fail (spaw != NULL);
+    g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw));
+    g_return_if_fail (attribute != NULL);
+
+    if (spaw->attribute) {
+        g_free (spaw->attribute);
+        spaw->attribute = NULL;
+    }
+
+    if (spaw->hasobj) {
+
+        if (spaw->src.object) {
+            spaw->modified_connection.disconnect();
+            spaw->release_connection.disconnect();
+            spaw->src.object = NULL;
+        }
+    } else {
+
+        if (spaw->src.repr) {
+            spaw->src.repr = Inkscape::GC::release(spaw->src.repr);
+        }
+    }
+
+    spaw->hasobj = FALSE;
+
+    if (repr) {
+        const gchar *val;
+
+        spaw->blocked = TRUE;
+        spaw->src.repr = Inkscape::GC::anchor(repr);
+        spaw->attribute = g_strdup (attribute);
+
+        val = repr->attribute(attribute);
+        gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) "");
+        spaw->blocked = FALSE;
+    }
+
+    gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL));
+
+} // end of sp_attribute_widget_set_repr()
+
+
+
+static void
+sp_attribute_widget_object_modified ( SPObject */*object*/,
+                                      guint flags,
+                                      SPAttributeWidget *spaw )
+{
+
+    if (flags && SP_OBJECT_MODIFIED_FLAG) {
+
+        const gchar *val, *text;
+        val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute);
+        text = gtk_entry_get_text (GTK_ENTRY (spaw));
+
+        if (val || text) {
+
+            if (!val || !text || strcmp (val, text)) {
+                /* We are different */
+                spaw->blocked = TRUE;
+                gtk_entry_set_text ( GTK_ENTRY (spaw),
+                                     val ? val : (const gchar *) "");
+                spaw->blocked = FALSE;
+            } // end of if()
+
+        } // end of if()
+
+    } //end of if()
+
+} // end of sp_attribute_widget_object_modified()
+
+
+
+static void
+sp_attribute_widget_object_release ( SPObject */*object*/,
+                                     SPAttributeWidget *spaw )
+{
+    sp_attribute_widget_set_object (spaw, NULL, NULL);
+}
+
+
+
+/* SPAttributeTable */
+
+static void sp_attribute_table_class_init (SPAttributeTableClass *klass);
+static void sp_attribute_table_init (SPAttributeTable *widget);
+static void sp_attribute_table_destroy (GtkObject *object);
+
+static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw);
+static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw);
+static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat);
+
+static GtkVBoxClass *table_parent_class;
+
+
+
+
+GType sp_attribute_table_get_type(void)
+{
+    static GtkType type = 0;
+    if (!type) {
+        GTypeInfo info = {
+            sizeof(SPAttributeTableClass),
+            0, // base_init
+            0, // base_finalize
+            (GClassInitFunc)sp_attribute_table_class_init,
+            0, // class_finalize
+            0, // class_data
+            sizeof(SPAttributeTable),
+            0, // n_preallocs
+            (GInstanceInitFunc)sp_attribute_table_init,
+            0 // value_table
+        };
+        type = g_type_register_static(GTK_TYPE_VBOX, "SPAttributeTable", &info, static_cast<GTypeFlags>(0));
+    }
+    return type;
+} // end of sp_attribute_table_get_type()
+
+
+
+static void
+sp_attribute_table_class_init (SPAttributeTableClass *klass)
+{
+    GtkObjectClass *object_class;
+    GtkWidgetClass *widget_class;
+
+    object_class = GTK_OBJECT_CLASS (klass);
+    widget_class = GTK_WIDGET_CLASS (klass);
+
+    table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX);
+
+    object_class->destroy = sp_attribute_table_destroy;
+
+} // end of sp_attribute_table_class_init()
+
+
+
+static void
+sp_attribute_table_init ( SPAttributeTable *spat )
+{
+    spat->blocked = FALSE;
+    spat->hasobj = FALSE;
+    spat->table = NULL;
+    spat->src.object = NULL;
+    spat->num_attr = 0;
+    spat->attributes = NULL;
+    spat->entries = NULL;
+
+    new (&spat->modified_connection) sigc::connection();
+    new (&spat->release_connection) sigc::connection();
+}
+
+static void
+sp_attribute_table_destroy ( GtkObject *object )
+{
+    SPAttributeTable *spat;
+
+    spat = SP_ATTRIBUTE_TABLE (object);
+
+    if (spat->attributes) {
+        gint i;
+        for (i = 0; i < spat->num_attr; i++) {
+            g_free (spat->attributes[i]);
+        }
+        g_free (spat->attributes);
+        spat->attributes = NULL;
+    }
+
+    if (spat->hasobj) {
+
+        if (spat->src.object) {
+            spat->modified_connection.disconnect();
+            spat->release_connection.disconnect();
+            spat->src.object = NULL;
+        }
+    } else {
+        if (spat->src.repr) {
+            spat->src.repr = Inkscape::GC::release(spat->src.repr);
+        }
+    } // end of if()
+
+    spat->modified_connection.~connection();
+    spat->release_connection.~connection();
+
+    if (spat->entries) {
+        g_free (spat->entries);
+        spat->entries = NULL;
+    }
+
+    spat->table = NULL;
+
+    if (((GtkObjectClass *) table_parent_class)->destroy) {
+        (* ((GtkObjectClass *) table_parent_class)->destroy) (object);
+    }
+
+} // end of sp_attribute_table_destroy()
+
+
+GtkWidget *
+sp_attribute_table_new ( SPObject *object,
+                         gint num_attr,
+                         const gchar **labels,
+                         const gchar **attributes )
+{
+    SPAttributeTable *spat;
+
+    g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL);
+    g_return_val_if_fail (!object || (num_attr > 0), NULL);
+    g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
+
+    spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
+
+    sp_attribute_table_set_object (spat, object, num_attr, labels, attributes);
+
+    return GTK_WIDGET (spat);
+
+} // end of sp_attribute_table_new()
+
+
+
+GtkWidget *
+sp_attribute_table_new_repr ( Inkscape::XML::Node *repr,
+                              gint num_attr,
+                              const gchar **labels,
+                              const gchar **attributes )
+{
+    SPAttributeTable *spat;
+
+    g_return_val_if_fail (!num_attr || (labels && attributes), NULL);
+
+    spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE);
+
+    sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes);
+
+    return GTK_WIDGET (spat);
+
+} // end of sp_attribute_table_new_repr()
+
+
+
+#define XPAD 4
+#define YPAD 0
+
+void
+sp_attribute_table_set_object ( SPAttributeTable *spat,
+                                SPObject *object,
+                                gint num_attr,
+                                const gchar **labels,
+                                const gchar **attributes )
+{
+
+    g_return_if_fail (spat != NULL);
+    g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
+    g_return_if_fail (!object || SP_IS_OBJECT (object));
+    g_return_if_fail (!object || (num_attr > 0));
+    g_return_if_fail (!num_attr || (labels && attributes));
+
+    if (spat->table) {
+        gtk_widget_destroy (spat->table);
+        spat->table = NULL;
+    }
+
+    if (spat->attributes) {
+        gint i;
+        for (i = 0; i < spat->num_attr; i++) {
+            g_free (spat->attributes[i]);
+        }
+        g_free (spat->attributes);
+        spat->attributes = NULL;
+    }
+
+    if (spat->entries) {
+        g_free (spat->entries);
+        spat->entries = NULL;
+    }
+
+    if (spat->hasobj) {
+        if (spat->src.object) {
+            spat->modified_connection.disconnect();
+            spat->release_connection.disconnect();
+            spat->src.object = NULL;
+        }
+    } else {
+        if (spat->src.repr) {
+            spat->src.repr = Inkscape::GC::release(spat->src.repr);
+        }
+    }
+
+    spat->hasobj = TRUE;
+
+    if (object) {
+        gint i;
+
+        spat->blocked = TRUE;
+
+        /* Set up object */
+        spat->src.object = object;
+        spat->num_attr = num_attr;
+
+        spat->modified_connection = object->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_attribute_table_object_modified), spat));
+        spat->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_attribute_table_object_release), spat));
+
+        /* Create table */
+        spat->table = gtk_table_new (num_attr, 2, FALSE);
+        gtk_container_add (GTK_CONTAINER (spat), spat->table);
+        /* Arrays */
+        spat->attributes = g_new0 (gchar *, num_attr);
+        spat->entries = g_new0 (GtkWidget *, num_attr);
+        /* Fill rows */
+        for (i = 0; i < num_attr; i++) {
+            GtkWidget *w;
+            const gchar *val;
+
+            spat->attributes[i] = g_strdup (attributes[i]);
+            w = gtk_label_new (_(labels[i]));
+            gtk_widget_show (w);
+            gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
+            gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
+                               GTK_FILL,
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               XPAD, YPAD );
+            w = gtk_entry_new ();
+            gtk_widget_show (w);
+            val = SP_OBJECT_REPR (object)->attribute(attributes[i]);
+            gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
+            gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               XPAD, YPAD );
+            spat->entries[i] = w;
+            g_signal_connect ( G_OBJECT (w), "changed",
+                               G_CALLBACK (sp_attribute_table_entry_changed),
+                               spat );
+        }
+        /* Show table */
+        gtk_widget_show (spat->table);
+
+        spat->blocked = FALSE;
+    }
+
+    gtk_widget_set_sensitive ( GTK_WIDGET (spat),
+                               (spat->src.object != NULL) );
+
+} // end of sp_attribute_table_set_object()
+
+
+
+void
+sp_attribute_table_set_repr ( SPAttributeTable *spat,
+                              Inkscape::XML::Node *repr,
+                              gint num_attr,
+                              const gchar **labels,
+                              const gchar **attributes )
+{
+    g_return_if_fail (spat != NULL);
+    g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat));
+    g_return_if_fail (!num_attr || (labels && attributes));
+
+    if (spat->table) {
+        gtk_widget_destroy (spat->table);
+        spat->table = NULL;
+    }
+
+    if (spat->attributes) {
+        gint i;
+        for (i = 0; i < spat->num_attr; i++) {
+            g_free (spat->attributes[i]);
+        }
+        g_free (spat->attributes);
+        spat->attributes = NULL;
+    }
+
+    if (spat->entries) {
+        g_free (spat->entries);
+        spat->entries = NULL;
+    }
+
+    if (spat->hasobj) {
+        if (spat->src.object) {
+            spat->modified_connection.disconnect();
+            spat->release_connection.disconnect();
+            spat->src.object = NULL;
+        }
+    } else {
+        if (spat->src.repr) {
+            spat->src.repr = Inkscape::GC::release(spat->src.repr);
+        }
+    }
+
+    spat->hasobj = FALSE;
+
+    if (repr) {
+        gint i;
+
+        spat->blocked = TRUE;
+
+        /* Set up repr */
+        spat->src.repr = Inkscape::GC::anchor(repr);
+        spat->num_attr = num_attr;
+        /* Create table */
+        spat->table = gtk_table_new (num_attr, 2, FALSE);
+        gtk_container_add (GTK_CONTAINER (spat), spat->table);
+        /* Arrays */
+        spat->attributes = g_new0 (gchar *, num_attr);
+        spat->entries = g_new0 (GtkWidget *, num_attr);
+
+        /* Fill rows */
+        for (i = 0; i < num_attr; i++) {
+            GtkWidget *w;
+            const gchar *val;
+
+            spat->attributes[i] = g_strdup (attributes[i]);
+            w = gtk_label_new (labels[i]);
+            gtk_widget_show (w);
+            gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
+            gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1,
+                               GTK_FILL,
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               XPAD, YPAD );
+            w = gtk_entry_new ();
+            gtk_widget_show (w);
+            val = repr->attribute(attributes[i]);
+            gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) "");
+            gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1,
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+                               XPAD, YPAD );
+            spat->entries[i] = w;
+            g_signal_connect ( G_OBJECT (w), "changed",
+                               G_CALLBACK (sp_attribute_table_entry_changed),
+                               spat );
+        }
+        /* Show table */
+        gtk_widget_show (spat->table);
+
+        spat->blocked = FALSE;
+    }
+
+    gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL));
+
+} // end of sp_attribute_table_set_repr()
+
+
+
+static void
+sp_attribute_table_object_modified ( SPObject */*object*/,
+                                     guint flags,
+                                     SPAttributeTable *spat )
+{
+    if (flags && SP_OBJECT_MODIFIED_FLAG)
+    {
+        gint i;
+        for (i = 0; i < spat->num_attr; i++) {
+            const gchar *val, *text;
+            val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]);
+            text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
+            if (val || text) {
+                if (!val || !text || strcmp (val, text)) {
+                    /* We are different */
+                    spat->blocked = TRUE;
+                    gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]),
+                                         val ? val : (const gchar *) "");
+                    spat->blocked = FALSE;
+                }
+            }
+        }
+    } // end of if()
+
+} // end of sp_attribute_table_object_modified()
+
+
+
+static void
+sp_attribute_table_object_release (SPObject */*object*/, SPAttributeTable *spat)
+{
+    sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL);
+}
+
+
+
+static void
+sp_attribute_table_entry_changed ( GtkEditable *editable,
+                                   SPAttributeTable *spat )
+{
+    if (!spat->blocked)
+    {
+        gint i;
+        for (i = 0; i < spat->num_attr; i++) {
+
+            if (GTK_WIDGET (editable) == spat->entries[i]) {
+                const gchar *text;
+                spat->blocked = TRUE;
+                text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i]));
+
+                if (!*text)
+                    text = NULL;
+
+                if (spat->hasobj && spat->src.object) {
+                    SP_OBJECT_REPR (spat->src.object)->setAttribute(spat->attributes[i], text, false);
+                    sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object), SP_VERB_NONE,
+                                      _("Set attribute"));
+
+                } else if (spat->src.repr) {
+
+                    spat->src.repr->setAttribute(spat->attributes[i], text, false);
+                    /* TODO: Warning! Undo will not be flushed in given case */
+                }
+                spat->blocked = FALSE;
+                return;
+            }
+        }
+        g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__);
+    } // end of if()
+
+} // end of sp_attribute_table_entry_changed()
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-attribute-widget.h b/src/widgets/sp-attribute-widget.h
new file mode 100644 (file)
index 0000000..01da29b
--- /dev/null
@@ -0,0 +1,130 @@
+/** @file
+ * @brief Widget that listens and modifies repr attributes
+ */
+/* Authors:
+ *  Lauris Kaplinski <lauris@kaplinski.com>
+ *
+ * Copyright (C) 2002 authors
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Licensed under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H
+#define SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H
+
+#include <glib.h>
+#include <sigc++/connection.h>
+
+#define SP_TYPE_ATTRIBUTE_WIDGET (sp_attribute_widget_get_type ())
+#define SP_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidget))
+#define SP_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidgetClass))
+#define SP_IS_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_WIDGET))
+#define SP_IS_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_WIDGET))
+
+#define SP_TYPE_ATTRIBUTE_TABLE (sp_attribute_table_get_type ())
+#define SP_ATTRIBUTE_TABLE(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTable))
+#define SP_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTableClass))
+#define SP_IS_ATTRIBUTE_TABLE(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_TABLE))
+#define SP_IS_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_TABLE))
+
+namespace Inkscape {
+namespace XML {
+class Node;
+}
+}
+
+
+struct SPAttributeWidget;
+struct SPAttributeWidgetClass;
+
+struct SPAttributeTable;
+struct SPAttributeTableClass;
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtkvbox.h>
+
+#include <forward.h>
+
+struct SPAttributeWidget {
+    GtkEntry entry;
+    guint blocked : 1;
+    guint hasobj : 1;
+    union {
+        SPObject *object;
+        Inkscape::XML::Node *repr;
+    } src;
+    gchar *attribute;
+
+    sigc::connection modified_connection;
+    sigc::connection release_connection;
+};
+
+struct SPAttributeWidgetClass {
+    GtkEntryClass entry_class;
+};
+
+GtkType sp_attribute_widget_get_type (void);
+
+GtkWidget *sp_attribute_widget_new (SPObject *object, const gchar *attribute);
+GtkWidget *sp_attribute_widget_new_repr (Inkscape::XML::Node *repr, const gchar *attribute);
+
+void sp_attribute_widget_set_object ( SPAttributeWidget *spw, 
+                                      SPObject *object, 
+                                      const gchar *attribute );
+void sp_attribute_widget_set_repr ( SPAttributeWidget *spw, 
+                                    Inkscape::XML::Node *repr, 
+                                    const gchar *attribute );
+
+/* SPAttributeTable */
+
+struct SPAttributeTable {
+    GtkVBox vbox;
+    guint blocked : 1;
+    guint hasobj : 1;
+    GtkWidget *table;
+    union {
+        SPObject *object;
+        Inkscape::XML::Node *repr;
+    } src;
+    gint num_attr;
+    gchar **attributes;
+    GtkWidget **entries;
+
+    sigc::connection modified_connection;
+    sigc::connection release_connection;
+};
+
+struct SPAttributeTableClass {
+    GtkEntryClass entry_class;
+};
+
+GtkType sp_attribute_table_get_type (void);
+
+GtkWidget *sp_attribute_table_new ( SPObject *object, gint num_attr, 
+                                    const gchar **labels, 
+                                    const gchar **attributes );
+GtkWidget *sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, gint num_attr, 
+                                         const gchar **labels, 
+                                         const gchar **attributes );
+void sp_attribute_table_set_object ( SPAttributeTable *spw, 
+                                     SPObject *object, gint num_attr, 
+                                     const gchar **labels, 
+                                     const gchar **attrs );
+void sp_attribute_table_set_repr ( SPAttributeTable *spw, 
+                                   Inkscape::XML::Node *repr, gint num_attr, 
+                                   const gchar **labels, 
+                                   const gchar **attrs );
+
+#endif
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp
new file mode 100644 (file)
index 0000000..b1678f2
--- /dev/null
@@ -0,0 +1,1838 @@
+/** @file
+ * @brief  Stroke style dialog
+ */
+/* Authors:
+ *   Lauris Kaplinski <lauris@kaplinski.com>
+ *   Bryce Harrington <brycehar@bryceharrington.org>
+ *   bulia byak <buliabyak@users.sf.net>
+ *   Maximilian Albert <maximilian.albert@gmail.com>
+ *   Josh Andler <scislac@users.sf.net>
+ *
+ * Copyright (C) 2001-2005 authors
+ * Copyright (C) 2001 Ximian, Inc.
+ * Copyright (C) 2004 John Cliff
+ * Copyright (C) 2008 Maximilian Albert (gtkmm-ification)
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#define noSP_SS_VERBOSE
+
+#include <glib/gmem.h>
+#include <gtk/gtk.h>
+#include <glibmm/i18n.h>
+
+#include "desktop-handles.h"
+#include "desktop-style.h"
+#include "dialogs/dialog-events.h"
+#include "display/nr-arena.h"
+#include "display/nr-arena-item.h"
+#include "document-private.h"
+#include "gradient-chemistry.h"
+#include "helper/stock-items.h"
+#include "helper/unit-menu.h"
+#include "helper/units.h"
+#include "inkscape.h"
+#include "io/sys.h"
+#include "marker.h"
+#include "path-prefix.h"
+#include "selection.h"
+#include "sp-linear-gradient.h"
+#include "sp-namedview.h"
+#include "sp-pattern.h"
+#include "sp-radial-gradient.h"
+#include "sp-rect.h"
+#include "sp-text.h"
+#include "style.h"
+#include "svg/css-ostringstream.h"
+#include "ui/cache/svg_preview_cache.h"
+#include "ui/icon-names.h"
+#include "widgets/dash-selector.h"
+#include "widgets/icon.h"
+#include "widgets/paint-selector.h"
+#include "widgets/sp-widget.h"
+#include "widgets/spw-utilities.h"
+#include "xml/repr.h"
+
+#include "widgets/stroke-style.h"
+
+
+/* Paint */
+
+static void sp_stroke_style_paint_selection_modified (SPWidget *spw, Inkscape::Selection *selection, guint flags, SPPaintSelector *psel);
+static void sp_stroke_style_paint_selection_changed (SPWidget *spw, Inkscape::Selection *selection, SPPaintSelector *psel);
+static void sp_stroke_style_paint_update(SPWidget *spw);
+
+static void sp_stroke_style_paint_mode_changed(SPPaintSelector *psel, SPPaintSelectorMode mode, SPWidget *spw);
+static void sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw);
+static void sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw);
+
+static void sp_stroke_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
+static void sp_stroke_style_widget_transientize_callback(Inkscape::Application *inkscape,
+                                                         SPDesktop *desktop,
+                                                         SPWidget *spw );
+
+/** Marker selection option menus */
+static Gtk::OptionMenu * marker_start_menu = NULL;
+static Gtk::OptionMenu * marker_mid_menu = NULL;
+static Gtk::OptionMenu * marker_end_menu = NULL;
+
+sigc::connection marker_start_menu_connection;
+sigc::connection marker_mid_menu_connection;
+sigc::connection marker_end_menu_connection;
+
+static SPObject *ink_extract_marker_name(gchar const *n, SPDocument *doc);
+static void      ink_markers_menu_update(Gtk::Container* spw, SPMarkerLoc const which);
+
+static Inkscape::UI::Cache::SvgPreview svg_preview_cache;
+
+/**
+ * Create the stroke style widget, and hook up all the signals.
+ */
+GtkWidget *
+sp_stroke_style_paint_widget_new(void)
+{
+    GtkWidget *spw, *psel;
+
+    spw = sp_widget_new_global(INKSCAPE);
+
+    psel = sp_paint_selector_new(false); // without fillrule selector
+    gtk_widget_show(psel);
+    gtk_container_add(GTK_CONTAINER(spw), psel);
+    gtk_object_set_data(GTK_OBJECT(spw), "paint-selector", psel);
+
+    gtk_signal_connect(GTK_OBJECT(spw), "modify_selection",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_modified),
+                       psel);
+    gtk_signal_connect(GTK_OBJECT(spw), "change_selection",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_changed),
+                       psel);
+
+    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_stroke_style_widget_change_subselection), spw);
+
+    g_signal_connect (G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK (sp_stroke_style_widget_transientize_callback), spw );
+
+    gtk_signal_connect(GTK_OBJECT(psel), "mode_changed",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_mode_changed),
+                       spw);
+    gtk_signal_connect(GTK_OBJECT(psel), "dragged",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_dragged),
+                       spw);
+    gtk_signal_connect(GTK_OBJECT(psel), "changed",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_changed),
+                       spw);
+
+    sp_stroke_style_paint_update (SP_WIDGET(spw));
+    return spw;
+}
+
+/**
+ * On signal modified, invokes an update of the stroke style paint object.
+ */
+static void
+sp_stroke_style_paint_selection_modified( SPWidget *spw,
+                                          Inkscape::Selection */*selection*/,
+                                          guint flags,
+                                          SPPaintSelector */*psel*/ )
+{
+    if (flags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG |
+                  SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
+        sp_stroke_style_paint_update(spw);
+    }
+}
+
+
+/**
+ * On signal selection changed, invokes an update of the stroke style paint object.
+ */
+static void
+sp_stroke_style_paint_selection_changed( SPWidget *spw,
+                                         Inkscape::Selection */*selection*/,
+                                         SPPaintSelector */*psel*/ )
+{
+    sp_stroke_style_paint_update (spw);
+}
+
+
+/**
+ * On signal change subselection, invoke an update of the stroke style widget.
+ */
+static void
+sp_stroke_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
+                                            SPDesktop */*desktop*/,
+                                            SPWidget *spw )
+{
+    sp_stroke_style_paint_update (spw);
+}
+
+/**
+ * Gets the active stroke style property, then sets the appropriate color, alpha, gradient,
+ * pattern, etc. for the paint-selector.
+ */
+static void
+sp_stroke_style_paint_update (SPWidget *spw)
+{
+    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
+        return;
+    }
+
+    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
+
+    SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector"));
+
+    // create temporary style
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
+    // query into it
+    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE);
+
+    switch (result) {
+        case QUERY_STYLE_NOTHING:
+        {
+            /* No paint at all */
+            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
+            break;
+        }
+
+        case QUERY_STYLE_SINGLE:
+        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
+        case QUERY_STYLE_MULTIPLE_SAME:
+        {
+            SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, false);
+            sp_paint_selector_set_mode (psel, pselmode);
+
+            if (query->stroke.set && query->stroke.isPaintserver()) {
+
+                SPPaintServer *server = SP_STYLE_STROKE_SERVER (query);
+
+                if (SP_IS_LINEARGRADIENT (server)) {
+                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
+                    sp_paint_selector_set_gradient_linear (psel, vector);
+
+                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
+                    sp_paint_selector_set_gradient_properties (psel,
+                                                       SP_GRADIENT_UNITS (lg),
+                                                       SP_GRADIENT_SPREAD (lg));
+                } else if (SP_IS_RADIALGRADIENT (server)) {
+                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
+                    sp_paint_selector_set_gradient_radial (psel, vector);
+
+                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
+                    sp_paint_selector_set_gradient_properties (psel,
+                                                       SP_GRADIENT_UNITS (rg),
+                                                       SP_GRADIENT_SPREAD (rg));
+                } else if (SP_IS_PATTERN (server)) {
+                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
+                    sp_update_pattern_list (psel, pat);
+                }
+            } else if (query->stroke.set && query->stroke.isColor()) {
+                sp_paint_selector_set_color_alpha (psel, &query->stroke.value.color, SP_SCALE24_TO_FLOAT (query->stroke_opacity.value));
+
+            }
+            break;
+        }
+
+        case QUERY_STYLE_MULTIPLE_DIFFERENT:
+        {
+            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
+            break;
+        }
+    }
+
+    sp_style_unref(query);
+
+    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
+}
+
+/**
+ * When the mode is changed, invoke a regular changed handler.
+ */
+static void
+sp_stroke_style_paint_mode_changed( SPPaintSelector *psel,
+                                    SPPaintSelectorMode /*mode*/,
+                                    SPWidget *spw )
+{
+    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
+        return;
+    }
+
+    /* TODO: Does this work?
+     * Not really, here we have to get old color back from object
+     * Instead of relying on paint widget having meaningful colors set
+     */
+    sp_stroke_style_paint_changed(psel, spw);
+}
+
+static gchar const *const undo_label_1 = "stroke:flatcolor:1";
+static gchar const *const undo_label_2 = "stroke:flatcolor:2";
+static gchar const *undo_label = undo_label_1;
+
+/**
+ * When a drag callback occurs on a paint selector object, if it is a RGB or CMYK
+ * color mode, then set the stroke opacity to psel's flat color.
+ */
+static void
+sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw)
+{
+    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
+        return;
+    }
+
+    switch (psel->mode) {
+        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
+        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
+        {
+            sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "stroke", "stroke-opacity");
+            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE,
+                                    _("Set stroke color"));
+            break;
+        }
+
+        default:
+            g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
+                       __FILE__, __LINE__, psel->mode);
+            break;
+    }
+}
+
+/**
+ * When the stroke style's paint settings change, this handler updates the
+ * repr's stroke css style and applies the style to relevant drawing items.
+ */
+static void
+sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw)
+{
+    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
+        return;
+    }
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
+
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    SPDocument *document = sp_desktop_document (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+    GSList const *items = selection->itemList();
+
+    switch (psel->mode) {
+        case SP_PAINT_SELECTOR_MODE_EMPTY:
+            // This should not happen.
+            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
+                        __FILE__, __LINE__, psel->mode);
+            break;
+        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
+            // This happens when you switch multiple objects with different gradients to flat color;
+            // nothing to do here.
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_NONE:
+        {
+            SPCSSAttr *css = sp_repr_css_attr_new();
+            sp_repr_css_set_property(css, "stroke", "none");
+
+            sp_desktop_set_style (desktop, css);
+
+            sp_repr_css_attr_unref(css);
+
+            sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
+                             _("Remove stroke"));
+            break;
+        }
+
+        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
+        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
+        {
+            sp_paint_selector_set_flat_color (psel, desktop, "stroke", "stroke-opacity");
+            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
+                                    _("Set stroke color"));
+
+            // on release, toggle undo_label so that the next drag will not be lumped with this one
+            if (undo_label == undo_label_1)
+                undo_label = undo_label_2;
+            else
+                undo_label = undo_label_1;
+
+            break;
+        }
+
+        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
+        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
+            if (items) {
+                SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
+                                                       ? SP_GRADIENT_TYPE_LINEAR
+                                                       : SP_GRADIENT_TYPE_RADIAL );
+                SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
+                if (!vector) {
+                    /* No vector in paint selector should mean that we just changed mode */
+
+                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
+                    int result = objects_query_fillstroke ((GSList *) items, query, false);
+                    guint32 common_rgb = 0;
+                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
+                        if (!query->fill.isColor()) {
+                            common_rgb = sp_desktop_get_color(desktop, false);
+                        } else {
+                            common_rgb = query->stroke.value.color.toRGBA32( 0xff );
+                        }
+                        vector = sp_document_default_gradient_vector(document, common_rgb);
+                    }
+                    sp_style_unref(query);
+
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                        if (!vector) {
+                            sp_item_set_gradient(SP_ITEM(i->data),
+                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), false),
+                                                 gradient_type, false);
+                        } else {
+                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
+                        }
+                    }
+                } else {
+                    vector = sp_gradient_ensure_vector_normalized(vector);
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
+                        sp_gradient_selector_attrs_to_gradient(gr, psel);
+                    }
+                }
+
+                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
+                                 _("Set gradient on stroke"));
+            }
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_PATTERN:
+
+            if (items) {
+
+                SPPattern *pattern = sp_paint_selector_get_pattern (psel);
+                if (!pattern) {
+
+                    /* No Pattern in paint selector should mean that we just
+                     * changed mode - dont do jack.
+                     */
+
+                } else {
+                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
+                    SPCSSAttr *css = sp_repr_css_attr_new ();
+                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
+                    sp_repr_css_set_property (css, "stroke", urltext);
+
+                    for (GSList const *i = items; i != NULL; i = i->next) {
+                         Inkscape::XML::Node *selrepr = SP_OBJECT_REPR (i->data);
+                         SPObject *selobj = SP_OBJECT (i->data);
+                         if (!selrepr)
+                             continue;
+
+                         SPStyle *style = SP_OBJECT_STYLE (selobj);
+                         if (style && style->stroke.isPaintserver()) {
+                             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (selobj);
+                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
+                                 // only if this object's pattern is not rooted in our selected pattern, apply
+                                 continue;
+                         }
+
+                         sp_repr_css_change_recursive (selrepr, css, "style");
+                     }
+
+                    sp_repr_css_attr_unref (css);
+                    g_free (urltext);
+
+                } // end if
+
+                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
+                                  _("Set pattern on stroke"));
+            } // end if
+
+            break;
+
+        case SP_PAINT_SELECTOR_MODE_UNSET:
+            if (items) {
+                    SPCSSAttr *css = sp_repr_css_attr_new ();
+                    sp_repr_css_unset_property (css, "stroke");
+                    sp_repr_css_unset_property (css, "stroke-opacity");
+                    sp_repr_css_unset_property (css, "stroke-width");
+                    sp_repr_css_unset_property (css, "stroke-miterlimit");
+                    sp_repr_css_unset_property (css, "stroke-linejoin");
+                    sp_repr_css_unset_property (css, "stroke-linecap");
+                    sp_repr_css_unset_property (css, "stroke-dashoffset");
+                    sp_repr_css_unset_property (css, "stroke-dasharray");
+
+                    sp_desktop_set_style (desktop, css);
+                    sp_repr_css_attr_unref (css);
+
+                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
+                                      _("Unset stroke"));
+            }
+            break;
+
+        default:
+            g_warning( "file %s: line %d: Paint selector should not be in "
+                       "mode %d",
+                       __FILE__, __LINE__,
+                       psel->mode );
+            break;
+    }
+
+    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
+}
+
+
+
+
+
+/* Line */
+
+static void sp_stroke_style_line_selection_modified(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data);
+static void sp_stroke_style_line_selection_changed(SPWidget *spw, Inkscape::Selection *selection, gpointer data);
+
+static void sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel);
+
+static void sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active);
+
+static void sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active);
+
+static void sp_stroke_style_width_changed(Gtk::Container *spw);
+static void sp_stroke_style_miterlimit_changed(Gtk::Container *spw);
+static void sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw);
+static void sp_stroke_style_line_dash_changed(Gtk::Container *spw);
+
+static void sp_stroke_style_update_marker_menus(Gtk::Container *spw, GSList const *objects);
+
+
+/**
+ * Helper function for creating radio buttons.  This should probably be re-thought out
+ * when reimplementing this with Gtkmm.
+ */
+static Gtk::RadioButton *
+sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon,
+                       Gtk::HBox *hb, Gtk::Container *spw,
+                       gchar const *key, gchar const *data)
+{
+    g_assert(icon != NULL);
+    g_assert(hb  != NULL);
+    g_assert(spw != NULL);
+
+    if (tb == NULL) {
+        tb = new Gtk::RadioButton();
+    } else {
+        Gtk::RadioButtonGroup grp = tb->get_group();
+        tb = new Gtk::RadioButton(grp);
+    }
+
+    tb->show();
+    tb->set_mode(false);
+    hb->pack_start(*tb, false, false, 0);
+    spw->set_data(icon, tb);
+    tb->set_data(key, (gpointer*)data);
+    tb->signal_toggled().connect(sigc::bind<Gtk::RadioButton *, Gtk::Container *>(
+                                     sigc::ptr_fun(&sp_stroke_style_any_toggled), tb, spw));
+    Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon)));
+    g_assert(px != NULL);
+    px->show();
+    tb->add(*px);
+
+    return tb;
+
+}
+
+static void
+sp_stroke_style_widget_transientize_callback(Inkscape::Application */*inkscape*/,
+                                             SPDesktop */*desktop*/,
+                                             SPWidget */*spw*/ )
+{
+// TODO:  Either of these will cause crashes sometimes
+//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
+//    ink_markers_menu_update(spw);
+}
+
+/**
+ * Creates a copy of the marker named mname, determines its visible and renderable
+ * area in menu_id's bounding box, and then renders it.  This allows us to fill in
+ * preview images of each marker in the marker menu.
+ */
+static Gtk::Image *
+sp_marker_prev_new(unsigned psize, gchar const *mname,
+                   SPDocument *source, SPDocument *sandbox,
+                   gchar const *menu_id, NRArena const */*arena*/, unsigned /*visionkey*/, NRArenaItem *root)
+{
+    // Retrieve the marker named 'mname' from the source SVG document
+    SPObject const *marker = source->getObjectById(mname);
+    if (marker == NULL)
+        return NULL;
+
+    // Create a copy repr of the marker with id="sample"
+    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(sandbox);
+    Inkscape::XML::Node *mrepr = SP_OBJECT_REPR (marker)->duplicate(xml_doc);
+    mrepr->setAttribute("id", "sample");
+
+    // Replace the old sample in the sandbox by the new one
+    Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (sandbox->getObjectById("defs"));
+    SPObject *oldmarker = sandbox->getObjectById("sample");
+    if (oldmarker)
+        oldmarker->deleteObject(false);
+    defsrepr->appendChild(mrepr);
+    Inkscape::GC::release(mrepr);
+
+// Uncomment this to get the sandbox documents saved (useful for debugging)
+    //FILE *fp = fopen (g_strconcat(menu_id, mname, ".svg", NULL), "w");
+    //sp_repr_save_stream (sp_document_repr_doc (sandbox), fp);
+    //fclose (fp);
+
+    // object to render; note that the id is the same as that of the menu we're building
+    SPObject *object = sandbox->getObjectById(menu_id);
+    sp_document_root (sandbox)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+    sp_document_ensure_up_to_date(sandbox);
+
+    if (object == NULL || !SP_IS_ITEM(object))
+        return NULL; // sandbox broken?
+
+    // Find object's bbox in document
+    Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object)));
+    Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc);
+
+    if (!dbox) {
+        return NULL;
+    }
+
+    /* Update to renderable state */
+    double sf = 0.8;
+
+    gchar *cache_name = g_strconcat(menu_id, mname, NULL);
+    Glib::ustring key = svg_preview_cache.cache_key(source->uri, cache_name, psize);
+    g_free (cache_name);
+    // TODO: is this correct?
+    Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key));
+
+    if (!pixbuf) {
+        pixbuf = Glib::wrap(render_pixbuf(root, sf, *dbox, psize));
+        svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj());
+    }
+
+    // Create widget
+    Gtk::Image *pb = new Gtk::Image(pixbuf);
+
+    return pb;
+}
+
+/**
+ *  Returns a list of markers in the defs of the given source document as a GSList object
+ *  Returns NULL if there are no markers in the document.
+ */
+GSList *
+ink_marker_list_get (SPDocument *source)
+{
+    if (source == NULL)
+        return NULL;
+
+    GSList *ml   = NULL;
+    SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS (source);
+    for ( SPObject *child = sp_object_first_child(SP_OBJECT(defs));
+          child != NULL;
+          child = SP_OBJECT_NEXT (child) )
+    {
+        if (SP_IS_MARKER(child)) {
+            ml = g_slist_prepend (ml, child);
+        }
+    }
+    return ml;
+}
+
+#define MARKER_ITEM_MARGIN 0
+
+/**
+ * Adds previews of markers in marker_list to the given menu widget
+ */
+static void
+sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPDocument *sandbox, gchar const *menu_id)
+{
+    // Do this here, outside of loop, to speed up preview generation:
+    NRArena const *arena = NRArena::create();
+    unsigned const visionkey = sp_item_display_key_new(1);
+    NRArenaItem *root =  sp_item_invoke_show(SP_ITEM(SP_DOCUMENT_ROOT (sandbox)), (NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY);
+
+    for (; marker_list != NULL; marker_list = marker_list->next) {
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) marker_list->data);
+        Gtk::MenuItem *i = new Gtk::MenuItem();
+        i->show();
+
+        if (repr->attribute("inkscape:stockid"))
+            i->set_data("stockid", (void *) "true");
+        else
+            i->set_data("stockid", (void *) "false");
+
+        gchar const *markid = repr->attribute("id");
+        i->set_data("marker", (void *) markid);
+
+        Gtk::HBox *hb = new Gtk::HBox(false, MARKER_ITEM_MARGIN);
+        hb->show();
+
+        // generate preview
+
+        Gtk::Image *prv = sp_marker_prev_new (22, markid, source, sandbox, menu_id, arena, visionkey, root);
+        prv->show();
+        hb->pack_start(*prv, false, false, 6);
+
+        // create label
+        Gtk::Label *l = new Gtk::Label(repr->attribute("id"));
+        l->show();
+        l->set_alignment(0.0, 0.5);
+
+        hb->pack_start(*l, true, true, 0);
+
+        hb->show();
+        i->add(*hb);
+
+        m->append(*i);
+    }
+
+    sp_item_invoke_hide(SP_ITEM(sp_document_root(sandbox)), visionkey);
+    nr_object_unref((NRObject *) arena);
+}
+
+/**
+ * sp_marker_list_from_doc()
+ *
+ * \brief Pick up all markers from source, except those that are in
+ * current_doc (if non-NULL), and add items to the m menu
+ *
+ */
+static void
+sp_marker_list_from_doc (Gtk::Menu *m, SPDocument */*current_doc*/, SPDocument *source, SPDocument */*markers_doc*/, SPDocument *sandbox, gchar const *menu_id)
+{
+    GSList *ml = ink_marker_list_get(source);
+    GSList *clean_ml = NULL;
+
+    for (; ml != NULL; ml = ml->next) {
+        if (!SP_IS_MARKER(ml->data))
+            continue;
+
+        // Add to the list of markers we really do wish to show
+        clean_ml = g_slist_prepend (clean_ml, ml->data);
+    }
+    sp_marker_menu_build(m, clean_ml, source, sandbox, menu_id);
+
+    g_slist_free (ml);
+    g_slist_free (clean_ml);
+}
+
+/**
+ * Returns a new document containing default start, mid, and end markers.
+ */
+SPDocument *
+ink_markers_preview_doc ()
+{
+gchar const *buffer = "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
+"  <defs id=\"defs\" />"
+
+"  <g id=\"marker-start\">"
+"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:url(#sample);marker-mid:none;marker-end:none\""
+"       d=\"M 12.5,13 L 25,13\" id=\"path1\" />"
+"    <rect style=\"fill:none;stroke:none\" id=\"rect2\""
+"       width=\"25\" height=\"25\" x=\"0\" y=\"0\" />"
+"  </g>"
+
+"  <g id=\"marker-mid\">"
+"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:url(#sample);marker-end:none\""
+"       d=\"M 0,113 L 12.5,113 L 25,113\" id=\"path11\" />"
+"    <rect style=\"fill:none;stroke:none\" id=\"rect22\""
+"       width=\"25\" height=\"25\" x=\"0\" y=\"100\" />"
+"  </g>"
+
+"  <g id=\"marker-end\">"
+"    <path style=\"fill:none;stroke:black;stroke-width:1.7;marker-start:none;marker-mid:none;marker-end:url(#sample)\""
+"       d=\"M 0,213 L 12.5,213\" id=\"path111\" />"
+"    <rect style=\"fill:none;stroke:none\" id=\"rect222\""
+"       width=\"25\" height=\"25\" x=\"0\" y=\"200\" />"
+"  </g>"
+
+"</svg>";
+
+    return sp_document_new_from_mem (buffer, strlen(buffer), FALSE);
+}
+
+static void
+ink_marker_menu_create_menu(Gtk::Menu *m, gchar const *menu_id, SPDocument *doc, SPDocument *sandbox)
+{
+    static SPDocument *markers_doc = NULL;
+
+    // add "None"
+    Gtk::MenuItem *i = new Gtk::MenuItem();
+    i->show();
+
+    i->set_data("marker", (void *) "none");
+
+    Gtk::HBox *hb = new Gtk::HBox(false,  MARKER_ITEM_MARGIN);
+    hb->show();
+
+    Gtk::Label *l = new Gtk::Label( _("None") );
+    l->show();
+    l->set_alignment(0.0, 0.5);
+
+    hb->pack_start(*l, true, true, 0);
+
+    hb->show();
+    i->add(*hb);
+    m->append(*i);
+
+    // find and load markers.svg
+    if (markers_doc == NULL) {
+        char *markers_source = g_build_filename(INKSCAPE_MARKERSDIR, "markers.svg", NULL);
+        if (Inkscape::IO::file_test(markers_source, G_FILE_TEST_IS_REGULAR)) {
+            markers_doc = sp_document_new(markers_source, FALSE);
+        }
+        g_free(markers_source);
+    }
+
+    // suck in from current doc
+    sp_marker_list_from_doc(m, NULL, doc, markers_doc, sandbox, menu_id);
+
+    // add separator
+    {
+        //Gtk::Separator *i = gtk_separator_menu_item_new();
+        Gtk::SeparatorMenuItem *i = new Gtk::SeparatorMenuItem();
+        i->show();
+        m->append(*i);
+    }
+
+    // suck in from markers.svg
+    if (markers_doc) {
+        sp_document_ensure_up_to_date(doc);
+        sp_marker_list_from_doc(m, doc, markers_doc, NULL, sandbox, menu_id);
+    }
+
+}
+
+/**
+ * Creates a menu widget to display markers from markers.svg
+ */
+static Gtk::OptionMenu *
+ink_marker_menu(Gtk::Widget */*tbl*/, gchar const *menu_id, SPDocument *sandbox)
+{
+    SPDesktop *desktop = inkscape_active_desktop();
+    SPDocument *doc = sp_desktop_document(desktop);
+    Gtk::OptionMenu *mnu = new Gtk::OptionMenu();
+
+    /* Create new menu widget */
+    Gtk::Menu *m = new Gtk::Menu();
+    m->show();
+
+    mnu->set_data("updating", (gpointer) FALSE);
+
+    if (!doc) {
+        Gtk::MenuItem *i = new Gtk::MenuItem(_("No document selected"));
+        i->show();
+        m->append(*i);
+        mnu->set_sensitive(false);
+
+    } else {
+        ink_marker_menu_create_menu(m, menu_id, doc, sandbox);
+
+        mnu->set_sensitive(true);
+    }
+
+    mnu->set_data("menu_id", const_cast<gchar *>(menu_id));
+    mnu->set_menu(*m);
+
+    /* Set history */
+    mnu->set_history(0);
+
+    return mnu;
+}
+
+/**
+ * Handles when user selects one of the markers from the marker menu.
+ * Defines a uri string to refer to it, then applies it to all selected
+ * items in the current desktop.
+ */
+static void
+sp_marker_select(Gtk::OptionMenu *mnu, Gtk::Container *spw, SPMarkerLoc const which)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    SPDesktop *desktop = inkscape_active_desktop();
+    SPDocument *document = sp_desktop_document(desktop);
+    if (!document) {
+        return;
+    }
+
+    /* Get Marker */
+    if (!mnu->get_menu()->get_active()->get_data("marker"))
+    {
+        return;
+    }
+    gchar *markid = static_cast<gchar *>(mnu->get_menu()->get_active()->get_data("marker"));
+    gchar const *marker = "";
+    if (strcmp(markid, "none")) {
+       gchar *stockid = static_cast<gchar *>(mnu->get_menu()->get_active()->get_data("stockid"));
+
+       gchar *markurn = markid;
+       if (!strcmp(stockid,"true")) markurn = g_strconcat("urn:inkscape:marker:",markid,NULL);
+       SPObject *mark = get_stock_item(markurn);
+       if (mark) {
+            Inkscape::XML::Node *repr = SP_OBJECT_REPR(mark);
+            marker = g_strconcat("url(#", repr->attribute("id"), ")", NULL);
+        }
+    } else {
+        marker = markid;
+    }
+    SPCSSAttr *css = sp_repr_css_attr_new();
+    gchar const *menu_id = static_cast<gchar const *>(mnu->get_data("menu_id"));
+    sp_repr_css_set_property(css, menu_id, marker);
+
+    // Also update the marker dropdown menus, so the document's markers
+    // show up at the top of the menu
+//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
+    ink_markers_menu_update(spw, which);
+
+    Inkscape::Selection *selection = sp_desktop_selection(desktop);
+    GSList const *items = selection->itemList();
+    for (; items != NULL; items = items->next) {
+         SPItem *item = (SPItem *) items->data;
+         if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) // can't set marker to rect, until it's converted to using <path>
+             continue;
+         Inkscape::XML::Node *selrepr = SP_OBJECT_REPR((SPItem *) items->data);
+         if (selrepr) {
+             sp_repr_css_change_recursive(selrepr, css, "style");
+         }
+         SP_OBJECT(items->data)->requestModified(SP_OBJECT_MODIFIED_FLAG);
+         SP_OBJECT(items->data)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+     }
+
+    sp_repr_css_attr_unref(css);
+
+    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
+                     _("Set markers"));
+
+};
+
+static unsigned int
+ink_marker_menu_get_pos(Gtk::Menu *mnu, gchar const *markname)
+{
+    if (markname == NULL)
+        markname = static_cast<gchar const *>(mnu->get_active()->get_data("marker"));
+
+    if (markname == NULL)
+        return 0;
+
+    std::vector<Gtk::Widget *> kids = mnu->get_children();
+    unsigned int i = 0;
+    for (; i < kids.size();) {
+        gchar const *mark = static_cast<gchar const *>(kids[i]->get_data("marker"));
+        if (mark && strcmp(mark, markname) == 0) {
+            break;
+        }
+        ++i;
+    }
+
+    return i;
+}
+
+static void
+ink_markers_menu_update(Gtk::Container* /*spw*/, SPMarkerLoc const which) {
+    SPDesktop  *desktop = inkscape_active_desktop();
+    SPDocument *document = sp_desktop_document(desktop);
+    SPDocument *sandbox = ink_markers_preview_doc ();
+    Gtk::Menu  *m;
+    int        pos;
+
+    // TODO: this code can be shortened by abstracting out marker_(start|mid|end)_...
+    switch (which) {
+        case SP_MARKER_LOC_START:
+            marker_start_menu_connection.block();
+            pos = ink_marker_menu_get_pos(marker_start_menu->get_menu(), NULL);
+            m = new Gtk::Menu();
+            m->show();
+            ink_marker_menu_create_menu(m, "marker-start", document, sandbox);
+            marker_start_menu->remove_menu();
+            marker_start_menu->set_menu(*m);
+            marker_start_menu->set_history(pos);
+            marker_start_menu_connection.unblock();
+            break;
+
+        case SP_MARKER_LOC_MID:
+            marker_mid_menu_connection.block();
+            pos = ink_marker_menu_get_pos(marker_mid_menu->get_menu(), NULL);
+            m = new Gtk::Menu();
+            m->show();
+            ink_marker_menu_create_menu(m, "marker-mid", document, sandbox);
+            marker_mid_menu->remove_menu();
+            marker_mid_menu->set_menu(*m);
+            marker_mid_menu->set_history(pos);
+            marker_mid_menu_connection.unblock();
+            break;
+
+        case SP_MARKER_LOC_END:
+            marker_end_menu_connection.block();
+            pos = ink_marker_menu_get_pos(marker_end_menu->get_menu(), NULL);
+            m = new Gtk::Menu();
+            m->show();
+            ink_marker_menu_create_menu(m, "marker-end", document, sandbox);
+            marker_end_menu->remove_menu();
+            marker_end_menu->set_menu(*m);
+            marker_end_menu->set_history(pos);
+            marker_end_menu_connection.unblock();
+            break;
+        default:
+            g_assert_not_reached();
+    }
+}
+
+/**
+ * Sets the stroke width units for all selected items.
+ * Also handles absolute and dimensionless units.
+ */
+static gboolean stroke_width_set_unit(SPUnitSelector *,
+                                      SPUnit const *old,
+                                      SPUnit const *new_units,
+                                      Gtk::Container *spw)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+
+    if (!desktop) {
+        return FALSE;
+    }
+
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+    if (selection->isEmpty())
+        return FALSE;
+
+    GSList const *objects = selection->itemList();
+
+    if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE) &&
+       (new_units->base == SP_UNIT_DIMENSIONLESS)) {
+
+        /* Absolute to percentage */
+        spw->set_data ("update", GUINT_TO_POINTER (TRUE));
+
+        Gtk::Adjustment *a = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
+        float w = sp_units_get_pixels (a->get_value(), *old);
+
+        gdouble average = stroke_average_width (objects);
+
+        if (average == NR_HUGE || average == 0)
+            return FALSE;
+
+        a->set_value (100.0 * w / average);
+
+        spw->set_data ("update", GUINT_TO_POINTER (FALSE));
+        return TRUE;
+
+    } else if ((old->base == SP_UNIT_DIMENSIONLESS) &&
+              (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) {
+
+        /* Percentage to absolute */
+        spw->set_data ("update", GUINT_TO_POINTER (TRUE));
+
+        Gtk::Adjustment *a = static_cast<Gtk::Adjustment *>(spw->get_data ("width"));
+
+        gdouble average = stroke_average_width (objects);
+
+        a->set_value (sp_pixels_get_units (0.01 * a->get_value() * average, *new_units));
+
+        spw->set_data ("update", GUINT_TO_POINTER (FALSE));
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+
+/**
+ * \brief  Creates a new widget for the line stroke style.
+ *
+ */
+Gtk::Container *
+sp_stroke_style_line_widget_new(void)
+{
+    Gtk::Widget *us;
+    SPDashSelector *ds;
+    GtkWidget *us_old, *spw_old;
+    Gtk::Container *spw;
+    Gtk::Table *t;
+    Gtk::Adjustment *a;
+    Gtk::SpinButton *sb;
+    Gtk::RadioButton *tb;
+    Gtk::HBox *f, *hb;
+
+    Gtk::Tooltips *tt = new Gtk::Tooltips();
+
+    spw_old = sp_widget_new_global(INKSCAPE);
+    spw = dynamic_cast<Gtk::Container *>(manage(Glib::wrap(spw_old)));
+
+    f = new Gtk::HBox(false, 0);
+    f->show();
+    spw->add(*f);
+
+    t = new Gtk::Table(3, 6, false);
+    t->show();
+    t->set_border_width(4);
+    t->set_row_spacings(4);
+    f->add(*t);
+    spw->set_data("stroke", t);
+
+    gint i = 0;
+
+    /* Stroke width */
+    spw_label(t, Q_("StrokeWidth|Width:"), 0, i);
+
+    hb = spw_hbox(t, 3, 1, i);
+
+// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate
+// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use
+// setHundredPercent to remember the aeraged width corresponding to 100%. Then the
+// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and
+// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that
+// function in desktop-style.
+
+    a = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 10.0);
+    spw->set_data("width", a);
+    sb = new Gtk::SpinButton(*a, 0.1, 3);
+    tt->set_tip(*sb, _("Stroke width"));
+    sb->show();
+
+    sp_dialog_defocus_on_enter_cpp(sb);
+
+    hb->pack_start(*sb, false, false, 0);
+    us_old = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
+    us = manage(Glib::wrap(us_old));
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (desktop)
+        sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us_old), sp_desktop_namedview(desktop)->doc_units);
+    sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us_old), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0);
+    g_signal_connect ( G_OBJECT (us_old), "set_unit", G_CALLBACK (stroke_width_set_unit), spw );
+    us->show();
+    sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT(a->gobj()) );
+    hb->pack_start(*us, FALSE, FALSE, 0);
+    spw->set_data("units", us_old);
+
+    a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw));
+    i++;
+
+    /* Join type */
+    // TRANSLATORS: The line join style specifies the shape to be used at the
+    //  corners of paths. It can be "miter", "round" or "bevel".
+    spw_label(t, _("Join:"), 0, i);
+
+    hb = spw_hbox(t, 3, 1, i);
+
+    tb = NULL;
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_MITER,
+                                hb, spw, "join", "miter");
+
+    // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner.
+    //  For an example, draw a triangle with a large stroke width and modify the
+    //  "Join" option (in the Fill and Stroke dialog).
+    tt->set_tip(*tb, _("Miter join"));
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_ROUND,
+                                hb, spw, "join", "round");
+
+    // TRANSLATORS: Round join: joining lines with a rounded corner.
+    //  For an example, draw a triangle with a large stroke width and modify the
+    //  "Join" option (in the Fill and Stroke dialog).
+    tt->set_tip(*tb, _("Round join"));
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_JOIN_BEVEL,
+                                hb, spw, "join", "bevel");
+
+    // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner.
+    //  For an example, draw a triangle with a large stroke width and modify the
+    //  "Join" option (in the Fill and Stroke dialog).
+    tt->set_tip(*tb, _("Bevel join"));
+
+    i++;
+
+    /* Miterlimit  */
+    // TRANSLATORS: Miter limit: only for "miter join", this limits the length
+    //  of the sharp "spike" when the lines connect at too sharp an angle.
+    // When two line segments meet at a sharp angle, a miter join results in a
+    //  spike that extends well beyond the connection point. The purpose of the
+    //  miter limit is to cut off such spikes (i.e. convert them into bevels)
+    //  when they become too long.
+    spw_label(t, _("Miter limit:"), 0, i);
+
+    hb = spw_hbox(t, 3, 1, i);
+
+    a = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 10.0);
+    spw->set_data("miterlimit", a);
+
+    sb = new Gtk::SpinButton(*a, 0.1, 2);
+    tt->set_tip(*sb, _("Maximum length of the miter (in units of stroke width)"));
+    sb->show();
+    spw->set_data("miterlimit_sb", sb);
+    sp_dialog_defocus_on_enter_cpp(sb);
+
+    hb->pack_start(*sb, false, false, 0);
+
+    a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw));
+    i++;
+
+    /* Cap type */
+    // TRANSLATORS: cap type specifies the shape for the ends of lines
+    spw_label(t, _("Cap:"), 0, i);
+
+    hb = spw_hbox(t, 3, 1, i);
+
+    tb = NULL;
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_BUTT,
+                                hb, spw, "cap", "butt");
+
+    // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point
+    //  of the line; the ends of the line are square
+    tt->set_tip(*tb, _("Butt cap"));
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_ROUND,
+                                hb, spw, "cap", "round");
+
+    // TRANSLATORS: Round cap: the line shape extends beyond the end point of the
+    //  line; the ends of the line are rounded
+    tt->set_tip(*tb, _("Round cap"));
+
+    tb = sp_stroke_radio_button(tb, INKSCAPE_ICON_STROKE_CAP_SQUARE,
+                                hb, spw, "cap", "square");
+
+    // TRANSLATORS: Square cap: the line shape extends beyond the end point of the
+    //  line; the ends of the line are square
+    tt->set_tip(*tb, _("Square cap"));
+
+    i++;
+
+
+    /* Dash */
+    spw_label(t, _("Dashes:"), 0, i);
+    ds = manage(new SPDashSelector);
+
+    ds->show();
+    t->attach(*ds, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
+    spw->set_data("dash", ds);
+    ds->changed_signal.connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_line_dash_changed), spw));
+    i++;
+
+    /* Drop down marker selectors*/
+    // TODO: this code can be shortened by iterating over the possible menus!
+
+    // doing this here once, instead of for each preview, to speed things up
+    SPDocument *sandbox = ink_markers_preview_doc ();
+
+    // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes
+    // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path.
+    spw_label(t, _("Start Markers:"), 0, i);
+    marker_start_menu = ink_marker_menu(spw ,"marker-start", sandbox);
+    tt->set_tip(*marker_start_menu, _("Start Markers are drawn on the first node of a path or shape"));
+    marker_start_menu_connection = marker_start_menu->signal_changed().connect(
+        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
+            sigc::ptr_fun(&sp_marker_select), marker_start_menu, spw, SP_MARKER_LOC_START));
+    marker_start_menu->show();
+    t->attach(*marker_start_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
+    spw->set_data("start_mark_menu", marker_start_menu);
+
+    i++;
+    spw_label(t, _("Mid Markers:"), 0, i);
+    marker_mid_menu = ink_marker_menu(spw ,"marker-mid", sandbox);
+    tt->set_tip(*marker_mid_menu, _("Mid Markers are drawn on every node of a path or shape except the first and last nodes"));
+    marker_mid_menu_connection = marker_mid_menu->signal_changed().connect(
+        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
+            sigc::ptr_fun(&sp_marker_select), marker_mid_menu,spw, SP_MARKER_LOC_MID));
+    marker_mid_menu->show();
+    t->attach(*marker_mid_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
+    spw->set_data("mid_mark_menu", marker_mid_menu);
+
+    i++;
+    spw_label(t, _("End Markers:"), 0, i);
+    marker_end_menu = ink_marker_menu(spw ,"marker-end", sandbox);
+    tt->set_tip(*marker_end_menu, _("End Markers are drawn on the last node of a path or shape"));
+    marker_end_menu_connection = marker_end_menu->signal_changed().connect(
+        sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>(
+            sigc::ptr_fun(&sp_marker_select), marker_end_menu, spw, SP_MARKER_LOC_END));
+    marker_end_menu->show();
+    t->attach(*marker_end_menu, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
+    spw->set_data("end_mark_menu", marker_end_menu);
+
+    i++;
+
+    // FIXME: we cheat and still use gtk+ signals
+
+    gtk_signal_connect(GTK_OBJECT(spw_old), "modify_selection",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_modified),
+                       spw);
+    gtk_signal_connect(GTK_OBJECT(spw_old), "change_selection",
+                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_changed),
+                       spw);
+
+    sp_stroke_style_line_update(spw, desktop ? sp_desktop_selection(desktop) : NULL);
+
+    return spw;
+}
+
+/**
+ * Callback for when stroke style widget is modified.
+ * Triggers update action.
+ */
+static void
+sp_stroke_style_line_selection_modified(SPWidget *,
+                                        Inkscape::Selection *selection,
+                                        guint flags,
+                                        gpointer data)
+{
+    Gtk::Container *spw = static_cast<Gtk::Container *>(data);
+    if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) {
+        sp_stroke_style_line_update(spw, selection);
+    }
+
+}
+
+/**
+ * Callback for when stroke style widget is changed.
+ * Triggers update action.
+ */
+static void
+sp_stroke_style_line_selection_changed(SPWidget *,
+                                       Inkscape::Selection *selection,
+                                       gpointer data)
+{
+    Gtk::Container *spw = static_cast<Gtk::Container *>(data);
+    sp_stroke_style_line_update(spw, selection);
+}
+
+/**
+ * Sets selector widgets' dash style from an SPStyle object.
+ */
+static void
+sp_dash_selector_set_from_style(SPDashSelector *dsel, SPStyle *style)
+{
+    if (style->stroke_dash.n_dash > 0) {
+        double d[64];
+        int len = MIN(style->stroke_dash.n_dash, 64);
+        for (int i = 0; i < len; i++) {
+            if (style->stroke_width.computed != 0)
+                d[i] = style->stroke_dash.dash[i] / style->stroke_width.computed;
+            else
+                d[i] = style->stroke_dash.dash[i]; // is there a better thing to do for stroke_width==0?
+        }
+        dsel->set_dash(len, d, style->stroke_width.computed != 0 ?
+                       style->stroke_dash.offset / style->stroke_width.computed  :
+                       style->stroke_dash.offset);
+    } else {
+        dsel->set_dash(0, NULL, 0.0);
+    }
+}
+
+/**
+ * Sets the join type for a line, and updates the stroke style widget's buttons
+ */
+static void
+sp_jointype_set (Gtk::Container *spw, unsigned const jointype)
+{
+    Gtk::RadioButton *tb = NULL;
+    switch (jointype) {
+        case SP_STROKE_LINEJOIN_MITER:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_MITER));
+            break;
+        case SP_STROKE_LINEJOIN_ROUND:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_ROUND));
+            break;
+        case SP_STROKE_LINEJOIN_BEVEL:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_BEVEL));
+            break;
+        default:
+            break;
+    }
+    sp_stroke_style_set_join_buttons(spw, tb);
+}
+
+/**
+ * Sets the cap type for a line, and updates the stroke style widget's buttons
+ */
+static void
+sp_captype_set (Gtk::Container *spw, unsigned const captype)
+{
+    Gtk::RadioButton *tb = NULL;
+    switch (captype) {
+        case SP_STROKE_LINECAP_BUTT:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_BUTT));
+            break;
+        case SP_STROKE_LINECAP_ROUND:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_ROUND));
+            break;
+        case SP_STROKE_LINECAP_SQUARE:
+            tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_SQUARE));
+            break;
+        default:
+            break;
+    }
+    sp_stroke_style_set_cap_buttons(spw, tb);
+}
+
+/**
+ * Callback for when stroke style widget is updated, including markers, cap type,
+ * join type, etc.
+ */
+static void
+sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    spw->set_data("update", GINT_TO_POINTER(TRUE));
+
+    Gtk::Table *sset = static_cast<Gtk::Table *>(spw->get_data("stroke"));
+    Gtk::Adjustment *width = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
+    Gtk::Adjustment *ml = static_cast<Gtk::Adjustment *>(spw->get_data("miterlimit"));
+    SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units"));
+    SPDashSelector *dsel = static_cast<SPDashSelector *>(spw->get_data("dash"));
+
+    // create temporary style
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
+    // query into it
+    int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
+    int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT);
+    int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP);
+    int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
+
+    if (result_sw == QUERY_STYLE_NOTHING) {
+        /* No objects stroked, set insensitive */
+        sset->set_sensitive(false);
+
+        spw->set_data("update", GINT_TO_POINTER(FALSE));
+        return;
+    } else {
+        sset->set_sensitive(true);
+
+        SPUnit const *unit = sp_unit_selector_get_unit(us);
+
+        if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) {
+            sp_unit_selector_set_unit(us, &sp_unit_get_by_id(SP_UNIT_PERCENT));
+        } else {
+            // same width, or only one object; no sense to keep percent, switch to absolute
+            if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) {
+                sp_unit_selector_set_unit(us, sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units);
+            }
+        }
+
+        unit = sp_unit_selector_get_unit(us);
+
+        if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) {
+            double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit);
+            width->set_value(avgwidth);
+        } else {
+            width->set_value(100);
+        }
+    }
+
+    if (result_ml != QUERY_STYLE_NOTHING)
+        ml->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness?
+
+    if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) {
+        sp_jointype_set(spw, query->stroke_linejoin.value);
+    } else {
+        sp_stroke_style_set_join_buttons(spw, NULL);
+    }
+
+    if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) {
+        sp_captype_set (spw, query->stroke_linecap.value);
+    } else {
+        sp_stroke_style_set_cap_buttons(spw, NULL);
+    }
+
+    sp_style_unref(query);
+
+    if (!sel || sel->isEmpty())
+        return;
+
+    GSList const *objects = sel->itemList();
+    SPObject * const object = SP_OBJECT(objects->data);
+    SPStyle * const style = SP_OBJECT_STYLE(object);
+
+    /* Markers */
+    sp_stroke_style_update_marker_menus(spw, objects); // FIXME: make this desktop query too
+
+    /* Dash */
+    sp_dash_selector_set_from_style(dsel, style); // FIXME: make this desktop query too
+
+    sset->set_sensitive(true);
+
+    spw->set_data("update", GINT_TO_POINTER(FALSE));
+}
+
+/**
+ * Sets a line's dash properties in a CSS style object.
+ */
+static void
+sp_stroke_style_set_scaled_dash(SPCSSAttr *css,
+                                int ndash, double *dash, double offset,
+                                double scale)
+{
+    if (ndash > 0) {
+        Inkscape::CSSOStringStream osarray;
+        for (int i = 0; i < ndash; i++) {
+            osarray << dash[i] * scale;
+            if (i < (ndash - 1)) {
+                osarray << ",";
+            }
+        }
+        sp_repr_css_set_property(css, "stroke-dasharray", osarray.str().c_str());
+
+        Inkscape::CSSOStringStream osoffset;
+        osoffset << offset * scale;
+        sp_repr_css_set_property(css, "stroke-dashoffset", osoffset.str().c_str());
+    } else {
+        sp_repr_css_set_property(css, "stroke-dasharray", "none");
+        sp_repr_css_set_property(css, "stroke-dashoffset", NULL);
+    }
+}
+
+/**
+ * Sets line properties like width, dashes, markers, etc. on all currently selected items.
+ */
+static void
+sp_stroke_style_scale_line(Gtk::Container *spw)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    spw->set_data("update", GINT_TO_POINTER(TRUE));
+
+    Gtk::Adjustment *wadj = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
+    SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units"));
+    SPDashSelector *dsel = static_cast<SPDashSelector *>(spw->get_data("dash"));
+    Gtk::Adjustment *ml = static_cast<Gtk::Adjustment *>(spw->get_data("miterlimit"));
+
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    SPDocument *document = sp_desktop_document (desktop);
+    Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+    GSList const *items = selection->itemList();
+
+    /* TODO: Create some standardized method */
+    SPCSSAttr *css = sp_repr_css_attr_new();
+
+    if (items) {
+
+        double width_typed = wadj->get_value();
+        double const miterlimit = ml->get_value();
+
+        SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
+
+        double *dash, offset;
+        int ndash;
+        dsel->get_dash(&ndash, &dash, &offset);
+
+        for (GSList const *i = items; i != NULL; i = i->next) {
+            /* Set stroke width */
+            double width;
+            if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) {
+                width = sp_units_get_pixels (width_typed, *unit);
+            } else { // percentage
+                gdouble old_w = SP_OBJECT_STYLE (i->data)->stroke_width.computed;
+                width = old_w * width_typed / 100;
+            }
+
+            {
+                Inkscape::CSSOStringStream os_width;
+                os_width << width;
+                sp_repr_css_set_property(css, "stroke-width", os_width.str().c_str());
+            }
+
+            {
+                Inkscape::CSSOStringStream os_ml;
+                os_ml << miterlimit;
+                sp_repr_css_set_property(css, "stroke-miterlimit", os_ml.str().c_str());
+            }
+
+            /* Set dash */
+            sp_stroke_style_set_scaled_dash(css, ndash, dash, offset, width);
+
+            sp_desktop_apply_css_recursive (SP_OBJECT(i->data), css, true);
+        }
+
+        g_free(dash);
+
+        if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) {
+            // reset to 100 percent
+            wadj->set_value(100.0);
+        }
+
+    }
+
+    // we have already changed the items, so set style without changing selection
+    // FIXME: move the above stroke-setting stuff, including percentages, to desktop-style
+    sp_desktop_set_style (desktop, css, false);
+
+    sp_repr_css_attr_unref(css);
+
+    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
+                     _("Set stroke style"));
+
+    spw->set_data("update", GINT_TO_POINTER(FALSE));
+}
+
+/**
+ * Callback for when the stroke style's width changes.
+ * Causes all line styles to be applied to all selected items.
+ */
+static void
+sp_stroke_style_width_changed(Gtk::Container *spw)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    sp_stroke_style_scale_line(spw);
+}
+
+/**
+ * Callback for when the stroke style's miterlimit changes.
+ * Causes all line styles to be applied to all selected items.
+ */
+static void
+sp_stroke_style_miterlimit_changed(Gtk::Container *spw)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    sp_stroke_style_scale_line(spw);
+}
+
+/**
+ * Callback for when the stroke style's dash changes.
+ * Causes all line styles to be applied to all selected items.
+ */
+
+static void
+sp_stroke_style_line_dash_changed(Gtk::Container *spw)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    sp_stroke_style_scale_line(spw);
+}
+
+/**
+ * \brief  This routine handles toggle events for buttons in the stroke style
+ *         dialog.
+ * When activated, this routine gets the data for the various widgets, and then
+ * calls the respective routines to update css properties, etc.
+ *
+ */
+static void
+sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw)
+{
+    if (spw->get_data("update")) {
+        return;
+    }
+
+    if (tb->get_active()) {
+
+        gchar const *join
+            = static_cast<gchar const *>(tb->get_data("join"));
+        gchar const *cap
+            = static_cast<gchar const *>(tb->get_data("cap"));
+
+        if (join) {
+            Gtk::SpinButton *ml = static_cast<Gtk::SpinButton *>(spw->get_data("miterlimit_sb"));
+            ml->set_sensitive(!strcmp(join, "miter"));
+        }
+
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+
+        /* TODO: Create some standardized method */
+        SPCSSAttr *css = sp_repr_css_attr_new();
+
+        if (join) {
+            sp_repr_css_set_property(css, "stroke-linejoin", join);
+
+            sp_desktop_set_style (desktop, css);
+
+            sp_stroke_style_set_join_buttons(spw, tb);
+        } else if (cap) {
+            sp_repr_css_set_property(css, "stroke-linecap", cap);
+
+            sp_desktop_set_style (desktop, css);
+
+            sp_stroke_style_set_cap_buttons(spw, tb);
+        }
+
+        sp_repr_css_attr_unref(css);
+
+        sp_document_done(sp_desktop_document(desktop), SP_VERB_DIALOG_FILL_STROKE,
+                         _("Set stroke style"));
+    }
+}
+
+/**
+ * Updates the join style toggle buttons
+ */
+static void
+sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active)
+{
+    Gtk::RadioButton *tb;
+
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_MITER));
+    tb->set_active(active == tb);
+
+    Gtk::SpinButton *ml = static_cast<Gtk::SpinButton *>(spw->get_data("miterlimit_sb"));
+    ml->set_sensitive(active == tb);
+
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_ROUND));
+    tb->set_active(active == tb);
+
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_JOIN_BEVEL));
+    tb->set_active(active == tb);
+}
+
+/**
+ * Updates the cap style toggle buttons
+ */
+static void
+sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active)
+{
+    Gtk::RadioButton *tb;
+
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_BUTT));
+    tb->set_active(active == tb);
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_ROUND));
+    tb->set_active(active == tb);
+    tb = static_cast<Gtk::RadioButton *>(spw->get_data(INKSCAPE_ICON_STROKE_CAP_SQUARE));
+    tb->set_active(active == tb);
+}
+
+/**
+ * Sets the current marker in the marker menu.
+ */
+static void
+ink_marker_menu_set_current(SPObject *marker, Gtk::OptionMenu *mnu)
+{
+    mnu->set_data("update", GINT_TO_POINTER(TRUE));
+
+    Gtk::Menu *m = mnu->get_menu();
+    if (marker != NULL) {
+        bool mark_is_stock = false;
+        if (SP_OBJECT_REPR(marker)->attribute("inkscape:stockid"))
+            mark_is_stock = true;
+
+        gchar *markname;
+        if (mark_is_stock)
+            markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("inkscape:stockid"));
+        else
+            markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("id"));
+
+        int markpos = ink_marker_menu_get_pos(m, markname);
+        mnu->set_history(markpos);
+
+        g_free (markname);
+    }
+    else {
+        mnu->set_history(0);
+    }
+    mnu->set_data("update", GINT_TO_POINTER(FALSE));
+}
+
+/**
+ * Updates the marker menus to highlight the appropriate marker and scroll to
+ * that marker.
+ */
+static void
+sp_stroke_style_update_marker_menus(Gtk::Container *spw, GSList const *objects)
+{
+    struct { char const *key; int loc; } const keyloc[] = {
+        { "start_mark_menu", SP_MARKER_LOC_START },
+        { "mid_mark_menu", SP_MARKER_LOC_MID },
+        { "end_mark_menu", SP_MARKER_LOC_END }
+    };
+
+    bool all_texts = true;
+    for (GSList *i = (GSList *) objects; i != NULL; i = i->next) {
+        if (!SP_IS_TEXT (i->data)) {
+            all_texts = false;
+        }
+    }
+
+    for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
+        Gtk::OptionMenu *mnu = static_cast<Gtk::OptionMenu *>(spw->get_data(keyloc[i].key));
+        // Per SVG spec, text objects cannot have markers; disable menus if only texts are selected
+        mnu->set_sensitive(!all_texts);
+    }
+
+    // We show markers of the first object in the list only
+    // FIXME: use the first in the list that has the marker of each type, if any
+    SPObject *object = SP_OBJECT(objects->data);
+
+    for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
+        // For all three marker types,
+
+        // find the corresponding menu
+        Gtk::OptionMenu *mnu = static_cast<Gtk::OptionMenu *>(spw->get_data(keyloc[i].key));
+
+        // Quit if we're in update state
+        if (mnu->get_data("update")) {
+            return;
+        }
+
+        if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) {
+            // If the object has this type of markers,
+
+            // Extract the name of the marker that the object uses
+            SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value, SP_OBJECT_DOCUMENT(object));
+            // Scroll the menu to that marker
+            ink_marker_menu_set_current(marker, mnu);
+
+        } else {
+            mnu->set_history(0);
+        }
+    }
+}
+
+
+/**
+ * Extract the actual name of the link
+ * e.g. get mTriangle from url(#mTriangle).
+ * \return Buffer containing the actual name, allocated from GLib;
+ * the caller should free the buffer when they no longer need it.
+ */
+static SPObject*
+ink_extract_marker_name(gchar const *n, SPDocument *doc)
+{
+    gchar const *p = n;
+    while (*p != '\0' && *p != '#') {
+        p++;
+    }
+
+    if (*p == '\0' || p[1] == '\0') {
+        return NULL;
+    }
+
+    p++;
+    int c = 0;
+    while (p[c] != '\0' && p[c] != ')') {
+        c++;
+    }
+
+    if (p[c] == '\0') {
+        return NULL;
+    }
+
+    gchar* b = g_strdup(p);
+    b[c] = '\0';
+
+    // FIXME: get the document from the object and let the caller pass it in
+    SPObject *marker = doc->getObjectById(b);
+    return marker;
+}
+
+/*
+  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:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h
new file mode 100644 (file)
index 0000000..b947209
--- /dev/null
@@ -0,0 +1,35 @@
+/** @file
+ * @brief  Stroke style dialog
+ */
+/* Author:
+ *   Lauris Kaplinski <lauris@ximian.com>
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_DIALOGS_STROKE_STYLE_H
+#define SEEN_DIALOGS_STROKE_STYLE_H
+
+#include <glib.h>
+
+#include <gtk/gtkwidget.h>
+
+#include "forward.h"
+#include "display/canvas-bpath.h"
+
+GtkWidget *sp_stroke_style_paint_widget_new (void);
+Gtk::Container *sp_stroke_style_line_widget_new (void);
+
+#endif
+
+/*
+  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:encoding=utf-8:textwidth=99 :
index 14acb188a1d02985b26a6e34346e68925d5865a0..e3dcbcc14a9ebfd3bd63ea2d879633c7e74f32e7 100644 (file)
@@ -36,7 +36,6 @@
 
 #include "../box3d-context.h"
 #include "../box3d.h"
-#include "calligraphic-profile-rename.h"
 #include "../conn-avoid-ref.h"
 #include "../connection-pool.h"
 #include "../connector-context.h"
@@ -87,6 +86,7 @@
 #include "../svg/css-ostringstream.h"
 #include "../tools-switch.h"
 #include "../tweak-context.h"
+#include "../ui/dialog/calligraphic-profile-rename.h"
 #include "../ui/icon-names.h"
 #include "../ui/widget/style-swatch.h"
 #include "../verbs.h"