summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiam P. White <inkscapebronyat-signgmaildotcom>2014-03-09 02:56:07 +0000
committerLiam P. White <inkscapebronyat-signgmaildotcom>2014-03-09 02:56:07 +0000
commitc515627314d3ec501dc6de928fb60b5d7895c557 (patch)
tree8a4e5c479e8b41df87494fe555934f42aa424537 /src
parentRemove all trace of the Tags dialog (diff)
parentRemove useless r variable and warning (diff)
downloadinkscape-c515627314d3ec501dc6de928fb60b5d7895c557.tar.gz
inkscape-c515627314d3ec501dc6de928fb60b5d7895c557.zip
Update to trunk
(bzr r13090.1.22)
Diffstat (limited to 'src')
-rw-r--r--src/attributes-test.h9
-rw-r--r--src/display/drawing-image.cpp3
-rw-r--r--src/display/drawing-surface.cpp2
-rw-r--r--src/event-log.cpp254
-rw-r--r--src/event-log.h24
-rw-r--r--src/extension/internal/wmf-inout.cpp167
-rw-r--r--src/gradient-drag.cpp4
-rw-r--r--src/libvpsc/generate-constraints.cpp11
-rw-r--r--src/marker.cpp4
-rw-r--r--src/selection-chemistry.cpp2
-rw-r--r--src/selection.h8
-rw-r--r--src/sp-image.cpp4
-rw-r--r--src/sp-pattern.cpp84
-rw-r--r--src/sp-use.cpp3
-rw-r--r--src/style-test.h55
-rw-r--r--src/style.cpp4
-rw-r--r--src/ui/dialog/export.cpp502
-rw-r--r--src/ui/dialog/export.h48
-rw-r--r--src/ui/dialog/symbols.cpp4
-rw-r--r--src/ui/dialog/undo-history.cpp130
-rw-r--r--src/ui/dialog/undo-history.h11
-rw-r--r--src/ui/tools/text-tool.cpp217
-rw-r--r--src/ui/tools/text-tool.h6
-rw-r--r--src/ui/tools/tool-base.h5
-rw-r--r--src/util/signal-blocker.h70
-rw-r--r--src/verbs.cpp6
26 files changed, 970 insertions, 667 deletions
diff --git a/src/attributes-test.h b/src/attributes-test.h
index eee12d3c1..ba34717ea 100644
--- a/src/attributes-test.h
+++ b/src/attributes-test.h
@@ -150,6 +150,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"in", true},
{"in2", true},
{"intercept", true},
+ {"isolation", true},
{"k", true},
{"k1", true},
{"k2", true},
@@ -181,6 +182,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"media", false},
{"method", false},
{"min", true},
+ {"mix-blend-mode", true},
{"mode", true},
{"name", true},
{"numOctaves", true},
@@ -213,6 +215,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"overflow", true},
{"overline-position", true},
{"overline-thickness", true},
+ {"paint-order", true},
{"panose-1", true},
{"path", true},
{"pathLength", false},
@@ -276,9 +279,9 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"text-align", true},
{"text-anchor", true},
{"text-decoration", true},
- {"text-decoration-line", false},
- {"text-decoration-style", false},
- {"text-decoration-color", false},
+ {"text-decoration-line", true},
+ {"text-decoration-style", true},
+ {"text-decoration-color", true},
{"text-indent", true},
{"text-rendering", true},
{"text-transform", true},
diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp
index 8fd81caac..5844c8b08 100644
--- a/src/display/drawing-image.cpp
+++ b/src/display/drawing-image.cpp
@@ -128,7 +128,8 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar
// Do nothing
break;
case SP_CSS_COLOR_RENDERING_OPTIMIZEQUALITY:
- dc.patternSetFilter( CAIRO_FILTER_BEST );
+ // In recent Cairo, BEST used Lanczos3, which is prohibitively slow
+ dc.patternSetFilter( CAIRO_FILTER_GOOD );
break;
case SP_CSS_COLOR_RENDERING_OPTIMIZESPEED:
default:
diff --git a/src/display/drawing-surface.cpp b/src/display/drawing-surface.cpp
index 94e0e1ab5..30579134b 100644
--- a/src/display/drawing-surface.cpp
+++ b/src/display/drawing-surface.cpp
@@ -123,7 +123,7 @@ DrawingSurface::scale() const
Geom::Affine
DrawingSurface::drawingTransform() const
{
- Geom::Affine ret = _scale * Geom::Translate(-_origin);
+ Geom::Affine ret = Geom::Translate(-_origin) * _scale;
return ret;
}
diff --git a/src/event-log.cpp b/src/event-log.cpp
index d0342fbe9..db680d6d2 100644
--- a/src/event-log.cpp
+++ b/src/event-log.cpp
@@ -1,34 +1,182 @@
/*
* Author:
* Gustav Broberg <broberg@kth.se>
+ * Jon A. Cruz <jon@joncruz.org>
*
- * Copyright (c) 2006, 2007 Authors
+ * Copyright (c) 2014 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include "util/signal-blocker.h"
+
#include "event-log.h"
#include <glibmm/i18n.h>
+#include <gtkmm/treemodel.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
#include "desktop.h"
#include "inkscape.h"
+#include "util/signal-blocker.h"
#include "util/ucompose.hpp"
#include "document.h"
#include "xml/repr.h"
#include "sp-object.h"
+namespace
+{
+
+class DialogConnection
+{
+public:
+ DialogConnection(Gtk::TreeView *event_list_view, Inkscape::EventLog::CallbackMap *callback_connections) :
+ _event_list_view(event_list_view),
+ _callback_connections(callback_connections),
+ _event_list_selection(_event_list_view->get_selection())
+ {
+ }
+
+ Gtk::TreeView *_event_list_view;
+
+ // Map of connections used to temporary block/unblock callbacks in a TreeView
+ Inkscape::EventLog::CallbackMap *_callback_connections;
+
+ Glib::RefPtr<Gtk::TreeSelection> _event_list_selection; /// @todo remove this and use _event_list_view's call
+};
+
+class ConnectionMatcher
+{
+public:
+ ConnectionMatcher(Gtk::TreeView *view,
+ Inkscape::EventLog::CallbackMap *callbacks) :
+ _view(view),
+ _callbacks(callbacks)
+ {
+ }
+
+ bool operator() (DialogConnection const &dlg)
+ {
+ return (_view == dlg._event_list_view) && (_callbacks == dlg._callback_connections);
+ }
+
+ Gtk::TreeView *_view;
+ Inkscape::EventLog::CallbackMap *_callbacks;
+};
+
+void addBlocker(std::vector<boost::shared_ptr<SignalBlocker> > &blockers, sigc::connection *connection)
+{
+ blockers.push_back(boost::make_shared<SignalBlocker>(connection));
+}
+
+
+} // namespace
+
namespace Inkscape {
+class EventLogPrivate
+{
+public:
+ EventLogPrivate() :
+ _connections()
+ {
+ }
+
+ bool isConnected() const
+ {
+ return !_connections.empty();
+ }
+
+ void addDialogConnection(Gtk::TreeView *event_list_view,
+ Inkscape::EventLog::CallbackMap *callback_connections,
+ Glib::RefPtr<Gtk::TreeStore> event_list_store,
+ Inkscape::EventLog::iterator &curr_event)
+ {
+ if (std::find_if(_connections.begin(), _connections.end(), ConnectionMatcher(event_list_view, callback_connections)) != _connections.end()) {
+ // skipping
+ }
+ else
+ {
+ DialogConnection dlg(event_list_view, callback_connections);
+
+ dlg._event_list_selection->set_mode(Gtk::SELECTION_SINGLE);
+
+ {
+ std::vector<boost::shared_ptr<SignalBlocker> > blockers;
+ addBlocker(blockers, &(*dlg._callback_connections)[Inkscape::EventLog::CALLB_SELECTION_CHANGE]);
+ addBlocker(blockers, &(*dlg._callback_connections)[Inkscape::EventLog::CALLB_EXPAND]);
+
+ dlg._event_list_view->expand_to_path(event_list_store->get_path(curr_event));
+ dlg._event_list_selection->select(curr_event);
+ }
+ _connections.push_back(dlg);
+ }
+ }
+
+ void removeDialogConnection(Gtk::TreeView *event_list_view, Inkscape::EventLog::CallbackMap *callback_connections)
+ {
+ std::vector<DialogConnection>::iterator it = std::find_if(_connections.begin(), _connections.end(), ConnectionMatcher(event_list_view, callback_connections));
+ if (it != _connections.end()) {
+ _connections.erase(it);
+ }
+ }
+
+ void collapseRow(Gtk::TreeModel::Path const &path)
+ {
+ std::vector<boost::shared_ptr<SignalBlocker> > blockers;
+ for (std::vector<DialogConnection>::iterator it(_connections.begin()); it != _connections.end(); ++it)
+ {
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_SELECTION_CHANGE]);
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_COLLAPSE]);
+ }
+
+ for (std::vector<DialogConnection>::iterator it(_connections.begin()); it != _connections.end(); ++it)
+ {
+ it->_event_list_view->collapse_row(path);
+ }
+ }
+
+ void selectRow(Gtk::TreeModel::Path const &path)
+ {
+ std::vector<boost::shared_ptr<SignalBlocker> > blockers;
+ for (std::vector<DialogConnection>::iterator it(_connections.begin()); it != _connections.end(); ++it)
+ {
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_SELECTION_CHANGE]);
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_EXPAND]);
+ }
+
+ for (std::vector<DialogConnection>::iterator it(_connections.begin()); it != _connections.end(); ++it)
+ {
+ it->_event_list_view->expand_to_path(path);
+ it->_event_list_selection->select(path);
+ it->_event_list_view->scroll_to_row(path);
+ }
+ }
+
+ void clearEventList(Glib::RefPtr<Gtk::TreeStore> eventListStore)
+ {
+ if (eventListStore) {
+ std::vector<boost::shared_ptr<SignalBlocker> > blockers;
+ for (std::vector<DialogConnection>::iterator it(_connections.begin()); it != _connections.end(); ++it)
+ {
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_SELECTION_CHANGE]);
+ addBlocker(blockers, &(*it->_callback_connections)[Inkscape::EventLog::CALLB_EXPAND]);
+ }
+
+ eventListStore->clear();
+ }
+ }
+
+ std::vector<DialogConnection> _connections;
+};
+
EventLog::EventLog(SPDocument* document) :
UndoStackObserver(),
- _connected (false),
+ _priv(new EventLogPrivate()),
_document (document),
_event_list_store (Gtk::TreeStore::create(_columns)),
- _event_list_selection (NULL),
- _event_list_view (NULL),
_curr_event_parent (NULL),
- _notifications_blocked (false),
- _callback_connections (NULL)
+ _notifications_blocked (false)
{
// add initial pseudo event
Gtk::TreeRow curr_row = *(_event_list_store->append());
@@ -39,16 +187,11 @@ EventLog::EventLog(SPDocument* document) :
}
EventLog::~EventLog() {
- // avoid crash by clearing entries here (see bug #1071082)
- if (_connected) {
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_EXPAND].block();
+ // avoid crash by clearing entries here (see bug #1071082)
+ _priv->clearEventList(_event_list_store);
- _event_list_store->clear();
-
- (*_callback_connections)[CALLB_EXPAND].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
- }
+ delete _priv;
+ _priv = 0;
}
void
@@ -70,10 +213,8 @@ EventLog::notifyUndoEvent(Event* log)
} else {
// if we're about to leave a branch, collapse it
- if ( !_curr_event->children().empty() && _connected ) {
- (*_callback_connections)[CALLB_COLLAPSE].block();
- _event_list_view->collapse_row(_event_list_store->get_path(_curr_event));
- (*_callback_connections)[CALLB_COLLAPSE].block(false);
+ if ( !_curr_event->children().empty() ) {
+ _priv->collapseRow(_event_list_store->get_path(_curr_event));
}
--_curr_event;
@@ -89,17 +230,9 @@ EventLog::notifyUndoEvent(Event* log)
checkForVirginity();
// update the view
- if (_connected) {
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_EXPAND].block();
-
+ if (_priv->isConnected()) {
Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
- _event_list_view->expand_to_path(curr_path);
- _event_list_selection->select(curr_path);
- _event_list_view->scroll_to_row(curr_path);
-
- (*_callback_connections)[CALLB_EXPAND].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
+ _priv->selectRow(curr_path);
}
updateUndoVerbs();
@@ -132,13 +265,7 @@ EventLog::notifyRedoEvent(Event* log)
{
// ...collapse it
- if (_connected) {
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_COLLAPSE].block();
- _event_list_view->collapse_row(_event_list_store->get_path(_curr_event->parent()));
- (*_callback_connections)[CALLB_COLLAPSE].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
- }
+ _priv->collapseRow(_event_list_store->get_path(_curr_event->parent()));
// ...and move to the next event at parent level
_curr_event = _curr_event->parent();
@@ -151,18 +278,9 @@ EventLog::notifyRedoEvent(Event* log)
checkForVirginity();
// update the view
- if (_connected) {
+ if (_priv->isConnected()) {
Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
-
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_EXPAND].block();
-
- _event_list_view->expand_to_path(curr_path);
- _event_list_selection->select(curr_path);
- _event_list_view->scroll_to_row(curr_path);
-
- (*_callback_connections)[CALLB_EXPAND].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
+ _priv->selectRow(curr_path);
}
updateUndoVerbs();
@@ -193,10 +311,8 @@ EventLog::notifyUndoCommitEvent(Event* log)
_curr_event = _last_event = curr_row;
// collapse if we're leaving a branch
- if (_curr_event_parent && _connected) {
- (*_callback_connections)[CALLB_COLLAPSE].block();
- _event_list_view->collapse_row(_event_list_store->get_path(_curr_event_parent));
- (*_callback_connections)[CALLB_COLLAPSE].block(false);
+ if (_curr_event_parent) {
+ _priv->collapseRow(_event_list_store->get_path(_curr_event_parent));
}
_curr_event_parent = (iterator)(NULL);
@@ -211,18 +327,9 @@ EventLog::notifyUndoCommitEvent(Event* log)
checkForVirginity();
// update the view
- if (_connected) {
+ if (_priv->isConnected()) {
Gtk::TreePath curr_path = _event_list_store->get_path(_curr_event);
-
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_EXPAND].block();
-
- _event_list_view->expand_to_path(curr_path);
- _event_list_selection->select(curr_path);
- _event_list_view->scroll_to_row(curr_path);
-
- (*_callback_connections)[CALLB_EXPAND].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
+ _priv->selectRow(curr_path);
}
updateUndoVerbs();
@@ -242,25 +349,14 @@ EventLog::notifyClearRedoEvent()
updateUndoVerbs();
}
-void
-EventLog::connectWithDialog(Gtk::TreeView *event_list_view, CallbackMap *callback_connections)
+void EventLog::addDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections)
{
- _event_list_view = event_list_view;
- _event_list_selection = event_list_view->get_selection();
- _event_list_selection->set_mode(Gtk::SELECTION_SINGLE);
-
- _callback_connections = callback_connections;
-
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block();
- (*_callback_connections)[CALLB_EXPAND].block();
-
- _event_list_view->expand_to_path(_event_list_store->get_path(_curr_event));
- _event_list_selection->select(_curr_event);
-
- (*_callback_connections)[CALLB_EXPAND].block(false);
- (*_callback_connections)[CALLB_SELECTION_CHANGE].block(false);
+ _priv->addDialogConnection(event_list_view, callback_connections, _event_list_store, _curr_event);
+}
- _connected = true;
+void EventLog::removeDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections)
+{
+ _priv->removeDialogConnection(event_list_view, callback_connections);
}
void
diff --git a/src/event-log.h b/src/event-log.h
index 78f0ae5d1..7e3ba6817 100644
--- a/src/event-log.h
+++ b/src/event-log.h
@@ -1,8 +1,9 @@
/*
* Author:
* Gustav Broberg <broberg@kth.se>
+ * Jon A. Cruz <jon@joncruz.org>
*
- * Copyright (c) 2006, 2007 Authors
+ * Copyright (c) 2014 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
@@ -22,12 +23,15 @@
#include <glibmm/refptr.h>
#include <gtkmm/treeselection.h>
#include <gtkmm/treeview.h>
+#include <sigc++/trackable.h>
#include "undo-stack-observer.h"
#include "event.h"
namespace Inkscape {
+class EventLogPrivate;
+
/**
* A simple log for maintaining a history of commited, undone and redone events along with their
* type. It implements the UndoStackObserver and should be registered with a
@@ -41,7 +45,7 @@ namespace Inkscape {
* expanded/collapsed state will be updated as events are commited, undone and redone. Whenever
* this happens, the event log will block the TreeView's callbacks to prevent circular updates.
*/
-class EventLog : public UndoStackObserver
+class EventLog : public UndoStackObserver, public sigc::trackable
{
public:
@@ -104,7 +108,12 @@ public:
/**
* Connect with a TreeView.
*/
- void connectWithDialog(Gtk::TreeView *event_list_view, CallbackMap *callback_connections);
+ void addDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections);
+
+ /**
+ * Disconnect from a TreeView.
+ */
+ void removeDialogConnection(Gtk::TreeView *event_list_view, CallbackMap *callback_connections);
/*
* Updates the sensitivity and names of SP_VERB_EDIT_UNDO and SP_VERB_EDIT_REDO to reflect the
@@ -113,14 +122,13 @@ public:
void updateUndoVerbs();
private:
- bool _connected; //< connected with dialog
+ EventLogPrivate *_priv;
+
SPDocument *_document; //< document that is logged
const EventModelColumns _columns;
Glib::RefPtr<Gtk::TreeStore> _event_list_store;
- Glib::RefPtr<Gtk::TreeSelection> _event_list_selection;
- Gtk::TreeView *_event_list_view;
iterator _curr_event; //< current event in _event_list_store
iterator _last_event; //< end position in _event_list_store
@@ -130,9 +138,6 @@ private:
bool _notifications_blocked; //< if notifications should be handled
- // Map of connections used to temporary block/unblock callbacks in a TreeView
- CallbackMap *_callback_connections;
-
// Helper functions
const_iterator _getUndoEvent() const; //< returns the current undoable event or NULL if none
@@ -146,7 +151,6 @@ private:
// noncopyable, nonassignable
EventLog(EventLog const &other);
EventLog& operator=(EventLog const &other);
-
};
} // namespace Inkscape
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index 3c348f5c4..3a62c9c16 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -455,58 +455,45 @@ uint32_t Wmf::add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsa
char *rgba_px = NULL; // RGBA pixels
const char *px = NULL; // DIB pixels
const U_RGBQUAD *ct = NULL; // DIB color table
- int32_t width, height, colortype, numCt, invert;
- if((iUsage != U_DIB_RGB_COLORS) ||
- !(dibparams = wget_DIB_params( // this returns pointers and values, but allocates no memory
- dib,
- &px,
- &ct,
- &numCt,
- &width,
- &height,
- &colortype,
- &invert
- ))
- ){
-
- if(!DIB_to_RGBA(
- px, // DIB pixel array
- ct, // DIB color table
- numCt, // DIB color table number of entries
- &rgba_px, // U_RGBA pixel array (32 bits), created by this routine, caller must free.
- width, // Width of pixel array in record
- height, // Height of pixel array in record
- colortype, // DIB BitCount Enumeration
- numCt, // Color table used if not 0
- invert // If DIB rows are in opposite order from RGBA rows
- ) &&
- rgba_px
- ){
- toPNG( // Get the image from the RGBA px into mempng
- &mempng,
- width, height, // of the SRC bitmap
- rgba_px
- );
- free(rgba_px);
+ int32_t width, height, colortype, numCt, invert; // if needed these values will be set by wget_DIB_params
+ if(iUsage == U_DIB_RGB_COLORS){
+ // next call returns pointers and values, but allocates no memory
+ dibparams = wget_DIB_params(dib, &px, &ct, &numCt, &width, &height, &colortype, &invert);
+ if(dibparams == U_BI_RGB){
+ if(!DIB_to_RGBA(
+ px, // DIB pixel array
+ ct, // DIB color table
+ numCt, // DIB color table number of entries
+ &rgba_px, // U_RGBA pixel array (32 bits), created by this routine, caller must free.
+ width, // Width of pixel array in record
+ height, // Height of pixel array in record
+ colortype, // DIB BitCount Enumeration
+ numCt, // Color table used if not 0
+ invert // If DIB rows are in opposite order from RGBA rows
+ )){
+ toPNG( // Get the image from the RGBA px into mempng
+ &mempng,
+ width, height, // of the SRC bitmap
+ rgba_px
+ );
+ free(rgba_px);
+ }
}
}
- gchar *base64String;
- if(dibparams == U_BI_JPEG || dibparams==U_BI_PNG){
+ gchar *base64String=NULL;
+ if(dibparams == U_BI_JPEG || dibparams==U_BI_PNG){ // image was binary png or jpg in source file
base64String = g_base64_encode((guchar*) px, numCt );
- idx = in_images(d, (char *) base64String);
}
- else if(mempng.buffer){
+ else if(mempng.buffer){ // image was DIB in source file, converted to png in this routine
base64String = g_base64_encode((guchar*) mempng.buffer, mempng.size );
free(mempng.buffer);
- idx = in_images(d, (char *) base64String);
}
- else {
- // insert a random 3x4 blotch otherwise
+ else { // failed conversion, insert the common bad image picture
width = 3;
height = 4;
- base64String = g_strdup("iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII=");
- idx = in_images(d, (char *) base64String);
+ base64String = bad_image_png();
}
+ idx = in_images(d, (char *) base64String);
if(!idx){ // add it if not already present - we looked at the actual data for comparison
if(d->images.count == d->images.size){ enlarge_images(d); }
idx = d->images.count;
@@ -545,7 +532,7 @@ uint32_t Wmf::add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsa
*(d->defs) += " ";
*(d->defs) += " </pattern>\n";
}
- g_free(base64String);
+ g_free(base64String); //wait until this point to free because it might be a duplicate image
return(idx-1);
}
@@ -563,16 +550,16 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *
mempng.buffer = NULL;
char *rgba_px = NULL; // RGBA pixels
- const U_RGBQUAD *ct = NULL; // color table, always NULL here
+ const U_RGBQUAD *ct = NULL; // color table, always NULL here
int32_t width, height, colortype, numCt, invert;
numCt = 0;
width = Bm16.Width; // bitmap width in pixels.
height = Bm16.Height; // bitmap height in scan lines.
colortype = Bm16.BitsPixel; // seems to be BitCount Enumeration
invert = 0;
- if(colortype < 16)return(0xFFFFFFFF); // these would need a colortable if they were a dib, no idea what bm16 is supposed to do instead.
+ if(colortype < 16)return(U_WMR_INVALID); // these would need a colortable if they were a dib, no idea what bm16 is supposed to do instead.
- if(!DIB_to_RGBA(// This is not really a dib, but close enough...
+ if(!DIB_to_RGBA(// This is not really a dib, but close enough so that it still works.
px, // DIB pixel array
ct, // DIB color table (always NULL here)
numCt, // DIB color table number of entries (always 0)
@@ -582,8 +569,7 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *
colortype, // DIB BitCount Enumeration
numCt, // Color table used if not 0
invert // If DIB rows are in opposite order from RGBA rows
- ) && rgba_px)
- {
+ )){
toPNG( // Get the image from the RGBA px into mempng
&mempng,
width, height, // of the SRC bitmap
@@ -591,17 +577,18 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *
);
free(rgba_px);
}
- gchar *base64String;
- if(mempng.buffer){
+
+ gchar *base64String=NULL;
+ if(mempng.buffer){ // image was Bm16 in source file, converted to png in this routine
base64String = g_base64_encode((guchar*) mempng.buffer, mempng.size );
free(mempng.buffer);
}
- else {
- // insert a random 3x4 blotch otherwise
+ else { // failed conversion, insert the common bad image picture
width = 3;
height = 4;
- base64String = g_strdup("iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII=");
+ base64String = bad_image_png();
}
+
idx = in_images(d, (char *) base64String);
if(!idx){ // add it if not already present - we looked at the actual data for comparison
if(d->images.count == d->images.size){ enlarge_images(d); }
@@ -639,7 +626,7 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *
*(d->defs) += "\" />\n";
*(d->defs) += " </pattern>\n";
}
- g_free(base64String);
+ g_free(base64String); //wait until this point to free because it might be a duplicate image
return(idx-1);
}
@@ -883,16 +870,13 @@ double
Wmf::pix_to_x_point(PWMF_CALLBACK_DATA d, double px, double /*py*/)
{
double x = _pix_x_to_point(d, px);
-
return x;
}
double
Wmf::pix_to_y_point(PWMF_CALLBACK_DATA d, double /*px*/, double py)
{
-
double y = _pix_y_to_point(d, py);
-
return y;
}
@@ -1054,7 +1038,6 @@ Wmf::select_brush(PWMF_CALLBACK_DATA d, int index)
const char *Bm16h; // Pointer to Bitmap16 header (px follows)
const char *dib; // Pointer to DIB
(void) U_WMRDIBCREATEPATTERNBRUSH_get(record, &Style, &cUsage, &Bm16h, &dib);
- // Bm16 not handled yet
if(dib || Bm16h){
if(dib){ tidx = add_dib_image(d, dib, cUsage); }
else if(Bm16h){
@@ -1064,7 +1047,7 @@ Wmf::select_brush(PWMF_CALLBACK_DATA d, int index)
px = Bm16h + U_SIZE_BITMAP16;
tidx = add_bm16_image(d, Bm16, px);
}
- if(tidx == 0xFFFFFFFF){ // Problem with the image, for instance, an unsupported bitmap16 type
+ if(tidx == U_WMR_INVALID){ // Problem with the image, for instance, an unsupported bitmap16 type
double r, g, b;
r = SP_COLOR_U_TO_F( U_RGBAGetR(d->dc[d->level].textColor));
g = SP_COLOR_U_TO_F( U_RGBAGetG(d->dc[d->level].textColor));
@@ -1384,10 +1367,9 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char
SVGOStringStream tmp_image;
+ tmp_image << "\n\t <image\n";
tmp_image << " y=\"" << dy << "\"\n x=\"" << dx <<"\"\n ";
- // The image ID is filled in much later when tmp_image is converted
-
MEMPNG mempng; // PNG in memory comes back in this
mempng.buffer = NULL;
@@ -1408,7 +1390,8 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char
}
if(colortype < 16)return; // these would need a colortable if they were a dib, no idea what bm16 is supposed to do instead.
- if(!DIB_to_RGBA( // This is not really a dib, but close enough...
+
+ if(!DIB_to_RGBA(// This is not really a dib, but close enough so that it still works.
px, // DIB pixel array
ct, // DIB color table (always NULL here)
numCt, // DIB color table number of entries (always 0)
@@ -1418,15 +1401,13 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char
colortype, // DIB BitCount Enumeration
numCt, // Color table used if not 0
invert // If DIB rows are in opposite order from RGBA rows
- ) &&
- rgba_px
- ){
- sub_px = RGBA_to_RGBA(
- rgba_px, // full pixel array from DIB
- width, // Width of pixel array
- height, // Height of pixel array
- sx,sy, // starting point in pixel array
- &sw,&sh // columns/rows to extract from the pixel array (output array size)
+ )){
+ sub_px = RGBA_to_RGBA( // returns either a subset (side effect: frees rgba_px) or NULL (for subset == entire image)
+ rgba_px, // full pixel array from DIB
+ width, // Width of pixel array
+ height, // Height of pixel array
+ sx,sy, // starting point in pixel array
+ &sw,&sh // columns/rows to extract from the pixel array (output array size)
);
if(!sub_px)sub_px=rgba_px;
@@ -1437,26 +1418,26 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char
);
free(sub_px);
}
- if(mempng.buffer){
+
+ gchar *base64String=NULL;
+ if(mempng.buffer){ // image was Bm16 in source file, converted to png in this routine
tmp_image << " xlink:href=\"data:image/png;base64,";
- gchar *base64String = g_base64_encode((guchar*) mempng.buffer, mempng.size );
+ base64String = g_base64_encode((guchar*) mempng.buffer, mempng.size );
free(mempng.buffer);
- tmp_image << base64String;
- g_free(base64String);
}
- else {
+ else { // unknown or unsupported image type or failed conversion, insert the common bad image picture
tmp_image << " xlink:href=\"data:image/png;base64,";
- // insert a random 3x4 blotch otherwise
- tmp_image << "iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII=";
+ base64String = bad_image_png();
}
+ tmp_image << base64String;
+ g_free(base64String);
tmp_image << "\"\n height=\"" << dh << "\"\n width=\"" << dw << "\"\n";
-
tmp_image << " transform=" << current_matrix(d, 0.0, 0.0, 0); // returns an identity matrix, no offsets.
- *(d->outsvg) += "\n\t <image\n";
- *(d->outsvg) += tmp_image.str().c_str();
+ tmp_image << " preserveAspectRatio=\"none\"\n";
+ tmp_image << "/> \n";
- *(d->outsvg) += "/> \n";
+ *(d->outsvg) += tmp_image.str().c_str();
*(d->path) = "";
}
@@ -1669,7 +1650,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
// incompatible change to text drawing detected (color or background change) forces out existing text
// OR
// next record is valid type and forces pending text to be drawn immediately
- if ((d->dc[d->level].dirty & DIRTY_TEXT) || ((wmr_mask != 0xFFFFFFFF) && (wmr_mask & U_DRAW_TEXT) && d->tri->dirty)){
+ if ((d->dc[d->level].dirty & DIRTY_TEXT) || ((wmr_mask != U_WMR_INVALID) && (wmr_mask & U_DRAW_TEXT) && d->tri->dirty)){
TR_layout_analyze(d->tri);
TR_layout_2_svg(d->tri);
SVGOStringStream ts;
@@ -1712,7 +1693,7 @@ std::cout << "BEFORE DRAW"
*/
if(
- (wmr_mask != 0xFFFFFFFF) && // next record is valid type
+ (wmr_mask != U_WMR_INVALID) && // next record is valid type
(d->mask & U_DRAW_VISIBLE) && // This record is drawable
(
(d->mask & U_DRAW_FORCE) || // This draw is forced by STROKE/FILL/STROKEANDFILL PATH
@@ -1852,6 +1833,20 @@ std::cout << "BEFORE DRAW"
d->dc[d->level].sizeWnd.y = d->PixelsOutY;
}
}
+ else {
+ /* There are a lot WMF files in circulation with the x,y values in the setwindowext reversed. If this is detected, swap them.
+ There is a remote possibility that the strange scaling this implies was intended, and those will be rendered incorrectly */
+ double Ox = d->PixelsOutX;
+ double Oy = d->PixelsOutY;
+ double Wx = d->dc[d->level].sizeWnd.x;
+ double Wy = d->dc[d->level].sizeWnd.y;
+ if(Wx != Wy && Geom::are_near(Ox/Wy, Oy/Wx, 1.01/MIN(Wx,Wy)) ){
+ int tmp;
+ tmp = d->dc[d->level].sizeWnd.x;
+ d->dc[d->level].sizeWnd.x = d->dc[d->level].sizeWnd.y;
+ d->dc[d->level].sizeWnd.y = tmp;
+ }
+ }
if (!d->dc[d->level].sizeView.x || !d->dc[d->level].sizeView.y) {
/* Previously it used sizeWnd, but that always resulted in scale = 1 if no viewport ever appeared, and in most files, it did not */
@@ -1984,7 +1979,7 @@ std::cout << "BEFORE DRAW"
int stat = wmr_arc_points(rc, ArcStart, ArcEnd,&f1, f2, &center, &start, &end, &size);
if(!stat){
tmp_path << "\n\tM " << pix_to_xy(d, start.x, start.y);
- tmp_path << " A " << pix_to_abs_size(d, size.x)/2.0 << "," << pix_to_abs_size(d, size.y)/2.0 ;
+ tmp_path << " A " << pix_to_abs_size(d, size.x)/2.0 << "," << pix_to_abs_size(d, size.y)/2.0;
tmp_path << " ";
tmp_path << 180.0 * current_rotation(d)/M_PI;
tmp_path << " ";
@@ -2036,7 +2031,7 @@ std::cout << "BEFORE DRAW"
if(!wmr_arc_points(rc, ArcStart, ArcEnd, &f1, f2, &center, &start, &end, &size)){
tmp_path << "\n\tM " << pix_to_xy(d, center.x, center.y);
tmp_path << "\n\tL " << pix_to_xy(d, start.x, start.y);
- tmp_path << " A " << pix_to_abs_size(d, size.x)/2.0 << "," << pix_to_abs_size(d, size.y)/2.0 ;
+ tmp_path << " A " << pix_to_abs_size(d, size.x)/2.0 << "," << pix_to_abs_size(d, size.y)/2.0;
tmp_path << " ";
tmp_path << 180.0 * current_rotation(d)/M_PI;
tmp_path << " ";
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index 0b250fe52..6773069de 100644
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -636,13 +636,13 @@ GrDrag::GrDrag(SPDesktop *desktop) :
style_set_connection(),
style_query_connection()
{
- sel_changed_connection = selection->connectChanged(
+ sel_changed_connection = selection->connectChangedFirst(
sigc::bind(
sigc::ptr_fun(&gr_drag_sel_changed),
(gpointer)this )
);
- sel_modified_connection = selection->connectModified(
+ sel_modified_connection = selection->connectModifiedFirst(
sigc::bind(
sigc::ptr_fun(&gr_drag_sel_modified),
(gpointer)this )
diff --git a/src/libvpsc/generate-constraints.cpp b/src/libvpsc/generate-constraints.cpp
index fabe5217f..288e7ed53 100644
--- a/src/libvpsc/generate-constraints.cpp
+++ b/src/libvpsc/generate-constraints.cpp
@@ -209,7 +209,6 @@ int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constrain
}
} else {
// Close event
- int r;
if(useNeighbourLists) {
for(NodeSet::iterator i=v->leftNeighbours->begin();
i!=v->leftNeighbours->end();i++
@@ -217,7 +216,7 @@ int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constrain
Node *u=*i;
double sep = (v->r->width()+u->r->width())/2.0;
constraints.push_back(new Constraint(u->v,v->v,sep));
- r=u->rightNeighbours->erase(v);
+ u->rightNeighbours->erase(v);
}
for(NodeSet::iterator i=v->rightNeighbours->begin();
@@ -226,22 +225,22 @@ int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constrain
Node *u=*i;
double sep = (v->r->width()+u->r->width())/2.0;
constraints.push_back(new Constraint(v->v,u->v,sep));
- r=u->leftNeighbours->erase(v);
+ u->leftNeighbours->erase(v);
}
} else {
Node *l=v->firstAbove, *r=v->firstBelow;
if(l!=NULL) {
double sep = (v->r->width()+l->r->width())/2.0;
constraints.push_back(new Constraint(l->v,v->v,sep));
- l->firstBelow=v->firstBelow;
+ l->firstBelow = v->firstBelow;
}
if(r!=NULL) {
double sep = (v->r->width()+r->r->width())/2.0;
constraints.push_back(new Constraint(v->v,r->v,sep));
- r->firstAbove=v->firstAbove;
+ r->firstAbove = v->firstAbove;
}
}
- r=scanline.erase(v);
+ scanline.erase(v);
delete v;
}
delete e;
diff --git a/src/marker.cpp b/src/marker.cpp
index fb7b0fd21..7fee16ead 100644
--- a/src/marker.cpp
+++ b/src/marker.cpp
@@ -206,7 +206,9 @@ void SPMarker::update(SPCtx *ctx, guint flags) {
SPItemCtx rctx = get_rctx( &ictx );
// Shift according to refX, refY
- this->c2p = Geom::Translate(this->viewBox.left()-this->refX.computed, this->viewBox.top()-this->refY.computed) * this->c2p;
+ Geom::Point ref( this->refX.computed, this->refY.computed );
+ ref *= c2p;
+ this->c2p = this->c2p * Geom::Translate( -ref );
// And invoke parent method
SPGroup::update((SPCtx *) &rctx, flags);
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 76be086a2..b3d9af910 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1747,7 +1747,7 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw)
DocumentUndo::done(sp_desktop_document(desktop),
ccw ? SP_VERB_OBJECT_ROTATE_90_CCW : SP_VERB_OBJECT_ROTATE_90_CW,
- ccw ? _("Rotate 90&#176; CCW") : _("Rotate 90&#176; CW"));
+ ccw ? _("Rotate 90\xc2\xb0 CCW") : _("Rotate 90\xc2\xb0 CW"));
}
void
diff --git a/src/selection.h b/src/selection.h
index 394ab64ff..373167a33 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -302,6 +302,10 @@ public:
sigc::connection connectChanged(sigc::slot<void, Selection *> const &slot) {
return _changed_signal.connect(slot);
}
+ sigc::connection connectChangedFirst(sigc::slot<void, Selection *> const &slot)
+ {
+ return _changed_signal.slots().insert(_changed_signal.slots().begin(), slot);
+ }
/**
* Connects a slot to be notified of selected object modifications.
@@ -319,6 +323,10 @@ public:
{
return _modified_signal.connect(slot);
}
+ sigc::connection connectModifiedFirst(sigc::slot<void, Selection *, guint> const &slot)
+ {
+ return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot);
+ }
private:
/** no copy. */
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 2c20331a9..cb8ede2b2 100644
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
@@ -813,9 +813,7 @@ void sp_image_refresh_if_outdated( SPImage* image )
if ( !val ) {
// stat call worked. Check time now
if ( st.st_mtime != image->pixbuf->modificationTime() ) {
- SPCtx *ctx = 0;
- unsigned int flags = SP_IMAGE_HREF_MODIFIED_FLAG;
- image->update(ctx, flags);
+ image->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG);
}
}
}
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index 425ca9efa..e465565c4 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -542,6 +542,7 @@ static bool pattern_hasItemChildren (SPPattern const *pat)
}
cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) {
+
bool needs_opacity = (1.0 - opacity) >= 1e-3;
bool visible = opacity >= 1e-3;
@@ -580,63 +581,69 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
}
}
- // viewBox to pattern server
- Geom::Affine vb2ps = Geom::identity();
- if (this->viewBox_set) {
- Geom::Rect vb = *pattern_viewBox(this);
- gdouble tmp_x = pattern_width (this) / vb.width();
- gdouble tmp_y = pattern_height (this) / vb.height();
-
- // FIXME: preserveAspectRatio must be taken into account here too!
- vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(this) - vb.left() * tmp_x, pattern_y(this) - vb.top() * tmp_y);
+ // ****** Geometry ******
+ //
+ // * "width" and "height" determine tile size.
+ // * "viewBox" (if defined) or "patternContentUnits" determines placement of content inside
+ // tile.
+ // * "x", "y", and "patternTransform" transform tile to user space after tile is generated.
+
+ // These functions recursively search up the tree to find the values.
+ double tile_x = pattern_x(this);
+ double tile_y = pattern_y(this);
+ double tile_width = pattern_width(this);
+ double tile_height = pattern_height(this);
+ if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ tile_x *= bbox->width();
+ tile_y *= bbox->height();
+ tile_width *= bbox->width();
+ tile_height *= bbox->height();
}
- // We must determine the size and scaling of the pattern at the time it is displayed and render
- // the pattern onto a surface with that size and at that resolution.
+ // Pattern size in pattern space
+ Geom::Rect pattern_tile = Geom::Rect::from_xywh(0, 0, tile_width, tile_height);
+
+ // Content to tile (pattern space)
+ Geom::Affine content2ps;
+ if (this->viewBox_set) {
+ // viewBox to pattern server (using SPViewBox)
+ viewBox = *pattern_viewBox(this);
+ c2p.setIdentity();
+ apply_viewbox( pattern_tile );
+ content2ps = c2p;
+ } else {
- // Pattern server to user
- Geom::Affine ps2user;
- ps2user = pattern_patternTransform(this);
- if (!this->viewBox_set && pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
- /* BBox to user coordinate system */
- Geom::Affine bbox2user (bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top());
- ps2user *= bbox2user;
+ // Content to bbox
+ if (pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0);
+ }
}
- ps2user = Geom::Translate (pattern_x (this), pattern_y (this)) * ps2user;
- // Pattern size in pattern space
- Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(this), pattern_y(this),
- pattern_width(this), pattern_height(this));
- if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
- // interpret x, y, width, height in relation to bbox
- Geom::Affine bbox2user(bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top());
- pattern_tile = pattern_tile * bbox2user;
- }
+ // Tile (pattern space) to user.
+ Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * pattern_patternTransform(this);
+
// Transform of object with pattern (includes screen scaling)
cairo_matrix_t cm;
cairo_get_matrix(base_ct, &cm);
Geom::Affine full(cm.xx, cm.yx, cm.xy, cm.yy, 0, 0);
- // The DrawingSurface class is suppose to handle the mapping from "logical space"
+ // The DrawingSurface class handles the mapping from "logical space"
// (coordinates in the rendering) to "physical space" (surface pixels).
// An oversampling is done as the pattern may not pixel align with the final surface.
// The cairo surface is created when the DrawingContext is declared.
- // oversample the pattern slightly
+ // Oversample the pattern
// TODO: find optimum value
// TODO: this is lame. instead of using descrim(), we should extract
// the scaling component from the complete matrix and use it
// to find the optimum tile size for rendering
// c is number of pixels in buffer x and y.
// Scale factor of 1.1 is too small... see bug #1251039
- Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*2.0);
-
- c[Geom::X] = ceil(c[Geom::X]);
- c[Geom::Y] = ceil(c[Geom::Y]);
+ Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*2.0);
- // Create drawing surface with size of pattern tile (in tile space) but with number of pixels
+ // Create drawing surface with size of pattern tile (in pattern space) but with number of pixels
// based on required resolution (c).
Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil());
Inkscape::DrawingContext dc(pattern_surface);
@@ -644,14 +651,14 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
pattern_tile *= pattern_surface.drawingTransform();
Geom::IntRect one_tile = pattern_tile.roundOutwards();
- // render pattern.
+ // Render pattern.
if (needs_opacity) {
dc.pushGroup(); // this group is for pattern + opacity
}
// TODO: make sure there are no leaks.
Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm!
- ctx.ctm = vb2ps * pattern_surface.drawingTransform();
+ ctx.ctm = content2ps * pattern_surface.drawingTransform();
dc.transform( pattern_surface.drawingTransform().inverse() );
drawing.update(Geom::IntRect::infinite(), ctx);
@@ -670,7 +677,8 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// << " width: " << cairo_image_surface_get_width( raw )
// << " height: " << cairo_image_surface_get_height( raw )
// << std::endl;
- // cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" );
+ // std::string filename = "sp-pattern-" + (std::string)getId() + ".png";
+ // cairo_surface_write_to_png( pattern_surface.raw(), filename.c_str() );
if (needs_opacity) {
dc.popGroupToSource(); // pop raw pattern
@@ -679,7 +687,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw());
// Apply transformation to user space. Also compensate for oversampling.
- ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform());
+ ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform() );
cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT);
diff --git a/src/sp-use.cpp b/src/sp-use.cpp
index e394e84c2..14f51159b 100644
--- a/src/sp-use.cpp
+++ b/src/sp-use.cpp
@@ -22,6 +22,7 @@
#include <2geom/transforms.h>
#include <glibmm/i18n.h>
+#include <glibmm/markup.h>
#include "display/drawing-group.h"
#include "attributes.h"
#include "document.h"
@@ -219,7 +220,7 @@ const char* SPUse::displayName() const {
gchar* SPUse::description() const {
if (this->child) {
if( SP_IS_SYMBOL( this->child ) ) {
- return g_strdup_printf(_("called %s"), this->child->title());
+ return g_strdup_printf(_("called %s"), Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", this->child->title()))).c_str());
}
static unsigned recursion_depth = 0;
diff --git a/src/style-test.h b/src/style-test.h
index 064773d1d..8a4055cc1 100644
--- a/src/style-test.h
+++ b/src/style-test.h
@@ -86,6 +86,59 @@ public:
// TestCase("fill:url(#painter) inherit", 0, "#painter"),
TestCase("fill:inherit"),
+
+// General tests (in order of appearance in sp_style_read), SPIPaint tested above
+ TestCase("visibility:hidden"), // SPIEnum
+ TestCase("visibility:collapse"),
+ TestCase("visibility:visible"),
+ TestCase("display:none"), // SPIEnum
+ TestCase("overflow:visible"), // SPIEnum
+ TestCase("overflow:auto"), // SPIEnum
+ TestCase("font-size:12", "font-size:12px"), // SPIFontSize
+ TestCase("font-size:12px"),
+ TestCase("font-size:12pt", "font-size:15px"),
+ TestCase("font-size:medium"),
+ TestCase("font-style:italic"), // SPIEnum
+ TestCase("font-variant:small-caps"), // SPIEnum
+ TestCase("font-weight:100"), // SPIEnum
+ TestCase("font-weight:normal"),
+ TestCase("font-weight:bolder"),
+ TestCase("font-stretch:condensed"), // SPIEnum
+ TestCase("text-indent:12em"), // SPILength?
+ TestCase("text-align:center"), // SPIEnum
+ TestCase("text-decoration: underline"), // SPITextDecoration
+ TestCase("line-height:24px"), // SPILengthOrNormal
+ TestCase("letter-spacing:2px"), // SPILengthOrNormal
+ TestCase("word-spacing:2px"), // SPILengthOrNormal
+ TestCase("text-transform:lowercase"), // SPIEnum
+ // ...
+ TestCase("baseline-shift:baseline"), // SPIBaselineShift
+ TestCase("baseline-shift:sub"),
+ TestCase("baseline-shift:12.5%"),
+ TestCase("baseline-shift:2px"),
+ TestCase("opacity:0.1"), // SPIScale24
+ // ...
+ TestCase("stroke-width:2px"), // SPILength
+ TestCase("stroke-linecap:round"), // SPIEnum
+ TestCase("stroke-linejoin:round"), // SPIEnum
+ TestCase("stroke-miterlimit:4"), // SPIFloat
+ TestCase("marker:url(#Arrow)"), // SPIString
+ TestCase("marker-start:url(#Arrow)"),
+ TestCase("marker-mid:url(#Arrow)"),
+ TestCase("marker-end:url(#Arrow)"),
+ TestCase("stroke-opacity:0.5"), // SPIScale24
+ TestCase("stroke-dasharray:0, 1, 0, 1"), // NRVpathDash
+ TestCase("stroke-dasharray:0 1 0 1","stroke-dasharray:0, 1, 0, 1"),
+ TestCase("stroke-dashoffset:13"), // NRVpathDash
+ // ...
+ TestCase("font-family:sans-serif"), // SPIString, text_private
+ //TestCase("filter:url(#myfilter)"), // filter
+
+ TestCase("opacity:0.1;fill:#ff0000;stroke:#0000ff;stroke-width:2px"),
+
+#ifdef WITH_SVG2
+ TestCase("paint-order:stroke"), // SPIPaintOrder
+#endif
TestCase(0)
};
@@ -107,8 +160,10 @@ public:
gchar *str0_set = sp_style_write_string( style, SP_STYLE_FLAG_IFSET );
//printf("<<%s>>\n", str0_set);
if ( cases[i].dst ) {
+ //std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].dst) << std::endl;
TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].dst) );
} else {
+ //std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].src) << std::endl;
TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].src) );
}
diff --git a/src/style.cpp b/src/style.cpp
index 7ad9749f0..f3a12db86 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -3731,7 +3731,7 @@ sp_style_read_ipaintorder(SPIPaintOrder *val, gchar const *str)
val->layer[i] = SP_CSS_PAINT_ORDER_STROKE;
val->layer_set[i] = true;
used[1] = true;
- } else if( !strcmp( c[i], "marker")) {
+ } else if( !strcmp( c[i], "markers")) {
val->layer[i] = SP_CSS_PAINT_ORDER_MARKER;
val->layer_set[i] = true;
used[2] = true;
@@ -4785,7 +4785,7 @@ sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key,
return g_snprintf(p, len, "%s:inherit;", key);
} else if (val->type == SP_FONT_SIZE_LITERAL) {
for (unsigned i = 0; enum_font_size[i].key; i++) {
- if (enum_font_size[i].value == static_cast< gint > (val->value) ) {
+ if (enum_font_size[i].value == static_cast< gint > (val->literal) ) {
return g_snprintf(p, len, "%s:%s;", key, enum_font_size[i].key);
}
}
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index 340a3dad0..f0a5f1bf5 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -144,11 +144,13 @@ namespace Dialog {
/** A list of strings that is used both in the preferences, and in the
data fields to describe the various values of \c selection_type. */
static const char * selection_names[SELECTION_NUMBER_OF] = {
- "page", "drawing", "selection", "custom"};
+ "page", "drawing", "selection", "custom"
+};
/** The names on the buttons for the various selection types. */
static const char * selection_labels[SELECTION_NUMBER_OF] = {
- N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")};
+ N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")
+};
Export::Export (void) :
UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT),
@@ -201,7 +203,7 @@ Export::Export (void) :
/* gets added to the vbox later, but the unit selector is needed
earlier than that */
unit_selector.setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR);
-
+
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
if (desktop) {
unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr);
@@ -232,28 +234,28 @@ Export::Export (void) :
#endif
x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0,
- t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaX0Change);
+ t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaX0Change);
x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0,
- t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaX1Change);
+ t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaX1Change);
width_adj = createSpinbutton ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
- t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaWidthChange);
+ t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaWidthChange);
y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0,
- t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaY0Change);
+ t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaY0Change);
y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0,
- t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaY1Change);
+ t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaY1Change);
height_adj = createSpinbutton ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
- t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1,
- &Export::onAreaHeightChange);
+ t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1,
+ &Export::onAreaHeightChange);
area_box.pack_start(togglebox, false, false, 3);
area_box.pack_start(*t, false, false, 0);
@@ -284,27 +286,27 @@ Export::Export (void) :
size_box.pack_start(*t);
bmwidth_adj = createSpinbutton ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0,
- t, 0, 0,
- _("_Width:"), _("pixels at"), 0, 1,
- &Export::onBitmapWidthChange);
+ t, 0, 0,
+ _("_Width:"), _("pixels at"), 0, 1,
+ &Export::onBitmapWidthChange);
xdpi_adj = createSpinbutton ( "xdpi",
- prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE),
- 0.01, 100000.0, 0.1, 1.0, t, 3, 0,
- "", _("dp_i"), 2, 1,
- &Export::onExportXdpiChange);
+ prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE),
+ 0.01, 100000.0, 0.1, 1.0, t, 3, 0,
+ "", _("dp_i"), 2, 1,
+ &Export::onExportXdpiChange);
bmheight_adj = createSpinbutton ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0,
- t, 0, 1,
- _("_Height:"), _("pixels at"), 0, 1,
- &Export::onBitmapHeightChange);
+ t, 0, 1,
+ _("_Height:"), _("pixels at"), 0, 1,
+ &Export::onBitmapHeightChange);
/** TODO
* There's no way to set ydpi currently, so we use the defaultxdpi value here, too...
*/
ydpi_adj = createSpinbutton ( "ydpi", prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE),
- 0.01, 100000.0, 0.1, 1.0, t, 3, 1,
- "", _("dpi"), 2, 0, NULL );
+ 0.01, 100000.0, 0.1, 1.0, t, 3, 1,
+ "", _("dpi"), 2, 0, NULL );
singleexport_box.pack_start(size_box);
}
@@ -482,18 +484,18 @@ void Export::set_default_filename () {
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max,
- float step, float page,
- Gtk::Grid *t, int x, int y,
- const Glib::ustring ll, const Glib::ustring lr,
- int digits, unsigned int sensitive,
- void (Export::*cb)() )
+ float step, float page,
+ Gtk::Grid *t, int x, int y,
+ const Glib::ustring& ll, const Glib::ustring& lr,
+ int digits, unsigned int sensitive,
+ void (Export::*cb)() )
#else
Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max,
- float step, float page,
- Gtk::Table *t, int x, int y,
- const Glib::ustring ll, const Glib::ustring lr,
- int digits, unsigned int sensitive,
- void (Export::*cb)() )
+ float step, float page,
+ Gtk::Table *t, int x, int y,
+ const Glib::ustring& ll, const Glib::ustring& lr,
+ int digits, unsigned int sensitive,
+ void (Export::*cb)() )
#endif
{
#if WITH_GTKMM_3_0
@@ -535,7 +537,9 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
sb->set_sensitive (sensitive);
pos++;
- if (!ll.empty()) { l->set_mnemonic_widget(*sb);}
+ if (!ll.empty()) {
+ l->set_mnemonic_widget(*sb);
+ }
if (!lr.empty()) {
l = new Gtk::Label(lr,true);
@@ -565,7 +569,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl
Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ustring &file_entry_text)
{
if (id.empty())
- { /* This should never happen */
+ { /* This should never happen */
id = "bitmap";
}
@@ -678,35 +682,35 @@ void Export::onSelectionModified ( guint /*flags*/ )
{
Inkscape::Selection * Sel;
switch (current_key) {
- case SELECTION_DRAWING:
- if ( SP_ACTIVE_DESKTOP ) {
- SPDocument *doc;
- doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
- if (bbox) {
- setArea ( bbox->left(),
- bbox->top(),
- bbox->right(),
- bbox->bottom());
- }
+ case SELECTION_DRAWING:
+ if ( SP_ACTIVE_DESKTOP ) {
+ SPDocument *doc;
+ doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
+ Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
+ if (bbox) {
+ setArea ( bbox->left(),
+ bbox->top(),
+ bbox->right(),
+ bbox->bottom());
}
- break;
- case SELECTION_SELECTION:
- Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP);
- if (Sel->isEmpty() == false) {
- Geom::OptRect bbox = Sel->visualBounds();
- if (bbox)
- {
- setArea ( bbox->left(),
- bbox->top(),
- bbox->right(),
- bbox->bottom());
- }
+ }
+ break;
+ case SELECTION_SELECTION:
+ Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP);
+ if (Sel->isEmpty() == false) {
+ Geom::OptRect bbox = Sel->visualBounds();
+ if (bbox)
+ {
+ setArea ( bbox->left(),
+ bbox->top(),
+ bbox->right(),
+ bbox->bottom());
}
- break;
- default:
- /* Do nothing for page or for custom */
- break;
+ }
+ break;
+ default:
+ /* Do nothing for page or for custom */
+ break;
}
return;
@@ -738,39 +742,39 @@ void Export::onAreaToggled ()
various backups. If you modify this without noticing you'll
probabaly screw something up. */
switch (key) {
- case SELECTION_SELECTION:
- if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false)
- {
- bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds();
- /* Only if there is a selection that we can set
- do we break, otherwise we fall through to the
- drawing */
- // std::cout << "Using selection: SELECTION" << std::endl;
- key = SELECTION_SELECTION;
- break;
- }
- case SELECTION_DRAWING:
- /** \todo
- * This returns wrong values if the document has a viewBox.
- */
- bbox = doc->getRoot()->desktopVisualBounds();
- /* If the drawing is valid, then we'll use it and break
- otherwise we drop through to the page settings */
- if (bbox) {
- // std::cout << "Using selection: DRAWING" << std::endl;
- key = SELECTION_DRAWING;
- break;
- }
- case SELECTION_PAGE:
- bbox = Geom::Rect(Geom::Point(0.0, 0.0),
- Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")));
-
- // std::cout << "Using selection: PAGE" << std::endl;
- key = SELECTION_PAGE;
+ case SELECTION_SELECTION:
+ if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false)
+ {
+ bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds();
+ /* Only if there is a selection that we can set
+ do we break, otherwise we fall through to the
+ drawing */
+ // std::cout << "Using selection: SELECTION" << std::endl;
+ key = SELECTION_SELECTION;
break;
- case SELECTION_CUSTOM:
- default:
+ }
+ case SELECTION_DRAWING:
+ /** \todo
+ * This returns wrong values if the document has a viewBox.
+ */
+ bbox = doc->getRoot()->desktopVisualBounds();
+ /* If the drawing is valid, then we'll use it and break
+ otherwise we drop through to the page settings */
+ if (bbox) {
+ // std::cout << "Using selection: DRAWING" << std::endl;
+ key = SELECTION_DRAWING;
break;
+ }
+ case SELECTION_PAGE:
+ bbox = Geom::Rect(Geom::Point(0.0, 0.0),
+ Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px")));
+
+ // std::cout << "Using selection: PAGE" << std::endl;
+ key = SELECTION_PAGE;
+ break;
+ case SELECTION_CUSTOM:
+ default:
+ break;
} // switch
current_key = key;
@@ -780,9 +784,9 @@ void Export::onAreaToggled ()
if ( key != SELECTION_CUSTOM && bbox ) {
setArea ( bbox->min()[Geom::X],
- bbox->min()[Geom::Y],
- bbox->max()[Geom::X],
- bbox->max()[Geom::Y]);
+ bbox->min()[Geom::Y],
+ bbox->max()[Geom::X],
+ bbox->max()[Geom::Y]);
}
} // end of if ( SP_ACTIVE_DESKTOP )
@@ -793,43 +797,43 @@ void Export::onAreaToggled ()
float xdpi = 0.0, ydpi = 0.0;
switch (key) {
- case SELECTION_PAGE:
- case SELECTION_DRAWING: {
- SPDocument * doc = SP_ACTIVE_DOCUMENT;
- sp_document_get_export_hints (doc, filename, &xdpi, &ydpi);
-
- if (filename.empty()) {
- if (!doc_export_name.empty()) {
- filename = doc_export_name;
- }
+ case SELECTION_PAGE:
+ case SELECTION_DRAWING: {
+ SPDocument * doc = SP_ACTIVE_DOCUMENT;
+ sp_document_get_export_hints (doc, filename, &xdpi, &ydpi);
+
+ if (filename.empty()) {
+ if (!doc_export_name.empty()) {
+ filename = doc_export_name;
}
- break;
}
- case SELECTION_SELECTION:
- if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
-
- sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi);
-
- /* If we still don't have a filename -- let's build
- one that's nice */
- if (filename.empty()) {
- const gchar * id = "object";
- const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
- for(; reprlst != NULL; reprlst = reprlst->next) {
- Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
- if (repr->attribute("id")) {
- id = repr->attribute("id");
- break;
- }
- }
+ break;
+ }
+ case SELECTION_SELECTION:
+ if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
- filename = create_filepath_from_id (id, filename_entry.get_text());
+ sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi);
+
+ /* If we still don't have a filename -- let's build
+ one that's nice */
+ if (filename.empty()) {
+ const gchar * id = "object";
+ const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
+ for(; reprlst != NULL; reprlst = reprlst->next) {
+ Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
+ if (repr->attribute("id")) {
+ id = repr->attribute("id");
+ break;
+ }
}
+
+ filename = create_filepath_from_id (id, filename_entry.get_text());
}
- break;
- case SELECTION_CUSTOM:
- default:
- break;
+ }
+ break;
+ case SELECTION_CUSTOM:
+ default:
+ break;
}
if (!filename.empty()) {
@@ -895,8 +899,8 @@ unsigned int Export::onProgressCallback(float value, void *dlg)
int evtcount = 0;
while ((evtcount < 16) && gdk_events_pending()) {
- gtk_main_iteration_do(FALSE);
- evtcount += 1;
+ gtk_main_iteration_do(FALSE);
+ evtcount += 1;
}
gtk_main_iteration_do(FALSE);
@@ -960,7 +964,7 @@ Glib::ustring Export::filename_add_extension (Glib::ustring filename, Glib::ustr
}
else
{
- return filename = filename + "." + extension;
+ return filename = filename + "." + extension;
}
}
}
@@ -1057,9 +1061,9 @@ void Export::onExport ()
// Do export
gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str());
MessageCleaner msgCleanup(desktop->messageStack()->pushF(Inkscape::IMMEDIATE_MESSAGE,
- _("Exporting file <b>%s</b>..."), safeFile), desktop);
+ _("Exporting file <b>%s</b>..."), safeFile), desktop);
MessageCleaner msgFlashCleanup(desktop->messageStack()->flashF(Inkscape::IMMEDIATE_MESSAGE,
- _("Exporting file <b>%s</b>..."), safeFile), desktop);
+ _("Exporting file <b>%s</b>..."), safeFile), desktop);
if (!sp_export_png_file (doc, path.c_str(),
*area, width, height, dpi, dpi,
@@ -1067,7 +1071,7 @@ void Export::onExport ()
onProgressCallback, (void*)prog_dlg,
TRUE, // overwrite without asking
hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL
- )) {
+ )) {
gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
desktop->messageStack()->flashF(Inkscape::ERROR_MESSAGE,
@@ -1096,7 +1100,7 @@ void Export::onExport ()
} else {
Glib::ustring filename = filename_entry.get_text();
- if (filename.empty()){
+ if (filename.empty()) {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename."));
sp_ui_error_dialog(_("You have to enter a filename"));
return;
@@ -1125,7 +1129,7 @@ void Export::onExport ()
Glib::ustring dirname = Glib::path_get_dirname(path);
if ( dirname.empty()
- || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) )
+ || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) )
{
gchar *safeDir = Inkscape::IO::sanitizeString(dirname.c_str());
gchar *error = g_strdup_printf(_("Directory %s does not exist or is not a directory.\n"),
@@ -1151,12 +1155,12 @@ void Export::onExport ()
/* Do export */
ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(),
- Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi,
- nv->pagecolor,
- onProgressCallback, (void*)prog_dlg,
- FALSE,
- hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL
- );
+ Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi,
+ nv->pagecolor,
+ onProgressCallback, (void*)prog_dlg,
+ FALSE,
+ hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL
+ );
if (status == EXPORT_ERROR) {
gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str());
gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
@@ -1189,19 +1193,65 @@ void Export::onExport ()
/* Setup the values in the document */
switch (current_key) {
- case SELECTION_PAGE:
- case SELECTION_DRAWING: {
- SPDocument * doc = SP_ACTIVE_DOCUMENT;
- Inkscape::XML::Node * repr = doc->getReprRoot();
- bool modified = false;
-
- bool saved = DocumentUndo::getUndoSensitive(doc);
- DocumentUndo::setUndoSensitive(doc, false);
-
- gchar const *temp_string = repr->attribute("inkscape:export-filename");
- if (temp_string == NULL || (filename_ext != temp_string)) {
- repr->setAttribute("inkscape:export-filename", filename_ext.c_str());
- modified = true;
+ case SELECTION_PAGE:
+ case SELECTION_DRAWING: {
+ SPDocument * doc = SP_ACTIVE_DOCUMENT;
+ Inkscape::XML::Node * repr = doc->getReprRoot();
+ bool modified = false;
+
+ bool saved = DocumentUndo::getUndoSensitive(doc);
+ DocumentUndo::setUndoSensitive(doc, false);
+
+ gchar const *temp_string = repr->attribute("inkscape:export-filename");
+ if (temp_string == NULL || (filename_ext != temp_string)) {
+ repr->setAttribute("inkscape:export-filename", filename_ext.c_str());
+ modified = true;
+ }
+ temp_string = repr->attribute("inkscape:export-xdpi");
+ if (temp_string == NULL || xdpi != atof(temp_string)) {
+ sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
+ modified = true;
+ }
+ temp_string = repr->attribute("inkscape:export-ydpi");
+ if (temp_string == NULL || ydpi != atof(temp_string)) {
+ sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
+ modified = true;
+ }
+ DocumentUndo::setUndoSensitive(doc, saved);
+
+ if (modified) {
+ doc->setModifiedSinceSave();
+ }
+ break;
+ }
+ case SELECTION_SELECTION: {
+ const GSList * reprlst;
+ SPDocument * doc = SP_ACTIVE_DOCUMENT;
+ bool modified = false;
+
+ bool saved = DocumentUndo::getUndoSensitive(doc);
+ DocumentUndo::setUndoSensitive(doc, false);
+ reprlst = sp_desktop_selection(desktop)->reprList();
+
+ for(; reprlst != NULL; reprlst = reprlst->next) {
+ Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data);
+ const gchar * temp_string;
+ Glib::ustring dir = Glib::path_get_dirname(filename.c_str());
+ const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI();
+ Glib::ustring docdir;
+ if (docURI)
+ {
+ docdir = Glib::path_get_dirname(docURI);
+ }
+ if (repr->attribute("id") == NULL ||
+ !(filename_ext.find_last_of(repr->attribute("id")) &&
+ ( !docURI ||
+ (dir == docdir)))) {
+ temp_string = repr->attribute("inkscape:export-filename");
+ if (temp_string == NULL || (filename_ext != temp_string)) {
+ repr->setAttribute("inkscape:export-filename", filename_ext.c_str());
+ modified = true;
+ }
}
temp_string = repr->attribute("inkscape:export-xdpi");
if (temp_string == NULL || xdpi != atof(temp_string)) {
@@ -1213,62 +1263,16 @@ void Export::onExport ()
sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
modified = true;
}
- DocumentUndo::setUndoSensitive(doc, saved);
-
- if (modified) {
- doc->setModifiedSinceSave();
- }
- break;
}
- case SELECTION_SELECTION: {
- const GSList * reprlst;
- SPDocument * doc = SP_ACTIVE_DOCUMENT;
- bool modified = false;
-
- bool saved = DocumentUndo::getUndoSensitive(doc);
- DocumentUndo::setUndoSensitive(doc, false);
- reprlst = sp_desktop_selection(desktop)->reprList();
-
- for(; reprlst != NULL; reprlst = reprlst->next) {
- Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data);
- const gchar * temp_string;
- Glib::ustring dir = Glib::path_get_dirname(filename.c_str());
- const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI();
- Glib::ustring docdir;
- if (docURI)
- {
- docdir = Glib::path_get_dirname(docURI);
- }
- if (repr->attribute("id") == NULL ||
- !(filename_ext.find_last_of(repr->attribute("id")) &&
- ( !docURI ||
- (dir == docdir)))) {
- temp_string = repr->attribute("inkscape:export-filename");
- if (temp_string == NULL || (filename_ext != temp_string)) {
- repr->setAttribute("inkscape:export-filename", filename_ext.c_str());
- modified = true;
- }
- }
- temp_string = repr->attribute("inkscape:export-xdpi");
- if (temp_string == NULL || xdpi != atof(temp_string)) {
- sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
- modified = true;
- }
- temp_string = repr->attribute("inkscape:export-ydpi");
- if (temp_string == NULL || ydpi != atof(temp_string)) {
- sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
- modified = true;
- }
- }
- DocumentUndo::setUndoSensitive(doc, saved);
+ DocumentUndo::setUndoSensitive(doc, saved);
- if (modified) {
- doc->setModifiedSinceSave();
- }
- break;
+ if (modified) {
+ doc->setModifiedSinceSave();
}
- default:
- break;
+ break;
+ }
+ default:
+ break;
}
}
@@ -1331,8 +1335,8 @@ void Export::onBrowse ()
// Copy the selected file name, converting from UTF-8 to UTF-16
std::string dirname = Glib::path_get_dirname(filename.raw());
if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) ||
- Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) ||
- dirname.empty() )
+ Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) ||
+ dirname.empty() )
{
Glib::ustring tmp;
filename = create_filepath_from_id(tmp, tmp);
@@ -1407,11 +1411,11 @@ bool Export::bbox_equal(Geom::Rect const &one, Geom::Rect const &two)
{
double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION);
return (
- (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) &&
- (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) &&
- (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) &&
- (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon)
- );
+ (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) &&
+ (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) &&
+ (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) &&
+ (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon)
+ );
}
/**
@@ -1454,48 +1458,48 @@ void Export::detectSize() {
for (int i = 0;
i < SELECTION_NUMBER_OF + 1 &&
- key == SELECTION_NUMBER_OF &&
- SP_ACTIVE_DESKTOP != NULL;
+ key == SELECTION_NUMBER_OF &&
+ SP_ACTIVE_DESKTOP != NULL;
i++) {
switch (this_test[i]) {
- case SELECTION_SELECTION:
- if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
- Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX);
+ case SELECTION_SELECTION:
+ if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
+ Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX);
- if ( bbox && bbox_equal(*bbox,current_bbox)) {
- key = SELECTION_SELECTION;
- }
+ if ( bbox && bbox_equal(*bbox,current_bbox)) {
+ key = SELECTION_SELECTION;
}
- break;
- case SELECTION_DRAWING: {
- SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
+ }
+ break;
+ case SELECTION_DRAWING: {
+ SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
+ Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
- if ( bbox && bbox_equal(*bbox,current_bbox) ) {
- key = SELECTION_DRAWING;
- }
- break;
+ if ( bbox && bbox_equal(*bbox,current_bbox) ) {
+ key = SELECTION_DRAWING;
}
+ break;
+ }
- case SELECTION_PAGE: {
- SPDocument *doc;
+ case SELECTION_PAGE: {
+ SPDocument *doc;
- doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
+ doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- Geom::Point x(0.0, 0.0);
- Geom::Point y(doc->getWidth().value("px"),
- doc->getHeight().value("px"));
- Geom::Rect bbox(x, y);
+ Geom::Point x(0.0, 0.0);
+ Geom::Point y(doc->getWidth().value("px"),
+ doc->getHeight().value("px"));
+ Geom::Rect bbox(x, y);
- if (bbox_equal(bbox,current_bbox)) {
- key = SELECTION_PAGE;
- }
+ if (bbox_equal(bbox,current_bbox)) {
+ key = SELECTION_PAGE;
+ }
- break;
- }
+ break;
+ }
default:
- break;
+ break;
}
}
// std::cout << std::endl;
@@ -1579,7 +1583,7 @@ void Export::areaYChange (Gtk::Adjustment *adj)
height = SP_EXPORT_MIN_SIZE;
//key = (const gchar *)g_object_get_data(G_OBJECT (adj), "key");
if (adj == y1_adj) {
- //if (!strcmp (key, "y0")) {
+ //if (!strcmp (key, "y0")) {
y1 = y0 + height * DPI_BASE / ydpi;
setValuePx(y1_adj, y1);
} else {
diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h
index 79e597414..6f3c0dfac 100644
--- a/src/ui/dialog/export.h
+++ b/src/ui/dialog/export.h
@@ -56,7 +56,9 @@ public:
Export ();
~Export ();
- static Export &getInstance() { return *new Export(); }
+ static Export &getInstance() {
+ return *new Export();
+ }
private:
@@ -97,7 +99,7 @@ private:
float getValue (Gtk::Adjustment *adj);
float getValuePx (Gtk::Adjustment *adj);
#endif
-
+
/**
* Helper function to create, style and pack spinbuttons for the export dialog.
*
@@ -121,20 +123,20 @@ private:
*/
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> createSpinbutton( gchar const *key, float val, float min, float max,
- float step, float page,
- Gtk::Grid *t, int x, int y,
- const Glib::ustring ll, const Glib::ustring lr,
- int digits, unsigned int sensitive,
- void (Export::*cb)() );
+ float step, float page,
+ Gtk::Grid *t, int x, int y,
+ const Glib::ustring& ll, const Glib::ustring& lr,
+ int digits, unsigned int sensitive,
+ void (Export::*cb)() );
#else
Gtk::Adjustment * createSpinbutton( gchar const *key, float val, float min, float max,
- float step, float page,
- Gtk::Table *t, int x, int y,
- const Glib::ustring ll, const Glib::ustring lr,
- int digits, unsigned int sensitive,
- void (Export::*cb)() );
+ float step, float page,
+ Gtk::Table *t, int x, int y,
+ const Glib::ustring& ll, const Glib::ustring& lr,
+ int digits, unsigned int sensitive,
+ void (Export::*cb)() );
#endif
-
+
/**
* One of the area select radio buttons was pressed
*/
@@ -153,8 +155,12 @@ private:
/**
* Area X value changed callback
*/
- void onAreaX0Change() {areaXChange(x0_adj);} ;
- void onAreaX1Change() {areaXChange(x1_adj);} ;
+ void onAreaX0Change() {
+ areaXChange(x0_adj);
+ } ;
+ void onAreaX1Change() {
+ areaXChange(x1_adj);
+ } ;
#if WITH_GTKMM_3_0
void areaXChange(Glib::RefPtr<Gtk::Adjustment>& adj);
#else
@@ -164,8 +170,12 @@ private:
/**
* Area Y value changed callback
*/
- void onAreaY0Change() {areaYChange(y0_adj);} ;
- void onAreaY1Change() {areaYChange(y1_adj);} ;
+ void onAreaY0Change() {
+ areaYChange(y0_adj);
+ } ;
+ void onAreaY1Change() {
+ areaYChange(y1_adj);
+ } ;
#if WITH_GTKMM_3_0
void areaYChange(Glib::RefPtr<Gtk::Adjustment>& adj);
#else
@@ -235,14 +245,14 @@ private:
/**
* Creates progress dialog for batch exporting.
- *
+ *
* @param progress_text Text to be shown in the progress bar
*/
Gtk::Dialog * create_progress_dialog (Glib::ustring progress_text);
/**
* Callback to be used in for loop to update the progress bar.
- *
+ *
* @param value number between 0 and 1 indicating the fraction of progress (0.17 = 17 % progress)
* @param dlg void pointer to the Gtk::Dialog progress dialog
*/
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index 62a2f8572..8e0d085a4 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -39,7 +39,7 @@
#include <gtkmm/treemodelcolumn.h>
#include <gtkmm/clipboard.h>
#include <glibmm/stringutils.h>
-
+#include <glibmm/markup.h>
#include <glibmm/i18n.h>
#include "path-prefix.h"
#include "io/sys.h"
@@ -687,7 +687,7 @@ void SymbolsDialog::add_symbol( SPObject* symbol ) {
if( pixbuf ) {
Gtk::ListStore::iterator row = store->append();
(*row)[columns->symbol_id] = Glib::ustring( id );
- (*row)[columns->symbol_title] = Glib::ustring( g_dpgettext2(NULL, "Symbol", title) );
+ (*row)[columns->symbol_title] = Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", title) ));
(*row)[columns->symbol_image] = pixbuf;
}
diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp
index a487eb930..2412c3ec9 100644
--- a/src/ui/dialog/undo-history.cpp
+++ b/src/ui/dialog/undo-history.cpp
@@ -5,8 +5,9 @@
/* Author:
* Gustav Broberg <broberg@kth.se>
* Abhishek Sharma
+ * Jon A. Cruz <jon@joncruz.org>
*
- * Copyright (C) 2006 Authors
+ * Copyright (C) 2014 Authors
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -24,6 +25,7 @@
#include "inkscape.h"
#include "verbs.h"
#include "desktop-handles.h"
+#include "util/signal-blocker.h"
#include "desktop.h"
#include <gtkmm/invisible.h>
@@ -131,39 +133,19 @@ UndoHistory& UndoHistory::getInstance()
return *new UndoHistory();
}
-void
-UndoHistory::setDesktop(SPDesktop* desktop)
-{
- Panel::setDesktop(desktop);
-
- if (!desktop) return;
-
- _document = sp_desktop_document(desktop);
-
- _event_log = desktop->event_log;
-
- _callback_connections[EventLog::CALLB_SELECTION_CHANGE].block();
-
- _event_list_store = _event_log->getEventListStore();
- _event_list_view.set_model(_event_list_store);
- _event_list_selection = _event_list_view.get_selection();
-
- _event_log->connectWithDialog(&_event_list_view, &_callback_connections);
- _event_list_view.scroll_to_row(_event_list_store->get_path(_event_list_selection->get_selected()));
-
- _callback_connections[EventLog::CALLB_SELECTION_CHANGE].block(false);
-}
-
UndoHistory::UndoHistory()
: UI::Widget::Panel ("", "/dialogs/undo-history", SP_VERB_DIALOG_UNDO_HISTORY),
- _document (sp_desktop_document(getDesktop())),
- _event_log (getDesktop() ? getDesktop()->event_log : NULL),
- _columns (_event_log ? &_event_log->getColumns() : NULL),
- _event_list_selection (_event_list_view.get_selection()),
- _desktop(NULL),
+ _document_replaced_connection(),
+ _desktop(getDesktop()),
+ _document(_desktop ? _desktop->doc() : NULL),
+ _event_log(_desktop ? _desktop->event_log : NULL),
+ _columns(_event_log ? &_event_log->getColumns() : NULL),
+ _scrolled_window(),
+ _event_list_store(),
+ _event_list_selection(_event_list_view.get_selection()),
_deskTrack(),
- _desktopChangeConn()
-
+ _desktopChangeConn(),
+ _callback_connections()
{
if ( !_document || !_event_log || !_columns ) return;
@@ -172,9 +154,9 @@ UndoHistory::UndoHistory()
_getContents()->pack_start(_scrolled_window);
_scrolled_window.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
- _event_list_store = _event_log->getEventListStore();
+ // connect with the EventLog
+ _connectEventLog();
- _event_list_view.set_model(_event_list_store);
_event_list_view.set_rules_hint(false);
_event_list_view.set_enable_search(false);
_event_list_view.set_headers_visible(false);
@@ -221,12 +203,12 @@ UndoHistory::UndoHistory()
_callback_connections[EventLog::CALLB_COLLAPSE] =
_event_list_view.signal_row_collapsed().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::UndoHistory::_onCollapseEvent));
- // connect with the EventLog
- _event_log->connectWithDialog(&_event_list_view, &_callback_connections);
-
_desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &UndoHistory::setDesktop) );
_deskTrack.connect(GTK_WIDGET(gobj()));
+ // connect to be informed of document changes
+ signalDocumentReplaced().connect(sigc::mem_fun(*this, &UndoHistory::_handleDocumentReplaced));
+
show_all_children();
// scroll to the selected row
@@ -239,6 +221,82 @@ UndoHistory::~UndoHistory()
}
+void UndoHistory::setDesktop(SPDesktop* desktop)
+{
+ Panel::setDesktop(desktop);
+
+ EventLog *newEventLog = desktop ? desktop->event_log : NULL;
+ if ((_desktop == desktop) && (_event_log == newEventLog)) {
+ // same desktop set
+ }
+ else
+ {
+ _connectDocument(desktop, desktop ? desktop->doc() : NULL);
+ }
+}
+
+void UndoHistory::_connectDocument(SPDesktop* desktop, SPDocument *document)
+{
+ // disconnect from prior
+ if (_event_log) {
+ _event_log->removeDialogConnection(&_event_list_view, &_callback_connections);
+ }
+
+ SignalBlocker blocker(&_callback_connections[EventLog::CALLB_SELECTION_CHANGE]);
+
+ _event_list_view.unset_model();
+
+ // connect to new EventLog/Desktop
+ _desktop = desktop;
+ _event_log = desktop ? desktop->event_log : NULL;
+ _document = desktop ? desktop->doc() : NULL;
+ _connectEventLog();
+}
+
+void UndoHistory::_connectEventLog()
+{
+ if (_event_log) {
+ _event_log->add_destroy_notify_callback(this, &_handleEventLogDestroyCB);
+ _event_list_store = _event_log->getEventListStore();
+
+ _event_list_view.set_model(_event_list_store);
+
+ _event_log->addDialogConnection(&_event_list_view, &_callback_connections);
+ _event_list_view.scroll_to_row(_event_list_store->get_path(_event_list_selection->get_selected()));
+ }
+}
+
+void UndoHistory::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document)
+{
+ if ((desktop != _desktop) || (document != _document)) {
+ _connectDocument(desktop, document);
+ }
+}
+
+void *UndoHistory::_handleEventLogDestroyCB(void *data)
+{
+ void *result = NULL;
+ if (data) {
+ UndoHistory *self = reinterpret_cast<UndoHistory*>(data);
+ result = self->_handleEventLogDestroy();
+ }
+ return result;
+}
+
+// called *after* _event_log has been destroyed.
+void *UndoHistory::_handleEventLogDestroy()
+{
+ if (_event_log) {
+ SignalBlocker blocker(&_callback_connections[EventLog::CALLB_SELECTION_CHANGE]);
+
+ _event_list_view.unset_model();
+ _event_list_store.reset();
+ _event_log = NULL;
+ }
+
+ return NULL;
+}
+
void
UndoHistory::_onListSelectionChange()
{
diff --git a/src/ui/dialog/undo-history.h b/src/ui/dialog/undo-history.h
index adf4f1936..b0cc283cf 100644
--- a/src/ui/dialog/undo-history.h
+++ b/src/ui/dialog/undo-history.h
@@ -3,8 +3,9 @@
*/
/* Author:
* Gustav Broberg <broberg@kth.se>
+ * Jon A. Cruz <jon@joncruz.org>
*
- * Copyright (C) 2006 Authors
+ * Copyright (C) 2014 Authors
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -134,6 +135,7 @@ public:
protected:
+ SPDesktop *_desktop;
SPDocument *_document;
EventLog *_event_log;
@@ -146,12 +148,17 @@ protected:
Gtk::TreeView _event_list_view;
Glib::RefPtr<Gtk::TreeSelection> _event_list_selection;
- SPDesktop *_desktop;
DesktopTracker _deskTrack;
sigc::connection _desktopChangeConn;
EventLog::CallbackMap _callback_connections;
+ static void *_handleEventLogDestroyCB(void *data);
+
+ void _connectDocument(SPDesktop* desktop, SPDocument *document);
+ void _connectEventLog();
+ void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document);
+ void *_handleEventLogDestroy();
void _onListSelectionChange();
void _onExpandEvent(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
void _onCollapseEvent(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp
index 4a171d1bd..ac830fe6b 100644
--- a/src/ui/tools/text-tool.cpp
+++ b/src/ui/tools/text-tool.cpp
@@ -61,11 +61,6 @@ namespace Inkscape {
namespace UI {
namespace Tools {
-static void sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc);
-static void sp_text_context_selection_modified(Inkscape::Selection *selection, guint flags, TextTool *tc);
-static bool sp_text_context_style_set(SPCSSAttr const *css, TextTool *tc);
-static int sp_text_context_style_query(SPStyle *style, int property, TextTool *tc);
-
static void sp_text_context_validate_cursor_iterators(TextTool *tc);
static void sp_text_context_update_cursor(TextTool *tc, bool scroll_to_see = true);
static void sp_text_context_update_text_selection(TextTool *tc);
@@ -77,15 +72,15 @@ static gint sptc_focus_out(GtkWidget *widget, GdkEventFocus *event, TextTool *tc
static void sptc_commit(GtkIMContext *imc, gchar *string, TextTool *tc);
namespace {
- ToolBase* createTextContext() {
- return new TextTool();
- }
+ ToolBase* createTextContext() {
+ return new TextTool();
+ }
- bool textContextRegistered = ToolFactory::instance().registerObject("/tools/text", createTextContext);
+ bool textContextRegistered = ToolFactory::instance().registerObject("/tools/text", createTextContext);
}
const std::string& TextTool::getPrefsPath() {
- return TextTool::prefsPath;
+ return TextTool::prefsPath;
}
const std::string TextTool::prefsPath = "/tools/text";
@@ -165,7 +160,7 @@ void TextTool::setup() {
*/
gtk_im_context_set_use_preedit(this->imc, FALSE);
gtk_im_context_set_client_window(this->imc,
- gtk_widget_get_window (canvas));
+ gtk_widget_get_window (canvas));
g_signal_connect(G_OBJECT(canvas), "focus_in_event", G_CALLBACK(sptc_focus_in), this);
g_signal_connect(G_OBJECT(canvas), "focus_out_event", G_CALLBACK(sptc_focus_out), this);
@@ -185,20 +180,20 @@ void TextTool::setup() {
this->shape_editor->set_item(item, SH_KNOTHOLDER);
}
- this->sel_changed_connection = sp_desktop_selection(desktop)->connectChanged(
- sigc::bind(sigc::ptr_fun(&sp_text_context_selection_changed), this)
- );
- this->sel_modified_connection = sp_desktop_selection(desktop)->connectModified(
- sigc::bind(sigc::ptr_fun(&sp_text_context_selection_modified), this)
- );
+ this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst(
+ sigc::mem_fun(*this, &TextTool::_selectionChanged)
+ );
+ this->sel_modified_connection = sp_desktop_selection(desktop)->connectModifiedFirst(
+ sigc::mem_fun(*this, &TextTool::_selectionModified)
+ );
this->style_set_connection = desktop->connectSetStyle(
- sigc::bind(sigc::ptr_fun(&sp_text_context_style_set), this)
- );
+ sigc::mem_fun(*this, &TextTool::_styleSet)
+ );
this->style_query_connection = desktop->connectQueryStyle(
- sigc::bind(sigc::ptr_fun(&sp_text_context_style_query), this)
- );
+ sigc::mem_fun(*this, &TextTool::_styleQueried)
+ );
- sp_text_context_selection_changed(sp_desktop_selection(desktop), this);
+ _selectionChanged(sp_desktop_selection(desktop));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (prefs->getBool("/tools/text/selcue")) {
@@ -396,7 +391,7 @@ bool TextTool::item_handler(SPItem* item, GdkEvent* event) {
}
if (!ret) {
- ret = ToolBase::item_handler(item, event);
+ ret = ToolBase::item_handler(item, event);
}
return ret;
@@ -437,7 +432,7 @@ static void sp_text_context_setup_text(TextTool *tc)
text_item->updateRepr();
text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT,
- _("Create text"));
+ _("Create text"));
}
/**
@@ -477,7 +472,7 @@ static void insert_uni_char(TextTool *const tc)
sp_text_context_update_cursor(tc);
sp_text_context_update_text_selection(tc);
DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_DIALOG_TRANSFORM,
- _("Insert Unicode character"));
+ _("Insert Unicode character"));
}
}
@@ -667,8 +662,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_desktop_apply_style_tool(desktop, ft->getRepr(), "/tools/text", true);
sp_desktop_selection(desktop)->set(ft);
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Flowed text is created."));
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Create flowed text"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Create flowed text"));
} else {
desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The frame is <b>too small</b> for the current font size. Flowed text not created."));
}
@@ -807,8 +801,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No-break space"));
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Insert no-break space"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Insert no-break space"));
return TRUE;
}
break;
@@ -844,8 +837,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_repr_css_set_property(css, "font-weight", "normal");
sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
sp_repr_css_attr_unref(css);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Make bold"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make bold"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -862,8 +854,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_repr_css_set_property(css, "font-style", "italic");
sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
sp_repr_css_attr_unref(css);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Make italic"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Make italic"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -901,8 +892,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("New line"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("New line"));
return TRUE;
}
case GDK_KEY_BackSpace:
@@ -943,8 +933,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Backspace"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Backspace"));
}
return TRUE;
case GDK_KEY_Delete:
@@ -982,8 +971,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT,
- _("Delete"));
+ DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Delete"));
}
return TRUE;
case GDK_KEY_Left:
@@ -999,8 +987,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*-1, 0));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT,
- _("Kern to the left"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:left", SP_VERB_CONTEXT_TEXT, _("Kern to the left"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorLeftWithControl();
@@ -1024,8 +1011,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(mul*1, 0));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT,
- _("Kern to the right"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:right", SP_VERB_CONTEXT_TEXT, _("Kern to the right"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorRightWithControl();
@@ -1049,8 +1035,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*-1));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT,
- _("Kern up"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:up", SP_VERB_CONTEXT_TEXT, _("Kern up"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorUpWithControl();
@@ -1074,8 +1059,7 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_kerning_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, Geom::Point(0, mul*1));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT,
- _("Kern down"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "kern:down", SP_VERB_CONTEXT_TEXT, _("Kern down"));
} else {
if (MOD__CTRL(event))
this->text_sel_end.cursorDownWithControl();
@@ -1150,8 +1134,7 @@ bool TextTool::root_handler(GdkEvent* event) {
} else {
sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, -90);
}
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT,
- _("Rotate counterclockwise"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:ccw", SP_VERB_CONTEXT_TEXT, _("Rotate counterclockwise"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -1171,8 +1154,7 @@ bool TextTool::root_handler(GdkEvent* event) {
} else {
sp_te_adjust_rotation(this->text, this->text_sel_start, this->text_sel_end, desktop, 90);
}
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT,
- _("Rotate clockwise"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "textrot:cw", SP_VERB_CONTEXT_TEXT, _("Rotate clockwise"));
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
return TRUE;
@@ -1188,15 +1170,13 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10);
else
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT,
- _("Contract line spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract line spacing"));
} else {
if (MOD__SHIFT(event))
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -10);
else
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, -1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT,
- _("Contract letter spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:dec", SP_VERB_CONTEXT_TEXT, _("Contract letter spacing"));
}
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
@@ -1213,15 +1193,13 @@ bool TextTool::root_handler(GdkEvent* event) {
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10);
else
sp_te_adjust_linespacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT,
- _("Expand line spacing"));
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "linespacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand line spacing"));
} else {
if (MOD__SHIFT(event))
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 10);
else
sp_te_adjust_tspan_letterspacing_screen(this->text, this->text_sel_start, this->text_sel_end, desktop, 1);
- DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT,
- _("Expand letter spacing"));\
+ DocumentUndo::maybeDone(sp_desktop_document(desktop), "letterspacing:inc", SP_VERB_CONTEXT_TEXT, _("Expand letter spacing"));\
}
sp_text_context_update_cursor(this);
sp_text_context_update_text_selection(this);
@@ -1305,32 +1283,32 @@ bool sp_text_paste_inline(ToolBase *ec)
Glib::ustring const clip_text = refClipboard->wait_for_text();
if (!clip_text.empty()) {
- // Fix for 244940
- // The XML standard defines the following as valid characters
- // (Extensible Markup Language (XML) 1.0 (Fourth Edition) paragraph 2.2)
- // char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
- // Since what comes in off the paste buffer will go right into XML, clean
- // the text here.
- Glib::ustring text(clip_text);
- Glib::ustring::iterator itr = text.begin();
- gunichar paste_string_uchar;
-
- while(itr != text.end())
- {
- paste_string_uchar = *itr;
-
- // Make sure we don't have a control character. We should really check
- // for the whole range above... Add the rest of the invalid cases from
- // above if we find additional issues
- if(paste_string_uchar >= 0x00000020 ||
- paste_string_uchar == 0x00000009 ||
- paste_string_uchar == 0x0000000A ||
- paste_string_uchar == 0x0000000D) {
- ++itr;
- } else {
- itr = text.erase(itr);
- }
- }
+ // Fix for 244940
+ // The XML standard defines the following as valid characters
+ // (Extensible Markup Language (XML) 1.0 (Fourth Edition) paragraph 2.2)
+ // char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+ // Since what comes in off the paste buffer will go right into XML, clean
+ // the text here.
+ Glib::ustring text(clip_text);
+ Glib::ustring::iterator itr = text.begin();
+ gunichar paste_string_uchar;
+
+ while(itr != text.end())
+ {
+ paste_string_uchar = *itr;
+
+ // Make sure we don't have a control character. We should really check
+ // for the whole range above... Add the rest of the invalid cases from
+ // above if we find additional issues
+ if(paste_string_uchar >= 0x00000020 ||
+ paste_string_uchar == 0x00000009 ||
+ paste_string_uchar == 0x0000000A ||
+ paste_string_uchar == 0x0000000D) {
+ ++itr;
+ } else {
+ itr = text.erase(itr);
+ }
+ }
if (!tc->text) { // create text if none (i.e. if nascent_object)
sp_text_context_setup_text(tc);
@@ -1351,7 +1329,7 @@ bool sp_text_paste_inline(ToolBase *ec)
begin = end + 1;
}
DocumentUndo::done(sp_desktop_document(ec->desktop), SP_VERB_CONTEXT_TEXT,
- _("Paste text"));
+ _("Paste text"));
return true;
}
@@ -1427,12 +1405,11 @@ bool sp_text_delete_selection(ToolBase *ec)
/**
* \param selection Should not be NULL.
*/
-static void
-sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc)
+void TextTool::_selectionChanged(Inkscape::Selection *selection)
{
g_assert(selection != NULL);
- ToolBase *ec = SP_EVENT_CONTEXT(tc);
+ ToolBase *ec = SP_EVENT_CONTEXT(this);
ec->shape_editor->unset_item(SH_KNOTHOLDER);
SPItem *item = selection->singleItem();
@@ -1440,70 +1417,68 @@ sp_text_context_selection_changed(Inkscape::Selection *selection, TextTool *tc)
ec->shape_editor->set_item(item, SH_KNOTHOLDER);
}
- if (tc->text && (item != tc->text)) {
- sp_text_context_forget_text(tc);
+ if (this->text && (item != this->text)) {
+ sp_text_context_forget_text(this);
}
- tc->text = NULL;
+ this->text = NULL;
if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
- tc->text = item;
- Inkscape::Text::Layout const *layout = te_get_layout(tc->text);
+ this->text = item;
+ Inkscape::Text::Layout const *layout = te_get_layout(this->text);
if (layout)
- tc->text_sel_start = tc->text_sel_end = layout->end();
+ this->text_sel_start = this->text_sel_end = layout->end();
} else {
- tc->text = NULL;
+ this->text = NULL;
}
// we update cursor without scrolling, because this position may not be final;
// item_handler moves cusros to the point of click immediately
- sp_text_context_update_cursor(tc, false);
- sp_text_context_update_text_selection(tc);
+ sp_text_context_update_cursor(this, false);
+ sp_text_context_update_text_selection(this);
}
-static void
-sp_text_context_selection_modified(Inkscape::Selection */*selection*/, guint /*flags*/, TextTool *tc)
+void TextTool::_selectionModified(Inkscape::Selection */*selection*/, guint /*flags*/)
{
- sp_text_context_update_cursor(tc);
- sp_text_context_update_text_selection(tc);
+ sp_text_context_update_cursor(this);
+ sp_text_context_update_text_selection(this);
}
-static bool sp_text_context_style_set(SPCSSAttr const *css, TextTool *tc)
+bool TextTool::_styleSet(SPCSSAttr const *css)
{
- if (tc->text == NULL)
+ if (this->text == NULL)
return false;
- if (tc->text_sel_start == tc->text_sel_end)
+ if (this->text_sel_start == this->text_sel_end)
return false; // will get picked up by the parent and applied to the whole text object
- sp_te_apply_style(tc->text, tc->text_sel_start, tc->text_sel_end, css);
- DocumentUndo::done(sp_desktop_document(tc->desktop), SP_VERB_CONTEXT_TEXT,
- _("Set text style"));
- sp_text_context_update_cursor(tc);
- sp_text_context_update_text_selection(tc);
+ sp_te_apply_style(this->text, this->text_sel_start, this->text_sel_end, css);
+ DocumentUndo::done(sp_desktop_document(this->desktop), SP_VERB_CONTEXT_TEXT,
+ _("Set text style"));
+ sp_text_context_update_cursor(this);
+ sp_text_context_update_text_selection(this);
return true;
}
-static int
-sp_text_context_style_query(SPStyle *style, int property, TextTool *tc)
+int TextTool::_styleQueried(SPStyle *style, int property)
{
- if (tc->text == NULL) {
+ if (this->text == NULL) {
return QUERY_STYLE_NOTHING;
}
- const Inkscape::Text::Layout *layout = te_get_layout(tc->text);
+ const Inkscape::Text::Layout *layout = te_get_layout(this->text);
if (layout == NULL) {
return QUERY_STYLE_NOTHING;
}
- sp_text_context_validate_cursor_iterators(tc);
+ sp_text_context_validate_cursor_iterators(this);
GSList *styles_list = NULL;
Inkscape::Text::Layout::iterator begin_it, end_it;
- if (tc->text_sel_start < tc->text_sel_end) {
- begin_it = tc->text_sel_start;
- end_it = tc->text_sel_end;
+ if (this->text_sel_start < this->text_sel_end) {
+ begin_it = this->text_sel_start;
+ end_it = this->text_sel_end;
} else {
- begin_it = tc->text_sel_end;
- end_it = tc->text_sel_start;
+ begin_it = this->text_sel_end;
+ end_it = this->text_sel_start;
}
if (begin_it == end_it) {
if (!begin_it.prevCharacter()) {
@@ -1717,7 +1692,7 @@ static void sptc_commit(GtkIMContext */*imc*/, gchar *string, TextTool *tc)
sp_text_context_update_text_selection(tc);
DocumentUndo::done(tc->text->document, SP_VERB_CONTEXT_TEXT,
- _("Type text"));
+ _("Type text"));
}
void sp_text_context_place_cursor (TextTool *tc, SPObject *text, Inkscape::Text::Layout::iterator where)
diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h
index c5336d378..ca2b3d19a 100644
--- a/src/ui/tools/text-tool.h
+++ b/src/ui/tools/text-tool.h
@@ -84,6 +84,12 @@ public:
virtual bool item_handler(SPItem* item, GdkEvent* event);
virtual const std::string& getPrefsPath();
+
+private:
+ void _selectionChanged(Inkscape::Selection *selection);
+ void _selectionModified(Inkscape::Selection *selection, guint flags);
+ bool _styleSet(SPCSSAttr const *css);
+ int _styleQueried(SPStyle *style, int property);
};
bool sp_text_paste_inline(ToolBase *ec);
diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h
index 3a536fc2c..eb8908f3e 100644
--- a/src/ui/tools/tool-base.h
+++ b/src/ui/tools/tool-base.h
@@ -14,6 +14,7 @@
#include <glib-object.h>
#include <gdk/gdk.h>
+#include <sigc++/trackable.h>
#include "knot.h"
#include "2geom/forward.h"
@@ -104,7 +105,9 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, gpointer const dse_item,
* plus few abstract base classes. Writing a new tool involves
* subclassing ToolBase.
*/
-class ToolBase {
+class ToolBase
+ : public sigc::trackable
+{
public:
void enableSelectionCue (bool enable=true);
void enableGrDrag (bool enable=true);
diff --git a/src/util/signal-blocker.h b/src/util/signal-blocker.h
new file mode 100644
index 000000000..06d9736f2
--- /dev/null
+++ b/src/util/signal-blocker.h
@@ -0,0 +1,70 @@
+/*
+ * Base RAII blocker for sgic++ signals.
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2014 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_UTIL_SIGNAL_BLOCKER_H
+#define SEEN_INKSCAPE_UTIL_SIGNAL_BLOCKER_H
+
+#include <string>
+#include <sigc++/connection.h>
+
+/**
+ * Base RAII blocker for sgic++ signals.
+ */
+class SignalBlocker
+{
+public:
+ /**
+ * Creates a new instance that if the signal is currently unblocked will block
+ * it until this instance is destructed and then will unblock it.
+ */
+ SignalBlocker( sigc::connection *connection ) :
+ _connection(connection),
+ _wasBlocked(_connection->blocked())
+ {
+ if (!_wasBlocked)
+ {
+ _connection->block();
+ }
+ }
+
+ /**
+ * Destructor that will unblock the signal if it was blocked initially by this
+ * instance.
+ */
+ ~SignalBlocker()
+ {
+ if (!_wasBlocked)
+ {
+ _connection->block(false);
+ }
+ }
+
+private:
+ // noncopyable, nonassignable
+ SignalBlocker(SignalBlocker const &other);
+ SignalBlocker& operator=(SignalBlocker const &other);
+
+ sigc::connection *_connection;
+ bool _wasBlocked;
+};
+
+#endif // SEEN_INKSCAPE_UTIL_SIGNAL_BLOCKER_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 26e5ce531..d0e3a966c 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -2478,7 +2478,7 @@ Verb *Verb::_base_verbs[] = {
new EditVerb(SP_VERB_EDIT_DESELECT, "EditDeselect", N_("D_eselect"),
N_("Deselect any selected objects or nodes"), INKSCAPE_ICON("edit-select-none")),
new EditVerb(SP_VERB_EDIT_DELETE_ALL_GUIDES, "EditRemoveAllGuides", N_("Delete All Guides"),
- N_("Create four guides aligned with the page borders"), NULL),
+ N_("Delete all the guides in the document"), NULL),
new EditVerb(SP_VERB_EDIT_GUIDES_AROUND_PAGE, "EditGuidesAroundPage", N_("Create _Guides Around the Page"),
N_("Create four guides aligned with the page borders"), NULL),
new EditVerb(SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER, "EditNextPathEffectParameter", N_("Next path effect parameter"),
@@ -2615,11 +2615,11 @@ Verb *Verb::_base_verbs[] = {
N_("Toggle visibility of current layer"), NULL),
// Object
- new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CW, "ObjectRotate90", N_("Rotate _90&#176; CW"),
+ new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CW, "ObjectRotate90", N_("Rotate _90\xc2\xb0 CW"),
// This is shared between tooltips and statusbar, so they
// must use UTF-8, not HTML entities for special characters.
N_("Rotate selection 90\xc2\xb0 clockwise"), INKSCAPE_ICON("object-rotate-right")),
- new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CCW, "ObjectRotate90CCW", N_("Rotate 9_0&#176; CCW"),
+ new ObjectVerb(SP_VERB_OBJECT_ROTATE_90_CCW, "ObjectRotate90CCW", N_("Rotate 9_0\xc2\xb0 CCW"),
// This is shared between tooltips and statusbar, so they
// must use UTF-8, not HTML entities for special characters.
N_("Rotate selection 90\xc2\xb0 counter-clockwise"), INKSCAPE_ICON("object-rotate-left")),