diff --git a/diagram.cpp b/diagram.cpp index 5739f7a9e..4f02d26b5 100644 --- a/diagram.cpp +++ b/diagram.cpp @@ -404,7 +404,7 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in foreach (Element *added_element, added_elements) added_items << added_element; foreach (DiagramTextItem *added_text, added_texts) added_items << added_text; foreach (QGraphicsItem *item, added_items) { - QPointF csg = item -> mapToScene(item -> boundingRect().topLeft()); + QPointF csg = item -> mapToScene(item -> boundingRect()).boundingRect().topLeft(); qreal px = csg.x(); qreal py = csg.y(); if (!init) { diff --git a/diagramcommands.cpp b/diagramcommands.cpp index ced62425e..dad838cce 100644 --- a/diagramcommands.cpp +++ b/diagramcommands.cpp @@ -138,9 +138,9 @@ DeleteElementsCommand::DeleteElementsCommand( /// Destructeur DeleteElementsCommand::~DeleteElementsCommand() { - foreach(QGraphicsItem *qgi, removed_elements) diagram -> qgiManager().release(qgi); - foreach(QGraphicsItem *qgi, removed_conductors) diagram -> qgiManager().release(qgi); foreach(QGraphicsItem *qgi, removed_texts) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, removed_conductors) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, removed_elements) diagram -> qgiManager().release(qgi); } /// annule les suppressions @@ -213,9 +213,9 @@ PasteDiagramCommand::PasteDiagramCommand( /// Destructeur PasteDiagramCommand::~PasteDiagramCommand() { - foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().release(qgi); - foreach(QGraphicsItem *qgi, conductors) diagram -> qgiManager().release(qgi); foreach(QGraphicsItem *qgi, texts) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, conductors) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().release(qgi); } /// annule le coller diff --git a/diagramview.cpp b/diagramview.cpp index 607e93068..8586794b7 100644 --- a/diagramview.cpp +++ b/diagramview.cpp @@ -31,6 +31,10 @@ DiagramView::DiagramView(QWidget *parent) : QGraphicsView(parent), is_adding_tex adjustSceneRect(); updateWindowTitle(); + context_menu = new QMenu(this); + paste_here = new QAction(QIcon(":/ico/paste.png"), tr("Coller ici"), this); + connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere())); + connect(scene, SIGNAL(selectionEmptinessChanged()), this, SLOT(slot_selectionChanged())); connect(&(scene -> border_and_inset), SIGNAL(borderChanged(QRectF, QRectF)), this, SLOT(adjustSceneRect())); connect(&(scene -> undoStack()), SIGNAL(cleanChanged(bool)), this, SLOT(updateWindowTitle())); @@ -244,48 +248,42 @@ void DiagramView::copy() { } /** - importe les elements contenus dans le presse-papier dans le schema + Importe les elements contenus dans le presse-papier dans le schema + @param pos coin superieur gauche (en coordonnees de la scene) du rectangle + englobant le contenu colle + @param clipboard_mode Type de presse-papier a prendre en compte */ -void DiagramView::paste() { - QString texte_presse_papier; +void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) { + QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode); + if ((texte_presse_papier).isEmpty()) return; + QDomDocument document_xml; - if ((texte_presse_papier = QApplication::clipboard() -> text()).isEmpty()) return; if (!document_xml.setContent(texte_presse_papier)) return; // listes pour recupere les elements et conducteurs ajoutes au schema par le coller QList elements_pasted; QList conductors_pasted; QList texts_pasted; - scene -> fromXml(document_xml, QPointF(), false, &elements_pasted, &conductors_pasted, &texts_pasted); + scene -> fromXml(document_xml, pos, false, &elements_pasted, &conductors_pasted, &texts_pasted); - // si quelque chose a effectivement ete ajoute au schema, on cree - if (elements_pasted.count() || conductors_pasted.count()) { + // si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation + if (elements_pasted.count() || conductors_pasted.count() || texts_pasted.count()) { scene -> clearSelection(); scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted, texts_pasted)); } } +/// Colle le contenu du presse-papier sur le schema a la position de la souris +void DiagramView::pasteHere() { + paste(mapToScene(paste_here_pos)); +} + /** gere les clics et plus particulierement le clic du milieu (= coller pour X11) */ void DiagramView::mousePressEvent(QMouseEvent *e) { if (e -> buttons() == Qt::MidButton) { - QString texte_presse_papier; - QDomDocument document_xml; - if ((texte_presse_papier = QApplication::clipboard() -> text(QClipboard::Selection)).isEmpty()) return; - if (!document_xml.setContent(texte_presse_papier)) return; - - // listes pour recupere les elements et conducteurs ajoutes au schema par le coller - QList elements_pasted; - QList conductors_pasted; - QList texts_pasted; - scene -> fromXml(document_xml, mapToScene(e -> pos()), false, &elements_pasted, &conductors_pasted, &texts_pasted); - - // si quelque chose a effectivement ete ajoute au schema, on cree - if (elements_pasted.count() || conductors_pasted.count()) { - scene -> clearSelection(); - scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted, texts_pasted)); - } + paste(mapToScene(e -> pos()), QClipboard::Selection); } else { if (is_adding_text && e -> buttons() == Qt::LeftButton) { DiagramTextItem *dti = new DiagramTextItem(); @@ -813,3 +811,52 @@ bool DiagramView::event(QEvent *e) { void DiagramView::addText() { is_adding_text = true; } + +/** + Gere le menu contextuel + @param e Evenement decrivant la demande de menu contextuel +*/ +void DiagramView::contextMenuEvent(QContextMenuEvent *e) { + if (QGraphicsItem *qgi = scene -> itemAt(mapToScene(e -> pos()))) { + if (!qgi -> isSelected()) scene -> clearSelection(); + qgi -> setSelected(true); + } + + if (QETDiagramEditor *qde = diagramEditor()) { + context_menu -> clear(); + if (scene -> selectedItems().isEmpty()) { + paste_here_pos = e -> pos(); + context_menu -> addAction(paste_here); + context_menu -> addSeparator(); + context_menu -> addAction(qde -> infos_diagram); + context_menu -> addAction(qde -> add_column); + context_menu -> addAction(qde -> remove_column); + context_menu -> addAction(qde -> expand_diagram); + context_menu -> addAction(qde -> shrink_diagram); + } else { + context_menu -> addAction(qde -> cut); + context_menu -> addAction(qde -> copy); + context_menu -> addSeparator(); + context_menu -> addAction(qde -> delete_selection); + context_menu -> addAction(qde -> rotate_selection); + context_menu -> addSeparator(); + context_menu -> addAction(qde -> conductor_prop); + context_menu -> addAction(qde -> conductor_reset); + } + + // affiche le menu contextuel + context_menu -> popup(e -> globalPos()); + } + e -> accept(); +} + +/// @return l'editeur de schemas parent ou 0 +QETDiagramEditor *DiagramView::diagramEditor() const { + // remonte la hierarchie des widgets + QWidget *w = const_cast(this); + while (w -> parentWidget() && !w -> isWindow()) { + w = w -> parentWidget(); + } + // la fenetre est supposee etre un QETDiagramEditor + return(qobject_cast(w)); +} diff --git a/diagramview.h b/diagramview.h index 781cc767f..b1bf8e65b 100644 --- a/diagramview.h +++ b/diagramview.h @@ -2,6 +2,7 @@ #define DIAGRAMVIEW_H #include class Diagram; +class QETDiagramEditor; /** Classe representant graphiquement un schema electrique */ @@ -22,6 +23,9 @@ class DiagramView : public QGraphicsView { private: Diagram *scene; + QMenu *context_menu; + QAction *paste_here; + QPoint paste_here_pos; bool is_adding_text; // methodes @@ -38,10 +42,12 @@ class DiagramView : public QGraphicsView { void expand(); void shrink(); Diagram *diagram() { return(scene); } + QETDiagramEditor *diagramEditor() const; bool hasSelectedItems(); void addText(); protected: + virtual void contextMenuEvent(QContextMenuEvent *); virtual void wheelEvent(QWheelEvent *); virtual bool event(QEvent *); @@ -76,7 +82,8 @@ class DiagramView : public QGraphicsView { void zoomReset(); void cut(); void copy(); - void paste(); + void paste(const QPointF & = QPointF(), QClipboard::Mode = QClipboard::Clipboard); + void pasteHere(); void adjustSceneRect(); void updateWindowTitle(); void editConductor(); diff --git a/qetdiagrameditor.h b/qetdiagrameditor.h index d261defb6..d93957fc0 100644 --- a/qetdiagrameditor.h +++ b/qetdiagrameditor.h @@ -74,7 +74,7 @@ class QETDiagramEditor : public QMainWindow { void slot_addText(); // attributs - private: + public: // Actions faisables au travers de menus dans l'application QElectroTech QActionGroup *grp_visu_sel; QAction *mode_selection;