diff --git a/qad_blockview/blockitem.cpp b/qad_blockview/blockitem.cpp index 4c77bf8..e4af171 100644 --- a/qad_blockview/blockitem.cpp +++ b/qad_blockview/blockitem.cpp @@ -309,7 +309,7 @@ void BlockItem::loadModel(const QByteArray & data) { } -QByteArray BlockItem::save() { +QByteArray BlockItem::save() const { ChunkStream cs; QMap > pp; foreach (BlockItemPin * p, pins()) { diff --git a/qad_blockview/blockitem.h b/qad_blockview/blockitem.h index 9187f5a..c79f9d8 100644 --- a/qad_blockview/blockitem.h +++ b/qad_blockview/blockitem.h @@ -147,7 +147,7 @@ public: QByteArray saveModel(); void loadModel(const QByteArray & data); - QByteArray save(); + QByteArray save() const; void load(const QByteArray & data); void arrangePins(); @@ -193,4 +193,13 @@ inline QDataStream & operator >>(QDataStream & s, BlockItemPin *& p) { } +inline QDataStream & operator <<(QDataStream & s, const BlockItem * b) {s << b->save(); return s;} +inline QDataStream & operator >>(QDataStream & s, BlockItem *& b) { + QByteArray ba; s >> ba; + b = new BlockItem(); + b->load(ba); + return s; +} + + #endif // BLOCKITEM_H diff --git a/qad_blockview/blockview.cpp b/qad_blockview/blockview.cpp index ec47db2..005a7b4 100644 --- a/qad_blockview/blockview.cpp +++ b/qad_blockview/blockview.cpp @@ -6,6 +6,9 @@ #include #include #include +#include + +const QString _BlockView_Mime_ = "_BlockView_copypaste_"; BlockView::BlockView(QWidget * parent): QGraphicsView(parent), tmp_bus(true) { @@ -43,6 +46,7 @@ void BlockView::_init() { thumb_anim.setPropertyName("_thumb"); thumb_anim.setEasingCurve(QEasingCurve::InCubic); connect(scene_, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustThumb())); + connect(scene_, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged())); centerOn(scene_->sceneRect().center()); setCacheMode(CacheBackground); setTransformationAnchor(QGraphicsView::AnchorUnderMouse); @@ -212,8 +216,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { copy_dp = QPointF(); //qDebug() << mm_cancel << mm_copy << mm_drag << new_branch << new_bus; if (mm_copy && mm_cancel) { - qDeleteAll(copy_items); - copy_items.clear(); + deleteCopyTemp(); mm_copy = moved = false; unsetCursor(); } @@ -339,10 +342,13 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { break; } sel_items = scene_->selectedItems(); + deleteCopyTemp(); + QList bi; foreach (QGraphicsItem * i, sel_items) { if (i->data(1006) == "item") { //qDebug() << "copy"; - BlockItem * ti = qgraphicsitem_cast(i)->copy(); + bi << qgraphicsitem_cast(i); + BlockItem * ti = bi.back()->copy(); ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine)); QColor bc = ti->g_main.brush().color(); bc.setAlphaF(bc.alphaF() * 0.5); ti->g_main.setBrush(bc); @@ -350,6 +356,13 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { scene_->addItem(ti); } } + QList ibi = internalBuses(bi); + foreach (BlockBusItem * i, ibi) { + i = i->copy(); + i->setOpacity(i->opacity() * 0.5); + copy_buses << i; + scene_->addItem(i); + } mm_copy = true; setCursor(Qt::DragCopyCursor); } @@ -400,6 +413,8 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { moved = true; foreach (QGraphicsItem * i, copy_items) i->setPos(i->pos() + mdp); + foreach (BlockBusItem * i, copy_buses) + i->movePolyline(mdp); } if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) { if (!mdp.isNull()) @@ -451,8 +466,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { if (!ci.isEmpty()) copyBlocks(ci, copy_dp); if (!bi.isEmpty()) copyBuses(bi, copy_dp); } - qDeleteAll(copy_items); - copy_items.clear(); + deleteCopyTemp(); blockSignals(false); if (moved) { moved = false; @@ -467,7 +481,7 @@ bool BlockView::eventFilter(QObject * o, QEvent * e) { QList ci; foreach (QGraphicsItem * b, sel_items) if (b->data(1006) == "item") - ci << qgraphicsitem_cast(b); + ci << b; emit actionEvent(BlockItemBase::BlockMove, ci); reconnectAll(); } @@ -655,6 +669,14 @@ void BlockView::scrollFromThumb() { } +void BlockView::deleteCopyTemp() { + qDeleteAll(copy_items); + copy_items.clear(); + qDeleteAll(copy_buses); + copy_buses.clear(); +} + + void BlockView::drawThumb() { if (!minimap) return; QPainter p(&widget_thumb); @@ -761,7 +783,8 @@ QList BlockView::buses() const { QList gi = scene_->items(); foreach (QGraphicsItem * i, gi) if (i->data(1005) == "connection") - ret << qgraphicsitem_cast(i); + if (!copy_buses.contains((BlockBusItem*)i)) + ret << qgraphicsitem_cast(i); return ret; } @@ -1203,6 +1226,15 @@ QList BlockView::internalBuses(const QList & item } +QList BlockView::selectedBlocks() { + QList ret; + foreach (QGraphicsItem * b, sel_items) + if (b->data(1006) == "item") + ret << qgraphicsitem_cast(b); + return ret; +} + + void BlockView::adjustThumb() { if (!scene()) return; QSizeF sr = sceneRect().size(), tr; @@ -1321,6 +1353,12 @@ void BlockView::removeJunk() { } +void BlockView::sceneSelectionChanged() { + bool ie = scene()->selectedItems().isEmpty(); + emit copyEnabledChanged(!ie); +} + + void BlockView::_setThumb(double v) { _talpha = v; QMetaObject::invokeMethod(&widget_thumb, "repaint", Qt::QueuedConnection); @@ -1382,6 +1420,32 @@ void BlockView::zoomReset() { } +void BlockView::copySelected() { + QList bll = selectedBlocks(); + if (bll.isEmpty()) return; + QList bul = internalBuses(bll); + QByteArray ba; + QDataStream s(&ba, QIODevice::ReadWrite); + s << bll << bul; + QMimeData * mime = new QMimeData(); + mime->setData(_BlockView_Mime_, ba); + QApplication::clipboard()->setMimeData(mime); +} + + +void BlockView::pasteSelected() { + const QMimeData * mime = QApplication::clipboard()->mimeData(); + if (!mime) return; + if (!mime->hasFormat(_BlockView_Mime_)) return; + QByteArray ba = mime->data(_BlockView_Mime_); + if (ba.isEmpty()) return; + QList bll; + QList bul; + QDataStream s(ba); + s >> bll >> bul; +} + + void BlockView::selectNone() { QList gi = scene_->items(); foreach (QGraphicsItem * i, gi) diff --git a/qad_blockview/blockview.h b/qad_blockview/blockview.h index 81c7a6d..9a87c11 100644 --- a/qad_blockview/blockview.h +++ b/qad_blockview/blockview.h @@ -100,8 +100,10 @@ protected: void unmarkPins(bool to_normal = false); void moveBuses(const QList & items, QPointF dp); QList internalBuses(const QList & items); + QList selectedBlocks(); double _thumb() const {return _talpha;} void scrollFromThumb(); + void deleteCopyTemp(); virtual void loadBus(BlockBusItem * bus) {} virtual void copyBlocks(QList items, QPointF offset) {} @@ -113,6 +115,7 @@ protected: QGraphicsItem * mm_ci; QList sel_items; QList copy_items; + QList copy_buses; BlockBusItem tmp_bus, * match_bus, * bus_from; BlockViewWavetrace wavetrace; QPoint press_point, screen_point, thumb_press; @@ -140,6 +143,7 @@ protected slots: void removedBus(QObject * o); void removedBlock(QObject * o); void removeJunk(); + void sceneSelectionChanged(); void _setThumb(double v); public slots: @@ -159,7 +163,10 @@ public slots: void zoomIn() {zoom(1.2);} void zoomOut() {zoom(1. / 1.2);} void zoomReset(); - + + void copySelected(); + void pasteSelected(); + void reconnectAll(); void selectNone(); void selectAll(); @@ -174,6 +181,7 @@ signals: void actionEvent(BlockItemBase::Action action, QList items); void blockRemoved(BlockItem * item); void connectionsChanged(); + void copyEnabledChanged(bool); };