diff --git a/src/db/db/dbVia.cc b/src/db/db/dbVia.cc index 0122e32eb..5287c29f9 100644 --- a/src/db/db/dbVia.cc +++ b/src/db/db/dbVia.cc @@ -21,6 +21,8 @@ */ #include "dbVia.h" +#include "dbLibraryManager.h" +#include "dbPCellDeclaration.h" namespace db { @@ -40,4 +42,37 @@ ViaType::init () top_wired = true; } +// --------------------------------------------------------------------------------------- + +std::vector +find_via_definitions_for (const std::string &technology, const db::LayerProperties &layer) +{ + std::vector via_defs; + + // Find vias with corresponding top an bottom layers + for (auto l = db::LibraryManager::instance ().begin (); l != db::LibraryManager::instance ().end (); ++l) { + + db::Library *lib = db::LibraryManager::instance ().lib (l->second); + if (lib->for_technologies () && ! lib->is_for_technology (technology)) { + continue; + } + + for (auto pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) { + + const db::PCellDeclaration *pcell = lib->layout ().pcell_declaration (pc->second); + + auto via_types = pcell->via_types (); + for (auto vt = via_types.begin (); vt != via_types.end (); ++vt) { + if ((vt->bottom.log_equal (layer) && vt->bottom_wired) || (vt->top.log_equal (layer) && vt->top_wired)) { + via_defs.push_back (SelectedViaDefinition (lib, pc->second, *vt)); + } + } + + } + + } + + return via_defs; +} + } diff --git a/src/db/db/dbVia.h b/src/db/db/dbVia.h index 93ce955d9..dd44a3aa7 100644 --- a/src/db/db/dbVia.h +++ b/src/db/db/dbVia.h @@ -26,6 +26,7 @@ #include "dbCommon.h" #include "dbLayerProperties.h" +#include "dbLibrary.h" #include @@ -158,6 +159,38 @@ private: void init (); }; +/** + * @brief Provides a via definition that is selected by "find_via_definitions_for" + */ +struct SelectedViaDefinition +{ + SelectedViaDefinition () + : lib (0), pcell (0) + { } + + SelectedViaDefinition (db::Library *_lib, db::pcell_id_type _pcell, const db::ViaType &_via_type) + : lib (_lib), pcell (_pcell), via_type (_via_type) + { } + + /** + * @brief The library from which the via is taken + */ + db::Library *lib; + + /** + * @brief The PCell from which the via is taken + */ + db::pcell_id_type pcell; + + /** + * @brief The selected via type + */ + db::ViaType via_type; +}; + +DB_PUBLIC std::vector +find_via_definitions_for (const std::string &technology, const db::LayerProperties &layer); + } #endif diff --git a/src/edt/edt/edtPlugin.cc b/src/edt/edt/edtPlugin.cc index c9e24b263..956883d01 100644 --- a/src/edt/edt/edtPlugin.cc +++ b/src/edt/edt/edtPlugin.cc @@ -43,6 +43,7 @@ #if defined(HAVE_QT) # include # include +# include #endif namespace edt @@ -506,40 +507,6 @@ private: static tl::RegisteredClass config_decl_main (new edt::MainPluginDeclaration (tl::to_string (tr ("Instances and shapes"))), 4000, "edt::MainService"); -void -commit_recent (lay::LayoutViewBase *view) -{ -#if defined(HAVE_QT) - lay::EditorOptionsPages *eo_pages = view->editor_options_pages (); - if (!eo_pages) { - return; - } - - for (std::vector::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) { - if ((*op)->active ()) { - (*op)->commit_recent (view); - } - } -#endif -} - -void -config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index) -{ -#if defined(HAVE_QT) - lay::EditorOptionsPages *eo_pages = view->editor_options_pages (); - if (!eo_pages) { - return; - } - - for (std::vector::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) { - if ((*op)->active ()) { - (*op)->config_recent_for_layer (view, lp, cv_index); - } - } -#endif -} - class PartialPluginDeclaration : public PluginDeclarationBase { diff --git a/src/edt/edt/edtPlugin.h b/src/edt/edt/edtPlugin.h index 3e1488c15..088a39190 100644 --- a/src/edt/edt/edtPlugin.h +++ b/src/edt/edt/edtPlugin.h @@ -24,6 +24,7 @@ #ifndef HDR_edtPlugin #define HDR_edtPlugin +#include "edtCommon.h" #include "layPlugin.h" #include @@ -57,16 +58,6 @@ namespace edt bool points_enabled (); bool texts_enabled (); bool instances_enabled (); - - /** - * @brief Commits the current configuration for the recently used configuration list - */ - void commit_recent (lay::LayoutViewBase *view); - - /** - * @brief Configure attributes for the most-recent entry with the given layer - */ - void config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index); } #endif diff --git a/src/edt/edt/edtRecentConfigurationPage.cc b/src/edt/edt/edtRecentConfigurationPage.cc index b0eb20414..e599cf2d4 100644 --- a/src/edt/edt/edtRecentConfigurationPage.cc +++ b/src/edt/edt/edtRecentConfigurationPage.cc @@ -365,40 +365,6 @@ RecentConfigurationPage::update_list (const std::list > mp_tree_widget->header ()->resizeSections (QHeaderView::ResizeToContents); } -static bool -set_or_request_current_layer (QWidget *parent, lay::LayoutViewBase *view, unsigned int cv_index, const db::LayerProperties &lp) -{ - bool ok = view->set_current_layer (cv_index, lp); - if (ok) { - return true; - } - - if (! view->control_panel ()) { - return false; - } - - const lay::CellView &cv = view->cellview (cv_index); - if (! cv.is_valid ()) { - return false; - } - - if (QMessageBox::question (parent, tr ("Create Layer"), tr ("Layer %1 does not exist yet. Create it now?").arg (tl::to_qstring (lp.to_string ()))) == QMessageBox::Yes) { - - lay::LayerPropertiesNode lpn; - lpn.set_source (lay::ParsedLayerSource (lp, cv_index)); - view->init_layer_properties (lpn); - - view->transaction (tl::to_string (QObject::tr ("Create new layer"))); - view->set_current_layer (lay::LayerPropertiesConstIterator (& view->insert_layer (view->end_layers (), lpn))); - view->commit (); - - return true; - - } - - return false; -} - void RecentConfigurationPage::item_clicked (QTreeWidgetItem *item) { @@ -418,7 +384,7 @@ RecentConfigurationPage::item_clicked (QTreeWidgetItem *item) ex.read (cv_index); } - set_or_request_current_layer (item->treeWidget (), view (), cv_index, lp); + edt::set_or_request_current_layer (view (), lp, cv_index); } else { dispatcher ()->config_set (c->cfg_name, v); diff --git a/src/edt/edt/edtServiceImpl.cc b/src/edt/edt/edtServiceImpl.cc index 70ed8b900..4f23739bf 100644 --- a/src/edt/edt/edtServiceImpl.cc +++ b/src/edt/edt/edtServiceImpl.cc @@ -30,11 +30,10 @@ #include "edtService.h" #include "edtPlugin.h" #include "dbEdge.h" -#include "dbLibrary.h" -#include "dbLibraryManager.h" -#include "dbPCellDeclaration.h" +#include "dbVia.h" #include "dbPolygonTools.h" #include "dbEdgeProcessor.h" +#include "dbLibraryManager.h" #include "layMarker.h" #include "layLayerProperties.h" #include "layLayoutViewBase.h" @@ -155,6 +154,26 @@ ShapeEditService::get_edit_layer () edt::config_recent_for_layer (view (), cv->layout ().get_properties ((unsigned int) layer), cv_index); } +void +ShapeEditService::change_edit_layer (const db::LayerProperties &lp) +{ + if (! mp_layout) { + return; + } + + int layer = mp_layout->get_layer_maybe (lp); + if (layer < 0) { + layer = mp_layout->insert_layer (lp); + } + m_layer = (unsigned int) layer; + + edt::set_or_request_current_layer (view (), lp, m_cv_index); + + // fetches the last configuration for the given layer + view ()->set_active_cellview_index (m_cv_index); + edt::config_recent_for_layer (view (), lp, m_cv_index); +} + void ShapeEditService::update_edit_layer (const lay::LayerPropertiesConstIterator &cl) { @@ -1471,41 +1490,9 @@ PathService::via () */ db::LayerProperties lp = layout ().get_properties (layer ()); + std::vector via_defs = db::find_via_definitions_for (layout ().technology_name (), lp); - // definitions of vias found - struct SelectedViaDefinition - { - SelectedViaDefinition () - : lib (0), pcell (0) - { } - - SelectedViaDefinition (db::Library *_lib, db::pcell_id_type _pcell, const db::ViaType &_via_type) - : lib (_lib), pcell (_pcell), via_type (_via_type) - { } - - db::Library *lib; - db::pcell_id_type pcell; - db::ViaType via_type; - }; - - std::vector via_defs; - - // Find vias with corresponding top an bottom layers - // @@@ TODO: move elsewhere - for (auto l = db::LibraryManager::instance ().begin (); l != db::LibraryManager::instance ().end (); ++l) { - db::Library *lib = db::LibraryManager::instance ().lib (l->second); - for (auto pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) { - const db::PCellDeclaration *pcell = lib->layout ().pcell_declaration (pc->second); - auto via_types = pcell->via_types (); - for (auto vt = via_types.begin (); vt != via_types.end (); ++vt) { - if ((vt->bottom.log_equal (lp) && vt->bottom_wired) || (vt->top.log_equal (lp) && vt->top_wired)) { - via_defs.push_back (SelectedViaDefinition (lib, pc->second, *vt)); - } - } - } - } - - SelectedViaDefinition via_def; + db::SelectedViaDefinition via_def; if (via_defs.size () == 0) { @@ -1578,8 +1565,7 @@ PathService::via () cell ().insert (db::CellInstArray (db::CellInst (via_cell), db::Trans (trans () * via_pos - db::Point ()))); - tl::warn << "@@@1 " << via_def.via_type.name; - // @@@ switch layer .. + change_edit_layer (lp_new); m_points.clear (); m_points.push_back (via_pos); @@ -1588,6 +1574,18 @@ PathService::via () update_marker (); } +void +PathService::push_segment (const db::Shape &shape, const db::Instance &instance) +{ + // @@@ +} + +void +PathService::pop_segment () +{ + // @@@ +} + bool PathService::configure (const std::string &name, const std::string &value) { diff --git a/src/edt/edt/edtServiceImpl.h b/src/edt/edt/edtServiceImpl.h index 92468dfb4..2665cf75c 100644 --- a/src/edt/edt/edtServiceImpl.h +++ b/src/edt/edt/edtServiceImpl.h @@ -51,6 +51,7 @@ public: protected: void get_edit_layer (); + void change_edit_layer (const db::LayerProperties &lp); const db::VCplxTrans &trans () const { return m_trans; } unsigned int layer () const { return m_layer; } @@ -244,15 +245,29 @@ protected: void config_finalize (); private: + struct PathSegment + { + PathSegment () : layer (0), cv_index (0) { } + + unsigned int layer; + int cv_index; + std::list > config; + db::Shape path_shape; + db::Instance via_instance; + }; + std::vector m_points; double m_width, m_bgnext, m_endext; enum { Flush = 0, Square, Variable, Round } m_type; bool m_needs_update; db::DPoint m_last; + std::list m_previous_segments; void update_marker (); db::Path get_path () const; void set_last_point (const db::DPoint &p); + void push_segment (const db::Shape &shape, const db::Instance &instance); + void pop_segment (); }; /** diff --git a/src/edt/edt/edtUtils.cc b/src/edt/edt/edtUtils.cc index 4a84aa661..cdc0fc525 100644 --- a/src/edt/edt/edtUtils.cc +++ b/src/edt/edt/edtUtils.cc @@ -31,8 +31,13 @@ #include "layCellView.h" #include "layLayoutViewBase.h" #include "layEditable.h" +#include "layEditorOptionsPages.h" #include "tlException.h" +#if defined(HAVE_QT) +# include +#endif + namespace edt { // ------------------------------------------------------------- @@ -74,6 +79,80 @@ std::map pcell_parameters_from_string (const std::stri return pm; } +void +commit_recent (lay::LayoutViewBase *view) +{ +#if defined(HAVE_QT) + lay::EditorOptionsPages *eo_pages = view->editor_options_pages (); + if (!eo_pages) { + return; + } + + for (std::vector::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) { + if ((*op)->active ()) { + (*op)->commit_recent (view); + } + } +#endif +} + +void +config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index) +{ +#if defined(HAVE_QT) + lay::EditorOptionsPages *eo_pages = view->editor_options_pages (); + if (!eo_pages) { + return; + } + + for (std::vector::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) { + if ((*op)->active ()) { + (*op)->config_recent_for_layer (view, lp, cv_index); + } + } +#endif +} + +bool +set_or_request_current_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, unsigned int cv_index) +{ +#if defined(HAVE_QT) + bool ok = view->set_current_layer (cv_index, lp); + if (ok) { + return true; + } + + if (! view->control_panel ()) { + return false; + } + + const lay::CellView &cv = view->cellview (cv_index); + if (! cv.is_valid ()) { + return false; + } + + if (QMessageBox::question (view->widget (), tr ("Create Layer"), tr ("Layer %1 does not exist yet. Create it now?").arg (tl::to_qstring (lp.to_string ()))) == QMessageBox::Yes) { + + lay::LayerPropertiesNode lpn; + lpn.set_source (lay::ParsedLayerSource (lp, cv_index)); + view->init_layer_properties (lpn); + + view->transaction (tl::to_string (QObject::tr ("Create new layer"))); + lay::LayerPropertiesConstIterator lpi = lay::LayerPropertiesConstIterator (& view->insert_layer (view->end_layers (), lpn)); + view->set_current_layer (lpi); + lpi->realize_source (); + view->commit (); + + return true; + + } + + return false; +#else + return true; +#endif +} + // ------------------------------------------------------------- // TransformationsVariants implementation // for a lay::LayoutView diff --git a/src/edt/edt/edtUtils.h b/src/edt/edt/edtUtils.h index de083b39a..a1a012cb2 100644 --- a/src/edt/edt/edtUtils.h +++ b/src/edt/edt/edtUtils.h @@ -66,6 +66,25 @@ std::map pcell_parameters_from_string (const std::stri bool get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index_type cell_index, db::pcell_parameters_type ¶meters_for_pcell); + +/** + * @brief Commits the current configuration for the recently used configuration list + */ +void +commit_recent (lay::LayoutViewBase *view); + +/** + * @brief Configure attributes for the most-recent entry with the given layer + */ +void +config_recent_for_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, int cv_index); + +/** + * @brief Request to make the given layer the current one (asks whether to create the layer if needed) + */ +bool +set_or_request_current_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, unsigned int cv_index); + /** * @brief A helper class that identifies clipboard data for edt:: */