diff --git a/src/edt/edt/edtServiceImpl.cc b/src/edt/edt/edtServiceImpl.cc index f8ab4eac6..943cdd2a8 100644 --- a/src/edt/edt/edtServiceImpl.cc +++ b/src/edt/edt/edtServiceImpl.cc @@ -1107,12 +1107,12 @@ PathService::config_finalize () InstService::InstService (db::Manager *manager, lay::LayoutView *view) : edt::Service (manager, view), m_angle (0.0), m_scale (1.0), - m_mirror (false), m_cell_name (""), m_lib_name (""), m_pcell_parameters (""), + m_mirror (false), m_cell_name (""), m_lib_name (""), m_pcell_parameters (), m_array (false), m_rows (1), m_columns (1), m_row_x (0.0), m_row_y (0.0), m_column_x (0.0), m_column_y (0.0), m_place_origin (false), m_reference_transaction_id (0), m_needs_update (true), m_has_valid_cell (false), m_in_drag_drop (false), - m_current_cell (0), m_drag_drop_cell (0), m_cv_index (-1) + m_current_cell (0), m_cv_index (-1) { // .. nothing yet .. } @@ -1142,22 +1142,44 @@ bool InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase *data) { const lay::CellDragDropData *cd = dynamic_cast (data); - if (view ()->is_editable () && cd && cd->layout () == & view ()->active_cellview ()->layout ()) { + if (view ()->is_editable () && cd && (cd->layout () == & view ()->active_cellview ()->layout () || cd->library ())) { view ()->cancel (); - // NOTE: the cancel above might delete the cell we are dragging (if that is - // a non-placed PCell). Hence we need to check whether the cell still is valid - if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) { + set_edit_marker (0); - set_edit_marker (0); + m_cv_index = view ()->active_cellview_index (); + m_in_drag_drop = true; - m_cv_index = view ()->active_cellview_index (); - m_in_drag_drop = true; - m_drag_drop_cell = cd->cell_index (); + if (cd->library ()) { + m_lib_name = cd->library ()->get_name (); + } else { + m_lib_name.clear (); + } + m_pcell_parameters.clear (); + m_cell_name.clear (); + + if (cd->is_pcell ()) { + + const db::PCellDeclaration *pcell_decl = cd->layout ()->pcell_declaration (cd->cell_index ()); + if (pcell_decl) { + + m_cell_name = pcell_decl->name (); + const std::vector &pd = pcell_decl->parameter_declarations(); + for (std::vector::const_iterator i = pd.begin (); i != pd.end (); ++i) { + m_pcell_parameters.insert (std::make_pair (i->get_name (), i->get_default ())); + } + + do_begin_edit (p); + return true; + + } + + } else if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) { + + m_cell_name = cd->layout ()->cell_name (cd->cell_index ()); do_begin_edit (p); - return true; } @@ -1260,10 +1282,6 @@ InstService::do_begin_edit (const db::DPoint &p) std::pair InstService::make_cell (const lay::CellView &cv) { - if (m_in_drag_drop) { - return std::make_pair (true, m_drag_drop_cell); - } - if (m_has_valid_cell) { return std::make_pair (true, m_current_cell); } @@ -1301,20 +1319,10 @@ InstService::make_cell (const lay::CellView &cv) const db::PCellDeclaration *pc_decl = layout->pcell_declaration (pci.second); if (pc_decl) { - std::map parameters; - tl::Extractor ex (m_pcell_parameters.c_str ()); - while (! ex.at_end ()) { - std::string n; - ex.read_word_or_quoted (n); - ex.test (":"); - ex.read (parameters.insert (std::make_pair (n, tl::Variant ())).first->second); - ex.test (";"); - } - const std::vector &pcp = pc_decl->parameter_declarations (); for (std::vector::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) { - std::map::const_iterator p = parameters.find (pd->get_name ()); - if (p != parameters.end ()) { + std::map::const_iterator p = m_pcell_parameters.find (pd->get_name ()); + if (p != m_pcell_parameters.end ()) { pv.push_back (p->second); } else { pv.push_back (pd->get_default ()); @@ -1491,9 +1499,20 @@ InstService::configure (const std::string &name, const std::string &value) } if (name == cfg_edit_inst_pcell_parameters) { - m_pcell_parameters = value; + + m_pcell_parameters.clear (); + tl::Extractor ex (value.c_str ()); + while (! ex.at_end ()) { + std::string n; + ex.read_word_or_quoted (n); + ex.test (":"); + ex.read (m_pcell_parameters.insert (std::make_pair (n, tl::Variant ())).first->second); + ex.test (";"); + } + m_needs_update = true; return true; // taken + } if (name == cfg_edit_inst_place_origin) { diff --git a/src/edt/edt/edtServiceImpl.h b/src/edt/edt/edtServiceImpl.h index 6a1b05e1e..54aa6abb9 100644 --- a/src/edt/edt/edtServiceImpl.h +++ b/src/edt/edt/edtServiceImpl.h @@ -223,7 +223,8 @@ private: double m_scale; bool m_mirror; db::DPoint m_disp; - std::string m_cell_name, m_lib_name, m_pcell_parameters; + std::string m_cell_name, m_lib_name; + std::map m_pcell_parameters; bool m_array; unsigned int m_rows, m_columns; double m_row_x, m_row_y, m_column_x, m_column_y; @@ -232,7 +233,7 @@ private: bool m_needs_update; bool m_has_valid_cell; bool m_in_drag_drop; - db::cell_index_type m_current_cell, m_drag_drop_cell; + db::cell_index_type m_current_cell; int m_cv_index; db::ICplxTrans m_trans; diff --git a/src/laybasic/laybasic/layCellTreeModel.cc b/src/laybasic/laybasic/layCellTreeModel.cc index eede8efef..6636d386e 100644 --- a/src/laybasic/laybasic/layCellTreeModel.cc +++ b/src/laybasic/laybasic/layCellTreeModel.cc @@ -26,6 +26,7 @@ #include "tlGlobPattern.h" #include "dbPCellHeader.h" #include "dbPCellVariant.h" +#include "dbLibrary.h" #include #include @@ -273,6 +274,7 @@ CellTreeModel::CellTreeModel (QWidget *parent, lay::LayoutView *view, int cv_ind m_pad = ((flags & NoPadding) == 0); mp_layout = & view->cellview (cv_index)->layout (); + mp_library = 0; tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ())); build_top_level (); @@ -293,6 +295,28 @@ CellTreeModel::CellTreeModel (QWidget *parent, db::Layout *layout, unsigned int m_pad = ((flags & NoPadding) == 0); mp_layout = layout; + mp_library = 0; + tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ())); + + build_top_level (); + + m_current_index = m_selected_indexes.begin (); +} + +CellTreeModel::CellTreeModel (QWidget *parent, db::Library *library, unsigned int flags, const db::Cell *base, Sorting sorting) + : QAbstractItemModel (parent), + m_flags (flags), + m_sorting (sorting), + mp_parent (parent), + mp_view (0), + m_cv_index (-1), + mp_base (base) +{ + m_flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0); + m_pad = ((flags & NoPadding) == 0); + + mp_layout = &library->layout (); + mp_library = library; tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ())); build_top_level (); @@ -309,18 +333,23 @@ void CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) { db::Layout *layout = & view->cellview (cv_index)->layout (); - - do_configure (layout, view, cv_index, flags, base, sorting); + do_configure (layout, 0, view, cv_index, flags, base, sorting); } void CellTreeModel::configure (db::Layout *layout, unsigned int flags, const db::Cell *base, Sorting sorting) { - do_configure (layout, 0, -1, flags, base, sorting); + do_configure (layout, 0, 0, -1, flags, base, sorting); } void -CellTreeModel::do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) +CellTreeModel::configure (db::Library *library, unsigned int flags, const db::Cell *base, Sorting sorting) +{ + do_configure (& library->layout (), library, 0, -1, flags, base, sorting); +} + +void +CellTreeModel::do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) { bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0); @@ -362,6 +391,7 @@ CellTreeModel::do_configure (db::Layout *layout, lay::LayoutView *view, int cv_i m_pad = ((flags & NoPadding) == 0); mp_layout = layout; + mp_library = library; tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ())); build_top_level (); @@ -447,7 +477,7 @@ void CellTreeModel::set_sorting (Sorting s) { if (s != m_sorting) { - do_configure (mp_layout, mp_view, m_cv_index, m_flags, mp_base, s); + do_configure (mp_layout, mp_library, mp_view, m_cv_index, m_flags, mp_base, s); } } @@ -566,19 +596,23 @@ CellTreeModel::mimeTypes () const QMimeData * CellTreeModel::mimeData(const QModelIndexList &indexes) const { - const db::Cell *c = 0; - for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end () && !c; ++i) { + for (QModelIndexList::const_iterator i = indexes.begin (); i != indexes.end (); ++i) { + if (i->isValid()) { - c = cell (*i); + + if (is_pcell (*i)) { + lay::CellDragDropData data (mp_layout, mp_library, pcell_id (*i), true); + return data.to_mime_data (); + } else if (cell (*i)) { + lay::CellDragDropData data (mp_layout, mp_library, cell_index (*i), false); + return data.to_mime_data (); + } + } + } - if (c) { - lay::CellDragDropData data (mp_layout, c->cell_index ()); - return data.to_mime_data (); - } else { - return 0; - } + return 0; } int diff --git a/src/laybasic/laybasic/layCellTreeModel.h b/src/laybasic/laybasic/layCellTreeModel.h index 0a72cba86..51b2c683f 100644 --- a/src/laybasic/laybasic/layCellTreeModel.h +++ b/src/laybasic/laybasic/layCellTreeModel.h @@ -37,6 +37,11 @@ namespace tl class GlobPattern; } +namespace db +{ + class Library; +} + namespace lay { @@ -88,6 +93,13 @@ public: */ CellTreeModel (QWidget *parent, db::Layout *layout, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + /** + * @brief Constructor + * + * This constructor does not take a view but rather a layout from a library. It does not display hidden status or similar. + */ + CellTreeModel (QWidget *parent, db::Library *library, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + /** * @brief Dtor */ @@ -110,10 +122,15 @@ public: void configure (lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); /** - * @brief Reconfigures the model with a pure Layout view + * @brief Reconfigures the model with a pure Layout */ void configure (db::Layout *layout, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + /** + * @brief Reconfigures the model with a pure Layout from a library + */ + void configure (db::Library *library, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + /** * @brief Gets the layout this model is connected to */ @@ -226,6 +243,7 @@ private: QWidget *mp_parent; lay::LayoutView *mp_view; db::Layout *mp_layout; + db::Library *mp_library; int m_cv_index; const db::Cell *mp_base; std::vector m_toplevel; @@ -236,7 +254,7 @@ private: void build_top_level (); void clear_top_level (); void search_children (const tl::GlobPattern &pattern, CellTreeItem *item); - void do_configure (db::Layout *layout, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting); + void do_configure (db::Layout *layout, db::Library *library, lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting); }; /** diff --git a/src/laybasic/laybasic/layLibrariesView.cc b/src/laybasic/laybasic/layLibrariesView.cc index bd990e7eb..77429e839 100644 --- a/src/laybasic/laybasic/layLibrariesView.cc +++ b/src/laybasic/laybasic/layLibrariesView.cc @@ -127,7 +127,6 @@ LibraryTreeWidget::keyPressEvent (QKeyEvent *event) void LibraryTreeWidget::startDrag (Qt::DropActions supportedActions) { -#if 0 // @@@ QModelIndex index = selectionModel ()->currentIndex (); if (index.isValid ()) { @@ -153,7 +152,6 @@ LibraryTreeWidget::startDrag (Qt::DropActions supportedActions) drag->exec(supportedActions, defaultDropAction); } -#endif // @@@ } void @@ -382,11 +380,10 @@ LibrariesView::set_split_mode (bool f) } } -#if 0 // @@@ void LibrariesView::clear_all () { - m_cellviews.clear (); + m_libraries.clear (); m_needs_update.clear (); m_force_close.clear (); @@ -397,7 +394,6 @@ LibrariesView::clear_all () mp_cell_list_headers.clear (); mp_cell_lists.clear (); } -#endif void LibrariesView::cm_cell_select () @@ -794,7 +790,7 @@ LibrariesView::do_update_content (int lib_index) LibraryTreeWidget *cell_list = new LibraryTreeWidget (cl_frame, "tree", mp_view->view_object_widget ()); cl_ly->addWidget (cell_list); - cell_list->setModel (new CellTreeModel (cell_list, &m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0)); + cell_list->setModel (new CellTreeModel (cell_list, m_libraries [i].get (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0)); cell_list->setUniformRowHeights (true); pl = cell_list->palette (); @@ -869,7 +865,7 @@ LibrariesView::do_update_content (int lib_index) CellTreeModel *model = dynamic_cast (mp_cell_lists [i]->model ()); if (model) { - model->configure (& m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0); + model->configure (m_libraries [i].get (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0); } } diff --git a/src/laybasic/laybasic/layLibrariesView.h b/src/laybasic/laybasic/layLibrariesView.h index 7589440a3..ef51699b6 100644 --- a/src/laybasic/laybasic/layLibrariesView.h +++ b/src/laybasic/laybasic/layLibrariesView.h @@ -302,10 +302,10 @@ private: // select active cellview from sender (sender must be a cell tree) void set_active_celltree_from_sender (); +#endif // clears all widgets of the cell lists void clear_all (); -#endif // display string of nth cellview std::string display_string (int n) const; diff --git a/src/laybasic/laybasic/layViewObject.cc b/src/laybasic/laybasic/layViewObject.cc index affdb81d2..37162137c 100644 --- a/src/laybasic/laybasic/layViewObject.cc +++ b/src/laybasic/laybasic/layViewObject.cc @@ -70,7 +70,9 @@ CellDragDropData::serialized () const stream << QString::fromUtf8 ("CellDragDropData"); stream << (quintptr) mp_layout; + stream << (quintptr) mp_library; stream << m_cell_index; + stream << m_is_pcell; return data; } @@ -88,7 +90,10 @@ CellDragDropData::deserialize (const QByteArray &ba) quintptr p = 0; stream >> p; mp_layout = reinterpret_cast (p); + stream >> p; + mp_library = reinterpret_cast (p); stream >> m_cell_index; + stream >> m_is_pcell; return true; } else { diff --git a/src/laybasic/laybasic/layViewObject.h b/src/laybasic/laybasic/layViewObject.h index 432eb585d..5b9185412 100644 --- a/src/laybasic/laybasic/layViewObject.h +++ b/src/laybasic/laybasic/layViewObject.h @@ -53,6 +53,12 @@ class QDragLeaveEvent; class QDropEvent; class QMimeData; +namespace db +{ + class Library; + class Layout; +} + namespace lay { class Viewport; @@ -113,7 +119,7 @@ public: * @brief Default ctor */ CellDragDropData () - : mp_layout (0), m_cell_index (0) + : mp_layout (0), mp_library (0), m_cell_index (0), m_is_pcell (false) { // .. nothing yet .. } @@ -124,8 +130,8 @@ public: * @param layout the layout where the cell lives in * @param cell_index The index of the cell */ - CellDragDropData (const db::Layout *layout, db::cell_index_type cell_index) - : mp_layout (layout), m_cell_index (cell_index) + CellDragDropData (const db::Layout *layout, const db::Library *library, db::cell_index_type cell_or_pcell_index, bool is_pcell) + : mp_layout (layout), mp_library (library), m_cell_index (cell_or_pcell_index), m_is_pcell (is_pcell) { // .. nothing yet .. } @@ -138,6 +144,14 @@ public: return mp_layout; } + /** + * @brief Gets the layout object where the cell lives in + */ + const db::Library *library () const + { + return mp_library; + } + /** * @brief Gets the index of the cell */ @@ -146,6 +160,14 @@ public: return m_cell_index; } + /** + * @brief Gets a value indicating whether the cell is a pcell + */ + bool is_pcell () const + { + return m_is_pcell; + } + /** * @brief Serializes itself to an QByteArray */ @@ -160,7 +182,9 @@ public: private: const db::Layout *mp_layout; + const db::Library *mp_library; db::cell_index_type m_cell_index; + bool m_is_pcell; }; /**