First attempt to implement non-collapsing cell trees. Still collapsing: on sorting change.

This commit is contained in:
Matthias Koefferlein 2017-10-24 21:36:54 +02:00
parent 6364530c69
commit 59b5c7d9df
3 changed files with 146 additions and 26 deletions

View File

@ -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
{

View File

@ -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)

View File

@ -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;
}