summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2008-11-21 05:24:08 +0000
committerTed Gould <ted@canonical.com>2008-11-21 05:24:08 +0000
commit44a3a78fb6a3863c0c7f3c1193837337e68a67e4 (patch)
tree1722ee5ec6f88c881cd4124923354b3c1311501b /src/ui
parentMerge from trunk (diff)
downloadinkscape-44a3a78fb6a3863c0c7f3c1193837337e68a67e4.tar.gz
inkscape-44a3a78fb6a3863c0c7f3c1193837337e68a67e4.zip
Merge from fe-moved
(bzr r6891)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/clipboard.cpp25
-rw-r--r--src/ui/dialog/CMakeLists.txt2
-rw-r--r--src/ui/dialog/Makefile_insert48
-rw-r--r--src/ui/dialog/align-and-distribute.cpp22
-rw-r--r--src/ui/dialog/align-and-distribute.h2
-rw-r--r--src/ui/dialog/debug.cpp252
-rw-r--r--src/ui/dialog/debug.h100
-rw-r--r--src/ui/dialog/dialog-manager.cpp12
-rw-r--r--src/ui/dialog/document-properties.cpp220
-rw-r--r--src/ui/dialog/document-properties.h27
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp2
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp28
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp15
-rw-r--r--src/ui/dialog/inkscape-preferences.h8
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp1
-rw-r--r--src/ui/dialog/livepatheffect-editor.h9
-rw-r--r--src/ui/dialog/messages.cpp16
-rw-r--r--src/ui/dialog/tile.cpp884
-rw-r--r--src/ui/dialog/tile.h183
-rw-r--r--src/ui/dialog/transformation.cpp26
-rw-r--r--src/ui/view/edit-widget.cpp2
-rw-r--r--src/ui/widget/object-composite-settings.cpp4
-rw-r--r--src/ui/widget/preferences-widget.cpp60
-rw-r--r--src/ui/widget/preferences-widget.h17
-rw-r--r--src/ui/widget/style-subject.cpp8
-rw-r--r--src/ui/widget/style-subject.h6
26 files changed, 1866 insertions, 113 deletions
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index e76af958f..0dc4a1d5b 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -407,15 +407,15 @@ bool ClipboardManagerImpl::pasteSize(bool separately, bool apply_x, bool apply_y
if (separately) {
for (GSList *i = const_cast<GSList*>(selection->itemList()) ; i ; i = i->next) {
SPItem *item = SP_ITEM(i->data);
- boost::optional<Geom::Rect> obj_size = sp_item_bbox_desktop(item);
- if ( !obj_size || obj_size->isEmpty() ) continue;
+ Geom::OptRect obj_size = sp_item_bbox_desktop(item);
+ if ( !obj_size ) continue;
sp_item_scale_rel(item, _getScale(min, max, *obj_size, apply_x, apply_y));
}
}
// resize the selection as a whole
else {
- boost::optional<Geom::Rect> sel_size = selection->bounds();
- if ( sel_size && !sel_size->isEmpty() ) {
+ Geom::OptRect sel_size = selection->bounds();
+ if ( sel_size ) {
sp_selection_scale_relative(selection, sel_size->midpoint(),
_getScale(min, max, *sel_size, apply_x, apply_y));
}
@@ -571,7 +571,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection)
}
}
- boost::optional<Geom::Rect> size = selection->bounds();
+ Geom::OptRect size = selection->bounds();
if (size) {
sp_repr_set_point(_clipnode, "min", size->min());
sp_repr_set_point(_clipnode, "max", size->max());
@@ -786,7 +786,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDocument *clipdoc, bool in_place)
selection->setReprList(pasted_objects); // Change the selection to the freshly pasted objects
sp_document_ensure_up_to_date(target_document); // What does this do?
- boost::optional<Geom::Rect> sel_bbox = selection->bounds(); //In desktop coordinates
+ Geom::OptRect sel_bbox = selection->bounds(); //In desktop coordinates
// PS: We could also have used the min/max corners calculated above, instead of selection->bounds() because
// we know that after pasting the upper left corner of the selection will be aligend to the corresponding
// page corner. Using the boundingbox of the selection is more foolproof though
@@ -1083,17 +1083,14 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/)
try {
if (out == outlist.end() && target == "image/png")
{
- NRRect area;
gdouble dpi = PX_PER_IN;
guint32 bgcolor = 0x00000000;
- area.x0 = SP_ROOT(_clipboardSPDoc->root)->x.computed;
- area.y0 = SP_ROOT(_clipboardSPDoc->root)->y.computed;
- area.x1 = area.x0 + sp_document_width (_clipboardSPDoc);
- area.y1 = area.y0 + sp_document_height (_clipboardSPDoc);
+ Geom::Point origin (SP_ROOT(_clipboardSPDoc->root)->x.computed, SP_ROOT(_clipboardSPDoc->root)->y.computed);
+ Geom::Rect area = Geom::Rect(origin, origin + sp_document_dimensions(_clipboardSPDoc));
- unsigned long int width = (unsigned long int) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
- unsigned long int height = (unsigned long int) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
+ unsigned long int width = (unsigned long int) (area.width() * dpi / PX_PER_IN + 0.5);
+ unsigned long int height = (unsigned long int) (area.height() * dpi / PX_PER_IN + 0.5);
// read from namedview
Inkscape::XML::Node *nv = sp_repr_lookup_name (_clipboardSPDoc->rroot, "sodipodi:namedview");
@@ -1102,7 +1099,7 @@ void ClipboardManagerImpl::_onGet(Gtk::SelectionData &sel, guint /*info*/)
if (nv && nv->attribute("inkscape:pageopacity"))
bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
- sp_export_png_file(_clipboardSPDoc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, NULL);
+ sp_export_png_file(_clipboardSPDoc, filename, area, width, height, dpi, dpi, bgcolor, NULL, NULL, true, NULL);
}
else
{
diff --git a/src/ui/dialog/CMakeLists.txt b/src/ui/dialog/CMakeLists.txt
index abdfa4dd8..5a0d6a08e 100644
--- a/src/ui/dialog/CMakeLists.txt
+++ b/src/ui/dialog/CMakeLists.txt
@@ -9,6 +9,7 @@ ENDIF(WIN32)
SET(ui_dialog_SRC
aboutbox.cpp
align-and-distribute.cpp
+debug.cpp
dialog.cpp
dialog-manager.cpp
dock-behavior.cpp
@@ -33,6 +34,7 @@ print.cpp
scriptdialog.cpp
#session-player.cpp
text-properties.cpp
+tile.cpp
tracedialog.cpp
transformation.cpp
tree-editor.cpp
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert
index 638be2832..6c301ef40 100644
--- a/src/ui/dialog/Makefile_insert
+++ b/src/ui/dialog/Makefile_insert
@@ -6,18 +6,19 @@ ui/dialog/clean:
rm -f ui/dialog/libuidialog.a $(ui_libuidialog_a_OBJECTS)
ui_dialog_libuidialog_a_SOURCES = \
- ui/dialog/dialog-manager.cpp \
- ui/dialog/dialog-manager.h \
+ 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/debug.cpp \
+ ui/dialog/debug.h \
ui/dialog/dialog.cpp \
ui/dialog/dialog.h \
- ui/dialog/panel-dialog.h \
- ui/dialog/behavior.h \
- ui/dialog/dock-behavior.h \
+ ui/dialog/dialog-manager.cpp \
+ ui/dialog/dialog-manager.h \
ui/dialog/dock-behavior.cpp \
- ui/dialog/floating-behavior.h \
- ui/dialog/floating-behavior.cpp \
- ui/dialog/align-and-distribute.cpp \
- ui/dialog/align-and-distribute.h \
+ ui/dialog/dock-behavior.h \
ui/dialog/document-metadata.cpp \
ui/dialog/document-metadata.h \
ui/dialog/document-properties.cpp \
@@ -28,40 +29,43 @@ ui_dialog_libuidialog_a_SOURCES = \
ui/dialog/filedialog.h \
ui/dialog/filedialogimpl-gtkmm.cpp \
ui/dialog/filedialogimpl-gtkmm.h \
+ ui/dialog/filedialogimpl-win32.cpp \
+ ui/dialog/filedialogimpl-win32.h \
ui/dialog/fill-and-stroke.cpp \
ui/dialog/fill-and-stroke.h \
- ui/dialog/filter-effects-dialog.h \
ui/dialog/filter-effects-dialog.cpp \
+ ui/dialog/filter-effects-dialog.h \
ui/dialog/find.cpp \
ui/dialog/find.h \
+ ui/dialog/floating-behavior.cpp \
+ ui/dialog/floating-behavior.h \
ui/dialog/inkscape-preferences.cpp \
ui/dialog/inkscape-preferences.h \
- ui/dialog/input.cpp \
- ui/dialog/input.h \
- ui/dialog/livepatheffect-editor.cpp \
- ui/dialog/livepatheffect-editor.h \
+ ui/dialog/input.cpp \
+ ui/dialog/input.h \
+ ui/dialog/livepatheffect-editor.cpp \
+ ui/dialog/livepatheffect-editor.h \
ui/dialog/memory.cpp \
ui/dialog/memory.h \
ui/dialog/messages.cpp \
ui/dialog/messages.h \
+ ui/dialog/ocaldialogs.cpp \
+ ui/dialog/ocaldialogs.h \
+ ui/dialog/panel-dialog.h \
ui/dialog/print.cpp \
ui/dialog/print.h \
ui/dialog/scriptdialog.cpp \
ui/dialog/scriptdialog.h \
- ui/dialog/svg-fonts-dialog.cpp \
+ ui/dialog/svg-fonts-dialog.cpp \
ui/dialog/svg-fonts-dialog.h \
+ ui/dialog/tile.cpp \
+ ui/dialog/tile.h \
ui/dialog/tracedialog.cpp \
ui/dialog/tracedialog.h \
ui/dialog/transformation.cpp \
ui/dialog/transformation.h \
ui/dialog/undo-history.cpp \
ui/dialog/undo-history.h \
- $(inkboard_dialogs) \
- ui/dialog/aboutbox.cpp \
- ui/dialog/aboutbox.h \
- ui/dialog/ocaldialogs.cpp \
- ui/dialog/ocaldialogs.h \
- ui/dialog/filedialogimpl-win32.h \
- ui/dialog/filedialogimpl-win32.cpp
+ $(inkboard_dialogs)
ui/dialog/aboutbox.$(OBJEXT): inkscape_version.h
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index 367a744c7..b509d041f 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -161,7 +161,7 @@ private :
selected.erase(master);
/*}*/
//Compute the anchor point
- boost::optional<Geom::Rect> b = sp_item_bbox_desktop (thing);
+ Geom::OptRect b = sp_item_bbox_desktop (thing);
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -178,7 +178,7 @@ private :
case AlignAndDistribute::DRAWING:
{
- boost::optional<Geom::Rect> b = sp_item_bbox_desktop
+ Geom::OptRect b = sp_item_bbox_desktop
( (SPItem *) sp_document_root (sp_desktop_document (desktop)) );
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
@@ -191,7 +191,7 @@ private :
case AlignAndDistribute::SELECTION:
{
- boost::optional<Geom::Rect> b = selection->bounds();
+ Geom::OptRect b = selection->bounds();
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -216,7 +216,7 @@ private :
prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
bool changed = false;
- boost::optional<Geom::Rect> b;
+ Geom::OptRect b;
if (sel_as_group)
b = selection->bounds();
@@ -331,7 +331,7 @@ private :
it != selected.end();
++it)
{
- boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it);
+ Geom::OptRect bbox = sp_item_bbox_desktop(*it);
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd));
}
@@ -607,7 +607,7 @@ private :
//Check 2 or more selected objects
if (selected.size() < 2) return;
- boost::optional<Geom::Rect> sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->bounds();
if (!sel_bbox) {
return;
}
@@ -629,7 +629,7 @@ private :
++it)
{
sp_document_ensure_up_to_date(sp_desktop_document (desktop));
- boost::optional<Geom::Rect> item_box = sp_item_bbox_desktop (*it);
+ Geom::OptRect item_box = sp_item_bbox_desktop (*it);
if (item_box) {
// find new center, staying within bbox
double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 +
@@ -780,7 +780,7 @@ void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*cont
void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
{
- daad->randomize_bbox = boost::optional<Geom::Rect>();
+ daad->randomize_bbox = Geom::OptRect();
}
/////////////////////////////////////////////////////////
@@ -961,7 +961,7 @@ AlignAndDistribute::AlignAndDistribute()
// Connect to the global selection change, to invalidate cached randomize_bbox
g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this);
- randomize_bbox = boost::optional<Geom::Rect>();
+ randomize_bbox = Geom::OptRect();
show_all_children();
@@ -1106,7 +1106,7 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
{
gdouble max = -1e18;
for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
- boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it);
+ Geom::OptRect b = sp_item_bbox_desktop (*it);
if (b) {
gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
if (dim > max) {
@@ -1123,7 +1123,7 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
{
gdouble max = 1e18;
for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
- boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it);
+ Geom::OptRect b = sp_item_bbox_desktop (*it);
if (b) {
gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
if (dim < max) {
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index 3d6b5984e..0d41bb221 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -65,7 +65,7 @@ public:
std::list<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal);
void setMode(bool nodeEdit);
- boost::optional<Geom::Rect> randomize_bbox;
+ Geom::OptRect randomize_bbox;
protected:
diff --git a/src/ui/dialog/debug.cpp b/src/ui/dialog/debug.cpp
new file mode 100644
index 000000000..b40796627
--- /dev/null
+++ b/src/ui/dialog/debug.cpp
@@ -0,0 +1,252 @@
+/** @file
+ * @brief A dialog that displays log messages
+ */
+/* Authors:
+ * Bob Jamison
+ * Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004 The Inkscape Organization
+ * 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/box.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/textview.h>
+#include <gtkmm/button.h>
+#include <gtkmm/menubar.h>
+#include <gtkmm/scrolledwindow.h>
+
+#include "debug.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+/**
+ * @brief A very simple dialog for displaying Inkscape messages - implementation
+ */
+class DebugDialogImpl : public DebugDialog, public Gtk::Dialog
+{
+public:
+ DebugDialogImpl();
+ ~DebugDialogImpl();
+
+ void show();
+ void hide();
+ void clear();
+ void message(char const *msg);
+ void captureLogMessages();
+ void releaseLogMessages();
+
+private:
+ Gtk::MenuBar menuBar;
+ Gtk::Menu fileMenu;
+ Gtk::ScrolledWindow textScroll;
+ Gtk::TextView messageText;
+
+ //Handler ID's
+ guint handlerDefault;
+ guint handlerGlibmm;
+ guint handlerAtkmm;
+ guint handlerPangomm;
+ guint handlerGdkmm;
+ guint handlerGtkmm;
+};
+
+void DebugDialogImpl::clear()
+{
+ Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
+ buffer->erase(buffer->begin(), buffer->end());
+}
+
+DebugDialogImpl::DebugDialogImpl()
+{
+ set_title(_("Messages"));
+ set_size_request(300, 400);
+
+ Gtk::VBox *mainVBox = get_vbox();
+
+ //## Add a menu for clear()
+ menuBar.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_File"), fileMenu) );
+ fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_Clear"),
+ sigc::mem_fun(*this, &DebugDialogImpl::clear) ) );
+ fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Capture log messages"),
+ sigc::mem_fun(*this, &DebugDialogImpl::captureLogMessages) ) );
+ fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Release log messages"),
+ sigc::mem_fun(*this, &DebugDialogImpl::releaseLogMessages) ) );
+ mainVBox->pack_start(menuBar, Gtk::PACK_SHRINK);
+
+
+ //### Set up the text widget
+ messageText.set_editable(false);
+ textScroll.add(messageText);
+ textScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
+ mainVBox->pack_start(textScroll);
+
+ show_all_children();
+
+ message("ready.");
+ message("enable log display by setting ");
+ message("dialogs.debug 'redirect' attribute to 1 in preferences.xml");
+
+ handlerDefault = 0;
+ handlerGlibmm = 0;
+ handlerAtkmm = 0;
+ handlerPangomm = 0;
+ handlerGdkmm = 0;
+ handlerGtkmm = 0;
+}
+
+
+DebugDialog *DebugDialog::create()
+{
+ DebugDialog *dialog = new DebugDialogImpl();
+ return dialog;
+}
+
+DebugDialogImpl::~DebugDialogImpl()
+{
+}
+
+void DebugDialogImpl::show()
+{
+ //call super()
+ Gtk::Dialog::show();
+ //sp_transientize((GtkWidget *)gobj()); //Make transient
+ raise();
+ Gtk::Dialog::present();
+}
+
+void DebugDialogImpl::hide()
+{
+ // call super
+ Gtk::Dialog::hide();
+}
+
+void DebugDialogImpl::message(char const *msg)
+{
+ Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
+ Glib::ustring uMsg = msg;
+ if (uMsg[uMsg.length()-1] != '\n')
+ uMsg += '\n';
+ buffer->insert (buffer->end(), uMsg);
+}
+
+/* static instance, to reduce dependencies */
+static DebugDialog *debugDialogInstance = NULL;
+
+DebugDialog *DebugDialog::getInstance()
+{
+ if (!debugDialogInstance) {
+ debugDialogInstance = new DebugDialogImpl();
+ }
+ return debugDialogInstance;
+}
+
+
+
+void DebugDialog::showInstance()
+{
+ DebugDialog *debugDialog = getInstance();
+ debugDialog->show();
+}
+
+
+
+
+/*##### THIS IS THE IMPORTANT PART ##### */
+void dialogLoggingFunction(const gchar */*log_domain*/,
+ GLogLevelFlags /*log_level*/,
+ const gchar *messageText,
+ gpointer user_data)
+{
+ DebugDialogImpl *dlg = (DebugDialogImpl *)user_data;
+ dlg->message(messageText);
+}
+
+
+void DebugDialogImpl::captureLogMessages()
+{
+ /*
+ This might likely need more code, to capture Gtkmm
+ and Glibmm warnings, or maybe just simply grab stdout/stderr
+ */
+ GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
+ G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE |
+ G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG);
+ if ( !handlerDefault ) {
+ handlerDefault = g_log_set_handler(NULL, flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ if ( !handlerGlibmm ) {
+ handlerGlibmm = g_log_set_handler("glibmm", flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ if ( !handlerAtkmm ) {
+ handlerAtkmm = g_log_set_handler("atkmm", flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ if ( !handlerPangomm ) {
+ handlerPangomm = g_log_set_handler("pangomm", flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ if ( !handlerGdkmm ) {
+ handlerGdkmm = g_log_set_handler("gdkmm", flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ if ( !handlerGtkmm ) {
+ handlerGtkmm = g_log_set_handler("gtkmm", flags,
+ dialogLoggingFunction, (gpointer)this);
+ }
+ message("log capture started");
+}
+
+void DebugDialogImpl::releaseLogMessages()
+{
+ if ( handlerDefault ) {
+ g_log_remove_handler(NULL, handlerDefault);
+ handlerDefault = 0;
+ }
+ if ( handlerGlibmm ) {
+ g_log_remove_handler("glibmm", handlerGlibmm);
+ handlerGlibmm = 0;
+ }
+ if ( handlerAtkmm ) {
+ g_log_remove_handler("atkmm", handlerAtkmm);
+ handlerAtkmm = 0;
+ }
+ if ( handlerPangomm ) {
+ g_log_remove_handler("pangomm", handlerPangomm);
+ handlerPangomm = 0;
+ }
+ if ( handlerGdkmm ) {
+ g_log_remove_handler("gdkmm", handlerGdkmm);
+ handlerGdkmm = 0;
+ }
+ if ( handlerGtkmm ) {
+ g_log_remove_handler("gtkmm", handlerGtkmm);
+ handlerGtkmm = 0;
+ }
+ message("log capture discontinued");
+}
+
+
+
+} //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/debug.h b/src/ui/dialog/debug.h
new file mode 100644
index 000000000..f2ad61dd4
--- /dev/null
+++ b/src/ui/dialog/debug.h
@@ -0,0 +1,100 @@
+/** @file
+ * @brief Dialog for displaying Inkscape messages
+ */
+/* Authors:
+ * Bob Jamison
+ * Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004 The Inkscape Organization
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_UI_DIALOGS_DEBUGDIALOG_H
+#define SEEN_UI_DIALOGS_DEBUGDIALOG_H
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+
+/**
+ * @brief A very simple dialog for displaying Inkscape messages.
+ *
+ * Messages sent to g_log(), g_warning(), g_message(), ets, are routed here,
+ * in order to avoid messing with the startup console.
+ */
+class DebugDialog
+{
+public:
+ DebugDialog() {};
+ /**
+ * Factory method
+ */
+ static DebugDialog *create();
+
+ /**
+ * Destructor
+ */
+ virtual ~DebugDialog() {};
+
+
+ /**
+ * Show the dialog
+ */
+ virtual void show() = 0;
+
+ /**
+ * Do not show the dialog
+ */
+ virtual void hide() = 0;
+
+ /**
+ * @brief Clear all information from the dialog
+ *
+ * Also a public method. Remove all text from the dialog
+ */
+ virtual void clear() = 0;
+
+ /**
+ * Display a message
+ */
+ virtual void message(char const *msg) = 0;
+
+ /**
+ * Redirect g_log() messages to this widget
+ */
+ virtual void captureLogMessages() = 0;
+
+ /**
+ * Return g_log() messages to normal handling
+ */
+ virtual void releaseLogMessages() = 0;
+
+ /**
+ * Factory method. Use this to create a new DebugDialog
+ */
+ static DebugDialog *getInstance();
+
+ /**
+ * Show the instance above
+ */
+ static void showInstance();
+};
+
+} //namespace Dialogs
+} //namespace UI
+} //namespace Inkscape
+
+#endif /* __DEBUGDIALOG_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index e73200a1f..7a8947adf 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -1,13 +1,13 @@
-/**
- * \brief Object for managing a set of dialogs, including their signals and
+/** @file
+ * @brief Object for managing a set of dialogs, including their signals and
* construction/caching/destruction of them.
- *
- * Authors:
+ */
+/* Authors:
* Bryce W. Harrington <bryce@bryceharrington.org>
* Jon Phillips <jon@rejon.org>
* Gustav Broberg <broberg@kth.se>
*
- * Copyright (C) 2004--2007 Authors
+ * Copyright (C) 2004-2007 Authors
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -34,13 +34,13 @@
#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/tiledialog.h"
#include "dialogs/iconpreview.h"
#include "ui/dialog/floating-behavior.h"
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 7c738c503..acf4dbb54 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -26,20 +26,30 @@
#include "ui/widget/scalar-unit.h"
#include "xml/node-event-vector.h"
+#include "xml/repr.h"
#include "helper/units.h"
#include "preferences.h"
#include "inkscape.h"
+#include "io/sys.h"
#include "verbs.h"
#include "document.h"
#include "desktop-handles.h"
#include "desktop.h"
#include "sp-namedview.h"
+#include "sp-object-repr.h"
+#include "sp-root.h"
#include "widgets/icon.h"
#include "document-properties.h"
#include "display/canvas-grid.h"
+#if ENABLE_LCMS
+#include <lcms.h>
+//#include "color-profile-fns.h"
+#include "color-profile.h"
+#endif // ENABLE_LCMS
+
using std::pair;
namespace Inkscape {
@@ -82,7 +92,7 @@ DocumentProperties::getInstance()
DocumentProperties::DocumentProperties()
: UI::Widget::Panel ("", "/dialogs/documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
_page_page(1, 1, true, true), _page_guides(1, 1),
- _page_snap(1, 1), _page_snap_dtls(1, 1),
+ _page_snap(1, 1), _page_snap_dtls(1, 1), _page_cms(1, 1),
//---------------------------------------------------------------
_rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false),
_rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false),
@@ -100,7 +110,6 @@ DocumentProperties::DocumentProperties()
_rcp_hgui(_("_Highlight color:"), _("Highlighted guideline color"), _("Color of a guideline when it is under mouse"), "guidehicolor", "guidehiopacity", _wr),
//---------------------------------------------------------------
_rcbs(_("_Enable snapping"), _("Toggle snapping on or off"), "inkscape:snap-global", _wr),
- _rcbsi(_("_Enable snap indicator"), _("After snapping, a symbol is drawn at the point that has snapped"), "inkscape:snap-indicator", _wr),
_rcbsnbb(_("_Bounding box corners"), _("Only available in the selector tool: snap bounding box corners to guides, to grids, and to other bounding boxes (but not to nodes or paths)"),
"inkscape:snap-bbox", _wr),
_rcbsnn(_("_Nodes"), _("Snap nodes (e.g. path nodes, special points in shapes, gradient handles, text base points, transformation origins, etc.) to guides, to grids, to paths and to other nodes"),
@@ -135,12 +144,16 @@ DocumentProperties::DocumentProperties()
_notebook.append_page(_grids_vbox, _("Grids"));
_notebook.append_page(_page_snap, _("Snap"));
_notebook.append_page(_page_snap_dtls, _("Snap points"));
+ _notebook.append_page(_page_cms, _("Color Management"));
build_page();
build_guides();
build_gridspage();
build_snap();
build_snap_dtls();
+#if ENABLE_LCMS
+ build_cms();
+#endif // ENABLE_LCMS
_grids_button_new.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onNewGrid));
_grids_button_remove.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onRemoveGrid));
@@ -312,8 +325,6 @@ DocumentProperties::build_snap()
slaves.clear();
slaves.push_back(&_rcbsnn);
slaves.push_back(&_rcbsnbb);
- slaves.push_back(&_rcbsi);
-
_rcbs.setSlaveWidgets(slaves);
Gtk::Label *label_g = manage (new Gtk::Label);
@@ -331,7 +342,6 @@ DocumentProperties::build_snap()
{
label_g, 0,
0, &_rcbs,
- 0, &_rcbsi,
0, 0,
label_w, 0,
0, &_rcbsnn,
@@ -375,12 +385,208 @@ DocumentProperties::build_snap_dtls()
0, 0,
label_m, 0,
0, &_rcbic,
- 0, &_rcbsm
+ 0, &_rcbsm
};
attach_all(_page_snap_dtls.table(), array, G_N_ELEMENTS(array));
}
+#if ENABLE_LCMS
+static void
+lcms_profile_get_name (cmsHPROFILE profile, const gchar **name)
+{
+ if (profile)
+ {
+ *name = cmsTakeProductDesc (profile);
+
+ if (! *name)
+ *name = cmsTakeProductName (profile);
+
+ if (*name && ! g_utf8_validate (*name, -1, NULL))
+ *name = _("(invalid UTF-8 string)");
+ }
+ else
+ {
+ *name = _("None");
+ }
+}
+
+void
+DocumentProperties::populate_available_profiles(){
+
+ // add "None"
+/* Gtk::MenuItem *i = new Gtk::MenuItem();
+ i->show();
+
+ i->set_data("filepath", NULL);
+ i->set_data("name", _("None"));
+
+ Gtk::HBox *hb = new Gtk::HBox(false, 0);
+ 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);
+ _menu.append(*i);
+*/
+ std::list<gchar *> sources;
+ sources.push_back( profile_path("color/icc") );
+ //sources.push_back( g_strdup(INKSCAPE_COLORPROFILESDIR) );
+
+ int index = 1;
+
+ // 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(_("Color profiles 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 );
+ gchar* full = g_build_filename(dirname, filename, NULL);
+ if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) {
+ cmsHPROFILE hProfile = cmsOpenProfileFromFile(full, "r");
+ if (hProfile != NULL){
+ const gchar* name;
+ lcms_profile_get_name(hProfile, &name);
+ Gtk::MenuItem* mi = new Gtk::MenuItem();
+ mi->set_data("filepath", g_strdup(full));
+ mi->set_data("name", g_strdup(name));
+ Gtk::HBox *hbox = new Gtk::HBox();
+ hbox->show();
+ Gtk::Label* lbl = manage(new Gtk::Label(name));
+ lbl->show();
+ hbox->pack_start(*lbl, true, true, 0);
+ mi->add(*hbox);
+ mi->show_all();
+ _menu.append(*mi);
+ // g_free((void*)name);
+ }
+ cmsCloseProfile(hProfile);
+ index++;
+ }
+ g_free(full);
+ g_free(lower);
+ }
+ g_dir_close(directory);
+ }
+ }
+
+ // toss the dirname
+ g_free(dirname);
+ sources.pop_front();
+ }
+ _menu.show_all();
+}
+
+void
+DocumentProperties::onEmbedProfile()
+{
+//store this profile in the SVG document (create <color-profile> element in the XML)
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (!desktop){
+ g_warning("No active desktop");
+ return;
+ }
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
+ Inkscape::XML::Node *cprofRepr = xml_doc->createElement("svg:color-profile");
+ cprofRepr->setAttribute("name", (gchar*) _menu.get_active()->get_data("name"));
+ cprofRepr->setAttribute("xlink:href", (gchar*) _menu.get_active()->get_data("filepath"));
+
+ /* Checks whether there is a defs element. Creates it when needed */
+ Inkscape::XML::Node *defsRepr = sp_repr_lookup_name(xml_doc, "svg:defs");
+ if (!defsRepr){
+ defsRepr = xml_doc->createElement("svg:defs");
+ xml_doc->root()->addChild(defsRepr, NULL);
+ }
+
+ g_assert(SP_ROOT(desktop->doc()->root)->defs);
+ defsRepr->addChild(cprofRepr, NULL);
+
+ Inkscape::GC::release(defsRepr);
+
+ // inform the document, so we can undo
+ sp_document_done(desktop->doc(), SP_VERB_EMBED_COLOR_PROFILE, _("Embed Color Profile"));
+
+ populate_embedded_profiles_box();
+}
+
+void
+DocumentProperties::populate_embedded_profiles_box()
+{
+ _EmbeddedProfilesListStore->clear();
+ const GSList *current = sp_document_get_resource_list( SP_ACTIVE_DOCUMENT, "iccprofile" );
+ while ( current ) {
+ SPObject* obj = SP_OBJECT(current->data);
+ Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj);
+ Gtk::TreeModel::Row row = *(_EmbeddedProfilesListStore->append());
+ row[_EmbeddedProfilesListColumns.nameColumn] = prof->name;
+// row[_EmbeddedProfilesListColumns.previewColumn] = "Color Preview";
+ current = g_slist_next(current);
+ }
+}
+
+
+void
+DocumentProperties::build_cms()
+{
+ _page_cms.show();
+
+ Gtk::Label *label_embed= manage (new Gtk::Label);
+ label_embed->set_markup (_("<b>Embedded Color Profiles:</b>"));
+ Gtk::Label *label_avail = manage (new Gtk::Label);
+ label_avail->set_markup (_("<b>Available Color Profiles:</b>"));
+
+ _embed_btn.set_label("Embed Profile");
+
+ Gtk::Widget *const array[] =
+ {
+ label_embed, 0,
+ &_EmbeddedProfilesListScroller, 0,
+ label_avail, 0,
+ &_combo_avail, &_embed_btn,
+ };
+
+ attach_all(_page_cms.table(), array, G_N_ELEMENTS(array));
+
+ populate_available_profiles();
+
+ _combo_avail.set_menu(_menu);
+ _combo_avail.set_history(0);
+ _combo_avail.show_all();
+
+ //# Set up the Embedded Profiles combo box
+ _EmbeddedProfilesListStore = Gtk::ListStore::create(_EmbeddedProfilesListColumns);
+ _EmbeddedProfilesList.set_model(_EmbeddedProfilesListStore);
+ _EmbeddedProfilesList.append_column(_("Profile Name"), _EmbeddedProfilesListColumns.nameColumn);
+// _EmbeddedProfilesList.append_column(_("Color Preview"), _EmbeddedProfilesListColumns.previewColumn);
+ _EmbeddedProfilesList.set_headers_visible(false);
+ _EmbeddedProfilesList.set_fixed_height_mode(true);
+
+ populate_embedded_profiles_box();
+
+ _EmbeddedProfilesListScroller.add(_EmbeddedProfilesList);
+ _EmbeddedProfilesListScroller.set_shadow_type(Gtk::SHADOW_IN);
+ _EmbeddedProfilesListScroller.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
+ _EmbeddedProfilesListScroller.set_size_request(-1, 90);
+
+ _embed_btn.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onEmbedProfile));
+}
+#endif // ENABLE_LCMS
+
/**
* Called for _updating_ the dialog (e.g. when a new grid was manually added in XML)
*/
@@ -515,8 +721,6 @@ DocumentProperties::update()
_rsu_gusn.setValue (nv->guidetolerance);
_rcbs.setActive (nv->snap_manager.snapprefs.getSnapEnabledGlobally());
- _rcbsi.setActive (nv->snapindicator);
-
//-----------------------------------------------------------grids page
update_gridspage();
diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h
index ab70b0d07..ff4739bfb 100644
--- a/src/ui/dialog/document-properties.h
+++ b/src/ui/dialog/document-properties.h
@@ -50,8 +50,15 @@ protected:
void build_snap();
void build_snap_dtls();
void build_gridspage();
+#if ENABLE_LCMS
+ void build_cms();
+#endif // ENABLE_LCMS
void init();
+
+ void populate_available_profiles();
+ void populate_embedded_profiles_box();
virtual void on_response (int);
+ void onEmbedProfile();
void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document);
void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop);
@@ -61,7 +68,7 @@ protected:
Gtk::Notebook _notebook;
NotebookPage _page_page, _page_guides;
- NotebookPage _page_snap, _page_snap_dtls;
+ NotebookPage _page_snap, _page_snap_dtls, _page_cms;
Gtk::VBox _grids_vbox;
Registry _wr;
@@ -74,13 +81,29 @@ protected:
RegisteredCheckButton _rcb_sgui, _rcbsng;
RegisteredColorPicker _rcp_gui, _rcp_hgui;
//---------------------------------------------------------------
- RegisteredCheckButton _rcbs, _rcbsi, _rcbsnbb, _rcbsnn, _rcbsnop;
+ RegisteredCheckButton _rcbs, _rcbsnbb, _rcbsnn, _rcbsnop;
RegisteredCheckButton _rcbsnon, _rcbsnbbp, _rcbsnbbn, _rcbsnpb;
ToleranceSlider _rsu_sno, _rsu_sn, _rsu_gusn;
//---------------------------------------------------------------
RegisteredCheckButton _rcbic, _rcbsm;
RegisteredCheckButton _rcbsigg, _rcbsils;
//---------------------------------------------------------------
+ Gtk::Menu _menu;
+ Gtk::OptionMenu _combo_avail;
+ Gtk::Button _embed_btn;
+ class EmbeddedProfilesColumns : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ EmbeddedProfilesColumns()
+ { add(nameColumn); add(previewColumn); }
+ Gtk::TreeModelColumn<Glib::ustring> nameColumn;
+ Gtk::TreeModelColumn<Glib::ustring> previewColumn;
+ };
+ EmbeddedProfilesColumns _EmbeddedProfilesListColumns;
+ Glib::RefPtr<Gtk::ListStore> _EmbeddedProfilesListStore;
+ Gtk::TreeView _EmbeddedProfilesList;
+ Gtk::ScrolledWindow _EmbeddedProfilesListScroller;
+ //---------------------------------------------------------------
Gtk::Notebook _grids_notebook;
Gtk::HBox _grids_hbox_crea;
Gtk::Label _grids_label_crea;
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index b47f2ccc7..d91af244b 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -864,7 +864,7 @@ bool FileOpenDialogImplWin32::set_svg_preview()
NRRectL bbox = {0, 0, scaledSvgWidth, scaledSvgHeight};
// write object bbox to area
- boost::optional<Geom::Rect> maybeArea(area);
+ Geom::OptRect maybeArea(area);
sp_document_ensure_up_to_date (svgDoc);
sp_item_invoke_bbox((SPItem *) svgDoc->root, maybeArea,
sp_item_i2r_affine((SPItem *)(svgDoc->root)), TRUE);
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 799bb2a24..08df7fd05 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -41,18 +41,18 @@
#include "path-prefix.h"
#include "preferences.h"
#include "selection.h"
-#include "sp-feblend.h"
-#include "sp-fecolormatrix.h"
-#include "sp-fecomponenttransfer.h"
-#include "sp-fecomposite.h"
-#include "sp-feconvolvematrix.h"
-#include "sp-fedisplacementmap.h"
-#include "sp-fedistantlight.h"
-#include "sp-femerge.h"
-#include "sp-femergenode.h"
-#include "sp-feoffset.h"
-#include "sp-fepointlight.h"
-#include "sp-fespotlight.h"
+#include "filters/blend.h"
+#include "filters/colormatrix.h"
+#include "filters/componenttransfer.h"
+#include "filters/composite.h"
+#include "filters/convolvematrix.h"
+#include "filters/displacementmap.h"
+#include "filters/distantlight.h"
+#include "filters/merge.h"
+#include "filters/mergenode.h"
+#include "filters/offset.h"
+#include "filters/pointlight.h"
+#include "filters/spotlight.h"
#include "sp-filter-primitive.h"
#include "sp-gaussian-blur.h"
@@ -84,7 +84,7 @@ int input_count(const SPFilterPrimitive* prim)
else if(SP_IS_FEMERGE(prim)) {
// Return the number of feMergeNode connections plus an extra
int count = 1;
- for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count);
+ for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count){};
return count;
}
else
@@ -1821,7 +1821,7 @@ int FilterEffectsDialog::PrimitiveList::find_index(const Gtk::TreeIter& target)
{
int i = 0;
for(Gtk::TreeIter iter = _model->children().begin();
- iter != target; ++iter, ++i);
+ iter != target; ++iter, ++i){};
return i;
}
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index d06d3a406..a436ce867 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -114,6 +114,7 @@ InkscapePreferences::InkscapePreferences()
initPageUI();
initPageMouse();
initPageScrolling();
+ initPageSnapping();
initPageSteps();
initPageWindows();
initPageMisc();
@@ -198,6 +199,20 @@ void InkscapePreferences::initPageScrolling()
_("When on, mouse wheel zooms without Ctrl and scrolls canvas with Ctrl; when off, it zooms with Ctrl and scrolls without Ctrl."));
}
+void InkscapePreferences::initPageSnapping()
+{
+
+ _snap_indicator.init( _("Enable snap indicator"), "/options/snapindicator/value", true);
+ _page_snapping.add_line( false, "", _snap_indicator, "",
+ _("After snapping, a symbol is drawn at the point that has snapped"));
+
+ _snap_delay.init("/options/snapdelay/value", 0, 1000, 50, 100, 300, 0);
+ _page_snapping.add_line( false, _("Delay (in msec):"), _snap_delay, "",
+ _("Postpone snapping as long as the mouse is moving, and then wait an additional fraction of a second. This additional delay is specified here. When set to zero or to a very small number, snapping will be immediate"), true);
+
+ this->AddPage(_page_snapping, _("Snapping"), PREFS_PAGE_SNAPPING);
+}
+
void InkscapePreferences::initPageSteps()
{
this->AddPage(_page_steps, _("Steps"), PREFS_PAGE_STEPS);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 98ecda855..a957ce657 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -72,6 +72,7 @@ enum {
PREFS_PAGE_UI,
PREFS_PAGE_MOUSE,
PREFS_PAGE_SCROLLING,
+ PREFS_PAGE_SNAPPING,
PREFS_PAGE_STEPS,
PREFS_PAGE_WINDOWS,
PREFS_PAGE_MISC
@@ -110,7 +111,7 @@ protected:
Gtk::TreeModel::Path _path_tools;
Gtk::TreeModel::Path _path_shapes;
- DialogPage _page_mouse, _page_scrolling, _page_steps, _page_tools, _page_windows,
+ DialogPage _page_mouse, _page_scrolling, _page_snapping, _page_steps, _page_tools, _page_windows,
_page_clones, _page_mask, _page_transforms, _page_filters, _page_select,
_page_importexport, _page_cms, _page_grids, _page_svgoutput, _page_misc,
_page_ui, _page_autosave, _page_bitmaps;
@@ -125,6 +126,9 @@ protected:
PrefSpinButton _scroll_wheel, _scroll_arrow_px, _scroll_arrow_acc, _scroll_auto_speed, _scroll_auto_thres;
PrefCheckButton _scroll_space;
PrefCheckButton _wheel_zoom;
+
+ Gtk::HScale *_slider_snapping_delay;
+ PrefCheckButton _snap_indicator;
PrefCombo _steps_rot_snap;
PrefCheckButton _steps_compass;
@@ -172,6 +176,7 @@ protected:
PrefSpinButton _importexport_export, _misc_recent, _misc_simpl;
ZoomCorrRulerSlider _ui_zoom_correction;
+ PrefSlider _snap_delay;
PrefSpinButton _misc_latency_skew;
PrefCheckButton _misc_comment, _misc_forkvectors, _misc_scripts, _misc_namedicon_delay;
PrefCombo _misc_small_toolbar;
@@ -255,6 +260,7 @@ protected:
void on_pagelist_selection_changed();
void initPageMouse();
void initPageScrolling();
+ void initPageSnapping();
void initPageSteps();
void initPageTools();
void initPageWindows();
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 8a7e0adeb..1c66160dd 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -27,6 +27,7 @@
#include "path-chemistry.h"
#include "live_effects/effect.h"
#include "live_effects/lpeobject.h"
+#include "live_effects/lpeobject-reference.h"
#include "gtkmm/widget.h"
#include <vector>
#include "inkscape.h"
diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h
index 370bd599a..1152e8bb8 100644
--- a/src/ui/dialog/livepatheffect-editor.h
+++ b/src/ui/dialog/livepatheffect-editor.h
@@ -19,8 +19,7 @@
#include <gtkmm/frame.h>
#include <gtkmm/tooltips.h>
#include "ui/widget/combo-enums.h"
-#include "live_effects/effect.h"
-#include "live_effects/lpeobject-reference.h"
+#include "live_effects/effect-enum.h"
#include <gtkmm/liststore.h>
#include <gtkmm/treeview.h>
#include <gtkmm/scrolledwindow.h>
@@ -29,9 +28,15 @@
class SPDesktop;
+class SPLPEItem;
namespace Inkscape {
+namespace LivePathEffect {
+ class Effect;
+ class LPEObjectReference;
+}
+
namespace UI {
namespace Dialog {
diff --git a/src/ui/dialog/messages.cpp b/src/ui/dialog/messages.cpp
index 958256310..31f9cc51e 100644
--- a/src/ui/dialog/messages.cpp
+++ b/src/ui/dialog/messages.cpp
@@ -99,8 +99,8 @@ void Messages::message(char *msg)
buffer->insert (buffer->end(), uMsg);
}
-
-void dialogLoggingFunction(const gchar */*log_domain*/,
+// dialogLoggingCallback is already used in debug.cpp
+static void dialogLoggingCallback(const gchar */*log_domain*/,
GLogLevelFlags /*log_level*/,
const gchar *messageText,
gpointer user_data)
@@ -123,27 +123,27 @@ void Messages::captureLogMessages()
G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG);
if ( !handlerDefault ) {
handlerDefault = g_log_set_handler(NULL, flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
if ( !handlerGlibmm ) {
handlerGlibmm = g_log_set_handler("glibmm", flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
if ( !handlerAtkmm ) {
handlerAtkmm = g_log_set_handler("atkmm", flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
if ( !handlerPangomm ) {
handlerPangomm = g_log_set_handler("pangomm", flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
if ( !handlerGdkmm ) {
handlerGdkmm = g_log_set_handler("gdkmm", flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
if ( !handlerGtkmm ) {
handlerGtkmm = g_log_set_handler("gtkmm", flags,
- dialogLoggingFunction, (gpointer)this);
+ dialogLoggingCallback, (gpointer)this);
}
message((char*)"log capture started");
}
diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp
new file mode 100644
index 000000000..7f45901c3
--- /dev/null
+++ b/src/ui/dialog/tile.cpp
@@ -0,0 +1,884 @@
+/*
+ * A simple dialog for creating grid type arrangements of selected objects
+ *
+ * Authors:
+ * Bob Jamison ( based off trace dialog)
+ * John Cliff
+ * Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004 Bob Jamison
+ * Copyright (C) 2004 John Cliff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+//#define DEBUG_GRID_ARRANGE 1
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtk/gtkdialog.h> //for GTK_RESPONSE* types
+#include <gtk/gtksizegroup.h>
+#include <glibmm/i18n.h>
+#include <gtkmm/stock.h>
+
+#include "verbs.h"
+#include "preferences.h"
+#include "inkscape.h"
+#include "desktop-handles.h"
+#include "selection.h"
+#include "document.h"
+#include "sp-item.h"
+#include "widgets/icon.h"
+#include "tile.h"
+
+/*
+ * Sort items by their x co-ordinates, taking account of y (keeps rows intact)
+ *
+ * <0 *elem1 goes before *elem2
+ * 0 *elem1 == *elem2
+ * >0 *elem1 goes after *elem2
+ */
+int
+sp_compare_x_position(SPItem *first, SPItem *second)
+{
+ using Geom::X;
+ using Geom::Y;
+
+ Geom::OptRect a = first->getBounds(sp_item_i2doc_affine(first));
+ Geom::OptRect b = second->getBounds(sp_item_i2doc_affine(second));
+
+ if ( !a || !b ) {
+ // FIXME?
+ return 0;
+ }
+
+ double const a_height = a->dimensions()[Y];
+ double const b_height = b->dimensions()[Y];
+
+ bool a_in_b_vert = false;
+ if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
+ a_in_b_vert = true;
+ } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
+ a_in_b_vert = true;
+ } else if (b->min()[Y] == a->min()[Y]) {
+ a_in_b_vert = true;
+ } else {
+ a_in_b_vert = false;
+ }
+
+ if (!a_in_b_vert) {
+ return -1;
+ }
+ if (a_in_b_vert && a->min()[X] > b->min()[X]) {
+ return 1;
+ }
+ if (a_in_b_vert && a->min()[X] < b->min()[X]) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Sort items by their y co-ordinates.
+ */
+int
+sp_compare_y_position(SPItem *first, SPItem *second)
+{
+ Geom::OptRect a = first->getBounds(sp_item_i2doc_affine(first));
+ Geom::OptRect b = second->getBounds(sp_item_i2doc_affine(second));
+
+ if ( !a || !b ) {
+ // FIXME?
+ return 0;
+ }
+
+ if (a->min()[Geom::Y] > b->min()[Geom::Y]) {
+ return 1;
+ }
+ if (a->min()[Geom::Y] < b->min()[Geom::Y]) {
+ return -1;
+ }
+
+ return 0;
+}
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+
+//#########################################################################
+//## E V E N T S
+//#########################################################################
+
+/*
+ *
+ * This arranges the selection in a grid pattern.
+ *
+ */
+
+void TileDialog::Grid_Arrange ()
+{
+
+ int cnt,row_cnt,col_cnt,a,row,col;
+ double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy;
+ double total_col_width,total_row_height;
+ col_width = 0;
+ row_height = 0;
+ total_col_width=0;
+ total_row_height=0;
+
+ // check for correct numbers in the row- and col-spinners
+ on_col_spinbutton_changed();
+ on_row_spinbutton_changed();
+
+ // set padding to manual values
+ paddingx = XPadSpinner.get_value();
+ paddingy = YPadSpinner.get_value();
+
+ std::vector<double> row_heights;
+ std::vector<double> col_widths;
+ std::vector<double> row_ys;
+ std::vector<double> col_xs;
+
+ int NoOfCols = NoOfColsSpinner.get_value_as_int();
+ int NoOfRows = NoOfRowsSpinner.get_value_as_int();
+
+ width = 0;
+ for (a=0;a<NoOfCols; a++){
+ col_widths.push_back(width);
+ }
+
+ height = 0;
+ for (a=0;a<NoOfRows; a++){
+ row_heights.push_back(height);
+ }
+ grid_left = 99999;
+ grid_top = 99999;
+
+ SPDesktop *desktop = getDesktop();
+ sp_document_ensure_up_to_date(sp_desktop_document(desktop));
+
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ const GSList *items = selection->itemList();
+ cnt=0;
+ for (; items != NULL; items = items->next) {
+ SPItem *item = SP_ITEM(items->data);
+ Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
+ if (!b) {
+ continue;
+ }
+
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+
+ cx = b->midpoint()[Geom::X];
+ cy = b->midpoint()[Geom::Y];
+
+ if (b->min()[Geom::X] < grid_left) {
+ grid_left = b->min()[Geom::X];
+ }
+ if (b->min()[Geom::Y] < grid_top) {
+ grid_top = b->min()[Geom::Y];
+ }
+ if (width > col_width) {
+ col_width = width;
+ }
+ if (height > row_height) {
+ row_height = height;
+ }
+ }
+
+
+ // require the sorting done before we can calculate row heights etc.
+
+ const GSList *items2 = selection->itemList();
+ GSList *rev = g_slist_copy((GSList *) items2);
+ GSList *sorted = NULL;
+ rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position);
+ sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position);
+
+
+ // Calculate individual Row and Column sizes if necessary
+
+
+ cnt=0;
+ const GSList *sizes = sorted;
+ for (; sizes != NULL; sizes = sizes->next) {
+ SPItem *item = SP_ITEM(sizes->data);
+ Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
+ if (b) {
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+ if (width > col_widths[(cnt % NoOfCols)]) {
+ col_widths[(cnt % NoOfCols)] = width;
+ }
+ if (height > row_heights[(cnt / NoOfCols)]) {
+ row_heights[(cnt / NoOfCols)] = height;
+ }
+ }
+
+ cnt++;
+ }
+
+
+ /// Make sure the top and left of the grid dont move by compensating for align values.
+ if (RowHeightButton.get_active()){
+ grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign));
+ }
+ if (ColumnWidthButton.get_active()){
+ grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign));
+ }
+
+ #ifdef DEBUG_GRID_ARRANGE
+ g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left);
+ #endif
+
+ // Calculate total widths and heights, allowing for columns and rows non uniformly sized.
+
+ if (ColumnWidthButton.get_active()){
+ total_col_width = col_width * NoOfCols;
+ col_widths.clear();
+ for (a=0;a<NoOfCols; a++){
+ col_widths.push_back(col_width);
+ }
+ } else {
+ for (a = 0; a < (int)col_widths.size(); a++)
+ {
+ total_col_width += col_widths[a] ;
+ }
+ }
+
+ if (RowHeightButton.get_active()){
+ total_row_height = row_height * NoOfRows;
+ row_heights.clear();
+ for (a=0;a<NoOfRows; a++){
+ row_heights.push_back(row_height);
+ }
+ } else {
+ for (a = 0; a < (int)row_heights.size(); a++)
+ {
+ total_row_height += row_heights[a] ;
+ }
+ }
+
+
+ Geom::OptRect sel_bbox = selection->bounds();
+ // Fit to bbox, calculate padding between rows accordingly.
+ if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
+#ifdef DEBUG_GRID_ARRANGE
+g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y));
+#endif
+ paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1);
+ paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1);
+ }
+
+/*
+ Horizontal align - Left = 0
+ Centre = 1
+ Right = 2
+
+ Vertical align - Top = 0
+ Middle = 1
+ Bottom = 2
+
+ X position is calculated by taking the grids left co-ord, adding the distance to the column,
+ then adding 1/2 the spacing multiplied by the align variable above,
+ Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it.
+
+*/
+
+ // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized.
+
+ for (a=0;a<NoOfCols; a++){
+ if (a<1) col_xs.push_back(0);
+ else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]);
+ }
+
+
+ for (a=0;a<NoOfRows; a++){
+ if (a<1) row_ys.push_back(0);
+ else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]);
+ }
+
+ cnt=0;
+ for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) {
+
+ GSList *current_row = NULL;
+ for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) {
+ current_row = g_slist_append (current_row, sorted->data);
+ sorted = sorted->next;
+ }
+
+ for (; current_row != NULL; current_row = current_row->next) {
+ SPItem *item=SP_ITEM(current_row->data);
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(item);
+ Geom::OptRect b = item->getBounds(sp_item_i2doc_affine(item));
+ Geom::Point min;
+ if (b) {
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+ min = b->min();
+ } else {
+ width = height = 0;
+ min = Geom::Point(0, 0);
+ }
+
+ row = cnt / NoOfCols;
+ col = cnt % NoOfCols;
+
+ new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
+ new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];
+
+ // signs are inverted between x and y due to y inversion
+ Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y);
+ Geom::Matrix const affine = Geom::Matrix(Geom::Translate(move));
+ sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
+ sp_item_write_transform(item, repr, item->transform, NULL);
+ SP_OBJECT (current_row->data)->updateRepr();
+ cnt +=1;
+ }
+ g_slist_free (current_row);
+ }
+
+ sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE,
+ _("Arrange in a grid"));
+
+}
+
+
+//#########################################################################
+//## E V E N T S
+//#########################################################################
+
+
+void TileDialog::_apply()
+{
+ Grid_Arrange();
+}
+
+
+/**
+ * changed value in # of columns spinbox.
+ */
+void TileDialog::on_row_spinbutton_changed()
+{
+ // quit if run by the attr_changed listener
+ if (updating) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ updating = true;
+ SPDesktop *desktop = getDesktop();
+
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+ GSList const *items = selection->itemList();
+ int selcount = g_slist_length((GSList *)items);
+
+ double PerCol = ceil(selcount / NoOfColsSpinner.get_value());
+ NoOfRowsSpinner.set_value(PerCol);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value());
+ updating=false;
+}
+
+/**
+ * changed value in # of rows spinbox.
+ */
+void TileDialog::on_col_spinbutton_changed()
+{
+ // quit if run by the attr_changed listener
+ if (updating) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ updating = true;
+ SPDesktop *desktop = getDesktop();
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+
+ GSList const *items = selection->itemList();
+ int selcount = g_slist_length((GSList *)items);
+
+ double PerRow = ceil(selcount / NoOfRowsSpinner.get_value());
+ NoOfColsSpinner.set_value(PerRow);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow);
+
+ updating=false;
+}
+
+/**
+ * changed value in x padding spinbox.
+ */
+void TileDialog::on_xpad_spinbutton_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/XPad", XPadSpinner.get_value());
+
+}
+
+/**
+ * changed value in y padding spinbox.
+ */
+void TileDialog::on_ypad_spinbutton_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/YPad", YPadSpinner.get_value());
+}
+
+
+/**
+ * checked/unchecked autosize Rows button.
+ */
+void TileDialog::on_RowSize_checkbutton_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (RowHeightButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20);
+ }
+ RowHeightBox.set_sensitive ( !RowHeightButton.get_active());
+}
+
+/**
+ * checked/unchecked autosize Rows button.
+ */
+void TileDialog::on_ColSize_checkbutton_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (ColumnWidthButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20);
+ }
+ ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active());
+}
+
+/**
+ * changed value in columns spinbox.
+ */
+void TileDialog::on_rowSize_spinbutton_changed()
+{
+ // quit if run by the attr_changed listener
+ if (updating) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ updating = true;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value());
+ updating=false;
+
+}
+
+/**
+ * changed value in rows spinbox.
+ */
+void TileDialog::on_colSize_spinbutton_changed()
+{
+ // quit if run by the attr_changed listener
+ if (updating) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ updating = true;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value());
+ updating=false;
+
+}
+
+/**
+ * changed Radio button in Spacing group.
+ */
+void TileDialog::Spacing_button_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (SpaceManualRadioButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/SpacingType", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/SpacingType", -20);
+ }
+
+ SizesHBox.set_sensitive ( SpaceManualRadioButton.get_active());
+}
+
+/**
+ * changed Radio button in Vertical Align group.
+ */
+void TileDialog::VertAlign_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (VertTopRadioButton.get_active()) {
+ VertAlign = 0;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 0);
+ } else if (VertCentreRadioButton.get_active()){
+ VertAlign = 1;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 1);
+ } else if (VertBotRadioButton.get_active()){
+ VertAlign = 2;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 2);
+ }
+}
+
+/**
+ * changed Radio button in Vertical Align group.
+ */
+void TileDialog::HorizAlign_changed()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (HorizLeftRadioButton.get_active()) {
+ HorizAlign = 0;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 0);
+ } else if (HorizCentreRadioButton.get_active()){
+ HorizAlign = 1;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 1);
+ } else if (HorizRightRadioButton.get_active()){
+ HorizAlign = 2;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 2);
+ }
+}
+
+/**
+ * Desktop selection changed
+ */
+void TileDialog::updateSelection()
+{
+ // quit if run by the attr_changed listener
+ if (updating) {
+ return;
+ }
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double col_width = 0;
+ double row_height = 0;
+ // in turn, prevent listener from responding
+ updating = true;
+ SPDesktop *desktop = getDesktop();
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ const GSList *items = selection->itemList();
+ int selcount = g_slist_length((GSList *)items);
+
+ if (NoOfColsSpinner.get_value()>1 && NoOfRowsSpinner.get_value()>1){
+ // Update the number of rows assuming number of columns wanted remains same.
+ double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value());
+ NoOfRowsSpinner.set_value(NoOfRows);
+
+ // if the selection has less than the number set for one row, reduce it appropriately
+ if (selcount<NoOfColsSpinner.get_value()) {
+ double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value());
+ NoOfColsSpinner.set_value(NoOfCols);
+ prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols);
+ }
+ } else {
+ double PerRow = ceil(sqrt(selcount));
+ double PerCol = ceil(sqrt(selcount));
+ NoOfRowsSpinner.set_value(PerRow);
+ NoOfColsSpinner.set_value(PerCol);
+ prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol));
+
+ }
+
+ updating=false;
+
+}
+
+
+
+/*##########################
+## Experimental
+##########################*/
+
+static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg)
+{
+ TileDialog *tledlg = (TileDialog *) dlg;
+ tledlg->updateSelection();
+}
+
+
+//#########################################################################
+//## C O N S T R U C T O R / D E S T R U C T O R
+//#########################################################################
+/**
+ * Constructor
+ */
+TileDialog::TileDialog()
+ : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE)
+{
+ // bool used by spin button callbacks to stop loops where they change each other.
+ updating = false;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+ // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!)
+ GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ {
+ // Selection Change signal
+ g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this);
+ }
+
+ Gtk::Box *contents = _getContents();
+
+#define MARGIN 2
+
+ //##Set up the panel
+
+ SPDesktop *desktop = getDesktop();
+
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ int selcount = 1;
+ if (!selection->isEmpty()) {
+ GSList const *items = selection->itemList();
+ selcount = g_slist_length((GSList *)items);
+ }
+
+
+ /*#### Number of Rows ####*/
+
+ double PerRow = ceil(sqrt(selcount));
+ double PerCol = ceil(sqrt(selcount));
+
+ #ifdef DEBUG_GRID_ARRANGE
+ g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount);
+ #endif
+
+ NoOfRowsLabel.set_label(_("Rows:"));
+ NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN);
+
+ NoOfRowsSpinner.set_digits(0);
+ NoOfRowsSpinner.set_increments(1, 5);
+ NoOfRowsSpinner.set_range(1.0, 100.0);
+ NoOfRowsSpinner.set_value(PerCol);
+ NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed));
+ tips.set_tip(NoOfRowsSpinner, _("Number of rows"));
+ NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN);
+ gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj());
+
+ RowHeightButton.set_label(_("Equal height"));
+ double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15);
+ if (AutoRow>0)
+ AutoRowSize=true;
+ else
+ AutoRowSize=false;
+ RowHeightButton.set_active(AutoRowSize);
+
+ NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN);
+
+ tips.set_tip(RowHeightButton, _("If not set, each row has the height of the tallest object in it"));
+ RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed));
+
+ {
+ /*#### Radio buttons to control vertical alignment ####*/
+
+ VertAlignLabel.set_label(_("Align:"));
+ VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN);
+
+ VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
+ VertAlignGroup = VertTopRadioButton.get_group();
+ VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0);
+
+ VertCentreRadioButton.set_group(VertAlignGroup);
+ VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
+ VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0);
+
+ VertBotRadioButton.set_group(VertAlignGroup);
+ VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
+ VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0);
+
+ VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1);
+ if (VertAlign == 0) {
+ VertTopRadioButton.set_active(TRUE);
+ }
+ else if (VertAlign == 1) {
+ VertCentreRadioButton.set_active(TRUE);
+ }
+ else if (VertAlign == 2){
+ VertBotRadioButton.set_active(TRUE);
+ }
+ VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN);
+ NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN);
+ }
+
+ SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN);
+
+
+ /*#### Label for X ####*/
+ padXByYLabel.set_label(" ");
+ XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN);
+ XByYLabel.set_markup(" &#215; ");
+ XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN);
+ SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN);
+ gtk_size_group_add_widget(_col2, (GtkWidget *) XByYLabelVBox.gobj());
+
+ /*#### Number of columns ####*/
+
+ NoOfColsLabel.set_label(_("Columns:"));
+ NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN);
+
+ NoOfColsSpinner.set_digits(0);
+ NoOfColsSpinner.set_increments(1, 5);
+ NoOfColsSpinner.set_range(1.0, 100.0);
+ NoOfColsSpinner.set_value(PerRow);
+ NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed));
+ tips.set_tip(NoOfColsSpinner, _("Number of columns"));
+ NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN);
+ gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj());
+
+ ColumnWidthButton.set_label(_("Equal width"));
+ double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15);
+ if (AutoCol>0)
+ AutoColSize=true;
+ else
+ AutoColSize=false;
+ ColumnWidthButton.set_active(AutoColSize);
+ NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN);
+
+ tips.set_tip(ColumnWidthButton, _("If not set, each column has the width of the widest object in it"));
+ ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed));
+
+
+ {
+ /*#### Radio buttons to control horizontal alignment ####*/
+
+ HorizAlignLabel.set_label(_("Align:"));
+ HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN);
+
+ HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
+
+ HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
+ HorizAlignGroup = HorizLeftRadioButton.get_group();
+ HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0);
+
+ HorizCentreRadioButton.set_group(HorizAlignGroup);
+ HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
+ HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0);
+
+ HorizRightRadioButton.set_group(HorizAlignGroup);
+ HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed));
+ HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0);
+
+ HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
+
+ HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1);
+ if (HorizAlign == 0) {
+ HorizLeftRadioButton.set_active(TRUE);
+ }
+ else if (HorizAlign == 1) {
+ HorizCentreRadioButton.set_active(TRUE);
+ }
+ else if (HorizAlign == 2) {
+ HorizRightRadioButton.set_active(TRUE);
+ }
+ HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN);
+ NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN);
+ }
+
+ SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN);
+
+ TileBox.pack_start(SpinsHBox, false, false, MARGIN);
+
+ {
+ /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/
+ SpaceByBBoxRadioButton.set_label(_("Fit into selection box"));
+ SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
+ SpacingGroup = SpaceByBBoxRadioButton.get_group();
+
+ SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN);
+
+ SpaceManualRadioButton.set_label(_("Set spacing:"));
+ SpaceManualRadioButton.set_group(SpacingGroup);
+ SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed));
+ SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN);
+
+ TileBox.pack_start(SpacingVBox, false, false, MARGIN);
+ }
+
+ {
+ /*#### Y Padding ####*/
+
+ GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_row");
+ YPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
+
+ YPadSpinner.set_digits(1);
+ YPadSpinner.set_increments(0.2, 2);
+ YPadSpinner.set_range(-10000, 10000);
+ double YPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15);
+ YPadSpinner.set_value(YPad);
+ YPadBox.pack_start(YPadSpinner, true, true, MARGIN);
+ tips.set_tip(YPadSpinner, _("Vertical spacing between rows (px units)"));
+ YPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed));
+ gtk_size_group_add_widget(_col1, (GtkWidget *) YPadBox.gobj());
+
+ SizesHBox.pack_start(YPadBox, false, false, MARGIN);
+ }
+
+ {
+ Gtk::HBox *spacer = new Gtk::HBox;
+ SizesHBox.pack_start(*spacer, false, false, 0);
+ gtk_size_group_add_widget(_col2, (GtkWidget *) spacer->gobj());
+ }
+
+ {
+ /*#### X padding ####*/
+
+ GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_MENU, "clonetiler_per_column");
+ XPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN);
+
+ XPadSpinner.set_digits(1);
+ XPadSpinner.set_increments(0.2, 2);
+ XPadSpinner.set_range(-10000, 10000);
+ double XPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15);
+ XPadSpinner.set_value(XPad);
+ XPadBox.pack_start(XPadSpinner, true, true, MARGIN);
+ tips.set_tip(XPadSpinner, _("Horizontal spacing between columns (px units)"));
+ XPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed));
+ gtk_size_group_add_widget(_col3, (GtkWidget *) XPadBox.gobj());
+
+ SizesHBox.pack_start(XPadBox, false, false, MARGIN);
+ }
+
+
+ TileBox.pack_start(SizesHBox, false, false, MARGIN);
+
+ contents->pack_start(TileBox);
+
+ double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15);
+ if (SpacingType>0) {
+ ManualSpacing=true;
+ } else {
+ ManualSpacing=false;
+ }
+ SpaceManualRadioButton.set_active(ManualSpacing);
+ SpaceByBBoxRadioButton.set_active(!ManualSpacing);
+ SizesHBox.set_sensitive (ManualSpacing);
+
+ //## The OK button
+ TileOkButton = addResponseButton(_("Arrange"), GTK_RESPONSE_APPLY);
+ tips.set_tip((*TileOkButton), _("Arrange selected objects"));
+
+ show_all_children();
+}
+
+} //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/tile.h b/src/ui/dialog/tile.h
new file mode 100644
index 000000000..075b2b33f
--- /dev/null
+++ b/src/ui/dialog/tile.h
@@ -0,0 +1,183 @@
+/** @file
+ * @brief Dialog for creating grid type arrangements of selected objects
+ */
+/* Authors:
+ * Bob Jamison ( based off trace dialog)
+ * John Cliff
+ * Other dudes from The Inkscape Organization
+ *
+ * Copyright (C) 2004 Bob Jamison
+ * Copyright (C) 2004 John Cliff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_UI_DIALOG_TILE_H
+#define SEEN_UI_DIALOG_TILE_H
+
+#include <gtkmm/box.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/button.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/radiobutton.h>
+
+#include "ui/widget/panel.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+
+/**
+ * Dialog for tiling an object
+ */
+class TileDialog : public UI::Widget::Panel {
+public:
+ TileDialog() ;
+ virtual ~TileDialog() {};
+
+ /**
+ * Do the actual work
+ */
+ void Grid_Arrange();
+
+ /**
+ * Respond to selection change
+ */
+ void updateSelection();
+
+ /**
+ * Callback from Apply
+ */
+ virtual void _apply();
+
+ // Callbacks from spinbuttons
+ void on_row_spinbutton_changed();
+ void on_col_spinbutton_changed();
+ void on_xpad_spinbutton_changed();
+ void on_ypad_spinbutton_changed();
+ void on_RowSize_checkbutton_changed();
+ void on_ColSize_checkbutton_changed();
+ void on_rowSize_spinbutton_changed();
+ void on_colSize_spinbutton_changed();
+ void Spacing_button_changed();
+ void VertAlign_changed();
+ void HorizAlign_changed();
+
+ static TileDialog& getInstance() {
+ static TileDialog instance;
+ return instance;
+ }
+
+private:
+ TileDialog(TileDialog const &d); // no copy
+ void operator=(TileDialog const &d); // no assign
+
+ bool userHidden;
+ bool updating;
+
+ Gtk::Notebook notebook;
+ Gtk::Tooltips tips;
+
+ Gtk::VBox TileBox;
+ Gtk::Button *TileOkButton;
+ Gtk::Button *TileCancelButton;
+
+ // Number selected label
+ Gtk::Label SelectionContentsLabel;
+
+
+ Gtk::HBox AlignHBox;
+ Gtk::HBox SpinsHBox;
+ Gtk::HBox SizesHBox;
+
+ // Number per Row
+ Gtk::VBox NoOfColsBox;
+ Gtk::Label NoOfColsLabel;
+ Gtk::SpinButton NoOfColsSpinner;
+ bool AutoRowSize;
+ Gtk::CheckButton RowHeightButton;
+
+ Gtk::VBox XByYLabelVBox;
+ Gtk::Label padXByYLabel;
+ Gtk::Label XByYLabel;
+
+ // Number per Column
+ Gtk::VBox NoOfRowsBox;
+ Gtk::Label NoOfRowsLabel;
+ Gtk::SpinButton NoOfRowsSpinner;
+ bool AutoColSize;
+ Gtk::CheckButton ColumnWidthButton;
+
+ // Vertical align
+ Gtk::Label VertAlignLabel;
+ Gtk::HBox VertAlignHBox;
+ Gtk::VBox VertAlignVBox;
+ Gtk::RadioButtonGroup VertAlignGroup;
+ Gtk::RadioButton VertCentreRadioButton;
+ Gtk::RadioButton VertTopRadioButton;
+ Gtk::RadioButton VertBotRadioButton;
+ double VertAlign;
+
+ // Horizontal align
+ Gtk::Label HorizAlignLabel;
+ Gtk::VBox HorizAlignVBox;
+ Gtk::HBox HorizAlignHBox;
+ Gtk::RadioButtonGroup HorizAlignGroup;
+ Gtk::RadioButton HorizCentreRadioButton;
+ Gtk::RadioButton HorizLeftRadioButton;
+ Gtk::RadioButton HorizRightRadioButton;
+ double HorizAlign;
+
+ // padding in x
+ Gtk::VBox XPadBox;
+ Gtk::Label XPadLabel;
+ Gtk::SpinButton XPadSpinner;
+
+ // padding in y
+ Gtk::VBox YPadBox;
+ Gtk::Label YPadLabel;
+ Gtk::SpinButton YPadSpinner;
+
+ // BBox or manual spacing
+ Gtk::VBox SpacingVBox;
+ Gtk::RadioButtonGroup SpacingGroup;
+ Gtk::RadioButton SpaceByBBoxRadioButton;
+ Gtk::RadioButton SpaceManualRadioButton;
+ bool ManualSpacing;
+
+
+
+ // Row height
+ Gtk::VBox RowHeightVBox;
+ Gtk::HBox RowHeightBox;
+ Gtk::Label RowHeightLabel;
+ Gtk::SpinButton RowHeightSpinner;
+
+ // Column width
+ Gtk::VBox ColumnWidthVBox;
+ Gtk::HBox ColumnWidthBox;
+ Gtk::Label ColumnWidthLabel;
+ Gtk::SpinButton ColumnWidthSpinner;
+};
+
+
+} //namespace Dialog
+} //namespace UI
+} //namespace Inkscape
+
+
+#endif /* __TILEDIALOG_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/transformation.cpp b/src/ui/dialog/transformation.cpp
index 899053cc9..a242aaa4c 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -457,7 +457,7 @@ Transformation::updatePageMove(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
if (!_check_move_relative.get_active()) {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
double x = bbox->min()[Geom::X];
double y = bbox->min()[Geom::Y];
@@ -478,7 +478,7 @@ void
Transformation::updatePageScale(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
double w = bbox->dimensions()[Geom::X];
double h = bbox->dimensions()[Geom::Y];
@@ -508,7 +508,7 @@ void
Transformation::updatePageSkew(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
double w = bbox->dimensions()[Geom::X];
double h = bbox->dimensions()[Geom::Y];
@@ -605,7 +605,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
if (_check_move_relative.get_active()) {
sp_selection_move_relative(selection, x, y);
} else {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
sp_selection_move_relative(selection,
x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
@@ -626,7 +626,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
it != selected.end();
++it)
{
- boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it);
+ Geom::OptRect bbox = sp_item_bbox_desktop(*it);
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.));
}
@@ -650,7 +650,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
it != selected.end();
++it)
{
- boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it);
+ Geom::OptRect bbox = sp_item_bbox_desktop(*it);
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.));
}
@@ -669,7 +669,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
}
}
} else {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
sp_selection_move_relative(selection,
x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
@@ -694,7 +694,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
Geom::Scale scale (0,0);
// the values are increments!
if (_units_scale.isAbsolute()) {
- boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item));
+ Geom::OptRect bbox(sp_item_bbox_desktop(item));
if (bbox) {
double new_width = scaleX;
if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
@@ -712,7 +712,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
sp_item_scale_rel (item, scale);
}
} else {
- boost::optional<Geom::Rect> bbox(selection->bounds());
+ Geom::OptRect bbox(selection->bounds());
if (bbox) {
Geom::Point center(bbox->midpoint()); // use rotation center?
Geom::Scale scale (0,0);
@@ -781,7 +781,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
} else { // absolute displacement
double skewX = _scalar_skew_horizontal.getValue("px");
double skewY = _scalar_skew_vertical.getValue("px");
- boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item));
+ Geom::OptRect bbox(sp_item_bbox_desktop(item));
if (bbox) {
double width = bbox->dimensions()[Geom::X];
double height = bbox->dimensions()[Geom::Y];
@@ -790,7 +790,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
}
}
} else { // transform whole selection
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
boost::optional<Geom::Point> center = selection->center();
if ( bbox && center ) {
@@ -873,7 +873,7 @@ Transformation::onMoveRelativeToggled()
//g_message("onMoveRelativeToggled: %f, %f px\n", x, y);
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
if (_check_move_relative.get_active()) {
@@ -1013,7 +1013,7 @@ Transformation::onClear()
_scalar_move_horizontal.setValue(0);
_scalar_move_vertical.setValue(0);
} else {
- boost::optional<Geom::Rect> bbox = selection->bounds();
+ Geom::OptRect bbox = selection->bounds();
if (bbox) {
_scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px");
_scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px");
diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp
index 5e7713044..dd437aad8 100644
--- a/src/ui/view/edit-widget.cpp
+++ b/src/ui/view/edit-widget.cpp
@@ -1404,7 +1404,7 @@ EditWidget::updateScrollbars (double scale)
Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)) );
SPObject* root = doc->root;
SPItem* item = SP_ITEM(root);
- boost::optional<Geom::Rect> deskarea = Geom::unify(darea, sp_item_bbox_desktop(item));
+ Geom::OptRect deskarea = Geom::unify(darea, sp_item_bbox_desktop(item));
/* Canvas region we always show unconditionally */
Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64),
diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp
index 9e39af75f..3ef4c7328 100644
--- a/src/ui/widget/object-composite-settings.cpp
+++ b/src/ui/widget/object-composite-settings.cpp
@@ -125,7 +125,7 @@ ObjectCompositeSettings::_blendBlurValueChanged()
// FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903
sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
- boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX);
double radius;
if (bbox) {
double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct?
@@ -271,7 +271,7 @@ ObjectCompositeSettings::_subjectChanged() {
case QUERY_STYLE_SINGLE:
case QUERY_STYLE_MULTIPLE_AVERAGED:
case QUERY_STYLE_MULTIPLE_SAME:
- boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX);
if (bbox) {
double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct?
_fe_cb.set_blur_sensitive(true);
diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp
index 72df1baab..395726511 100644
--- a/src/ui/widget/preferences-widget.cpp
+++ b/src/ui/widget/preferences-widget.cpp
@@ -461,6 +461,66 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl
this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
}
+void
+PrefSlider::on_slider_value_changed()
+{
+ if (this->is_visible() || freeze) //only take action if user changed value
+ {
+ freeze = true;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble(_prefs_path, _slider.get_value());
+ _sb.set_value(_slider.get_value());
+ freeze = false;
+ }
+}
+
+void
+PrefSlider::on_spinbutton_value_changed()
+{
+ if (this->is_visible() || freeze) //only take action if user changed value
+ {
+ freeze = true;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble(_prefs_path, _sb.get_value());
+ _slider.set_value(_sb.get_value());
+ freeze = false;
+ }
+}
+
+void
+PrefSlider::init(Glib::ustring const &prefs_path,
+ double lower, double upper, double step_increment, double page_increment, double default_value, int digits)
+{
+ _prefs_path = prefs_path;
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double value = prefs->getDoubleLimited(prefs_path, default_value, lower, upper);
+
+ freeze = false;
+
+ _slider.set_range (lower, upper);
+ _slider.set_increments (step_increment, page_increment);
+ _slider.set_value (value);
+ _slider.set_digits(digits);
+ _slider.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed));
+
+ _sb.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_spinbutton_value_changed));
+ _sb.set_range (lower, upper);
+ _sb.set_increments (step_increment, page_increment);
+ _sb.set_value (value);
+ _sb.set_digits(digits);
+
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
+ Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
+ alignment1->add(_sb);
+
+ table->attach(_slider, 0, 1, 0, 1);
+ table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
+
+ this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
+}
+
void PrefCombo::init(Glib::ustring const &prefs_path,
Glib::ustring labels[], int values[], int num_items, int default_value)
{
diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h
index dbc319c1a..1576184ac 100644
--- a/src/ui/widget/preferences-widget.h
+++ b/src/ui/widget/preferences-widget.h
@@ -122,6 +122,23 @@ private:
bool freeze; // used to block recursive updates of slider and spinbutton
};
+class PrefSlider : public Gtk::HBox
+{
+public:
+ void init(Glib::ustring const &prefs_path,
+ double lower, double upper, double step_increment, double page_increment, double default_value, int digits);
+
+private:
+ void on_slider_value_changed();
+ void on_spinbutton_value_changed();
+
+ Glib::ustring _prefs_path;
+ Gtk::SpinButton _sb;
+ Gtk::HScale _slider;
+ bool freeze; // used to block recursive updates of slider and spinbutton
+};
+
+
class PrefCombo : public Gtk::ComboBoxText
{
public:
diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp
index a2e8a2547..a7359242d 100644
--- a/src/ui/widget/style-subject.cpp
+++ b/src/ui/widget/style-subject.cpp
@@ -65,12 +65,12 @@ StyleSubject::iterator StyleSubject::Selection::begin() {
}
}
-boost::optional<Geom::Rect> StyleSubject::Selection::getBounds(SPItem::BBoxType type) {
+Geom::OptRect StyleSubject::Selection::getBounds(SPItem::BBoxType type) {
Inkscape::Selection *selection = _getSelection();
if (selection) {
return selection->bounds(type);
} else {
- return boost::optional<Geom::Rect>();
+ return Geom::OptRect();
}
}
@@ -143,12 +143,12 @@ StyleSubject::iterator StyleSubject::CurrentLayer::begin() {
return iterator(_getLayerSList());
}
-boost::optional<Geom::Rect> StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) {
+Geom::OptRect StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) {
SPObject *layer = _getLayer();
if (layer && SP_IS_ITEM(layer)) {
return sp_item_bbox_desktop(SP_ITEM(layer), type);
} else {
- return boost::optional<Geom::Rect>();
+ return Geom::OptRect();
}
}
diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h
index 231a88728..6f46efff5 100644
--- a/src/ui/widget/style-subject.h
+++ b/src/ui/widget/style-subject.h
@@ -44,7 +44,7 @@ public:
virtual iterator begin() = 0;
virtual iterator end() { return iterator(NULL); }
- virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0;
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0;
virtual int queryStyle(SPStyle *query, int property) = 0;
virtual void setCSS(SPCSSAttr *css) = 0;
@@ -67,7 +67,7 @@ public:
~Selection();
virtual iterator begin();
- virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
virtual int queryStyle(SPStyle *query, int property);
virtual void setCSS(SPCSSAttr *css);
@@ -88,7 +88,7 @@ public:
~CurrentLayer();
virtual iterator begin();
- virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
virtual int queryStyle(SPStyle *query, int property);
virtual void setCSS(SPCSSAttr *css);