mirror of https://github.com/KLayout/klayout.git
First attempt to implement non-collapsing cell trees. Still collapsing: on sorting change.
This commit is contained in:
parent
6364530c69
commit
59b5c7d9df
|
|
@ -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<lay::CellTreeItem *> 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<db::cell_index_type> 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<db::cell_index_type>::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<lay::CellTreeItem *>::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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 <CellTreeModel *> (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 <CellTreeModel *> (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;
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue