Split tree models and make other features work with it
This commit is contained in:
parent
4c0db11608
commit
5d5324c073
@ -46,15 +46,29 @@ void TreeView::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
void TreeView::leaveEvent(QEvent *event) { Q_EMIT hoverIndexChanged(QModelIndex()); }
|
void TreeView::leaveEvent(QEvent *event) { Q_EMIT hoverIndexChanged(QModelIndex()); }
|
||||||
|
|
||||||
DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), selectionModel(nullptr)
|
DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr)
|
||||||
{
|
{
|
||||||
|
tabWidget = new QTabWidget();
|
||||||
|
|
||||||
// Add tree view
|
// Add tree view
|
||||||
treeView = new TreeView();
|
for(int i=0;i<6;i++)
|
||||||
treeModel = new TreeModel::Model();
|
{
|
||||||
treeView->setModel(treeModel);
|
treeView[i] = new TreeView();
|
||||||
treeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
treeModel[i] = new TreeModel::Model();
|
||||||
treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
treeView[i]->setModel(treeModel[i]);
|
||||||
treeView->viewport()->setMouseTracking(true);
|
treeView[i]->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
treeView[i]->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
treeView[i]->viewport()->setMouseTracking(true);
|
||||||
|
selectionModel[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabWidget->addTab(treeView[0], "Bels");
|
||||||
|
tabWidget->addTab(treeView[1], "Wires");
|
||||||
|
tabWidget->addTab(treeView[2], "Pips");
|
||||||
|
tabWidget->addTab(treeView[3], "Cells");
|
||||||
|
tabWidget->addTab(treeView[4], "Nets");
|
||||||
|
tabWidget->addTab(treeView[5], "Groups");
|
||||||
|
|
||||||
// Add property view
|
// Add property view
|
||||||
variantManager = new QtVariantPropertyManager(this);
|
variantManager = new QtVariantPropertyManager(this);
|
||||||
readOnlyManager = new QtVariantPropertyManager(this);
|
readOnlyManager = new QtVariantPropertyManager(this);
|
||||||
@ -80,7 +94,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(actionFirst, &QAction::triggered, this, [this] {
|
connect(actionFirst, &QAction::triggered, this, [this] {
|
||||||
history_ignore = true;
|
history_ignore = true;
|
||||||
history_index = 0;
|
history_index = 0;
|
||||||
selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
|
auto h = history.at(history_index);
|
||||||
|
selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
|
||||||
|
if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -90,7 +106,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(actionPrev, &QAction::triggered, this, [this] {
|
connect(actionPrev, &QAction::triggered, this, [this] {
|
||||||
history_ignore = true;
|
history_ignore = true;
|
||||||
history_index--;
|
history_index--;
|
||||||
selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
|
auto h = history.at(history_index);
|
||||||
|
selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
|
||||||
|
if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -100,7 +118,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(actionNext, &QAction::triggered, this, [this] {
|
connect(actionNext, &QAction::triggered, this, [this] {
|
||||||
history_ignore = true;
|
history_ignore = true;
|
||||||
history_index++;
|
history_index++;
|
||||||
selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
|
auto h = history.at(history_index);
|
||||||
|
selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
|
||||||
|
if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -110,7 +130,9 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(actionLast, &QAction::triggered, this, [this] {
|
connect(actionLast, &QAction::triggered, this, [this] {
|
||||||
history_ignore = true;
|
history_ignore = true;
|
||||||
history_index = int(history.size() - 1);
|
history_index = int(history.size() - 1);
|
||||||
selectionModel->setCurrentIndex(history.at(history_index), QItemSelectionModel::ClearAndSelect);
|
auto h = history.at(history_index);
|
||||||
|
selectionModel[h.first]->setCurrentIndex(h.second, QItemSelectionModel::ClearAndSelect);
|
||||||
|
if (tabWidget->currentIndex()!=h.first) tabWidget->setCurrentIndex(h.first);
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,11 +142,15 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(actionClear, &QAction::triggered, this, [this] {
|
connect(actionClear, &QAction::triggered, this, [this] {
|
||||||
history_index = -1;
|
history_index = -1;
|
||||||
history.clear();
|
history.clear();
|
||||||
QModelIndex index = selectionModel->selectedIndexes().at(0);
|
int num = tabWidget->currentIndex();
|
||||||
|
if (selectionModel[num]->selectedIndexes().size()> 0)
|
||||||
|
{
|
||||||
|
QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
ElementType type = treeModel->nodeFromIndex(index)->type();
|
ElementType type = treeModel[num]->nodeFromIndex(index)->type();
|
||||||
if (type != ElementType::NONE)
|
if (type != ElementType::NONE)
|
||||||
addToHistory(index);
|
addToHistory(num, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateButtons();
|
updateButtons();
|
||||||
});
|
});
|
||||||
@ -142,7 +168,7 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
vbox1->setSpacing(5);
|
vbox1->setSpacing(5);
|
||||||
vbox1->setContentsMargins(0, 0, 0, 0);
|
vbox1->setContentsMargins(0, 0, 0, 0);
|
||||||
vbox1->addWidget(searchEdit);
|
vbox1->addWidget(searchEdit);
|
||||||
vbox1->addWidget(treeView);
|
vbox1->addWidget(tabWidget);
|
||||||
|
|
||||||
QWidget *toolbarWidget = new QWidget();
|
QWidget *toolbarWidget = new QWidget();
|
||||||
QHBoxLayout *hbox = new QHBoxLayout;
|
QHBoxLayout *hbox = new QHBoxLayout;
|
||||||
@ -177,11 +203,13 @@ DesignWidget::DesignWidget(QWidget *parent) : QWidget(parent), ctx(nullptr), sel
|
|||||||
connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
|
connect(propertyEditor->treeWidget(), &QTreeWidget::itemDoubleClicked, this, &DesignWidget::onItemDoubleClicked);
|
||||||
connect(propertyEditor, &QtTreePropertyBrowser::hoverPropertyChanged, this, &DesignWidget::onHoverPropertyChanged);
|
connect(propertyEditor, &QtTreePropertyBrowser::hoverPropertyChanged, this, &DesignWidget::onHoverPropertyChanged);
|
||||||
|
|
||||||
connect(treeView, &TreeView::customContextMenuRequested, this, &DesignWidget::prepareMenuTree);
|
for(int num=0;num<6;num++) {
|
||||||
connect(treeView, &TreeView::doubleClicked, this, &DesignWidget::onDoubleClicked);
|
connect(treeView[num], &TreeView::customContextMenuRequested, [this,num](const QPoint &pos) { prepareMenuTree(num, pos); });
|
||||||
connect(treeView, &TreeView::hoverIndexChanged, this, &DesignWidget::onHoverIndexChanged);
|
connect(treeView[num], &TreeView::doubleClicked, [this](const QModelIndex &index) { onDoubleClicked(index); } );
|
||||||
selectionModel = treeView->selectionModel();
|
connect(treeView[num], &TreeView::hoverIndexChanged, [this,num](QModelIndex index) { onHoverIndexChanged(num, index); } );
|
||||||
connect(selectionModel, &QItemSelectionModel::selectionChanged, this, &DesignWidget::onSelectionChanged);
|
selectionModel[num] = treeView[num]->selectionModel();
|
||||||
|
connect(selectionModel[num], &QItemSelectionModel::selectionChanged, [this,num](const QItemSelection &selected, const QItemSelection &deselected) { onSelectionChanged(num, selected, deselected); });
|
||||||
|
}
|
||||||
|
|
||||||
history_index = -1;
|
history_index = -1;
|
||||||
history_ignore = false;
|
history_ignore = false;
|
||||||
@ -207,13 +235,13 @@ void DesignWidget::updateButtons()
|
|||||||
actionLast->setEnabled(history_index < (count - 1));
|
actionLast->setEnabled(history_index < (count - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::addToHistory(QModelIndex item)
|
void DesignWidget::addToHistory(int tab, QModelIndex item)
|
||||||
{
|
{
|
||||||
if (!history_ignore) {
|
if (!history_ignore) {
|
||||||
int count = int(history.size());
|
int count = int(history.size());
|
||||||
for (int i = count - 1; i > history_index; i--)
|
for (int i = count - 1; i > history_index; i--)
|
||||||
history.pop_back();
|
history.pop_back();
|
||||||
history.push_back(item);
|
history.push_back(std::make_pair(tab,item));
|
||||||
history_index++;
|
history_index++;
|
||||||
}
|
}
|
||||||
history_ignore = false;
|
history_ignore = false;
|
||||||
@ -236,7 +264,12 @@ void DesignWidget::newContext(Context *ctx)
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
treeModel->loadContext(ctx);
|
|
||||||
|
getTreeByElementType(ElementType::BEL)->loadContext(ElementType::BEL, ctx);
|
||||||
|
getTreeByElementType(ElementType::WIRE)->loadContext(ElementType::WIRE, ctx);
|
||||||
|
getTreeByElementType(ElementType::PIP)->loadContext(ElementType::PIP, ctx);
|
||||||
|
getTreeByElementType(ElementType::CELL)->loadContext(ElementType::CELL, ctx);
|
||||||
|
getTreeByElementType(ElementType::NET)->loadContext(ElementType::NET, ctx);
|
||||||
}
|
}
|
||||||
updateTree();
|
updateTree();
|
||||||
}
|
}
|
||||||
@ -260,7 +293,8 @@ void DesignWidget::updateTree()
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
treeModel->updateCellsNets(ctx);
|
getTreeByElementType(ElementType::CELL)->updateCells(ctx);
|
||||||
|
getTreeByElementType(ElementType::NET)->updateNets(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QtProperty *DesignWidget::addTopLevelProperty(const QString &id)
|
QtProperty *DesignWidget::addTopLevelProperty(const QString &id)
|
||||||
@ -315,6 +349,38 @@ ElementType DesignWidget::getElementTypeByName(QString type)
|
|||||||
return ElementType::NONE;
|
return ElementType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TreeModel::Model *DesignWidget::getTreeByElementType(ElementType type)
|
||||||
|
{
|
||||||
|
if (type == ElementType::NONE)
|
||||||
|
return nullptr;
|
||||||
|
if (type == ElementType::BEL)
|
||||||
|
return treeModel[0];
|
||||||
|
if (type == ElementType::WIRE)
|
||||||
|
return treeModel[1];
|
||||||
|
if (type == ElementType::PIP)
|
||||||
|
return treeModel[2];
|
||||||
|
if (type == ElementType::NET)
|
||||||
|
return treeModel[3];
|
||||||
|
if (type == ElementType::CELL)
|
||||||
|
return treeModel[4];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int DesignWidget::getIndexByElementType(ElementType type)
|
||||||
|
{
|
||||||
|
if (type == ElementType::NONE)
|
||||||
|
return -1;
|
||||||
|
if (type == ElementType::BEL)
|
||||||
|
return 0;
|
||||||
|
if (type == ElementType::WIRE)
|
||||||
|
return 1;
|
||||||
|
if (type == ElementType::PIP)
|
||||||
|
return 2;
|
||||||
|
if (type == ElementType::NET)
|
||||||
|
return 3;
|
||||||
|
if (type == ElementType::CELL)
|
||||||
|
return 4;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
void DesignWidget::addProperty(QtProperty *topItem, int propertyType, const QString &name, QVariant value,
|
void DesignWidget::addProperty(QtProperty *topItem, int propertyType, const QString &name, QVariant value,
|
||||||
const ElementType &type)
|
const ElementType &type)
|
||||||
{
|
{
|
||||||
@ -340,13 +406,14 @@ void DesignWidget::onClickedBel(BelId bel, bool keep)
|
|||||||
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
|
|
||||||
item = treeModel->nodeForIdType(ElementType::BEL, ctx->getBelName(bel));
|
item = getTreeByElementType(ElementType::BEL)->nodeForIdType(ElementType::BEL, ctx->getBelName(bel));
|
||||||
if (!item)
|
if (!item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep);
|
Q_EMIT selected(getDecals(ElementType::BEL, ctx->getBelName(bel)), keep);
|
||||||
}
|
}
|
||||||
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
|
if (tabWidget->currentIndex()!=0) tabWidget->setCurrentIndex(0);
|
||||||
|
selectionModel[0]->setCurrentIndex(getTreeByElementType(ElementType::BEL)->indexFromNode(*item),
|
||||||
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,13 +424,14 @@ void DesignWidget::onClickedWire(WireId wire, bool keep)
|
|||||||
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
|
|
||||||
item = treeModel->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire));
|
item = getTreeByElementType(ElementType::WIRE)->nodeForIdType(ElementType::WIRE, ctx->getWireName(wire));
|
||||||
if (!item)
|
if (!item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep);
|
Q_EMIT selected(getDecals(ElementType::WIRE, ctx->getWireName(wire)), keep);
|
||||||
}
|
}
|
||||||
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
|
if (tabWidget->currentIndex()!=1) tabWidget->setCurrentIndex(1);
|
||||||
|
selectionModel[1]->setCurrentIndex(getTreeByElementType(ElementType::WIRE)->indexFromNode(*item),
|
||||||
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,41 +442,42 @@ void DesignWidget::onClickedPip(PipId pip, bool keep)
|
|||||||
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
std::lock_guard<std::mutex> lock_ui(ctx->ui_mutex);
|
||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
|
|
||||||
item = treeModel->nodeForIdType(ElementType::PIP, ctx->getPipName(pip));
|
item = getTreeByElementType(ElementType::PIP)->nodeForIdType(ElementType::PIP, ctx->getPipName(pip));
|
||||||
if (!item)
|
if (!item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep);
|
Q_EMIT selected(getDecals(ElementType::PIP, ctx->getPipName(pip)), keep);
|
||||||
}
|
}
|
||||||
selectionModel->setCurrentIndex(treeModel->indexFromNode(*item),
|
if (tabWidget->currentIndex()!=2) tabWidget->setCurrentIndex(2);
|
||||||
|
selectionModel[2]->setCurrentIndex(getTreeByElementType(ElementType::PIP)->indexFromNode(*item),
|
||||||
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
keep ? QItemSelectionModel::Select : QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::onSelectionChanged(const QItemSelection &, const QItemSelection &)
|
void DesignWidget::onSelectionChanged(int num, const QItemSelection &, const QItemSelection &)
|
||||||
{
|
{
|
||||||
if (selectionModel->selectedIndexes().size() == 0)
|
if (selectionModel[num]->selectedIndexes().size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (selectionModel->selectedIndexes().size() > 1) {
|
if (selectionModel[num]->selectedIndexes().size() > 1) {
|
||||||
std::vector<DecalXY> decals;
|
std::vector<DecalXY> decals;
|
||||||
for (auto index : selectionModel->selectedIndexes()) {
|
for (auto index : selectionModel[num]->selectedIndexes()) {
|
||||||
TreeModel::Item *item = treeModel->nodeFromIndex(index);
|
TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
|
||||||
std::vector<DecalXY> d = getDecals(item->type(), item->id());
|
std::vector<DecalXY> d = getDecals(item->type(), item->id());
|
||||||
std::move(d.begin(), d.end(), std::back_inserter(decals));
|
std::move(d.begin(), d.end(), std::back_inserter(decals));
|
||||||
}
|
}
|
||||||
Q_EMIT selected(decals, false);
|
Q_EMIT selected(decals, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QModelIndex index = selectionModel->selectedIndexes().at(0);
|
QModelIndex index = selectionModel[num]->selectedIndexes().at(0);
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
TreeModel::Item *clickItem = treeModel->nodeFromIndex(index);
|
TreeModel::Item *clickItem = treeModel[num]->nodeFromIndex(index);
|
||||||
|
|
||||||
ElementType type = clickItem->type();
|
ElementType type = clickItem->type();
|
||||||
if (type == ElementType::NONE)
|
if (type == ElementType::NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addToHistory(index);
|
addToHistory(num, index);
|
||||||
|
|
||||||
clearProperties();
|
clearProperties();
|
||||||
|
|
||||||
@ -714,7 +783,7 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
|||||||
if (type == ElementType::NONE)
|
if (type == ElementType::NONE)
|
||||||
continue;
|
continue;
|
||||||
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
||||||
auto node = treeModel->nodeForIdType(type, value);
|
auto node = getTreeByElementType(type)->nodeForIdType(type, value);
|
||||||
if (!node)
|
if (!node)
|
||||||
continue;
|
continue;
|
||||||
items.append(*node);
|
items.append(*node);
|
||||||
@ -755,16 +824,16 @@ void DesignWidget::prepareMenuProperty(const QPoint &pos)
|
|||||||
menu.exec(tree->mapToGlobal(pos));
|
menu.exec(tree->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::prepareMenuTree(const QPoint &pos)
|
void DesignWidget::prepareMenuTree(int num, const QPoint &pos)
|
||||||
{
|
{
|
||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
|
|
||||||
if (selectionModel->selectedIndexes().size() == 0)
|
if (selectionModel[num]->selectedIndexes().size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QList<TreeModel::Item *> items;
|
QList<TreeModel::Item *> items;
|
||||||
for (auto index : selectionModel->selectedIndexes()) {
|
for (auto index : selectionModel[num]->selectedIndexes()) {
|
||||||
TreeModel::Item *item = treeModel->nodeFromIndex(index);
|
TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
|
||||||
items.append(item);
|
items.append(item);
|
||||||
}
|
}
|
||||||
if (items.size() == 1) {
|
if (items.size() == 1) {
|
||||||
@ -787,23 +856,26 @@ void DesignWidget::prepareMenuTree(const QPoint &pos)
|
|||||||
action->setChecked(true);
|
action->setChecked(true);
|
||||||
connect(action, &QAction::triggered, this, [this, i, items] { updateHighlightGroup(items, i); });
|
connect(action, &QAction::triggered, this, [this, i, items] { updateHighlightGroup(items, i); });
|
||||||
}
|
}
|
||||||
menu.exec(treeView->mapToGlobal(pos));
|
menu.exec(treeView[num]->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
|
void DesignWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
|
||||||
{
|
{
|
||||||
QtProperty *selectedProperty = propertyEditor->itemToBrowserItem(item)->property();
|
QtProperty *selectedProperty = propertyEditor->itemToBrowserItem(item)->property();
|
||||||
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
ElementType type = getElementTypeByName(selectedProperty->propertyId());
|
||||||
auto it = treeModel->nodeForIdType(type, ctx->id(selectedProperty->valueText().toStdString()));
|
auto it = getTreeByElementType(type)->nodeForIdType(type, ctx->id(selectedProperty->valueText().toStdString()));
|
||||||
if (it)
|
if (it) {
|
||||||
selectionModel->setCurrentIndex(treeModel->indexFromNode(*it), QItemSelectionModel::ClearAndSelect);
|
int num = getIndexByElementType(type);
|
||||||
|
if (tabWidget->currentIndex()!=num) tabWidget->setCurrentIndex(num);
|
||||||
|
selectionModel[num]->setCurrentIndex(getTreeByElementType(type)->indexFromNode(*it), QItemSelectionModel::ClearAndSelect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::onDoubleClicked(const QModelIndex &index) { Q_EMIT zoomSelected(); }
|
void DesignWidget::onDoubleClicked(const QModelIndex &index) { Q_EMIT zoomSelected(); }
|
||||||
|
|
||||||
void DesignWidget::onSearchInserted()
|
void DesignWidget::onSearchInserted()
|
||||||
{
|
{
|
||||||
if (currentSearch == searchEdit->text()) {
|
if (currentSearch == searchEdit->text() && currentIndexTab == tabWidget->currentIndex()) {
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
if (currentIndex >= currentSearchIndexes.size())
|
if (currentIndex >= currentSearchIndexes.size())
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
@ -812,17 +884,18 @@ void DesignWidget::onSearchInserted()
|
|||||||
std::lock_guard<std::mutex> lock(ctx->mutex);
|
std::lock_guard<std::mutex> lock(ctx->mutex);
|
||||||
|
|
||||||
currentSearch = searchEdit->text();
|
currentSearch = searchEdit->text();
|
||||||
currentSearchIndexes = treeModel->search(searchEdit->text());
|
currentSearchIndexes = treeModel[tabWidget->currentIndex()]->search(searchEdit->text());
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
|
currentIndexTab = tabWidget->currentIndex();
|
||||||
}
|
}
|
||||||
if (currentSearchIndexes.size() > 0 && currentIndex < currentSearchIndexes.size())
|
if (currentSearchIndexes.size() > 0 && currentIndex < currentSearchIndexes.size())
|
||||||
selectionModel->setCurrentIndex(currentSearchIndexes.at(currentIndex), QItemSelectionModel::ClearAndSelect);
|
selectionModel[tabWidget->currentIndex()]->setCurrentIndex(currentSearchIndexes.at(currentIndex), QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignWidget::onHoverIndexChanged(QModelIndex index)
|
void DesignWidget::onHoverIndexChanged(int num, QModelIndex index)
|
||||||
{
|
{
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
TreeModel::Item *item = treeModel->nodeFromIndex(index);
|
TreeModel::Item *item = treeModel[num]->nodeFromIndex(index);
|
||||||
if (item->type() != ElementType::NONE) {
|
if (item->type() != ElementType::NONE) {
|
||||||
std::vector<DecalXY> decals = getDecals(item->type(), item->id());
|
std::vector<DecalXY> decals = getDecals(item->type(), item->id());
|
||||||
if (decals.size() > 0)
|
if (decals.size() > 0)
|
||||||
@ -841,7 +914,7 @@ void DesignWidget::onHoverPropertyChanged(QtBrowserItem *item)
|
|||||||
if (type != ElementType::NONE) {
|
if (type != ElementType::NONE) {
|
||||||
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
IdString value = ctx->id(selectedProperty->valueText().toStdString());
|
||||||
if (value != IdString()) {
|
if (value != IdString()) {
|
||||||
auto node = treeModel->nodeForIdType(type, value);
|
auto node = getTreeByElementType(type)->nodeForIdType(type, value);
|
||||||
if (node) {
|
if (node) {
|
||||||
std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
|
std::vector<DecalXY> decals = getDecals((*node)->type(), (*node)->id());
|
||||||
if (decals.size() > 0)
|
if (decals.size() > 0)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define DESIGNWIDGET_H
|
#define DESIGNWIDGET_H
|
||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QTabWidget>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
@ -65,9 +66,11 @@ class DesignWidget : public QWidget
|
|||||||
const ElementType &type = ElementType::NONE);
|
const ElementType &type = ElementType::NONE);
|
||||||
QString getElementTypeName(ElementType type);
|
QString getElementTypeName(ElementType type);
|
||||||
ElementType getElementTypeByName(QString type);
|
ElementType getElementTypeByName(QString type);
|
||||||
|
TreeModel::Model *getTreeByElementType(ElementType type);
|
||||||
|
int getIndexByElementType(ElementType type);
|
||||||
int getElementIndex(ElementType type);
|
int getElementIndex(ElementType type);
|
||||||
void updateButtons();
|
void updateButtons();
|
||||||
void addToHistory(QModelIndex item);
|
void addToHistory(int tab, QModelIndex item);
|
||||||
std::vector<DecalXY> getDecals(ElementType type, IdString value);
|
std::vector<DecalXY> getDecals(ElementType type, IdString value);
|
||||||
void updateHighlightGroup(QList<TreeModel::Item *> item, int group);
|
void updateHighlightGroup(QList<TreeModel::Item *> item, int group);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
@ -78,12 +81,12 @@ class DesignWidget : public QWidget
|
|||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void prepareMenuProperty(const QPoint &pos);
|
void prepareMenuProperty(const QPoint &pos);
|
||||||
void prepareMenuTree(const QPoint &pos);
|
void prepareMenuTree(int num, const QPoint &pos);
|
||||||
void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
void onSelectionChanged(int num, const QItemSelection &selected, const QItemSelection &deselected);
|
||||||
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
|
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||||
void onDoubleClicked(const QModelIndex &index);
|
void onDoubleClicked(const QModelIndex &index);
|
||||||
void onSearchInserted();
|
void onSearchInserted();
|
||||||
void onHoverIndexChanged(QModelIndex index);
|
void onHoverIndexChanged(int num, QModelIndex index);
|
||||||
void onHoverPropertyChanged(QtBrowserItem *item);
|
void onHoverPropertyChanged(QtBrowserItem *item);
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void newContext(Context *ctx);
|
void newContext(Context *ctx);
|
||||||
@ -95,9 +98,11 @@ class DesignWidget : public QWidget
|
|||||||
private:
|
private:
|
||||||
Context *ctx;
|
Context *ctx;
|
||||||
|
|
||||||
TreeView *treeView;
|
QTabWidget *tabWidget;
|
||||||
QItemSelectionModel *selectionModel;
|
|
||||||
TreeModel::Model *treeModel;
|
TreeView *treeView[6];
|
||||||
|
QItemSelectionModel *selectionModel[6];
|
||||||
|
TreeModel::Model *treeModel[6];
|
||||||
QLineEdit *searchEdit;
|
QLineEdit *searchEdit;
|
||||||
QtVariantPropertyManager *variantManager;
|
QtVariantPropertyManager *variantManager;
|
||||||
QtVariantPropertyManager *readOnlyManager;
|
QtVariantPropertyManager *readOnlyManager;
|
||||||
@ -108,7 +113,7 @@ class DesignWidget : public QWidget
|
|||||||
QMap<QtProperty *, QString> propertyToId;
|
QMap<QtProperty *, QString> propertyToId;
|
||||||
QMap<QString, QtProperty *> idToProperty;
|
QMap<QString, QtProperty *> idToProperty;
|
||||||
|
|
||||||
std::vector<QModelIndex> history;
|
std::vector<std::pair<int,QModelIndex>> history;
|
||||||
int history_index;
|
int history_index;
|
||||||
bool history_ignore;
|
bool history_ignore;
|
||||||
|
|
||||||
@ -124,6 +129,7 @@ class DesignWidget : public QWidget
|
|||||||
QString currentSearch;
|
QString currentSearch;
|
||||||
QList<QModelIndex> currentSearchIndexes;
|
QList<QModelIndex> currentSearchIndexes;
|
||||||
int currentIndex;
|
int currentIndex;
|
||||||
|
int currentIndexTab;
|
||||||
};
|
};
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_END
|
NEXTPNR_NAMESPACE_END
|
||||||
|
@ -154,7 +154,7 @@ Model::Model(QObject *parent) : QAbstractItemModel(parent), root_(new Item("Elem
|
|||||||
|
|
||||||
Model::~Model() {}
|
Model::~Model() {}
|
||||||
|
|
||||||
void Model::loadContext(Context *ctx)
|
void Model::loadContext(ElementType type, Context *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
@ -166,7 +166,8 @@ void Model::loadContext(Context *ctx)
|
|||||||
// cross-arch. So we only do this for ICE40 by querying the ChipDB
|
// cross-arch. So we only do this for ICE40 by querying the ChipDB
|
||||||
// directly.
|
// directly.
|
||||||
// TODO(q3k): once AnyId and the tree API land in Arch, move this over.
|
// TODO(q3k): once AnyId and the tree API land in Arch, move this over.
|
||||||
#ifdef ARCH_ICE40
|
{
|
||||||
|
if (type==ElementType::BEL)
|
||||||
{
|
{
|
||||||
std::map<std::pair<int, int>, std::vector<BelId>> belMap;
|
std::map<std::pair<int, int>, std::vector<BelId>> belMap;
|
||||||
for (auto bel : ctx->getBels()) {
|
for (auto bel : ctx->getBels()) {
|
||||||
@ -174,9 +175,12 @@ void Model::loadContext(Context *ctx)
|
|||||||
belMap[std::pair<int, int>(loc.x, loc.y)].push_back(bel);
|
belMap[std::pair<int, int>(loc.x, loc.y)].push_back(bel);
|
||||||
}
|
}
|
||||||
auto belGetter = [](Context *ctx, BelId id) { return ctx->getBelName(id); };
|
auto belGetter = [](Context *ctx, BelId id) { return ctx->getBelName(id); };
|
||||||
bel_root_ = std::unique_ptr<BelXYRoot>(
|
root_ = std::unique_ptr<ElementXYRoot<BelId>>(
|
||||||
new BelXYRoot(ctx, "Bels", root_.get(), belMap, belGetter, ElementType::BEL));
|
new ElementXYRoot<BelId>(ctx, "Bels", nullptr, belMap, belGetter, ElementType::BEL));
|
||||||
|
}
|
||||||
|
#ifdef ARCH_ICE40
|
||||||
|
if (type==ElementType::WIRE)
|
||||||
|
{
|
||||||
std::map<std::pair<int, int>, std::vector<WireId>> wireMap;
|
std::map<std::pair<int, int>, std::vector<WireId>> wireMap;
|
||||||
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
for (int i = 0; i < ctx->chip_info->num_wires; i++) {
|
||||||
const auto wire = &ctx->chip_info->wire_data[i];
|
const auto wire = &ctx->chip_info->wire_data[i];
|
||||||
@ -185,9 +189,12 @@ void Model::loadContext(Context *ctx)
|
|||||||
wireMap[std::pair<int, int>(wire->x, wire->y)].push_back(wireid);
|
wireMap[std::pair<int, int>(wire->x, wire->y)].push_back(wireid);
|
||||||
}
|
}
|
||||||
auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); };
|
auto wireGetter = [](Context *ctx, WireId id) { return ctx->getWireName(id); };
|
||||||
wire_root_ = std::unique_ptr<WireXYRoot>(
|
root_ = std::unique_ptr<ElementXYRoot<WireId>>(
|
||||||
new WireXYRoot(ctx, "Wires", root_.get(), wireMap, wireGetter, ElementType::WIRE));
|
new ElementXYRoot<WireId>(ctx, "Wires", nullptr, wireMap, wireGetter, ElementType::WIRE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type==ElementType::PIP)
|
||||||
|
{
|
||||||
std::map<std::pair<int, int>, std::vector<PipId>> pipMap;
|
std::map<std::pair<int, int>, std::vector<PipId>> pipMap;
|
||||||
for (int i = 0; i < ctx->chip_info->num_pips; i++) {
|
for (int i = 0; i < ctx->chip_info->num_pips; i++) {
|
||||||
const auto pip = &ctx->chip_info->pip_data[i];
|
const auto pip = &ctx->chip_info->pip_data[i];
|
||||||
@ -196,20 +203,22 @@ void Model::loadContext(Context *ctx)
|
|||||||
pipMap[std::pair<int, int>(pip->x, pip->y)].push_back(pipid);
|
pipMap[std::pair<int, int>(pip->x, pip->y)].push_back(pipid);
|
||||||
}
|
}
|
||||||
auto pipGetter = [](Context *ctx, PipId id) { return ctx->getPipName(id); };
|
auto pipGetter = [](Context *ctx, PipId id) { return ctx->getPipName(id); };
|
||||||
pip_root_ = std::unique_ptr<PipXYRoot>(
|
root_ = std::unique_ptr<ElementXYRoot<PipId>>(
|
||||||
new PipXYRoot(ctx, "Pips", root_.get(), pipMap, pipGetter, ElementType::PIP));
|
new ElementXYRoot<PipId>(ctx, "Pips", nullptr, pipMap, pipGetter, ElementType::PIP));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
cell_root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Cells"), root_.get(), ElementType::CELL));
|
if (type==ElementType::CELL) root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Cells"), nullptr, ElementType::CELL));
|
||||||
net_root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Nets"), root_.get(), ElementType::NET));
|
if (type==ElementType::NET) root_ = std::unique_ptr<IdStringList>(new IdStringList(QString("Nets"), nullptr, ElementType::NET));
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
|
|
||||||
updateCellsNets(ctx);
|
if (type==ElementType::CELL) updateCells(ctx);
|
||||||
|
if (type==ElementType::NET) updateNets(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::updateCellsNets(Context *ctx)
|
void Model::updateCells(Context *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
@ -220,13 +229,23 @@ void Model::updateCellsNets(Context *ctx)
|
|||||||
for (auto &pair : ctx->cells) {
|
for (auto &pair : ctx->cells) {
|
||||||
cells.push_back(pair.first);
|
cells.push_back(pair.first);
|
||||||
}
|
}
|
||||||
cell_root_->updateElements(ctx, cells);
|
root_->updateElements(ctx, cells);
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::updateNets(Context *ctx)
|
||||||
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
|
||||||
std::vector<IdString> nets;
|
std::vector<IdString> nets;
|
||||||
for (auto &pair : ctx->nets) {
|
for (auto &pair : ctx->nets) {
|
||||||
nets.push_back(pair.first);
|
nets.push_back(pair.first);
|
||||||
}
|
}
|
||||||
net_root_->updateElements(ctx, nets);
|
root_->updateElements(ctx, nets);
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
@ -302,11 +321,7 @@ QList<QModelIndex> Model::search(QString text)
|
|||||||
{
|
{
|
||||||
const int limit = 500;
|
const int limit = 500;
|
||||||
QList<Item *> list;
|
QList<Item *> list;
|
||||||
cell_root_->search(list, text, limit);
|
root_->search(list, text, limit);
|
||||||
net_root_->search(list, text, limit);
|
|
||||||
bel_root_->search(list, text, limit);
|
|
||||||
wire_root_->search(list, text, limit);
|
|
||||||
pip_root_->search(list, text, limit);
|
|
||||||
|
|
||||||
QList<QModelIndex> res;
|
QList<QModelIndex> res;
|
||||||
for (auto i : list) {
|
for (auto i : list) {
|
||||||
|
@ -102,6 +102,10 @@ class Item
|
|||||||
virtual bool canFetchMore() const { return false; }
|
virtual bool canFetchMore() const { return false; }
|
||||||
virtual void fetchMore() {}
|
virtual void fetchMore() {}
|
||||||
|
|
||||||
|
virtual boost::optional<Item *> getById(IdString id) { return boost::none; }
|
||||||
|
virtual void search(QList<Item *> &results, QString text, int limit) { }
|
||||||
|
virtual void updateElements(Context *ctx, std::vector<IdString> elements) { }
|
||||||
|
|
||||||
virtual ~Item()
|
virtual ~Item()
|
||||||
{
|
{
|
||||||
if (parent_ != nullptr) {
|
if (parent_ != nullptr) {
|
||||||
@ -150,13 +154,13 @@ class IdStringList : public Item
|
|||||||
static std::vector<QString> alphaNumSplit(const QString &str);
|
static std::vector<QString> alphaNumSplit(const QString &str);
|
||||||
|
|
||||||
// getById finds a child for the given IdString.
|
// getById finds a child for the given IdString.
|
||||||
IdStringItem *getById(IdString id) const { return managed_.at(id).get(); }
|
virtual boost::optional<Item *> getById(IdString id) override { return managed_.at(id).get(); }
|
||||||
|
|
||||||
// (Re-)create children from a list of IdStrings.
|
// (Re-)create children from a list of IdStrings.
|
||||||
void updateElements(Context *ctx, std::vector<IdString> elements);
|
virtual void updateElements(Context *ctx, std::vector<IdString> elements) override;
|
||||||
|
|
||||||
// Find children that contain the given text.
|
// Find children that contain the given text.
|
||||||
void search(QList<Item *> &results, QString text, int limit);
|
virtual void search(QList<Item *> &results, QString text, int limit) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ElementList is a dynamic list of ElementT (BelId,WireId,...) that are
|
// ElementList is a dynamic list of ElementT (BelId,WireId,...) that are
|
||||||
@ -220,7 +224,7 @@ template <typename ElementT> class ElementList : public Item
|
|||||||
virtual void fetchMore() override { fetchMore(100); }
|
virtual void fetchMore() override { fetchMore(100); }
|
||||||
|
|
||||||
// getById finds a child for the given IdString.
|
// getById finds a child for the given IdString.
|
||||||
boost::optional<Item *> getById(IdString id)
|
virtual boost::optional<Item *> getById(IdString id) override
|
||||||
{
|
{
|
||||||
// Search requires us to load all our elements...
|
// Search requires us to load all our elements...
|
||||||
while (canFetchMore())
|
while (canFetchMore())
|
||||||
@ -234,7 +238,7 @@ template <typename ElementT> class ElementList : public Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find children that contain the given text.
|
// Find children that contain the given text.
|
||||||
void search(QList<Item *> &results, QString text, int limit)
|
virtual void search(QList<Item *> &results, QString text, int limit) override
|
||||||
{
|
{
|
||||||
// Last chance to bail out from loading entire tree into memory.
|
// Last chance to bail out from loading entire tree into memory.
|
||||||
if (limit != -1 && results.size() > limit)
|
if (limit != -1 && results.size() > limit)
|
||||||
@ -315,7 +319,7 @@ template <typename ElementT> class ElementXYRoot : public Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getById finds a child for the given IdString.
|
// getById finds a child for the given IdString.
|
||||||
boost::optional<Item *> getById(IdString id)
|
virtual boost::optional<Item *> getById(IdString id) override
|
||||||
{
|
{
|
||||||
// For now, scan linearly all ElementLists.
|
// For now, scan linearly all ElementLists.
|
||||||
// TODO(q3k) fix this once we have tree API from arch
|
// TODO(q3k) fix this once we have tree API from arch
|
||||||
@ -329,7 +333,7 @@ template <typename ElementT> class ElementXYRoot : public Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find children that contain the given text.
|
// Find children that contain the given text.
|
||||||
void search(QList<Item *> &results, QString text, int limit)
|
virtual void search(QList<Item *> &results, QString text, int limit) override
|
||||||
{
|
{
|
||||||
for (auto &l : managed_lists_) {
|
for (auto &l : managed_lists_) {
|
||||||
if (limit != -1 && results.size() > limit)
|
if (limit != -1 && results.size() > limit)
|
||||||
@ -345,15 +349,12 @@ class Model : public QAbstractItemModel
|
|||||||
Context *ctx_ = nullptr;
|
Context *ctx_ = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using BelXYRoot = ElementXYRoot<BelId>;
|
|
||||||
using WireXYRoot = ElementXYRoot<WireId>;
|
|
||||||
using PipXYRoot = ElementXYRoot<PipId>;
|
|
||||||
|
|
||||||
Model(QObject *parent = nullptr);
|
Model(QObject *parent = nullptr);
|
||||||
~Model();
|
~Model();
|
||||||
|
|
||||||
void loadContext(Context *ctx);
|
void loadContext(ElementType type, Context *ctx);
|
||||||
void updateCellsNets(Context *ctx);
|
void updateCells(Context *ctx);
|
||||||
|
void updateNets(Context *ctx);
|
||||||
Item *nodeFromIndex(const QModelIndex &idx) const;
|
Item *nodeFromIndex(const QModelIndex &idx) const;
|
||||||
QModelIndex indexFromNode(Item *node)
|
QModelIndex indexFromNode(Item *node)
|
||||||
{
|
{
|
||||||
@ -369,24 +370,12 @@ class Model : public QAbstractItemModel
|
|||||||
boost::optional<Item *> nodeForIdType(ElementType type, IdString id) const
|
boost::optional<Item *> nodeForIdType(ElementType type, IdString id) const
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ElementType::BEL:
|
case ElementType::NONE:
|
||||||
if (bel_root_ == nullptr)
|
|
||||||
return boost::none;
|
return boost::none;
|
||||||
return bel_root_->getById(id);
|
|
||||||
case ElementType::WIRE:
|
|
||||||
if (wire_root_ == nullptr)
|
|
||||||
return boost::none;
|
|
||||||
return wire_root_->getById(id);
|
|
||||||
case ElementType::PIP:
|
|
||||||
if (pip_root_ == nullptr)
|
|
||||||
return boost::none;
|
|
||||||
return pip_root_->getById(id);
|
|
||||||
case ElementType::CELL:
|
|
||||||
return cell_root_->getById(id);
|
|
||||||
case ElementType::NET:
|
|
||||||
return net_root_->getById(id);
|
|
||||||
default:
|
default:
|
||||||
|
if (root_ == nullptr)
|
||||||
return boost::none;
|
return boost::none;
|
||||||
|
return root_->getById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,11 +393,6 @@ class Model : public QAbstractItemModel
|
|||||||
private:
|
private:
|
||||||
// Tree elements that we manage the memory for.
|
// Tree elements that we manage the memory for.
|
||||||
std::unique_ptr<Item> root_;
|
std::unique_ptr<Item> root_;
|
||||||
std::unique_ptr<BelXYRoot> bel_root_;
|
|
||||||
std::unique_ptr<WireXYRoot> wire_root_;
|
|
||||||
std::unique_ptr<PipXYRoot> pip_root_;
|
|
||||||
std::unique_ptr<IdStringList> cell_root_;
|
|
||||||
std::unique_ptr<IdStringList> net_root_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace TreeModel
|
}; // namespace TreeModel
|
||||||
|
Loading…
Reference in New Issue
Block a user