From 3cf6ef2cec342887ecf3263bca1d3a7ea2fdf5c4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 8 Jul 2024 23:28:19 +0200 Subject: [PATCH] WIP --- src/edt/edt/edtInstPropertiesPage.cc | 42 ++++++------ src/edt/edt/edtInstPropertiesPage.h | 2 +- src/edt/edt/edtMainService.cc | 9 +-- src/edt/edt/edtPropertiesPages.cc | 26 ++++---- src/edt/edt/edtPropertiesPages.h | 2 +- src/edt/edt/edtService.cc | 90 +++++++++++++++----------- src/edt/edt/edtService.h | 97 ++++++++++++++++------------ src/lay/lay/layFillDialog.cc | 2 +- 8 files changed, 149 insertions(+), 121 deletions(-) diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index d84474411..3baeb5a4b 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -47,7 +47,7 @@ namespace edt // ------------------------------------------------------------------------- -static std::string cell_name_from_sel (const edt::Service::obj_iterator &pos, edt::Service *service) +static std::string cell_name_from_sel (EditableSelectionIterator::pointer pos, edt::Service *service) { if (! pos->is_cell_inst ()) { return std::string (); @@ -81,7 +81,7 @@ struct SelectionPtrSort // .. nothing yet .. } - bool operator() (const edt::Service::obj_iterator &a, const edt::Service::obj_iterator &b) + bool operator() (EditableSelectionIterator::pointer a, EditableSelectionIterator::pointer b) { return cell_name_from_sel (a, mp_service) < cell_name_from_sel (b, mp_service); } @@ -104,10 +104,9 @@ static bool is_orthogonal (const db::DVector &rv, const db::DVector &cv) InstPropertiesPage::InstPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent) : lay::PropertiesPage (parent, manager, service), mp_service (service), m_enable_cb_callback (true), mp_pcell_parameters (0) { - const edt::Service::objects &selection = service->selection (); - m_selection_ptrs.reserve (selection.size ()); - for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) { - m_selection_ptrs.push_back (s); + m_selection_ptrs.reserve (service->selection_size ()); + for (EditableSelectionIterator s = service->begin_selection (); ! s.at_end (); ++s) { + m_selection_ptrs.push_back (s.operator-> ()); } std::sort (m_selection_ptrs.begin (), m_selection_ptrs.end (), SelectionPtrSort (service)); @@ -221,7 +220,7 @@ BEGIN_PROTECTED lib = lib_cbx->current_library (); layout = &lib->layout (); } else { - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); layout = &cv->layout (); } @@ -300,7 +299,7 @@ InstPropertiesPage::select_entries (const std::vector &entries) std::string InstPropertiesPage::description (size_t entry) const { - edt::Service::obj_iterator pos = m_selection_ptrs [entry]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [entry]; std::string d = cell_name_from_sel (pos, mp_service); if (! pos->is_cell_inst ()) { @@ -343,12 +342,12 @@ InstPropertiesPage::update () return; } - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; tl_assert (pos->is_cell_inst ()); std::set highlights; for (auto i = m_indexes.begin (); i != m_indexes.end (); ++i) { - highlights.insert (m_selection_ptrs [*i].operator-> ()); + highlights.insert (m_selection_ptrs [*i]); } mp_service->highlight (highlights); @@ -472,7 +471,7 @@ InstPropertiesPage::show_cell () return; } - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; lay::CellView::unspecific_cell_path_type path (mp_service->view ()->cellview (pos->cv_index ()).combined_unspecific_path ()); for (lay::ObjectInstPath::iterator p = pos->begin (); p != pos->end (); ++p) { @@ -509,7 +508,7 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & std::unique_ptr appl (new CombinedChangeApplicator ()); - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); bool du = dbu_cb->isChecked (); @@ -786,16 +785,15 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance & void InstPropertiesPage::recompute_selection_ptrs (const std::vector &new_sel) { - std::map ptrs; + std::map ptrs; - const edt::Service::objects &selection = mp_service->selection (); - for (edt::Service::obj_iterator pos = selection.begin (); pos != selection.end (); ++pos) { - ptrs.insert (std::make_pair (*pos, pos)); + for (EditableSelectionIterator pos = mp_service->begin_selection (); ! pos.at_end (); ++pos) { + ptrs.insert (std::make_pair (*pos, pos.operator -> ())); } m_selection_ptrs.clear (); for (std::vector::const_iterator s = new_sel.begin (); s != new_sel.end (); ++s) { - std::map::const_iterator pm = ptrs.find (*s); + std::map::const_iterator pm = ptrs.find (*s); tl_assert (pm != ptrs.end ()); m_selection_ptrs.push_back (pm->second); } @@ -814,7 +812,7 @@ InstPropertiesPage::do_apply (bool current_only, bool relative) std::unique_ptr applicator; { - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; tl_assert (pos->is_cell_inst ()); const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); @@ -846,7 +844,7 @@ InstPropertiesPage::do_apply (bool current_only, bool relative) std::vector new_sel; new_sel.reserve (m_selection_ptrs.size ()); - for (std::vector::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) { + for (std::vector::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) { new_sel.push_back (**p); } @@ -859,7 +857,7 @@ InstPropertiesPage::do_apply (bool current_only, bool relative) for (auto ii = m_indexes.begin (); ii != m_indexes.end (); ++ii) { size_t index = *ii; - edt::Service::obj_iterator pos = m_selection_ptrs [*ii]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [*ii]; // only update objects from the same layout - this is not practical limitation but saves a lot of effort for // managing different property id's etc. @@ -958,7 +956,7 @@ InstPropertiesPage::update_pcell_parameters () } else { - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); layout = &cv->layout (); @@ -982,7 +980,7 @@ InstPropertiesPage::update_pcell_parameters () std::vector parameters; - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); db::Cell &cell = cv->layout ().cell (pos->cell_index ()); std::pair pci = cell.is_pcell_instance (pos->back ().inst_ptr); diff --git a/src/edt/edt/edtInstPropertiesPage.h b/src/edt/edt/edtInstPropertiesPage.h index 713dff328..e9b2f9c81 100644 --- a/src/edt/edt/edtInstPropertiesPage.h +++ b/src/edt/edt/edtInstPropertiesPage.h @@ -58,7 +58,7 @@ private: void recompute_selection_ptrs (const std::vector &new_sel); protected: - std::vector m_selection_ptrs; + std::vector m_selection_ptrs; std::vector m_indexes; edt::Service *mp_service; bool m_enable_cb_callback; diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index 2477a7788..461b3c046 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -310,8 +310,7 @@ MainService::cm_descend () std::vector edt_services = view ()->get_plugins (); for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end () && common_inst.valid (); ++es) { - const edt::Service::objects &selection = (*es)->selection (); - for (edt::Service::objects::const_iterator sel = selection.begin (); sel != selection.end () && common_inst.valid (); ++sel) { + for (EditableSelectionIterator sel = (*es)->begin_selection (); ! sel.at_end () && common_inst.valid (); ++sel) { common_inst.add (*sel, 1); } } @@ -335,12 +334,10 @@ MainService::cm_descend () for (std::vector::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) { - const edt::Service::objects &selection = (*es)->selection (); - new_selections.push_back (std::vector ()); - new_selections.back ().reserve (selection.size ()); + new_selections.back ().reserve ((*es)->selection_size ()); - for (edt::Service::objects::const_iterator sel = selection.begin (); sel != selection.end (); ++sel) { + for (EditableSelectionIterator sel = (*es)->begin_selection (); ! sel.at_end (); ++sel) { new_selections.back ().push_back (*sel); lay::ObjectInstPath &new_sel = new_selections.back ().back (); diff --git a/src/edt/edt/edtPropertiesPages.cc b/src/edt/edt/edtPropertiesPages.cc index ac31333c7..1e4bf2114 100644 --- a/src/edt/edt/edtPropertiesPages.cc +++ b/src/edt/edt/edtPropertiesPages.cc @@ -47,10 +47,9 @@ ShapePropertiesPage::ShapePropertiesPage (const std::string &description, edt::S : lay::PropertiesPage (parent, manager, service), m_description (description), mp_service (service), m_enable_cb_callback (true) { - const edt::Service::objects &selection = service->selection (); - m_selection_ptrs.reserve (selection.size ()); - for (edt::Service::obj_iterator s = selection.begin (); s != selection.end (); ++s) { - m_selection_ptrs.push_back (s); + m_selection_ptrs.reserve (service->selection_size ()); + for (edt::EditableSelectionIterator s = service->begin_selection (); ! s.at_end (); ++s) { + m_selection_ptrs.push_back (s.operator-> ()); } m_prop_id = 0; mp_service->clear_highlights (); @@ -191,7 +190,7 @@ ShapePropertiesPage::update () { std::set highlights; for (auto i = m_indexes.begin (); i != m_indexes.end (); ++i) { - highlights.insert (m_selection_ptrs [*i].operator-> ()); + highlights.insert (m_selection_ptrs [*i]); } mp_service->highlight (highlights); @@ -201,16 +200,15 @@ ShapePropertiesPage::update () void ShapePropertiesPage::recompute_selection_ptrs (const std::vector &new_sel) { - std::map ptrs; + std::map ptrs; - const edt::Service::objects &selection = mp_service->selection (); - for (edt::Service::obj_iterator pos = selection.begin (); pos != selection.end (); ++pos) { - ptrs.insert (std::make_pair (*pos, pos)); + for (EditableSelectionIterator pos = mp_service->begin_selection (); ! pos.at_end (); ++pos) { + ptrs.insert (std::make_pair (*pos, pos.operator-> ())); } m_selection_ptrs.clear (); for (std::vector::const_iterator s = new_sel.begin (); s != new_sel.end (); ++s) { - std::map::const_iterator pm = ptrs.find (*s); + std::map::const_iterator pm = ptrs.find (*s); tl_assert (pm != ptrs.end ()); m_selection_ptrs.push_back (pm->second); } @@ -228,7 +226,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative) unsigned int cv_index = m_selection_ptrs [m_indexes.front ()]->cv_index (); { - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; tl_assert (! pos->is_cell_inst ()); const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); @@ -261,7 +259,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative) std::vector new_sel; new_sel.reserve (m_selection_ptrs.size ()); - for (std::vector::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) { + for (std::vector::const_iterator p = m_selection_ptrs.begin (); p != m_selection_ptrs.end (); ++p) { new_sel.push_back (**p); } @@ -274,7 +272,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative) for (auto i = m_indexes.begin (); i != m_indexes.end (); ++i) { size_t index = *i; - edt::Service::obj_iterator pos = m_selection_ptrs [*i]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [*i]; // only update objects from the same layout - this is not practical limitation but saves a lot of effort for // managing different property id's etc. @@ -376,7 +374,7 @@ ShapePropertiesPage::update_shape () return; } - edt::Service::obj_iterator pos = m_selection_ptrs [m_indexes.front ()]; + EditableSelectionIterator::pointer pos = m_selection_ptrs [m_indexes.front ()]; const lay::CellView &cv = mp_service->view ()->cellview (pos->cv_index ()); double dbu = cv->layout ().dbu (); diff --git a/src/edt/edt/edtPropertiesPages.h b/src/edt/edt/edtPropertiesPages.h index ae3ffbd2e..21a22aaaf 100644 --- a/src/edt/edt/edtPropertiesPages.h +++ b/src/edt/edt/edtPropertiesPages.h @@ -71,7 +71,7 @@ private: protected: std::string m_description; - std::vector m_selection_ptrs; + std::vector m_selection_ptrs; std::vector m_indexes; edt::Service *mp_service; bool m_enable_cb_callback; diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index d0f766888..66b4e2ad5 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -459,8 +459,7 @@ Service::copy_selected () unsigned int inst_mode = 0; if (m_hier_copy_mode < 0) { - const objects &sel = selection (); - for (objects::const_iterator r = sel.begin (); r != sel.end () && ! need_to_ask_for_copy_mode; ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end () && ! need_to_ask_for_copy_mode; ++r) { if (r->is_cell_inst ()) { const db::Cell &cell = view ()->cellview (r->cv_index ())->layout ().cell (r->back ().inst_ptr.cell_index ()); if (! cell.is_proxy ()) { @@ -500,12 +499,10 @@ Service::copy_selected () void Service::copy_selected (unsigned int inst_mode) { - const objects &sel = selection (); - // create one ClipboardData object per cv_index because, this one assumes that there is // only one source layout object. std::set cv_indices; - for (objects::const_iterator r = sel.begin (); r != sel.end (); ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { cv_indices.insert (r->cv_index ()); } @@ -515,7 +512,7 @@ Service::copy_selected (unsigned int inst_mode) // add the selected objects to the clipboard data objects. const lay::CellView &cv = view ()->cellview (*cvi); - for (objects::const_iterator r = sel.begin (); r != sel.end (); ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { if (r->cv_index () == *cvi) { if (! r->is_cell_inst ()) { cd->get ().add (cv->layout (), r->layer (), r->shape (), cv.context_trans () * r->trans ()); @@ -618,8 +615,7 @@ Service::selection_bbox () db::DBox box; - const objects &sel = selection (); - for (objects::const_iterator r = sel.begin (); r != sel.end (); ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { const lay::CellView &cv = view ()->cellview (r->cv_index ()); const db::Layout &layout = cv->layout (); @@ -699,13 +695,10 @@ Service::transform (const db::DCplxTrans &trans, const std::vector obj_ptrs; - obj_ptrs.reserve (sel.size ()); - for (objects::iterator r = sel.begin (); r != sel.end (); ++r) { - obj_ptrs.push_back (r); + std::vector obj_ptrs; + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { + obj_ptrs.push_back (r.operator-> ()); } // build the transformation variants cache @@ -717,7 +710,7 @@ Service::transform (const db::DCplxTrans &trans, const std::vector >, std::vector > shapes_by_cell; n = 0; - for (objects::iterator r = sel.begin (); r != sel.end (); ++r, ++n) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r, ++n) { if (! r->is_cell_inst ()) { shapes_by_cell.insert (std::make_pair (std::make_pair (r->cell_index (), std::make_pair (r->cv_index (), r->layer ())), std::vector ())).first->second.push_back (n); } @@ -740,7 +733,7 @@ Service::transform (const db::DCplxTrans &trans, const std::vector::iterator si = sbc->second.begin (); si != sbc->second.end (); ++si) { - objects::iterator s = obj_ptrs [*si]; + EditableSelectionIterator::pointer s = obj_ptrs [*si]; // mt = transformation in DBU units db::ICplxTrans mt; @@ -764,14 +757,14 @@ Service::transform (const db::DCplxTrans &trans, const std::vector::iterator si = sbc->second.begin (); si != sbc->second.end (); ++si) { - objects::iterator &s = obj_ptrs [*si]; + EditableSelectionIterator::pointer &s = obj_ptrs [*si]; lay::ObjectInstPath new_path (*s); new_path.set_shape (new_shapes.find (s->shape ())->second); // modify the selection - m_selection.erase (s); - s = m_selection.insert (new_path).first; + m_selection.erase (*s); + s = m_selection.insert (new_path).first.operator-> (); } @@ -787,7 +780,7 @@ Service::transform (const db::DCplxTrans &trans, const std::vector, std::vector > insts_by_cell; n = 0; - for (objects::iterator r = sel.begin (); r != sel.end (); ++r, ++n) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r, ++n) { if (r->is_cell_inst ()) { insts_by_cell.insert (std::make_pair (std::make_pair (r->cell_index (), r->cv_index ()), std::vector ())).first->second.push_back (n); } @@ -810,7 +803,7 @@ Service::transform (const db::DCplxTrans &trans, const std::vector::iterator ii = ibc->second.begin (); ii != ibc->second.end (); ++ii) { - objects::iterator i = obj_ptrs [*ii]; + EditableSelectionIterator::pointer i = obj_ptrs [*ii]; // mt = transformation in DBU units db::ICplxTrans mt; @@ -836,14 +829,14 @@ Service::transform (const db::DCplxTrans &trans, const std::vector::iterator ii = ibc->second.begin (); ii != ibc->second.end (); ++ii) { - objects::iterator &i = obj_ptrs [*ii]; + EditableSelectionIterator::pointer &i = obj_ptrs [*ii]; lay::ObjectInstPath new_path (*i); new_path.back ().inst_ptr = new_insts.find (i->back ().inst_ptr)->second; // modify the selection - m_selection.erase (i); - i = m_selection.insert (new_path).first; + m_selection.erase (*i); + i = m_selection.insert (new_path).first.operator-> (); } @@ -1039,8 +1032,7 @@ Service::del_selected () std::set needs_cleanup; // delete all shapes and instances. - const objects &sel = selection (); - for (objects::const_iterator r = sel.begin (); r != sel.end (); ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { const lay::CellView &cv = view ()->cellview (r->cv_index ()); if (cv.is_valid ()) { db::Cell &cell = cv->layout ().cell (r->cell_index ()); @@ -1326,11 +1318,12 @@ static std::string path_to_string (const db::Layout &layout, const lay::ObjectIn void Service::display_status (bool transient) { - const objects *sel = transient ? &transient_selection () : &selection (); + EditableSelectionIterator r = transient ? begin_transient_selection () : begin_selection (); + EditableSelectionIterator rr = r; + ++rr; - if (sel->size () == 1) { + if (rr.at_end ()) { - objects::const_iterator r = sel->begin (); const db::Layout &layout = view ()->cellview (r->cv_index ())->layout (); if (m_cell_inst_service) { @@ -1606,6 +1599,18 @@ Service::transient_selection () const return m_transient_selection; } +EditableSelectionIterator +Service::begin_selection () const +{ + return EditableSelectionIterator (this, false); +} + +EditableSelectionIterator +Service::begin_transient_selection () const +{ + return EditableSelectionIterator (this, true); +} + bool Service::select (const lay::ObjectInstPath &obj, lay::Editable::SelectionMode mode) { @@ -1730,17 +1735,15 @@ Service::selection_to_view () void Service::do_selection_to_view () { - const objects &sel = selection (); - // Hint: this is a lower bound: - m_markers.reserve (sel.size ()); + m_markers.reserve (selection_size ()); // build the transformation variants cache TransformationVariants tv (view ()); // Build markers - for (objects::const_iterator r = sel.begin (); r != sel.end (); ++r) { + for (EditableSelectionIterator r = begin_selection (); ! r.at_end (); ++r) { const lay::CellView &cv = view ()->cellview (r->cv_index ()); @@ -1939,12 +1942,14 @@ Service::handle_guiding_shape_changes (const lay::ObjectInstPath &obj) const bool Service::handle_guiding_shape_changes () { + EditableSelectionIterator s = begin_selection (); + // just allow one guiding shape to be selected - if (selection ().empty ()) { + if (s.at_end ()) { return false; } - std::pair gs = handle_guiding_shape_changes (*selection ().begin ()); + std::pair gs = handle_guiding_shape_changes (*s); if (gs.first) { // remove superfluous proxies @@ -1966,7 +1971,20 @@ Service::handle_guiding_shape_changes () // Implementation of EditableSelectionIterator EditableSelectionIterator::EditableSelectionIterator (const std::vector &services, bool transient) - : m_services (services), m_service (0), m_transient_selection (transient) + : m_services (services.begin (), services.end ()), m_service (0), m_transient_selection (transient) +{ + init (); +} + +EditableSelectionIterator::EditableSelectionIterator (const edt::Service *service, bool transient) + : m_services (), m_service (0), m_transient_selection (transient) +{ + m_services.push_back (service); + init (); +} + +void +EditableSelectionIterator::init () { if (! m_services.empty ()) { if (m_transient_selection) { diff --git a/src/edt/edt/edtService.h b/src/edt/edt/edtService.h index dc0250f81..3b34ffe5a 100644 --- a/src/edt/edt/edtService.h +++ b/src/edt/edt/edtService.h @@ -71,6 +71,41 @@ std::map pcell_parameters_from_string (const std::stri // ------------------------------------------------------------- +/** + * @brief A utility class to implement a selection iterator across all editor services + */ +class EditableSelectionIterator +{ +public: + typedef std::set objects; + typedef objects::value_type value_type; + typedef objects::const_iterator iterator_type; + typedef const value_type *pointer; + typedef const value_type &reference; + typedef std::forward_iterator_tag iterator_category; + typedef void difference_type; + + EditableSelectionIterator (const std::vector &services, bool transient); + EditableSelectionIterator (const edt::Service *service, bool transient); + + bool at_end () const; + + EditableSelectionIterator &operator++ (); + reference operator* () const; + pointer operator-> () const; + +private: + std::vector m_services; + unsigned int m_service; + bool m_transient_selection; + iterator_type m_iter, m_end; + + void next (); + void init (); +}; + +// ------------------------------------------------------------- + class EDT_PUBLIC Service : public lay::EditorServiceBase, public db::Object @@ -226,16 +261,6 @@ public: return m_color; } - /** - * @brief Get the selection container - */ - const objects &selection () const; - - /** - * @brief Get the transient selection container - */ - const objects &transient_selection () const; - /** * @brief Access to the view object */ @@ -257,11 +282,21 @@ public: */ void clear_previous_selection (); + /** + * @brief Gets the selection iterator + */ + EditableSelectionIterator begin_selection () const; + /** * @brief Establish a transient selection */ bool transient_select (const db::DPoint &pos); + /** + * @brief Gets the transient selection iterator + */ + EditableSelectionIterator begin_transient_selection () const; + /** * @brief Turns the transient selection to the selection */ @@ -585,6 +620,8 @@ protected: lay::PointSnapToObjectResult snap2_details (const db::DPoint &p) const; private: + friend class EditableSelectionIterator; + // The layout view that the editor service is attached to lay::LayoutViewBase *mp_view; @@ -685,6 +722,16 @@ private: */ void apply_highlights (); + /** + * @brief Get the selection container + */ + const objects &selection () const; + + /** + * @brief Get the transient selection container + */ + const objects &transient_selection () const; + private: void copy_selected (unsigned int inst_mode); void update_vector_snapped_point (const db::DPoint &pt, db::DVector &vr, bool &result_set) const; @@ -692,36 +739,6 @@ private: void update_vector_snapped_marker (const lay::InstanceMarker *sm, const db::DTrans &trans, db::DVector &vr, bool &result_set, size_t &count) const; }; -/** - * @brief A utility class to implement a selection iterator across all editor services - */ -class EditableSelectionIterator -{ -public: - typedef edt::Service::objects::value_type value_type; - typedef edt::Service::objects::const_iterator iterator_type; - typedef const value_type *pointer; - typedef const value_type &reference; - typedef std::forward_iterator_tag iterator_category; - typedef void difference_type; - - EditableSelectionIterator (const std::vector &services, bool transient); - - bool at_end () const; - - EditableSelectionIterator &operator++ (); - reference operator* () const; - pointer operator-> () const; - -private: - std::vector m_services; - unsigned int m_service; - bool m_transient_selection; - iterator_type m_iter, m_end; - - void next (); -}; - /** * @brief Gets the combined selections over all editor services in the layout view */ diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index e37bf4cce..6c6d267b8 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -408,7 +408,7 @@ FillDialog::get_fill_parameters () // selection std::vector edt_services = mp_view->get_plugins (); for (std::vector::const_iterator s = edt_services.begin (); s != edt_services.end (); ++s) { - for (edt::Service::objects::const_iterator sel = (*s)->selection ().begin (); sel != (*s)->selection ().end (); ++sel) { + for (edt::EditableSelectionIterator sel = (*s)->begin_selection (); ! sel.at_end (); ++sel) { if (! sel->is_cell_inst () && (sel->shape ().is_polygon () || sel->shape ().is_path () || sel->shape ().is_box ())) { db::Polygon poly; sel->shape ().polygon (poly);