From 245a8abbb16f68e9a5d072f34c621320d340f94e Mon Sep 17 00:00:00 2001 From: xavier Date: Sat, 24 Mar 2012 14:34:25 +0000 Subject: [PATCH] Diagram editor: users may now enter visualisation mode by pressing Ctrl and Shift. git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/branches/0.3@1593 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- sources/diagramview.cpp | 121 +++++++++++++++++++++++++++++++++++----- sources/diagramview.h | 9 +++ 2 files changed, 117 insertions(+), 13 deletions(-) diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index c88c83ca1..e925c19b0 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -43,7 +43,7 @@ @param diagram Schema a afficher ; si diagram vaut 0, un nouveau Diagram est utilise @param parent Le QWidget parent de cette vue de schema */ -DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(parent), is_adding_text(false) { +DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(parent), is_adding_text(false), is_moving_view_(false) { setAttribute(Qt::WA_DeleteOnClose, true); setInteractive(true); @@ -364,7 +364,7 @@ void DiagramView::copy() { @param clipboard_mode Type de presse-papier a prendre en compte */ void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) { - if (scene -> isReadOnly()) return; + if (!isInteractive() || scene -> isReadOnly()) return; QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode); if ((texte_presse_papier).isEmpty()) return; @@ -397,15 +397,21 @@ void DiagramView::pasteHere() { * le clic pour ajouter un champ de texte independant */ void DiagramView::mousePressEvent(QMouseEvent *e) { - if (e -> buttons() == Qt::MidButton) { - paste(mapToScene(e -> pos()), QClipboard::Selection); - } else { - if (!scene -> isReadOnly() && is_adding_text && e -> buttons() == Qt::LeftButton) { - addDiagramTextAtPos(mapToScene(e -> pos())); - is_adding_text = false; - } - QGraphicsView::mousePressEvent(e); + if (fresh_focus_in_) { + switchToVisualisationModeIfNeeded(e); + fresh_focus_in_ = false; } + if (isInteractive() && !scene -> isReadOnly()) { + if (e -> buttons() == Qt::MidButton) { + paste(mapToScene(e -> pos()), QClipboard::Selection); + } else { + if (is_adding_text && e -> buttons() == Qt::LeftButton) { + addDiagramTextAtPos(mapToScene(e -> pos())); + is_adding_text = false; + } + } + } + QGraphicsView::mousePressEvent(e); } /** @@ -425,6 +431,35 @@ void DiagramView::wheelEvent(QWheelEvent *e) { } } +/** + Handles "Focus in" events. Reimplemented here to store the fact the focus + was freshly acquired again using the mouse. This information is later used + in DiagramView::mousePressEvent(). +*/ +void DiagramView::focusInEvent(QFocusEvent *e) { + if (e -> reason() == Qt::MouseFocusReason) { + fresh_focus_in_ = true; + } +} + +/** + Handles "key press" events. Reimplemented here to switch to visualisation + mode if needed. +*/ +void DiagramView::keyPressEvent(QKeyEvent *e) { + switchToVisualisationModeIfNeeded(e); + QGraphicsView::keyPressEvent(e); +} + +/** + Handles "key release" events. Reimplemented here to switch to selection + mode if needed. +*/ +void DiagramView::keyReleaseEvent(QKeyEvent *e) { + switchToSelectionModeIfNeeded(e); + QGraphicsView::keyReleaseEvent(e); +} + /** @return le titre de cette vue ; cela correspond au titre du schema visualise precede de la mention "Schema". Si le titre du schema est vide, @@ -1005,9 +1040,7 @@ bool DiagramView::event(QEvent *e) { // vue plutot que de remonter vers les QMenu / QAction if ( e -> type() == QEvent::ShortcutOverride && - scene -> hasFocus() && - scene -> focusItem() && - scene -> focusItem() -> isSelected() + selectedItemHasFocus() ) { e -> accept(); return(true); @@ -1015,6 +1048,66 @@ bool DiagramView::event(QEvent *e) { return(QGraphicsView::event(e)); } +/** + Switch to visualisation mode if the user is pressing Ctrl and Shift. + @return true if the view was switched to visualisation mode, false + otherwise. +*/ +bool DiagramView::switchToVisualisationModeIfNeeded(QInputEvent *e) { + if (isCtrlShifting(e) && !selectedItemHasFocus()) { + if (dragMode() != QGraphicsView::ScrollHandDrag) { + is_moving_view_ = true; + setVisualisationMode(); + return(true); + } + } + return(false); +} + +/** + Switch back to selection mode if the user is not pressing Ctrl and Shift. + @return true if the view was switched to selection mode, false + otherwise. +*/ +bool DiagramView::switchToSelectionModeIfNeeded(QInputEvent *e) { + if (is_moving_view_ && !selectedItemHasFocus() && !isCtrlShifting(e)) { + setSelectionMode(); + is_moving_view_ = false; + return(true); + } + return(false); +} + +/** + @return true if the user is pressing Ctrl and Shift simultaneously. +*/ +bool DiagramView::isCtrlShifting(QInputEvent *e) { + bool result = false; + // note: QInputEvent::modifiers and QKeyEvent::modifiers() do not return the + // same values, hence the casts + if (e -> type() == QEvent::KeyPress || e -> type() == QEvent::KeyRelease) { + if (QKeyEvent *ke = static_cast(e)) { + result = (ke -> modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)); + } + } else if (e -> type() >= QEvent::MouseButtonPress && e -> type() <= QEvent::MouseMove) { + if (QMouseEvent *me = static_cast(e)) { + result = (me -> modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)); + } + } + return(result); +} + +/** + @return true if there is a selected item and that item has the focus. +*/ +bool DiagramView::selectedItemHasFocus() { + return( + scene -> hasFocus() && + scene -> focusItem() && + scene -> focusItem() -> isSelected() + ); +} + /** Passe le DiagramView en mode "ajout de texte". Un clic cree alors un nouveau champ de texte. @@ -1031,6 +1124,8 @@ void DiagramView::addText() { @return le champ de texte ajoute */ IndependentTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) { + if (!isInteractive() || scene -> isReadOnly()) return(0); + // cree un nouveau champ de texte IndependentTextItem *iti = new IndependentTextItem("_"); diff --git a/sources/diagramview.h b/sources/diagramview.h index bd5cd87b5..0e49f42b4 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -47,6 +47,8 @@ class DiagramView : public QGraphicsView { QAction *find_element_; QPoint paste_here_pos; bool is_adding_text; + bool is_moving_view_; ///< Indicate whether the visualisation mode has been enabled due to mouse/keyboard interactions + bool fresh_focus_in_; ///< Indicate the focus was freshly gained ElementsLocation next_location_; QPoint next_position_; @@ -71,7 +73,14 @@ class DiagramView : public QGraphicsView { virtual void mouseDoubleClickEvent(QMouseEvent *); virtual void contextMenuEvent(QContextMenuEvent *); virtual void wheelEvent(QWheelEvent *); + virtual void focusInEvent(QFocusEvent *); + virtual void keyPressEvent(QKeyEvent *); + virtual void keyReleaseEvent(QKeyEvent *); virtual bool event(QEvent *); + virtual bool switchToVisualisationModeIfNeeded(QInputEvent *e); + virtual bool switchToSelectionModeIfNeeded(QInputEvent *e); + virtual bool isCtrlShifting(QInputEvent *); + virtual bool selectedItemHasFocus(); private: void mousePressEvent(QMouseEvent *);