diff --git a/sources/diagramcontent.cpp b/sources/diagramcontent.cpp index e89d7a532..6f11f1ab3 100644 --- a/sources/diagramcontent.cpp +++ b/sources/diagramcontent.cpp @@ -265,6 +265,51 @@ int DiagramContent::removeNonMovableItems() return count_; } +DiagramContent &DiagramContent::operator+=(const DiagramContent &other) +{ + for(Element *elmt : other.m_elements) + if(!m_elements.contains(elmt)) + m_elements << elmt; + + for(IndependentTextItem *iti : other.m_text_fields) + if(!m_text_fields.contains(iti)) + m_text_fields << iti; + + for(DiagramImageItem *dii : other.m_images) + if(!m_images.contains(dii)) + m_images << dii; + + for(QetShapeItem *qsi : other.m_shapes) + if(!m_shapes.contains(qsi)) + m_shapes << qsi; + + for(Conductor *c : other.m_conductors_to_update) + if(!m_conductors_to_update.contains(c)) + m_conductors_to_update << c; + + for(Conductor *c : other.m_conductors_to_move) + if(!m_conductors_to_move.contains(c)) + m_conductors_to_move << c; + + for(Conductor *c : other.m_other_conductors) + if(!m_other_conductors.contains(c)) + m_other_conductors << c; + + for(DynamicElementTextItem *deti : other.m_element_texts) + if(!m_element_texts.contains(deti)) + m_element_texts << deti; + + for(ElementTextItemGroup *etig : other.m_texts_groups) + if(!m_texts_groups.contains(etig)) + m_texts_groups << etig; + + for(QGraphicsItem *qgi : other.m_selected_items) + if(!m_selected_items.contains(qgi)) + m_selected_items << qgi; + + return *this; +} + /** * @brief DiagramContent::items * @param filter diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h index 13409b28e..853d1aa36 100644 --- a/sources/diagramcontent.h +++ b/sources/diagramcontent.h @@ -85,6 +85,8 @@ class DiagramContent int count(int = All) const; void clear(); int removeNonMovableItems(); + + DiagramContent& operator+=(const DiagramContent& other); }; QDebug &operator<<(QDebug, DiagramContent &); #endif diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 8c74501d1..b5afd838f 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -44,6 +44,7 @@ #include "qetshapeitem.h" #include "undocommand/deleteqgraphicsitemcommand.h" #include "dynamicelementtextitem.h" +#include "multipastedialog.h" /** Constructeur @@ -86,6 +87,12 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : m_context_menu = new QMenu(this); m_paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this); connect(m_paste_here, SIGNAL(triggered()), this, SLOT(pasteHere())); + + m_multi_paste = new QAction(QET::Icons::EditPaste, tr("Collage multiple"), this); + connect(m_multi_paste, &QAction::triggered, [this]() { + MultiPasteDialog d(this->m_diagram, this); + d.exec(); + }); connect(m_diagram, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*))); connect(m_diagram, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); @@ -1061,6 +1068,7 @@ void DiagramView::contextMenuEvent(QContextMenuEvent *e) { } else { m_context_menu -> addAction(qde -> m_cut); m_context_menu -> addAction(qde -> m_copy); + m_context_menu->addAction(m_multi_paste); m_context_menu -> addSeparator(); m_context_menu -> addAction(qde -> m_conductor_reset); m_context_menu -> addSeparator(); diff --git a/sources/diagramview.h b/sources/diagramview.h index becc2b723..2beb67446 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -53,6 +53,7 @@ class DiagramView : public QGraphicsView DVEventInterface *m_event_interface = nullptr; QMenu *m_context_menu = nullptr; QAction *m_paste_here = nullptr; + QAction *m_multi_paste = nullptr; QPoint m_paste_here_pos; QPointF m_rubber_band_origin; bool m_fresh_focus_in, diff --git a/sources/ui/multipastedialog.cpp b/sources/ui/multipastedialog.cpp new file mode 100644 index 000000000..2cc004e68 --- /dev/null +++ b/sources/ui/multipastedialog.cpp @@ -0,0 +1,81 @@ +#include "multipastedialog.h" +#include "ui_multipastedialog.h" +#include "diagram.h" +#include "diagramcommands.h" + +MultiPasteDialog::MultiPasteDialog(Diagram *diagram, QWidget *parent) : + QDialog(parent), + ui(new Ui::MultiPasteDialog), + m_diagram(diagram) +{ + ui->setupUi(this); + + connect(ui->m_x_sb, static_cast(&QSpinBox::valueChanged), this, &MultiPasteDialog::updatePreview); + connect(ui->m_y_sb, static_cast(&QSpinBox::valueChanged), this, &MultiPasteDialog::updatePreview); + connect(ui->m_copy_count, static_cast(&QSpinBox::valueChanged), this, &MultiPasteDialog::updatePreview); + + QRectF br; + for (QGraphicsItem *item : m_diagram->selectedItems()) + br = br.united(item->mapToScene(item->boundingRect()).boundingRect()); + m_origin = br.topLeft(); + + m_document = m_diagram->toXml(false); + updatePreview(); +} + +MultiPasteDialog::~MultiPasteDialog() +{ + if(m_accept == false) + { + for(QGraphicsItem *item : m_pasted_content.items()) + { + if(item->scene() && item->scene() == m_diagram) + { + m_diagram->removeItem(item); + delete item; + } + } + } + + delete ui; +} + +void MultiPasteDialog::updatePreview() +{ + //First of all we remove all precedent items added from the previous preview. + for(QGraphicsItem *item : m_pasted_content.items()) + { + if(item->scene() && item->scene() == m_diagram) + { + m_diagram->removeItem(item); + delete item; + } + } + m_pasted_content.clear(); + + QPointF offset(ui->m_x_sb->value(), ui->m_y_sb->value()); + QPointF pos = m_origin+offset; + + for(int i=0 ; im_copy_count->value() ; i++) + { + DiagramContent dc; + m_diagram->fromXml(m_document, pos, false, &dc); + + m_pasted_content += dc; + pos += offset; + } + + if(m_pasted_content.count()) + m_diagram->adjustSceneRect(); +} + +void MultiPasteDialog::on_m_button_box_accepted() +{ + if(m_pasted_content.count()) + { + m_diagram->clearSelection(); + m_diagram->undoStack().push(new PasteDiagramCommand(m_diagram, m_pasted_content)); + m_diagram->adjustSceneRect(); + m_accept = true; + } +} diff --git a/sources/ui/multipastedialog.h b/sources/ui/multipastedialog.h new file mode 100644 index 000000000..2767e759d --- /dev/null +++ b/sources/ui/multipastedialog.h @@ -0,0 +1,35 @@ +#ifndef MULTIPASTEDIALOG_H +#define MULTIPASTEDIALOG_H + +#include +#include "diagramcontent.h" +#include "QDomDocument" + +class Diagram; + +namespace Ui { + class MultiPasteDialog; +} + +class MultiPasteDialog : public QDialog +{ + Q_OBJECT + + public: + explicit MultiPasteDialog(Diagram *diagram, QWidget *parent = 0); + ~MultiPasteDialog(); + void updatePreview(); + + private slots: + void on_m_button_box_accepted(); + + private: + Ui::MultiPasteDialog *ui; + Diagram *m_diagram = nullptr; + DiagramContent m_pasted_content; + QPointF m_origin; + QDomDocument m_document; + bool m_accept = false; +}; + +#endif // MULTIPASTEDIALOG_H diff --git a/sources/ui/multipastedialog.ui b/sources/ui/multipastedialog.ui new file mode 100644 index 000000000..fb96a846a --- /dev/null +++ b/sources/ui/multipastedialog.ui @@ -0,0 +1,150 @@ + + + MultiPasteDialog + + + + 0 + 0 + 261 + 110 + + + + Collage multiple + + + + + + + + Décalage + + + + + + + px + + + x: + + + -1000 + + + 1000 + + + 10 + + + 100 + + + + + + + px + + + y: + + + -1000 + + + 1000 + + + 10 + + + 0 + + + + + + + + + + + Nombre de copie + + + + + + + 1 + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + m_button_box + accepted() + MultiPasteDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + m_button_box + rejected() + MultiPasteDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +