gui: restore lookup into tree after new model
This commit is contained in:
parent
e9e7004bf9
commit
bf43c27567
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user