401 lines
12 KiB
C++
401 lines
12 KiB
C++
#include "blockeditor.h"
|
|
#include "ui_blockeditor.h"
|
|
#include "drawtools.h"
|
|
#include "blockview.h"
|
|
#include <QToolBar>
|
|
#include <QComboBox>
|
|
#include <QFileDialog>
|
|
#include <QFile>
|
|
#include <QTimer>
|
|
|
|
|
|
BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEditor) {
|
|
init = false;
|
|
m_editorMode = false;
|
|
m_pinsEditable = true;
|
|
ui->setupUi(this);
|
|
src_title = windowTitle();
|
|
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
|
block.setFlags(QGraphicsItem::GraphicsItemFlags());
|
|
ui->blockView->addItem(&block);
|
|
ui->blockView->viewport()->installEventFilter(this);
|
|
DrawTools * drawtools = new DrawTools(ui->blockView);
|
|
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem*)), this, SLOT(addItem(QGraphicsItem*)));
|
|
drawtools->textEditCombo()->addItems(QStringList() << "%name" << "%value" << "%id");
|
|
ui->layoutProperties->addWidget(drawtools->propertyWidget());
|
|
ui->actionRemove_items->setEnabled(false);
|
|
ui->button_color->setColor(Qt::lightGray);
|
|
ui->treePins->setItemDelegateForColumn(1, new PinBusDelegate());
|
|
connect(ui->treePins, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(updateBlock()));
|
|
ui->treePins->viewport()->installEventFilter(this);
|
|
|
|
QToolBar * bar;
|
|
bar = new QToolBar(ui->widgetBar);
|
|
bar->setOrientation(Qt::Vertical);
|
|
bar->addActions(drawtools->actionsForAdd());
|
|
ui->widgetBar->setMinimumSize(bar->sizeHint());
|
|
|
|
bar = new QToolBar(ui->widgetBarZ);
|
|
bar->setOrientation(Qt::Vertical);
|
|
bar->addActions(drawtools->actionsForZ());
|
|
bar->addSeparator();
|
|
bar->addActions(QList<QAction*>() << ui->actionRemove_items);
|
|
ui->widgetBarZ->setMinimumSize(bar->sizeHint());
|
|
init = true;
|
|
on_buttonClear_clicked();
|
|
}
|
|
|
|
|
|
BlockEditor::~BlockEditor() {
|
|
init = false;
|
|
delete ui;
|
|
}
|
|
|
|
|
|
void BlockEditor::loadFile(QString path) {
|
|
if (path.isEmpty()) return;
|
|
QFile f(path);
|
|
if (f.open(QIODevice::ReadOnly)) {
|
|
cur_file = path;
|
|
loadModel(f.readAll());
|
|
QDir::setCurrent(QFileInfo(path).dir().path());
|
|
}
|
|
setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(path).baseName()));
|
|
}
|
|
|
|
|
|
void BlockEditor::loadModel(const QByteArray &model) {
|
|
BlockItem b;
|
|
b.loadModel(model);
|
|
ui->spin_w->setValue(b.width());
|
|
ui->spin_h->setValue(b.height());
|
|
ui->spin_margin->setValue(b.pinsMargin());
|
|
ui->button_color->setColor(b.color());
|
|
block.loadModel(model);
|
|
treePinsClear();
|
|
ui->treePins->blockSignals(true);
|
|
QVector<BlockItemPin * > pins = block.pins();
|
|
foreach (BlockItemPin * p, pins) {
|
|
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << p->text() << QString::number(p->busType()));
|
|
ti->setData(0, Qt::UserRole, qulonglong(p));
|
|
ti->setData(0, Qt::UserRole + 1, (int)p->alignment());
|
|
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
|
pin_tli[p->alignment()]->addChild(ti);
|
|
}
|
|
foreach (QGraphicsItem * i, block.decors()) {
|
|
i->setData(1002, false);
|
|
i->setData(1100, true);
|
|
}
|
|
ui->treePins->blockSignals(false);
|
|
}
|
|
|
|
|
|
QByteArray BlockEditor::saveModel() {
|
|
return block.saveModel();
|
|
}
|
|
|
|
|
|
void BlockEditor::setEditorMode(bool editorMode) {
|
|
m_editorMode = editorMode;
|
|
ui->buttonClear->setVisible(!editorMode);
|
|
ui->buttonSave->setVisible(!editorMode);
|
|
ui->buttonSaveAs->setVisible(!editorMode);
|
|
ui->buttonLoad->setVisible(!editorMode);
|
|
}
|
|
|
|
|
|
void BlockEditor::setPinsEditable(bool pinsEditable) {
|
|
m_pinsEditable = pinsEditable;
|
|
ui->treePins->setVisible(pinsEditable);
|
|
ui->buttonPinAdd->setVisible(pinsEditable);
|
|
ui->buttonPinClear->setVisible(pinsEditable);
|
|
ui->buttonPinDelete->setVisible(pinsEditable);
|
|
ui->buttonPinDup->setVisible(pinsEditable);
|
|
ui->groupPins->setVisible(pinsEditable);
|
|
}
|
|
|
|
|
|
void BlockEditor::selectionChanged() {
|
|
if (!init) return;
|
|
ui->actionRemove_items->setEnabled(!ui->blockView->scene()->selectedItems().isEmpty());
|
|
}
|
|
|
|
|
|
void BlockEditor::addItem(QGraphicsItem *item) {
|
|
block.addDecor(item);
|
|
item->setData(1002, false);
|
|
item->setData(1100, true);
|
|
}
|
|
|
|
|
|
void BlockEditor::updateBlock() {
|
|
block.setSize(ui->spin_w->value(), ui->spin_h->value());
|
|
block.setColor(ui->button_color->color());
|
|
block.setPinsMargin(ui->spin_margin->value());
|
|
}
|
|
|
|
|
|
void BlockEditor::treePinsClear() {
|
|
ui->treePins->blockSignals(true);
|
|
ui->treePins->clear();
|
|
QFont bf(font()); bf.setBold(true);
|
|
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
|
|
QStringList an = QStringList() << "Left" << "Right" << "Top" << "Bottom";
|
|
pin_tli.clear();
|
|
for (int i = 0; i < al.size(); ++i) {
|
|
QTreeWidgetItem * ti = new QTreeWidgetItem();
|
|
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
|
|
ti->setData(0, Qt::UserRole, al[i]);
|
|
ti->setText(0, an[i]);
|
|
ti->setFont(0, bf);
|
|
ui->treePins->addTopLevelItem(ti);
|
|
ti->setFirstColumnSpanned(true);
|
|
ti->setExpanded(true);
|
|
pin_tli[al[i]] = ti;
|
|
}
|
|
ui->treePins->blockSignals(false);
|
|
}
|
|
|
|
|
|
bool BlockEditor::eventFilter(QObject *o, QEvent *e) {
|
|
if (!init) QWidget::eventFilter(o, e);
|
|
if (o == ui->treePins->viewport()) {
|
|
if (e->type() == QEvent::Drop) {
|
|
QTimer::singleShot(0, this, SLOT(arrangePins()));
|
|
}
|
|
}
|
|
if (o == ui->blockView->viewport()) {
|
|
if (e->type() == QEvent::Resize) {
|
|
ui->blockView->centerOn(&block);
|
|
}
|
|
}
|
|
return QWidget::eventFilter(o, e);
|
|
}
|
|
|
|
|
|
void BlockEditor::changeEvent(QEvent * e) {
|
|
QWidget::changeEvent(e);
|
|
switch (e->type()) {
|
|
case QEvent::LanguageChange:
|
|
ui->retranslateUi(this);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
|
|
void BlockEditor::on_actionRemove_items_triggered() {
|
|
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
|
foreach (QGraphicsItem * i, si)
|
|
block.removeDecor(i);
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonSave_clicked() {
|
|
if (cur_file.isEmpty()) {
|
|
on_buttonSaveAs_clicked();
|
|
return;
|
|
}
|
|
QFile f(cur_file);
|
|
if (f.open(QIODevice::WriteOnly)) {
|
|
f.write(saveModel());
|
|
//setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(c).baseName()));
|
|
}
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonSaveAs_clicked() {
|
|
QString c = QFileDialog::getSaveFileName(this, "Save block model to file", cur_file, "*.blockmodel");
|
|
if (!c.isEmpty()) {
|
|
QFile f(c);
|
|
if (f.open(QIODevice::WriteOnly)) {
|
|
cur_file = c;
|
|
f.write(saveModel());
|
|
setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(c).baseName()));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonLoad_clicked() {
|
|
QString c = QFileDialog::getOpenFileName(this, "Save block model to file", cur_file, "*.blockmodel");
|
|
loadFile(c);
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonClear_clicked() {
|
|
BlockItem b;
|
|
ui->spin_w->setValue(b.width());
|
|
ui->spin_h->setValue(b.height());
|
|
ui->spin_margin->setValue(b.pinsMargin());
|
|
ui->button_color->setColor(b.color());
|
|
block.loadModel(QByteArray());
|
|
treePinsClear();
|
|
}
|
|
|
|
|
|
|
|
void BlockEditor::on_buttonPinAdd_clicked() {
|
|
ui->treePins->blockSignals(true);
|
|
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << "" << "0");
|
|
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
|
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0))));
|
|
ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft);
|
|
pin_tli[Qt::AlignLeft]->addChild(ti);
|
|
ui->treePins->setCurrentItem(ti);
|
|
ui->treePins->blockSignals(false);
|
|
updateBlock();
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonPinDup_clicked() {
|
|
QTreeWidgetItem * ci = ui->treePins->currentItem();
|
|
if (ci == 0) return;
|
|
ui->treePins->blockSignals(true);
|
|
QTreeWidgetItem * ti = ci->clone();
|
|
ti->setText(0, ti->text(0));
|
|
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
|
Qt::Alignment al = (Qt::Alignment)ci->data(0, Qt::UserRole + 1).toInt();
|
|
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(al, ci->text(1).toInt(), ci->text(0))));
|
|
ti->setData(0, Qt::UserRole + 1, (int)al);
|
|
pin_tli[al]->addChild(ti);
|
|
ui->treePins->setCurrentItem(ti);
|
|
ui->treePins->blockSignals(false);
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonPinDelete_clicked() {
|
|
ui->treePins->blockSignals(true);
|
|
QList<QTreeWidgetItem*> si = ui->treePins->selectedItems();
|
|
foreach (QTreeWidgetItem * i, si) {
|
|
if (!i->parent()) continue;
|
|
block.removePin((BlockItemPin*)(i->data(0, Qt::UserRole).toLongLong()));
|
|
delete i;
|
|
}
|
|
ui->treePins->blockSignals(false);
|
|
}
|
|
|
|
|
|
void BlockEditor::on_buttonPinClear_clicked() {
|
|
treePinsClear();
|
|
block.clearPins();
|
|
}
|
|
|
|
|
|
void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
|
|
if (!item) return;
|
|
BlockItemPin * pin = (BlockItemPin*)item->data(0, Qt::UserRole).toULongLong();
|
|
if (!pin) return;
|
|
switch (column) {
|
|
case 0:
|
|
ui->treePins->blockSignals(true);
|
|
item->setText(0, item->text(0));
|
|
pin->setText(item->text(0));
|
|
ui->treePins->blockSignals(false);
|
|
break;
|
|
case 1: pin->setBusType(item->text(1).toInt()); break;
|
|
};
|
|
}
|
|
|
|
|
|
|
|
void BlockEditor::arrangePins() {
|
|
QVector<BlockItemPin * > pins = block.pins();
|
|
// block.clearPins();
|
|
QList<QTreeWidgetItem*> tli = pin_tli.values();
|
|
foreach (QTreeWidgetItem * ti, tli) {
|
|
for (int i = 0; i < ti->childCount(); ++i) {
|
|
foreach (BlockItemPin * p, pins)
|
|
if (p == (BlockItemPin*)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) {
|
|
p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole).toInt());
|
|
BlockItemPin * np = block.addPin(p, false);
|
|
ti->child(i)->setData(0, Qt::UserRole, qulonglong(np));
|
|
ti->child(i)->setData(0, Qt::UserRole + 1, ti->data(0, Qt::UserRole).toInt());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// for (int i = 0; i < ui->treePins->topLevelItemCount(); ++i) {
|
|
// QTreeWidgetItem * ti = ui->treePins->topLevelItem(i);
|
|
// if (tli.contains(ti)) continue;
|
|
// ti = ui->treePins->takeTopLevelItem(i);
|
|
// pin_tli[ti->data(0, Qt::UserRole + 1).toInt()]->addChild(ti);
|
|
// foreach (BlockItemPin * p, pins)
|
|
// if (p->text() == ti->text(0)) {
|
|
// p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole + 1).toInt());
|
|
// block.addPin(p, false);
|
|
// break;
|
|
// }
|
|
// }
|
|
block.arrangePins();
|
|
}
|
|
|
|
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
|
|
|
|
QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
|
QComboBox * combo = new QComboBox(parent);
|
|
int cv = index.data().toInt();
|
|
combo->addItem("Left", int(Qt::AlignLeft)); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
|
|
combo->addItem("Right", int(Qt::AlignRight)); if (cv == Qt::AlignRight) combo->setCurrentIndex(1);
|
|
combo->addItem("Top", int(Qt::AlignTop)); if (cv == Qt::AlignTop) combo->setCurrentIndex(2);
|
|
combo->addItem("Bottom", int(Qt::AlignBottom)); if (cv == Qt::AlignBottom) combo->setCurrentIndex(3);
|
|
combo->setGeometry(option.rect);
|
|
return combo;
|
|
}
|
|
|
|
|
|
QString PinAlignDelegate::displayText(const QVariant & value, const QLocale & locale) const {
|
|
int cv = value.toInt();
|
|
switch (cv) {
|
|
case Qt::AlignLeft: return tr("Left"); break;
|
|
case Qt::AlignRight: return tr("Right"); break;
|
|
case Qt::AlignTop: return tr("Top"); break;
|
|
case Qt::AlignBottom: return tr("Bottom"); break;
|
|
}
|
|
return tr("unknown");
|
|
}
|
|
|
|
|
|
void PinAlignDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
|
|
model->setData(index, ((QComboBox*)editor)->itemData(((QComboBox*)editor)->currentIndex()).toInt());
|
|
}
|
|
|
|
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
/// ***********************************************************
|
|
|
|
|
|
QWidget * PinBusDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
|
QSpinBox * spin = new QSpinBox(parent);
|
|
spin->setMinimum(-2147483648);
|
|
spin->setMaximum(2147483647);
|
|
spin->setValue(index.data().toInt());
|
|
return spin;
|
|
}
|
|
|
|
|
|
QString PinBusDelegate::displayText(const QVariant & value, const QLocale & locale) const {
|
|
int cv = value.toInt();
|
|
return QString::number(cv);
|
|
}
|
|
|
|
|
|
void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
|
|
model->setData(index, ((QSpinBox*)editor)->value());
|
|
}
|
|
|
|
|
|
|
|
//void BlockEditor::on_treePins_itemSelectionChanged() {
|
|
// arrangePins();
|
|
// qDebug() << "111111111111111";
|
|
//}
|