diff --git a/src/laybasic/laybasic/layCellTreeModel.cc b/src/laybasic/laybasic/layCellTreeModel.cc index 3c85fcbbf..70cea465b 100644 --- a/src/laybasic/laybasic/layCellTreeModel.cc +++ b/src/laybasic/laybasic/layCellTreeModel.cc @@ -281,6 +281,124 @@ CellTreeModel::~CellTreeModel () clear_top_level (); } +void +CellTreeModel::configure (lay::LayoutView *view, int cv_index, unsigned int flags, const db::Cell *base, Sorting sorting) +{ + bool flat = ((flags & Flat) != 0) && ((flags & TopCells) == 0); + db::Layout *layout = & view->cellview (cv_index)->layout (); + + bool need_reset = false; + if (flat != m_flat || layout != mp_layout || sorting != m_sorting || view != mp_view) { + + need_reset = true; + beginResetModel (); + + } + + std::vector old_toplevel_items; + old_toplevel_items.swap (m_toplevel); + + if (view != mp_view) { + + mp_view->cell_visibility_changed_event.remove (this, &CellTreeModel::signal_data_changed); + mp_view->cellview_changed_event.remove (this, &CellTreeModel::signal_data_changed_with_int); + + mp_view = view; + + mp_view->cell_visibility_changed_event.add (this, &CellTreeModel::signal_data_changed); + mp_view->cellview_changed_event.add (this, &CellTreeModel::signal_data_changed_with_int); + + } + + m_cv_index = cv_index; + m_flags = flags; + mp_base = base; + m_selected_indexes.clear (); + m_current_index = m_selected_indexes.begin (); + + m_sorting = sorting; + m_flat = flat; + m_pad = ((flags & NoPadding) == 0); + + mp_layout = layout; + tl_assert (! mp_layout->under_construction () && ! (mp_layout->manager () && mp_layout->manager ()->transacting ())); + + build_top_level (); + + if (need_reset) { + + endResetModel (); + + } else { + + // Translate persistent indexes: translation happens according to the path given by + // a sequence of cell indexes. + + QModelIndexList indexes = persistentIndexList (); + QModelIndexList new_indexes; + + for (QModelIndexList::const_iterator index = indexes.begin (); index != indexes.end (); ++index) { + + std::vector path; + CellTreeItem *item = (CellTreeItem *) index->internalPointer (); + while (item) { + path.push_back (item->cell_index ()); + item = item->parent (); + } + + CellTreeItem *parent = 0; + + if (! path.empty ()) { + + // because we push_back'd on our way up: + std::reverse (path.begin (), path.end ()); + + for (std::vector::const_iterator ci = path.begin (); ci != path.end (); ++ci) { + + CellTreeItem *new_parent = 0; + + if (! layout->is_valid_cell_index (*ci)) { + // can't translate this index + } else if (parent == 0) { + for (int i = 0; i < int (m_toplevel.size ()) && !new_parent; ++i) { + if (m_toplevel [i]->cell_index () == *ci) { + new_parent = m_toplevel [i]; + } + } + } else { + for (int i = 0; i < parent->children () && !new_parent; ++i) { + if (parent->child (i)->cell_index () == *ci) { + new_parent = parent->child (i); + } + } + } + + parent = new_parent; + + } + + } + + if (parent) { + new_indexes << createIndex (index->row (), index->column (), (void *) parent); + } else { + new_indexes << QModelIndex (); + } + + } + + changePersistentIndexList (indexes, new_indexes); + + } + + signal_data_changed (); + + // TODO: harden against exceptions + for (std::vector::iterator t = old_toplevel_items.begin (); t != old_toplevel_items.end (); ++t) { + delete *t; + } +} + void CellTreeModel::set_sorting (Sorting s) { @@ -299,6 +417,12 @@ CellTreeModel::set_sorting (Sorting s) } } +void +CellTreeModel::signal_data_changed () +{ + emit layoutChanged (); +} + void CellTreeModel::clear_top_level () { @@ -543,6 +667,19 @@ CellTreeModel::headerData (int /*section*/, Qt::Orientation /*orientation*/, int return QVariant (); } +bool searchItemPtr(CellTreeItem *parent, CellTreeItem *search) +{ + if (parent == search) { + return true; + } + for (int i = 0; i < parent->children(); ++i) { + if (searchItemPtr(parent->child(i), search)) { + return true; + } + } + return false; +} + int CellTreeModel::rowCount (const QModelIndex &parent) const { diff --git a/src/laybasic/laybasic/layCellTreeModel.h b/src/laybasic/laybasic/layCellTreeModel.h index c5435588c..3bb40f802 100644 --- a/src/laybasic/laybasic/layCellTreeModel.h +++ b/src/laybasic/laybasic/layCellTreeModel.h @@ -103,6 +103,11 @@ public: virtual QStringList mimeTypes () const; virtual QMimeData *mimeData (const QModelIndexList &indexes) const; + /** + * @brief Reconfigures the model + */ + void configure (lay::LayoutView *view, int cv_index, unsigned int flags = 0, const db::Cell *base = 0, Sorting sorting = ByName); + /** * @brief Gets the layout this model is connected to */ @@ -208,10 +213,7 @@ public: * something changed. However, in our current architecture, it does not. So we * need to tell the model that something has changed. */ - void signal_data_changed () - { - emit dataChanged (topLeft (), bottomRight ()); - } + void signal_data_changed (); /** * @brief Signal to the owner of the model that the data has changed (with an int parameter) diff --git a/src/laybasic/laybasic/layHierarchyControlPanel.cc b/src/laybasic/laybasic/layHierarchyControlPanel.cc index 4f6331cd7..ea271f41e 100644 --- a/src/laybasic/laybasic/layHierarchyControlPanel.cc +++ b/src/laybasic/laybasic/layHierarchyControlPanel.cc @@ -339,10 +339,6 @@ HierarchyControlPanel::HierarchyControlPanel (lay::LayoutView *view, QWidget *pa mp_view->cellviews_changed_event.add (this, &HierarchyControlPanel::update_required); mp_view->hier_changed_event.add (this, &HierarchyControlPanel::update_required); - /* @@@ - mp_tree_style.reset (new BackgroundAwareTreeStyle (style ())); - @@@ */ - do_update_content (); } @@ -976,28 +972,13 @@ HierarchyControlPanel::do_update_content (int cv_index) m_force_close [i] = false; - mp_cell_lists [i]->collapse (mp_cell_lists [i]->rootIndex ()); - - CellTreeModel *old_model = dynamic_cast (mp_cell_lists [i]->model ()); - mp_cell_lists [i]->setModel (new CellTreeModel (mp_cell_lists [i], mp_view, i, m_flat ? CellTreeModel::Flat : 0, 0, m_sorting)); - if (old_model) { - delete old_model; + CellTreeModel *model = dynamic_cast (mp_cell_lists [i]->model ()); + if (model) { + model->configure (mp_view, i, m_flat ? CellTreeModel::Flat : 0, 0, m_sorting); } } - // enable root decoration - mp_cell_lists [i]->setRootIsDecorated (! m_flat); - - // locate the item and make selected - mp_cell_lists [i]->clearSelection (); - - QModelIndex index = index_from_path (m_cellviews [i].combined_unspecific_path (), i); - if (index.isValid ()) { - mp_cell_lists [i]->scrollTo (index); - mp_cell_lists [i]->setCurrentIndex (index); - } - m_needs_update [i] = false; }