From d84f78e4e864e7cc5e3e12cffdf2c74bd3ecf757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=8B=D1=87=D0=BA=D0=BE=D0=B2=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Mon, 16 Jan 2017 17:26:19 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@157 a8b55f48-bf90-11e4-a774-851b48703e85 --- qad_blockview/CMakeLists.txt | 4 + qad_blockview/blockeditor.cpp | 340 +++++++++++++++++++++ qad_blockview/blockeditor.h | 80 +++++ qad_blockview/blockeditor.ui | 458 +++++++++++++++++++++++++++++ qad_blockview/blockeditor_main.cpp | 10 + qad_blockview/blockitem.cpp | 5 +- 6 files changed, 896 insertions(+), 1 deletion(-) create mode 100644 qad_blockview/blockeditor.cpp create mode 100644 qad_blockview/blockeditor.h create mode 100644 qad_blockview/blockeditor.ui create mode 100644 qad_blockview/blockeditor_main.cpp diff --git a/qad_blockview/CMakeLists.txt b/qad_blockview/CMakeLists.txt index c61cf4b..bba99c9 100644 --- a/qad_blockview/CMakeLists.txt +++ b/qad_blockview/CMakeLists.txt @@ -16,11 +16,15 @@ file(GLOB MOCS "./*.h") file(GLOB CPPS "./*.cpp") file(GLOB UIS "./*.ui") file(GLOB RES "./*.qrc") +file(GLOB MAINCPPS "./*_main.cpp") +list(REMOVE_ITEM CPPS ${MAINCPPS}) qt4_wrap_ui(CUIS ${UIS}) qt4_wrap_cpp(CMOCS ${MOCS} OPTIONS -nw) qt4_add_resources(CRES ${RES}) add_library(${PROJECT_NAME} SHARED ${CPPS} ${CUIS} ${CMOCS} ${CRES} ${MOCS}) target_link_libraries(${PROJECT_NAME} ${LIBS}) +add_executable(blockeditor WIN32 "blockeditor_main.cpp" ${CRES}) +target_link_libraries(blockeditor ${LIBS} ${PROJECT_NAME}) if (LIB) if (WIN32) set(CMAKE_INSTALL_PREFIX ${MINGW_DIR}) diff --git a/qad_blockview/blockeditor.cpp b/qad_blockview/blockeditor.cpp new file mode 100644 index 0000000..737a854 --- /dev/null +++ b/qad_blockview/blockeditor.cpp @@ -0,0 +1,340 @@ +#include "blockeditor.h" +#include "ui_blockeditor.h" +#include "drawtools.h" +#include "blockview.h" +#include +#include +#include +#include +#include + + +BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEditor) { + init = false; + ui->setupUi(this); + connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); + block.setFlags(0); + ui->blockView->addItem(&block); + ui->blockView->viewport()->installEventFilter(this); + DrawTools * drawtools = new DrawTools(ui->blockView); + drawtools->setAlignCompact(true); + 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::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(1002, false); + i->setData(1100, true); + } + ui->treePins->blockSignals(false); +} + + +QByteArray BlockEditor::saveModel() { + return block.saveModel(); +} + + +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 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::on_actionRemove_items_triggered() { + QList si = ui->blockView->scene()->selectedItems(); + foreach (QGraphicsItem * i, si) + block.removeDecor(i); +} + + +void BlockEditor::on_buttonSave_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()); + } + } +} + + +void BlockEditor::on_buttonLoad_clicked() { + QString c = QFileDialog::getOpenFileName(this, "Save block model to file", cur_file, "*.blockmodel"); + if (!c.isEmpty()) { + QFile f(c); + if (f.open(QIODevice::ReadOnly)) { + cur_file = c; + loadModel(f.readAll()); + } + } +} + + +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; + } + } + } + +// 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 "Left"; break; + case Qt::AlignRight: return "Right"; break; + case Qt::AlignTop: return "Top"; break; + case Qt::AlignBottom: return "Bottom"; break; + } + return "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()); +} + diff --git a/qad_blockview/blockeditor.h b/qad_blockview/blockeditor.h new file mode 100644 index 0000000..e0a5234 --- /dev/null +++ b/qad_blockview/blockeditor.h @@ -0,0 +1,80 @@ +#ifndef BLOCKEDITOR_H +#define BLOCKEDITOR_H + +#include +#include +#include +#include "blockitem.h" + + +namespace Ui { +class BlockEditor; +} + + +class BlockEditor : public QWidget +{ + Q_OBJECT + +public: + explicit BlockEditor(QWidget *parent = 0); + ~BlockEditor(); + + +public slots: + void loadModel(const QByteArray & model); + QByteArray saveModel(); + +private slots: + void selectionChanged(); + void addItem(QGraphicsItem * item); + void updateBlock(); + void treePinsClear(); + void arrangePins(); + void on_actionRemove_items_triggered(); + void on_buttonSave_clicked(); + void on_buttonLoad_clicked(); + void on_buttonClear_clicked(); + void on_buttonPinAdd_clicked(); + void on_buttonPinDup_clicked(); + void on_buttonPinDelete_clicked(); + void on_buttonPinClear_clicked(); + void on_treePins_itemChanged(QTreeWidgetItem *item, int column); + +private: + bool eventFilter(QObject * o, QEvent * e); + + Ui::BlockEditor *ui; + QMap pin_tli; + BlockItem block; + QString cur_file; + bool init; +}; + + + +class PinAlignDelegate: public QStyledItemDelegate { + Q_OBJECT +public: + PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} + QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; + QString displayText(const QVariant & value, const QLocale & locale) const; + void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);} +}; + + +class PinBusDelegate: public QStyledItemDelegate { + Q_OBJECT +public: + PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {} + QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const; + QString displayText(const QVariant & value, const QLocale & locale) const; + void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const; + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);} +private: + typedef QPair ISPair; + QVector buses; +}; + +#endif // BLOCKEDITOR_H diff --git a/qad_blockview/blockeditor.ui b/qad_blockview/blockeditor.ui new file mode 100644 index 0000000..a07c7ce --- /dev/null +++ b/qad_blockview/blockeditor.ui @@ -0,0 +1,458 @@ + + + BlockEditor + + + + 0 + 0 + 901 + 861 + + + + Form + + + + + + Qt::Vertical + + + + Qt::Horizontal + + + + Block parameters + + + Qt::AlignCenter + + + + 4 + + + + + Width: + + + + + + + 1000 + + + 20 + + + 100 + + + + + + + Heigth: + + + + + + + 1000 + + + 20 + + + 60 + + + + + + + Pins margin: + + + + + + + 100 + + + 10 + + + 10 + + + + + + + Color: + + + + + + + + + + + Pins + + + Qt::AlignCenter + + + + 2 + + + + + + 0 + 200 + + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::ScrollPerPixel + + + false + + + false + + + 200 + + + + Name + + + + + Bus + + + + + + + + + + Add + + + + :/icons/list-add.png:/icons/list-add.png + + + + + + + Clone + + + + :/icons/edit-copy.png:/icons/edit-copy.png + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 20 + + + + + + + + Remove selected + + + + :/icons/edit-delete.png:/icons/edit-delete.png + + + + + + + Remove all + + + + :/icons/edit-clear.png:/icons/edit-clear.png + + + + + + + Qt::Vertical + + + + 20 + 1 + + + + + + + + + + + + + 0 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Save + + + + :/icons/document-save.png:/icons/document-save.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Load + + + + :/icons/document-open.png:/icons/document-open.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Clear + + + + :/icons/edit-clear.png:/icons/edit-clear.png + + + + + + + + + + :/icons/edit-delete.png:/icons/edit-delete.png + + + Remove items + + + + + + BlockView + QGraphicsView +
blockview.h
+
+ + ColorButton + QPushButton +
colorbutton.h
+
+
+ + + + + + spin_w + valueChanged(int) + BlockEditor + updateBlock() + + + 170 + 21 + + + 254 + 1 + + + + + spin_h + valueChanged(int) + BlockEditor + updateBlock() + + + 250 + 49 + + + 373 + 5 + + + + + spin_margin + valueChanged(int) + BlockEditor + updateBlock() + + + 350 + 90 + + + 492 + 8 + + + + + button_color + colorChanged(QColor) + BlockEditor + updateBlock() + + + 561 + 115 + + + 613 + 6 + + + + + + updateBlock() + +
diff --git a/qad_blockview/blockeditor_main.cpp b/qad_blockview/blockeditor_main.cpp new file mode 100644 index 0000000..24a6356 --- /dev/null +++ b/qad_blockview/blockeditor_main.cpp @@ -0,0 +1,10 @@ +#include +#include "blockeditor.h" + + +int main(int argc, char * argv[]) { + QApplication a(argc, argv); + BlockEditor w; + w.show(); + return a.exec(); +} diff --git a/qad_blockview/blockitem.cpp b/qad_blockview/blockitem.cpp index 68c4eef..aef76d2 100644 --- a/qad_blockview/blockitem.cpp +++ b/qad_blockview/blockitem.cpp @@ -260,6 +260,8 @@ void BlockItem::loadModel(const QByteArray & data) { //qDebug() << "load from" << data.size() << "bytes"; clearPins(); clearDecors(); + col = Qt::lightGray; + _resize(QSizeF(100., 60.)); if (data.isEmpty()) return; /*QDataStream s(data); {QPointF _v; s >> _v;} @@ -407,7 +409,8 @@ void BlockItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { void BlockItem::arrangePins() { //double w = g_main.rect().width(), h = g_main.rect().height(); - QVector pl = pins(); + QSet pl; + pl = pl.fromList(pins().toList()); pins_.clear(); foreach (BlockItemPin * p, pl) pins_[p->alignment()] << p;