#include "blockeditor.h" #include "blockview.h" #include "drawtools.h" #include "ui_blockeditor.h" #include #include #include #include #include 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()); block.is_blockeditor = true; 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() << 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 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(bvidMoveParent, false); i->setData(bvidCorrectMove, 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(bvidMoveParent, false); item->setData(bvidCorrectMove, 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 al = QList() << 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 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()); } } 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 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 pins = block.pins(); QList 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; } } } 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()); }