Code

NR::Maybe => boost::optional
[inkscape.git] / src / selection.cpp
index d3b667a128a0e76cdd5650ed276898bc41af71ba..b71f27815214e527d8059792c352bdf5d21b5e4c 100644 (file)
@@ -30,6 +30,8 @@
 #include "sp-path.h"
 #include "sp-item-group.h"
 #include "box3d.h"
+#include "box3d.h"
+#include "persp3d.h"
 
 #include <sigc++/functors/mem_fun.h>
 
@@ -159,6 +161,27 @@ void Selection::add(SPObject *obj, bool persist_selection_context/* = false */)
     _emitChanged(persist_selection_context);
 }
 
+void Selection::add_box_perspective(SPBox3D *box) {
+    Persp3D *persp = box3d_get_perspective(box);
+    std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
+    if (p != _persps.end()) {
+        (*p).second++;
+    } else {
+        _persps[persp] = 1;
+    }
+}
+
+void Selection::add_3D_boxes_recursively(SPObject *obj) {
+    std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
+
+    for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
+        SPBox3D *box = *i;
+        box3d_add_to_selection(box);
+        _3dboxes.push_back(box);
+        add_box_perspective(box);
+    }
+}
+
 void Selection::_add(SPObject *obj) {
     // unselect any of the item's ancestors and descendants which may be selected
     // (to prevent double-selection)
@@ -167,10 +190,7 @@ void Selection::_add(SPObject *obj) {
 
     _objs = g_slist_prepend(_objs, obj);
 
-    if (SP_IS_BOX3D(obj)) {
-        // keep track of selected boxes for transformations
-        box3d_add_to_selection(SP_BOX3D(obj));
-    }
+    add_3D_boxes_recursively(obj);
 
     _release_connections[obj] = obj->connectRelease(sigc::mem_fun(*this, (void (Selection::*)(SPObject *))&Selection::remove));
     _modified_connections[obj] = obj->connectModified(sigc::mem_fun(*this, &Selection::_schedule_modified));
@@ -199,6 +219,36 @@ void Selection::remove(SPObject *obj) {
     _emitChanged();
 }
 
+void Selection::remove_box_perspective(SPBox3D *box) {
+    Persp3D *persp = box3d_get_perspective(box);
+    std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
+    if (p == _persps.end()) {
+        g_print ("Warning! Trying to remove unselected perspective from selection!\n");
+        return;
+    }
+    if ((*p).second > 1) {
+        _persps[persp]--;
+    } else {
+        _persps.erase(p);
+    }
+}
+
+void Selection::remove_3D_boxes_recursively(SPObject *obj) {
+    std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
+
+    for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
+        SPBox3D *box = *i;
+        box3d_remove_from_selection(box);
+        std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box);
+        if (b == _3dboxes.end()) {
+            g_print ("Warning! Trying to remove unselected box from selection.\n");
+            return;
+        }
+        _3dboxes.erase(b);
+        remove_box_perspective(box);
+    }
+}
+
 void Selection::_remove(SPObject *obj) {
     _modified_connections[obj].disconnect();
     _modified_connections.erase(obj);
@@ -206,10 +256,7 @@ void Selection::_remove(SPObject *obj) {
     _release_connections[obj].disconnect();
     _release_connections.erase(obj);
 
-    if (SP_IS_BOX3D(obj)) {
-        // keep track of selected boxes for transformations
-        box3d_remove_from_selection(SP_BOX3D(obj));
-    }
+    remove_3D_boxes_recursively(obj);
 
     _objs = g_slist_remove(_objs, obj);
 }
@@ -294,6 +341,18 @@ GSList const *Selection::reprList() {
     return _reprs;
 }
 
+std::list<Persp3D *> const Selection::perspList() {
+    std::list<Persp3D *> pl;
+    for (std::map<Persp3D *, unsigned int>::iterator p = _persps.begin(); p != _persps.end(); ++p) {
+        pl.push_back((*p).first);
+    }
+    return pl;
+}
+
+std::list<SPBox3D *> const Selection::box3DList() {
+    return _3dboxes;
+}
+
 SPObject *Selection::single() {
     if ( _objs != NULL && _objs->next == NULL ) {
         return reinterpret_cast<SPObject *>(_objs->data);
@@ -323,11 +382,11 @@ NRRect *Selection::bounds(NRRect *bbox, SPItem::BBoxType type) const
     return bbox;
 }
 
-NR::Maybe<NR::Rect> Selection::bounds(SPItem::BBoxType type) const
+boost::optional<NR::Rect> Selection::bounds(SPItem::BBoxType type) const
 {
     GSList const *items = const_cast<Selection *>(this)->itemList();
 
-    NR::Maybe<NR::Rect> bbox = NR::Nothing();
+    boost::optional<NR::Rect> bbox;
     for ( GSList const *i = items ; i != NULL ; i = i->next ) {
         bbox = NR::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type));
     }
@@ -348,20 +407,20 @@ NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const {
 
     for ( GSList const *iter=items ; iter != NULL ; iter = iter->next ) {
         SPItem *item=SP_ITEM(iter->data);
-        NR::Matrix i2doc(sp_item_i2doc_affine(item));
+        NR::Matrix i2doc(from_2geom(sp_item_i2doc_affine(item)));
         sp_item_invoke_bbox(item, bbox, i2doc, FALSE, type);
     }
 
     return bbox;
 }
 
-NR::Maybe<NR::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const {
+boost::optional<NR::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const {
     NRRect r;
     return boundsInDocument(&r, type)->upgrade();
 }
 
 /** Extract the position of the center from the first selected object */
-NR::Maybe<NR::Point> Selection::center() const {
+boost::optional<NR::Point> Selection::center() const {
     GSList *items = (GSList *) const_cast<Selection *>(this)->itemList();
     NR::Point center;
     if (items) {
@@ -370,11 +429,11 @@ NR::Maybe<NR::Point> Selection::center() const {
             return first->getCenter();
         }
     }
-    NR::Maybe<NR::Rect> bbox = bounds();
+    boost::optional<NR::Rect> bbox = bounds();
     if (bbox) {
         return bounds()->midpoint();
     } else {
-        return NR::Nothing();
+        return boost::optional<NR::Point>();
     }
 }
 
@@ -414,7 +473,7 @@ std::vector<NR::Point> Selection::getSnapPointsConvexHull() const {
             cvh.add(*i);
         }
 
-        NR::Maybe<NR::Rect> rHull = cvh.bounds();
+        boost::optional<NR::Rect> rHull = cvh.bounds();
         if (rHull) {
             for ( unsigned i = 0 ; i < 4 ; ++i ) {
                 pHull.push_back(rHull->corner(i));