summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Jeanmougin <marc@jeanmougin.fr>2017-05-23 20:48:47 +0000
committerMarc Jeanmougin <marcjeanmougin@free.fr>2017-05-23 20:48:47 +0000
commitde37ea2c3d4a1c857186dda0b113da04cd2bd79b (patch)
tree4b52381825a1d0efcbe4cada1c4bf61ade04b6a1
parentcmake/MSYS2: Include libyaml for xverb feature (diff)
parentselection chemistry: cancel if we hit top/bottom (diff)
downloadinkscape-de37ea2c3d4a1c857186dda0b113da04cd2bd79b.tar.gz
inkscape-de37ea2c3d4a1c857186dda0b113da04cd2bd79b.zip
merge chr[] branch : Objects panel improvements, mem leaks.
(bzr r15700)
-rw-r--r--src/live_effects/lpe-bspline.cpp1
-rw-r--r--src/live_effects/lpe-clone-original.cpp12
-rw-r--r--src/live_effects/lpe-copy_rotate.cpp4
-rw-r--r--src/live_effects/lpe-measure-line.cpp11
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp4
-rw-r--r--src/live_effects/parameter/path.cpp3
-rw-r--r--src/object-set.h2
-rw-r--r--src/path-chemistry.cpp3
-rw-r--r--src/selection-chemistry.cpp54
-rw-r--r--src/sp-item-group.cpp1
-rw-r--r--src/sp-item.cpp8
-rw-r--r--src/sp-item.h4
-rw-r--r--src/sp-pattern.cpp6
-rw-r--r--src/svg/svg-affine-test.h4
-rw-r--r--src/ui/dialog/objects.cpp115
-rw-r--r--src/ui/dialog/objects.h5
-rw-r--r--src/ui/widget/clipmaskicon.cpp24
-rw-r--r--src/ui/widget/clipmaskicon.h4
-rw-r--r--src/verbs.cpp14
-rw-r--r--src/verbs.h2
-rw-r--r--src/widgets/stroke-marker-selector.cpp14
21 files changed, 214 insertions, 81 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 5c227e68a..dbd67beda 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -168,6 +168,7 @@ void LPEBSpline::changeWeight(double weight_ammount)
doBSplineFromWidget(curve, weight_ammount/100.0);
gchar *str = sp_svg_write_path(curve->get_pathvector());
path->getRepr()->setAttribute("inkscape:original-d", str);
+ g_free(str);
}
}
diff --git a/src/live_effects/lpe-clone-original.cpp b/src/live_effects/lpe-clone-original.cpp
index d97a990af..31bf0e270 100644
--- a/src/live_effects/lpe-clone-original.cpp
+++ b/src/live_effects/lpe-clone-original.cpp
@@ -138,10 +138,14 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
dest_affine *= Geom::Translate(preserve_affine.translation());
affine_previous = preserve_affine;
preserve_affine = Geom::identity();
- SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(dest_affine));
+ gchar * str = sp_svg_transform_write(dest_affine);
+ SP_ITEM(dest)->getRepr()->setAttribute("transform", str);
+ g_free(str);
}
} else {
- SP_ITEM(dest)->getRepr()->setAttribute("transform",sp_svg_transform_write(affine_origin));
+ gchar * str = sp_svg_transform_write(affine_origin);
+ SP_ITEM(dest)->getRepr()->setAttribute("transform", str);
+ g_free(str);
}
} else if ( shape_dest && shape_origin && live && (std::strcmp(attribute, "d") == 0)) {
SPCurve *c = NULL;
@@ -176,7 +180,9 @@ LPECloneOriginal::cloneAttrbutes(SPObject *origin, SPObject *dest, bool live, co
c->set_pathvector(c_pv);
if (!path_origin) {
shape_dest->setCurveInsync(c, TRUE);
- dest->getRepr()->setAttribute(attribute, sp_svg_write_path(c_pv));
+ gchar *str = sp_svg_write_path(c_pv);
+ dest->getRepr()->setAttribute(attribute, str);
+ g_free(str);
} else {
shape_dest->setCurve(c, TRUE);
}
diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp
index f8be0f2a5..e80ad80cb 100644
--- a/src/live_effects/lpe-copy_rotate.cpp
+++ b/src/live_effects/lpe-copy_rotate.cpp
@@ -274,7 +274,9 @@ LPECopyRotate::toItem(Geom::Affine transform, size_t i, bool reset)
Inkscape::GC::release(phantom);
}
cloneD(SP_OBJECT(sp_lpe_item), elemref, true, reset);
- elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform));
+ gchar *str = sp_svg_transform_write(transform);
+ elemref->getRepr()->setAttribute("transform" , str);
+ g_free(str);
SP_ITEM(elemref)->setHidden(false);
if (elemref->parent != container) {
Inkscape::XML::Node *copy = phantom->duplicate(xml_doc);
diff --git a/src/live_effects/lpe-measure-line.cpp b/src/live_effects/lpe-measure-line.cpp
index 892744462..f7892cbe7 100644
--- a/src/live_effects/lpe-measure-line.cpp
+++ b/src/live_effects/lpe-measure-line.cpp
@@ -260,7 +260,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl
rtspan = xml_doc->createElement("svg:tspan");
rtspan->setAttribute("sodipodi:role", "line");
}
- const char * transform;
+ gchar * transform;
Geom::Affine affine = Geom::Affine(Geom::Translate(pos).inverse());
angle = std::fmod(angle, 2*M_PI);
if (angle < 0) angle += 2*M_PI;
@@ -276,6 +276,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl
transform = NULL;
}
rtext->setAttribute("transform", transform);
+ g_free(transform);
SPCSSAttr *css = sp_repr_css_attr_new();
sp_repr_css_attr_add_from_string(css, anotation_format.param_getSVGValue());
Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
@@ -317,7 +318,7 @@ LPEMeasureLine::createTextLabel(Geom::Point pos, double length, Geom::Coord angl
g_snprintf(length_str, 64, "%.*f", (int)precision, length);
setlocale (LC_NUMERIC, oldlocale);
g_free (oldlocale);
- Glib::ustring label_value = Glib::ustring(format.param_getSVGValue());
+ Glib::ustring label_value(format.param_getSVGValue());
size_t s = label_value.find(Glib::ustring("{measure}"),0);
if(s < label_value.length()) {
label_value.replace(s,s+9,length_str);
@@ -413,17 +414,19 @@ LPEMeasureLine::createLine(Geom::Point start,Geom::Point end, const char * id, b
}
line = elemref->getRepr();
- const char * line_str = sp_svg_write_path( line_pathv );
+ gchar * line_str = sp_svg_write_path( line_pathv );
line->setAttribute("d" , line_str);
line->setAttribute("transform", NULL);
+ g_free(line_str);
} else {
if (remove) {
return;
}
line = xml_doc->createElement("svg:path");
line->setAttribute("id", id);
- const char * line_str = sp_svg_write_path( line_pathv );
+ gchar * line_str = sp_svg_write_path( line_pathv );
line->setAttribute("d" , line_str);
+ g_free(line_str);
}
line->setAttribute("sodipodi:insensitive", "true");
line_pathv.clear();
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index 186b97fe3..b1f10c242 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -291,7 +291,9 @@ LPEMirrorSymmetry::toMirror(Geom::Affine transform)
Inkscape::GC::release(phantom);
}
cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true);
- elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform));
+ gchar *str = sp_svg_transform_write(transform);
+ elemref->getRepr()->setAttribute("transform" , str);
+ g_free(str);
if (elemref->parent != container) {
Inkscape::XML::Node *copy = phantom->duplicate(xml_doc);
copy->setAttribute("id", elemref_id);
diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp
index aa87508ab..6e90c9279 100644
--- a/src/live_effects/parameter/path.cpp
+++ b/src/live_effects/parameter/path.cpp
@@ -245,8 +245,9 @@ PathParam::param_editOncanvas(SPItem *item, SPDesktop * dt)
r.lpe_key = param_key;
Geom::PathVector stored_pv = _pathvector;
param_write_to_repr("M0,0 L1,0");
- const char *svgd = sp_svg_write_path(stored_pv);
+ gchar *svgd = sp_svg_write_path(stored_pv);
param_write_to_repr(svgd);
+ g_free(svgd);
} else {
r.item = ref.getObject();
}
diff --git a/src/object-set.h b/src/object-set.h
index 02259824c..82d2988c7 100644
--- a/src/object-set.h
+++ b/src/object-set.h
@@ -377,8 +377,10 @@ public:
//z-order management
//in selection-chemistry.cpp
+ void stackUp(bool skip_undo = false);
void raise(bool skip_undo = false);
void raiseToTop(bool skip_undo = false);
+ void stackDown(bool skip_undo = false);
void lower(bool skip_undo = false);
void lowerToBottom(bool skip_undo = false);
void toNextLayer(bool skip_undo = false);
diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp
index b66bcf368..7840c4ca8 100644
--- a/src/path-chemistry.cpp
+++ b/src/path-chemistry.cpp
@@ -255,8 +255,9 @@ ObjectSet::breakApart(bool skip_undo)
repr->setAttribute("inkscape:original-d", str);
else
repr->setAttribute("d", str);
+ str = sp_svg_transform_write(transform);
+ repr->setAttribute("transform", str);
g_free(str);
- repr->setAttribute("transform", sp_svg_transform_write(transform));
// add the new repr to the parent
parent->appendChild(repr);
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 5d585ab5d..b3d910700 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1140,6 +1140,53 @@ void ObjectSet::lowerToBottom(bool skip_undo){
}
}
+void ObjectSet::stackUp(bool skip_undo) {
+ if (isEmpty()) {
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to stack up."));
+ return;
+ }
+
+ std::vector<SPItem*> selection(items().begin(), items().end());
+ sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool);
+
+ for (auto item: selection | boost::adaptors::reversed) {
+ if (!item->raiseOne()) { // stop if top was reached
+ if(document() && !skip_undo)
+ DocumentUndo::cancel(document());
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("We hit top."));
+ return;
+ }
+ }
+
+ if(document() && !skip_undo)
+ DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_UP,
+ //TRANSLATORS: undo history: "stack up" means to raise an object of its ordinal position by 1
+ C_("Undo action", "stack up"));
+}
+
+void ObjectSet::stackDown(bool skip_undo) {
+ if (isEmpty()) {
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to stack down."));
+ return;
+ }
+
+ std::vector<SPItem*> selection(items().begin(), items().end());
+ sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool);
+
+ for (auto item: selection) {
+ if (!item->lowerOne()) { // stop if bottom was reached
+ if(document() && !skip_undo)
+ DocumentUndo::cancel(document());
+ selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("We hit bottom."));
+ return;
+ }
+ }
+
+ if(document() && !skip_undo)
+ DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_DOWN,
+ //TRANSLATORS: undo history: "stack down" means to lower an object of its ordinal position by 1
+ C_("Undo action", "stack down"));
+}
void
sp_undo(SPDesktop *desktop, SPDocument *)
@@ -3175,8 +3222,11 @@ void ObjectSet::toSymbol()
the_parent_repr->appendChild(clone);
if( single_group && transform.isTranslation() ) {
- if( !transform.isIdentity() )
- clone->setAttribute("transform", sp_svg_transform_write( transform ));
+ if( !transform.isIdentity() ) {
+ gchar *c = sp_svg_transform_write( transform );
+ clone->setAttribute("transform", c);
+ g_free(c);
+ }
}
// Change selection to new <use> element.
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index f2c0d2f2c..88b2bb1f9 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -594,6 +594,7 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
Geom::Affine ttrans = ctrans.inverse() * SP_ITEM(text)->transform * ctrans;
gchar *affinestr = sp_svg_transform_write(ttrans);
nrepr->setAttribute("transform", affinestr);
+ g_free(affinestr);
}
} else {
nrepr->setAttribute("transform", affinestr);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index e2f678957..368f8896c 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -306,15 +306,17 @@ void SPItem::raiseToTop() {
}
}
-void SPItem::raiseOne() {
+bool SPItem::raiseOne() {
auto next_higher = std::find_if(++parent->children.iterator_to(*this), parent->children.end(), &is_item);
if (next_higher != parent->children.end()) {
Inkscape::XML::Node *ref = next_higher->getRepr();
getRepr()->parent()->changeOrder(getRepr(), ref);
+ return true;
}
+ return false;
}
-void SPItem::lowerOne() {
+bool SPItem::lowerOne() {
using Inkscape::Algorithms::find_last_if;
auto next_lower = find_last_if(parent->children.begin(), parent->children.iterator_to(*this), &is_item);
@@ -325,7 +327,9 @@ void SPItem::lowerOne() {
ref = next_lower->getRepr();
}
getRepr()->parent()->changeOrder(getRepr(), ref);
+ return true;
}
+ return false;
}
void SPItem::lowerToBottom() {
diff --git a/src/sp-item.h b/src/sp-item.h
index a03bab9f3..c4d353a1d 100644
--- a/src/sp-item.h
+++ b/src/sp-item.h
@@ -212,8 +212,8 @@ public:
Geom::Affine getRelativeTransform(SPObject const *obj) const;
- void raiseOne();
- void lowerOne();
+ bool raiseOne();
+ bool lowerOne();
void raiseToTop();
void lowerToBottom();
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index 377c035fc..1e198506b 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -372,8 +372,9 @@ void SPPattern::transform_multiply(Geom::Affine postmul, bool set)
}
_pattern_transform_set = true;
- Glib::ustring c = sp_svg_transform_write(_pattern_transform);
+ gchar *c = sp_svg_transform_write(_pattern_transform);
getRepr()->setAttribute("patternTransform", c);
+ g_free(c);
}
const gchar *SPPattern::produce(const std::vector<Inkscape::XML::Node *> &reprs, Geom::Rect bounds,
@@ -390,8 +391,9 @@ const gchar *SPPattern::produce(const std::vector<Inkscape::XML::Node *> &reprs,
sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]);
//TODO: Maybe is better handle it in sp_svg_transform_write
if(transform != Geom::Affine()){
- Glib::ustring t = sp_svg_transform_write(transform);
+ gchar *t = sp_svg_transform_write(transform);
repr->setAttribute("patternTransform", t);
+ g_free(t);
}
defsrepr->appendChild(repr);
const gchar *pat_id = repr->attribute("id");
diff --git a/src/svg/svg-affine-test.h b/src/svg/svg-affine-test.h
index af670a3a8..829ef8a5a 100644
--- a/src/svg/svg-affine-test.h
+++ b/src/svg/svg-affine-test.h
@@ -67,7 +67,9 @@ public:
void testWriteIdentity()
{
- TS_ASSERT_EQUALS(sp_svg_transform_write(Geom::identity()) , (void*)0)
+ gchar str = sp_svg_transform_write(Geom::identity());
+ TS_ASSERT_EQUALS(str, NULL);
+ g_free(str);
}
void testReadMatrix()
diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp
index c7c696cdc..fd78fec90 100644
--- a/src/ui/dialog/objects.cpp
+++ b/src/ui/dialog/objects.cpp
@@ -30,6 +30,7 @@
#include "helper/action.h"
#include "inkscape.h"
#include "layer-manager.h"
+#include "shortcuts.h"
#include "sp-clippath.h"
#include "sp-mask.h"
#include "sp-root.h"
@@ -308,11 +309,13 @@ void ObjectsPanel::_objectsChanged(SPObject */*obj*/)
SPRoot* root = document->getRoot();
if ( root ) {
_selectedConnection.block();
+ _documentChangedCurrentLayer.block();
//Clear the tree store
_store->clear();
//Add all items recursively
_addObject( root, 0 );
_selectedConnection.unblock();
+ _documentChangedCurrentLayer.unblock();
//Set the tree selection
_objectsSelected(_desktop->selection);
//Handle button sensitivity
@@ -350,13 +353,17 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow)
row[_model->_colLocked] = !item->isSensitive();
row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0;
row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00;
- row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0);
+ row[_model->_colClipMask] = item ? (
+ (item->clip_ref && item->clip_ref->getObject() ? 1 : 0) |
+ (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)
+ ) : 0;
//row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0;
//If our parent object is a group and it's expanded, expand the tree
if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded())
{
_tree.expand_to_path( _store->get_path(iter) );
+ _tree.collapse_row( _store->get_path(iter) );
}
//Add an object watcher to the item
@@ -413,7 +420,10 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj)
row[_model->_colLocked] = item ? !item->isSensitive() : false;
row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0;
row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0;
- row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0;
+ row[_model->_colClipMask] = item ? (
+ (item->clip_ref && item->clip_ref->getObject() ? 1 : 0) |
+ (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)
+ ) : 0;
//row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0;
return true;
@@ -473,13 +483,13 @@ void ObjectsPanel::_objectsSelected( Selection *sel ) {
_setCompositingValues(item);
setOpacity = false;
}
- _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, (*i)==items.back()));
+ _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, (*i)==items.back(), false));
}
if (!item) {
if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) {
item = SP_ITEM(_desktop->currentLayer());
_setCompositingValues(item);
- _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true));
+ _store->foreach(sigc::bind<SPItem *, bool>( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, false, true));
}
}
_selectedConnection.unblock();
@@ -545,7 +555,7 @@ void ObjectsPanel::_setCompositingValues(SPItem *item)
* @param scrollto Whether to scroll to the item
* @return Whether to continue searching the tree
*/
-bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto)
+bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto, bool expand)
{
bool stopGoing = false;
@@ -554,13 +564,16 @@ bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeI
{
//We found the item! Expand to the path and select it in the tree.
_tree.expand_to_path( path );
+ if (!expand)
+ // but don't expand itself, just the path
+ _tree.collapse_row(path);
Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection();
select->select(iter);
if (scrollto) {
//Scroll to the item in the tree
- _tree.scroll_to_row(path);
+ _tree.scroll_to_row(path, 0.5);
}
stopGoing = true;
@@ -577,6 +590,7 @@ void ObjectsPanel::_pushTreeSelectionToCurrent()
if ( _desktop && _desktop->currentRoot() ) {
//block connections for selection and compositing values to prevent interference
_selectionChangedConnection.block();
+ _documentChangedCurrentLayer.block();
//Clear the selection and then iterate over the tree selection, pushing each item to the desktop
_desktop->selection->clear();
@@ -584,6 +598,7 @@ void ObjectsPanel::_pushTreeSelectionToCurrent()
_tree.get_selection()->selected_foreach_iter( sigc::bind<bool *>(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity));
//unblock connections
_selectionChangedConnection.unblock();
+ _documentChangedCurrentLayer.unblock();
_checkTreeSelection();
}
@@ -682,53 +697,63 @@ void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const b
*/
bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event)
{
+ if (!_desktop)
+ return false;
+
+ unsigned int shortcut;
+ shortcut = Inkscape::UI::Tools::get_group0_keyval(event) |
+ ( event->state & GDK_SHIFT_MASK ?
+ SP_SHORTCUT_SHIFT_MASK : 0 ) |
+ ( event->state & GDK_CONTROL_MASK ?
+ SP_SHORTCUT_CONTROL_MASK : 0 ) |
+ ( event->state & GDK_MOD1_MASK ?
+ SP_SHORTCUT_ALT_MASK : 0 );
+
+ switch (shortcut) {
+ // how to get users key binding for the action “start-interactive-search” ??
+ // ctrl+f is just the default
+ case GDK_KEY_f | SP_SHORTCUT_CONTROL_MASK:
+ return false;
+ break;
+ // shall we slurp ctrl+w to close panel?
+
+ // defocus:
+ case GDK_KEY_Escape:
+ if (_desktop->canvas) {
+ gtk_widget_grab_focus (GTK_WIDGET(_desktop->canvas));
+ return true;
+ }
+ break;
+ }
+
+ // invoke user defined shortcuts first
+ bool done = sp_shortcut_invoke(shortcut, _desktop);
+ if (done)
+ return true;
+ // handle events for the treeview
bool empty = _desktop->selection->isEmpty();
switch (Inkscape::UI::Tools::get_group0_keyval(event)) {
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
- case GDK_KEY_F2:
{
- Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected();
- if (iter && !_text_renderer->property_editable()) {
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *focus_column = 0;
+
+ _tree.get_cursor(path, focus_column);
+ if (focus_column == _name_column && !_text_renderer->property_editable()) {
//Rename item
- Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter);
_text_renderer->property_editable() = true;
- _tree.set_cursor(*path, *_name_column, true);
+ _tree.set_cursor(path, *_name_column, true);
grab_focus();
return true;
}
- }
- break;
- case GDK_KEY_Home:
- //Move item(s) to top of containing group/layer
- _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT );
- break;
- case GDK_KEY_End:
- //Move item(s) to bottom of containing group/layer
- _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK );
- break;
- case GDK_KEY_Page_Up:
- {
- //Move item(s) up in containing group/layer
- int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE;
- _fireAction( empty ? SP_VERB_LAYER_RAISE : ch );
- break;
- }
- case GDK_KEY_Page_Down:
- {
- //Move item(s) down in containing group/layer
- int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER;
- _fireAction( empty ? SP_VERB_LAYER_LOWER : ch );
+ return false;
break;
}
-
- //TODO: Handle Ctrl-A, etc.
- default:
- return false;
}
- return true;
+ return false;
}
/**
@@ -1172,7 +1197,7 @@ bool ObjectsPanel::_executeAction()
}
else
{
- _fireAction( SP_VERB_SELECTION_RAISE );
+ _fireAction( SP_VERB_SELECTION_STACK_UP );
}
}
break;
@@ -1184,7 +1209,7 @@ bool ObjectsPanel::_executeAction()
}
else
{
- _fireAction( SP_VERB_SELECTION_LOWER );
+ _fireAction( SP_VERB_SELECTION_STACK_DOWN );
}
}
break;
@@ -1734,6 +1759,8 @@ ObjectsPanel::ObjectsPanel() :
//Set the expander and search columns
_tree.set_expander_column( *_tree.get_column(nameColNum) );
_tree.set_search_column(_model->_colLabel);
+ // use ctrl+f to start search
+ _tree.set_enable_search(false);
//Set up the tree selection
_tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
@@ -1893,8 +1920,8 @@ ObjectsPanel::ObjectsPanel() :
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
- _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, "gtk-go-up", _("Up"), (int)BUTTON_UP ) );
- _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, "gtk-go-down", _("Down"), (int)BUTTON_DOWN ) );
+ _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_STACK_UP, "gtk-go-up", _("Up"), (int)BUTTON_UP ) );
+ _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_STACK_DOWN, "gtk-go-down", _("Down"), (int)BUTTON_DOWN ) );
_popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem()));
@@ -2033,6 +2060,7 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop )
if ( desktop != _desktop ) {
_documentChangedConnection.disconnect();
+ _documentChangedCurrentLayer.disconnect();
_selectionChangedConnection.disconnect();
if ( _desktop ) {
_desktop = 0;
@@ -2042,6 +2070,9 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop )
if ( _desktop ) {
//Connect desktop signals
_documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument));
+
+ _documentChangedCurrentLayer = _desktop->connectCurrentLayerChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsChanged));
+
_selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected));
setDocument(_desktop, _desktop->doc());
diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h
index 018f9191f..21305669e 100644
--- a/src/ui/dialog/objects.h
+++ b/src/ui/dialog/objects.h
@@ -77,6 +77,9 @@ private:
//Connection for when the document changes
sigc::connection _documentChangedConnection;
+ //Connection for when the active layer changes
+ sigc::connection _documentChangedCurrentLayer;
+
//Connection for when the active selection in the document changes
sigc::connection _selectionChangedConnection;
@@ -216,7 +219,7 @@ private:
bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj);
void _objectsSelected(Selection *sel);
- bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto);
+ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto, bool expand);
void _objectsChanged(SPObject *obj);
void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow );
diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp
index 4f791042a..a1e3eaf82 100644
--- a/src/ui/widget/clipmaskicon.cpp
+++ b/src/ui/widget/clipmaskicon.cpp
@@ -27,13 +27,13 @@ namespace Widget {
ClipMaskIcon::ClipMaskIcon() :
Glib::ObjectBase(typeid(ClipMaskIcon)),
Gtk::CellRendererPixbuf(),
- _pixClipName(INKSCAPE_ICON("path-intersection")),
- _pixInverseName(INKSCAPE_ICON("path-difference")),
- _pixMaskName(INKSCAPE_ICON("mask-intersection")),
+ _pixClipName(INKSCAPE_ICON("path-cut")),
+ _pixMaskName(INKSCAPE_ICON("path-difference")),
+ _pixBothName(INKSCAPE_ICON("bitmap-trace")),
_property_active(*this, "active", 0),
_property_pixbuf_clip(*this, "pixbuf_on", Glib::RefPtr<Gdk::Pixbuf>(0)),
- _property_pixbuf_inverse(*this, "pixbuf_on", Glib::RefPtr<Gdk::Pixbuf>(0)),
- _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr<Gdk::Pixbuf>(0))
+ _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr<Gdk::Pixbuf>(0)),
+ _property_pixbuf_both(*this, "pixbuf_on", Glib::RefPtr<Gdk::Pixbuf>(0))
{
property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
@@ -43,22 +43,22 @@ ClipMaskIcon::ClipMaskIcon() :
if (!icon_theme->has_icon(_pixClipName)) {
Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixClipName.data()), Inkscape::ICON_SIZE_DECORATION );
}
- if (!icon_theme->has_icon(_pixInverseName)) {
- Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixInverseName.data()), Inkscape::ICON_SIZE_DECORATION );
- }
if (!icon_theme->has_icon(_pixMaskName)) {
Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixMaskName.data()), Inkscape::ICON_SIZE_DECORATION );
}
+ if (!icon_theme->has_icon(_pixBothName)) {
+ Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixBothName.data()), Inkscape::ICON_SIZE_DECORATION );
+ }
if (icon_theme->has_icon(_pixClipName)) {
_property_pixbuf_clip = icon_theme->load_icon(_pixClipName, phys, (Gtk::IconLookupFlags)0);
}
- if (icon_theme->has_icon(_pixInverseName)) {
- _property_pixbuf_inverse = icon_theme->load_icon(_pixInverseName, phys, (Gtk::IconLookupFlags)0);
- }
if (icon_theme->has_icon(_pixMaskName)) {
_property_pixbuf_mask = icon_theme->load_icon(_pixMaskName, phys, (Gtk::IconLookupFlags)0);
}
+ if (icon_theme->has_icon(_pixBothName)) {
+ _property_pixbuf_both = icon_theme->load_icon(_pixBothName, phys, (Gtk::IconLookupFlags)0);
+ }
property_pixbuf() = Glib::RefPtr<Gdk::Pixbuf>(0);
}
@@ -108,7 +108,7 @@ void ClipMaskIcon::render_vfunc( const Cairo::RefPtr<Cairo::Context>& cr,
property_pixbuf() = _property_pixbuf_mask;
break;
case 3:
- property_pixbuf() = _property_pixbuf_inverse;
+ property_pixbuf() = _property_pixbuf_both;
break;
default:
property_pixbuf() = Glib::RefPtr<Gdk::Pixbuf>(0);
diff --git a/src/ui/widget/clipmaskicon.h b/src/ui/widget/clipmaskicon.h
index 0d149edb8..deb4554df 100644
--- a/src/ui/widget/clipmaskicon.h
+++ b/src/ui/widget/clipmaskicon.h
@@ -58,13 +58,13 @@ private:
int phys;
Glib::ustring _pixClipName;
- Glib::ustring _pixInverseName;
Glib::ustring _pixMaskName;
+ Glib::ustring _pixBothName;
Glib::Property<int> _property_active;
Glib::Property< Glib::RefPtr<Gdk::Pixbuf> > _property_pixbuf_clip;
- Glib::Property< Glib::RefPtr<Gdk::Pixbuf> > _property_pixbuf_inverse;
Glib::Property< Glib::RefPtr<Gdk::Pixbuf> > _property_pixbuf_mask;
+ Glib::Property< Glib::RefPtr<Gdk::Pixbuf> > _property_pixbuf_both;
};
diff --git a/src/verbs.cpp b/src/verbs.cpp
index b7b6da340..22ded60b3 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1179,6 +1179,12 @@ void SelectionVerb::perform(SPAction *action, void *data)
case SP_VERB_SELECTION_LOWER:
selection->lower();
break;
+ case SP_VERB_SELECTION_STACK_UP:
+ selection->stackUp();
+ break;
+ case SP_VERB_SELECTION_STACK_DOWN:
+ selection->stackDown();
+ break;
case SP_VERB_SELECTION_GROUP:
selection->group();
break;
@@ -2685,6 +2691,14 @@ Verb *Verb::_base_verbs[] = {
N_("Raise selection one step"), INKSCAPE_ICON("selection-raise")),
new SelectionVerb(SP_VERB_SELECTION_LOWER, "SelectionLower", N_("_Lower"),
N_("Lower selection one step"), INKSCAPE_ICON("selection-lower")),
+
+
+ new SelectionVerb(SP_VERB_SELECTION_STACK_UP, "SelectionStackUp", N_("_Stack up"),
+ N_("Stack selection one step up"), INKSCAPE_ICON("layer-raise")),
+ new SelectionVerb(SP_VERB_SELECTION_STACK_DOWN, "SelectionStackDown", N_("_Stack down"),
+ N_("Stack selection one step down"), INKSCAPE_ICON("layer-lower")),
+
+
new SelectionVerb(SP_VERB_SELECTION_GROUP, "SelectionGroup", N_("_Group"),
N_("Group selected objects"), INKSCAPE_ICON("object-group")),
new SelectionVerb(SP_VERB_SELECTION_UNGROUP, "SelectionUnGroup", N_("_Ungroup"),
diff --git a/src/verbs.h b/src/verbs.h
index 6846f1f40..a383bc365 100644
--- a/src/verbs.h
+++ b/src/verbs.h
@@ -116,6 +116,8 @@ enum {
SP_VERB_SELECTION_TO_BACK,
SP_VERB_SELECTION_RAISE,
SP_VERB_SELECTION_LOWER,
+ SP_VERB_SELECTION_STACK_UP,
+ SP_VERB_SELECTION_STACK_DOWN,
SP_VERB_SELECTION_GROUP,
SP_VERB_SELECTION_UNGROUP,
SP_VERB_SELECTION_UNGROUP_POP_SELECTION,
diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp
index b0c23a88c..3f81bef5c 100644
--- a/src/widgets/stroke-marker-selector.cpp
+++ b/src/widgets/stroke-marker-selector.cpp
@@ -54,8 +54,13 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) :
set_cell_data_func(image_renderer, sigc::mem_fun(*this, &MarkerComboBox::prepareImageRenderer));
gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(gobj()), MarkerComboBox::separator_cb, NULL, NULL);
+ Glib::ustring no_marker("no-marker");
+ Glib::RefPtr<Gtk::IconTheme> iconTheme = Gtk::IconTheme::get_default();
+ if (!iconTheme->has_icon(no_marker)) {
+ Inkscape::queueIconPrerender( INKSCAPE_ICON(no_marker.data()), Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+ }
empty_image = new Gtk::Image( Glib::wrap(
- sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("no-marker") ) ) );
+ sp_pixbuf_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON(no_marker.data()) ) ) );
sandbox = ink_markers_preview_doc ();
desktop = SP_ACTIVE_DESKTOP;
@@ -71,6 +76,7 @@ MarkerComboBox::MarkerComboBox(gchar const *id, int l) :
MarkerComboBox::~MarkerComboBox() {
delete combo_id;
delete sandbox;
+ delete empty_image;
if (doc) {
modified_connection.disconnect();
@@ -393,7 +399,7 @@ void MarkerComboBox::add_markers (GSList *marker_list, SPDocument *source, gbool
gchar const *markid = repr->attribute("inkscape:stockid") ? repr->attribute("inkscape:stockid") : repr->attribute("id");
// generate preview
- Gtk::Image *prv = create_marker_image (22, repr->attribute("id"), source, drawing, visionkey);
+ Gtk::Image *prv = create_marker_image (24, repr->attribute("id"), source, drawing, visionkey);
prv->show();
// Add history before separator, others after
@@ -424,14 +430,14 @@ void
MarkerComboBox::update_marker_image(gchar const *mname)
{
gchar *cache_name = g_strconcat(combo_id, mname, NULL);
- Glib::ustring key = svg_preview_cache.cache_key(doc->getURI(), cache_name, 22);
+ Glib::ustring key = svg_preview_cache.cache_key(doc->getURI(), cache_name, 24);
g_free (cache_name);
svg_preview_cache.remove_preview_from_cache(key);
Inkscape::Drawing drawing;
unsigned const visionkey = SPItem::display_key_new(1);
drawing.setRoot(sandbox->getRoot()->invoke_show(drawing, visionkey, SP_ITEM_SHOW_DISPLAY));
- Gtk::Image *prv = create_marker_image(22, mname, doc, drawing, visionkey);
+ Gtk::Image *prv = create_marker_image(24, mname, doc, drawing, visionkey);
if (prv) {
prv->show();
}