gui: restore lookup into tree after new model

This commit is contained in:
Sergiusz Bazanski 2018-08-01 01:59:58 +01:00
parent e9e7004bf9
commit bf43c27567
2 changed files with 94 additions and 16 deletions

View File

@ -309,25 +309,34 @@ QtProperty *DesignWidget::addSubGroup(QtProperty *topItem, const QString &name)
void DesignWidget::onClickedBel(BelId bel, bool keep) void DesignWidget::onClickedBel(BelId bel, bool keep)
{ {
//LazyTreeItem *item = treeModel->nodeForIdType(ElementType::BEL, ctx->getBelName(bel).c_str(ctx)); auto item = treeModel->nodeForIdType(ElementType::BEL, ctx->getBelName(bel));
//selectionModel->setCurrentIndex(treeModel->indexFromNode(item), if (!item)
// keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect); return;
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep); Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep);
} }
void DesignWidget::onClickedWire(WireId wire, bool keep) void DesignWidget::onClickedWire(WireId wire, bool keep)
{ {
//LazyTreeItem *item = treeModel->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire).c_str(ctx)); auto item = treeModel->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire));
//selectionModel->setCurrentIndex(treeModel->indexFromNode(item), if (!item)
// keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect); return;
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep); Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep);
} }
void DesignWidget::onClickedPip(PipId pip, bool keep) void DesignWidget::onClickedPip(PipId pip, bool keep)
{ {
//LazyTreeItem *item = treeModel->nodeForIdType(ElementType::PIP, ctx->getPipName(pip).c_str(ctx)); auto item = treeModel->nodeForIdType(ElementType::PIP, ctx->getPipName(pip));
//selectionModel->setCurrentIndex(treeModel->indexFromNode(item), if (!item)
// keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect); return;
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep); Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep);
} }

View File

@ -21,8 +21,9 @@
#define TREEMODEL_H #define TREEMODEL_H
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <boost/optional.hpp>
#include "nextpnr.h" #include "nextpnr.h"
#include "log.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -75,11 +76,22 @@ class LazyTreeItem
return children_.at(index); return children_.at(index);
} }
int indexOf(LazyTreeItem *child) const int indexOf(const LazyTreeItem *child) const
{
// Dropping the const for indexOf to work.
return children_.indexOf((LazyTreeItem *)child, 0);
}
int indexOf(LazyTreeItem *child)
{ {
return children_.indexOf(child, 0); return children_.indexOf(child, 0);
} }
const LazyTreeItem *parent() const
{
return parent_;
}
LazyTreeItem *parent() LazyTreeItem *parent()
{ {
return parent_; return parent_;
@ -146,7 +158,7 @@ class ElementList : public LazyTreeItem
const ElementMap *map_; const ElementMap *map_;
int x_, y_; int x_, y_;
ElementGetter getter_; ElementGetter getter_;
std::vector<std::unique_ptr<StaticTreeItem>> managed_; std::unordered_map<IdString, std::unique_ptr<StaticTreeItem>> managed_;
ElementType child_type_; ElementType child_type_;
// scope valid until map gets mutated... // scope valid until map gets mutated...
@ -180,7 +192,7 @@ class ElementList : public LazyTreeItem
name.remove(0, prefix.size()); name.remove(0, prefix.size());
auto item = new IdStringItem(ctx_, idstring, this, child_type_); auto item = new IdStringItem(ctx_, idstring, this, child_type_);
managed_.push_back(std::move(std::unique_ptr<StaticTreeItem>(item))); managed_[idstring] = std::move(std::unique_ptr<StaticTreeItem>(item));
} }
} }
@ -193,6 +205,18 @@ class ElementList : public LazyTreeItem
{ {
return IdString(); return IdString();
} }
boost::optional<LazyTreeItem*> getById(IdString id)
{
// Search requires us to load all our elements...
while (canFetchMore()) fetchMore();
auto res = managed_.find(id);
if (res != managed_.end()) {
return res->second.get();
}
return boost::none;
}
}; };
class IdStringList : public StaticTreeItem class IdStringList : public StaticTreeItem
@ -232,6 +256,11 @@ class IdStringList : public StaticTreeItem
return res; return res;
} }
IdStringItem *getById(IdString id) const
{
return managed_.at(id).get();
}
void updateElements(Context *ctx, std::vector<IdString> elements) void updateElements(Context *ctx, std::vector<IdString> elements)
{ {
// for any elements that are not yet in managed_, created them. // for any elements that are not yet in managed_, created them.
@ -310,7 +339,8 @@ class ElementXYRoot : public StaticTreeItem
private: private:
Context *ctx_; Context *ctx_;
std::vector<std::unique_ptr<LazyTreeItem>> managed_; std::vector<std::unique_ptr<StaticTreeItem>> managed_labels_;
std::vector<std::unique_ptr<ElementList<ElementT>>> managed_lists_;
ElementMap map_; ElementMap map_;
ElementGetter getter_; ElementGetter getter_;
ElementType child_type_; ElementType child_type_;
@ -335,14 +365,27 @@ class ElementXYRoot : public StaticTreeItem
// create X item for tree // create X item for tree
auto item = new StaticTreeItem(QString("X%1").arg(i), this, child_type_); auto item = new StaticTreeItem(QString("X%1").arg(i), this, child_type_);
managed_.push_back(std::move(std::unique_ptr<LazyTreeItem>(item))); managed_labels_.push_back(std::move(std::unique_ptr<StaticTreeItem>(item)));
for (auto j : y_present) { for (auto j : y_present) {
auto item2 = new ElementList<ElementT>(ctx_, QString("Y%1").arg(j), item, &map_, i, j, getter_, child_type_); auto item2 = new ElementList<ElementT>(ctx_, QString("Y%1").arg(j), item, &map_, i, j, getter_, child_type_);
item2->fetchMore(1); item2->fetchMore(1);
managed_.push_back(std::move(std::unique_ptr<LazyTreeItem>(item2))); managed_lists_.push_back(std::move(std::unique_ptr<ElementList<ElementT>>(item2)));
} }
} }
} }
boost::optional<LazyTreeItem*> getById(IdString id)
{
// For now, scan linearly all ElementLists.
// TODO(q3k) fix this once we have tree API from arch
for (auto &l : managed_lists_) {
auto res = l->getById(id);
if (res) {
return res;
}
}
return boost::none;
}
}; };
class ContextTreeModel : public QAbstractItemModel class ContextTreeModel : public QAbstractItemModel
@ -358,7 +401,33 @@ class ContextTreeModel : public QAbstractItemModel
void loadContext(Context *ctx); void loadContext(Context *ctx);
void updateCellsNets(Context *ctx); void updateCellsNets(Context *ctx);
LazyTreeItem *nodeFromIndex(const QModelIndex &idx) const; LazyTreeItem *nodeFromIndex(const QModelIndex &idx) const;
QModelIndex indexFromNode(LazyTreeItem *node)
{
const LazyTreeItem *parent = node->parent();
if (parent == nullptr)
return QModelIndex();
return createIndex(parent->indexOf(node), 0, node);
}
QList<QModelIndex> search(QString text); QList<QModelIndex> search(QString text);
boost::optional<LazyTreeItem*> nodeForIdType(ElementType type, IdString id) const
{
switch (type) {
case ElementType::BEL:
return bel_root_->getById(id);
case ElementType::WIRE:
return wire_root_->getById(id);
case ElementType::PIP:
return pip_root_->getById(id);
case ElementType::CELL:
return cell_root_->getById(id);
case ElementType::NET:
return net_root_->getById(id);
default:
return boost::none;
}
}
// Override QAbstractItemModel methods // Override QAbstractItemModel methods
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;