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
This commit is contained in:
xavier
2012-03-24 14:34:25 +00:00
parent 7370edbb4e
commit 245a8abbb1
2 changed files with 117 additions and 13 deletions

View File

@@ -43,7 +43,7 @@
@param diagram Schema a afficher ; si diagram vaut 0, un nouveau Diagram est utilise @param diagram Schema a afficher ; si diagram vaut 0, un nouveau Diagram est utilise
@param parent Le QWidget parent de cette vue de schema @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); setAttribute(Qt::WA_DeleteOnClose, true);
setInteractive(true); setInteractive(true);
@@ -364,7 +364,7 @@ void DiagramView::copy() {
@param clipboard_mode Type de presse-papier a prendre en compte @param clipboard_mode Type de presse-papier a prendre en compte
*/ */
void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) { 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); QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode);
if ((texte_presse_papier).isEmpty()) return; if ((texte_presse_papier).isEmpty()) return;
@@ -397,15 +397,21 @@ void DiagramView::pasteHere() {
* le clic pour ajouter un champ de texte independant * le clic pour ajouter un champ de texte independant
*/ */
void DiagramView::mousePressEvent(QMouseEvent *e) { void DiagramView::mousePressEvent(QMouseEvent *e) {
if (e -> buttons() == Qt::MidButton) { if (fresh_focus_in_) {
paste(mapToScene(e -> pos()), QClipboard::Selection); switchToVisualisationModeIfNeeded(e);
} else { fresh_focus_in_ = false;
if (!scene -> isReadOnly() && is_adding_text && e -> buttons() == Qt::LeftButton) {
addDiagramTextAtPos(mapToScene(e -> pos()));
is_adding_text = false;
}
QGraphicsView::mousePressEvent(e);
} }
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 @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, 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 // vue plutot que de remonter vers les QMenu / QAction
if ( if (
e -> type() == QEvent::ShortcutOverride && e -> type() == QEvent::ShortcutOverride &&
scene -> hasFocus() && selectedItemHasFocus()
scene -> focusItem() &&
scene -> focusItem() -> isSelected()
) { ) {
e -> accept(); e -> accept();
return(true); return(true);
@@ -1015,6 +1048,66 @@ bool DiagramView::event(QEvent *e) {
return(QGraphicsView::event(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<QKeyEvent *>(e)) {
result = (ke -> modifiers() == (Qt::ControlModifier | Qt::ShiftModifier));
}
} else if (e -> type() >= QEvent::MouseButtonPress && e -> type() <= QEvent::MouseMove) {
if (QMouseEvent *me = static_cast<QMouseEvent *>(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 Passe le DiagramView en mode "ajout de texte". Un clic cree alors un
nouveau champ de texte. nouveau champ de texte.
@@ -1031,6 +1124,8 @@ void DiagramView::addText() {
@return le champ de texte ajoute @return le champ de texte ajoute
*/ */
IndependentTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) { IndependentTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) {
if (!isInteractive() || scene -> isReadOnly()) return(0);
// cree un nouveau champ de texte // cree un nouveau champ de texte
IndependentTextItem *iti = new IndependentTextItem("_"); IndependentTextItem *iti = new IndependentTextItem("_");

View File

@@ -47,6 +47,8 @@ class DiagramView : public QGraphicsView {
QAction *find_element_; QAction *find_element_;
QPoint paste_here_pos; QPoint paste_here_pos;
bool is_adding_text; 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_; ElementsLocation next_location_;
QPoint next_position_; QPoint next_position_;
@@ -71,7 +73,14 @@ class DiagramView : public QGraphicsView {
virtual void mouseDoubleClickEvent(QMouseEvent *); virtual void mouseDoubleClickEvent(QMouseEvent *);
virtual void contextMenuEvent(QContextMenuEvent *); virtual void contextMenuEvent(QContextMenuEvent *);
virtual void wheelEvent(QWheelEvent *); virtual void wheelEvent(QWheelEvent *);
virtual void focusInEvent(QFocusEvent *);
virtual void keyPressEvent(QKeyEvent *);
virtual void keyReleaseEvent(QKeyEvent *);
virtual bool event(QEvent *); virtual bool event(QEvent *);
virtual bool switchToVisualisationModeIfNeeded(QInputEvent *e);
virtual bool switchToSelectionModeIfNeeded(QInputEvent *e);
virtual bool isCtrlShifting(QInputEvent *);
virtual bool selectedItemHasFocus();
private: private:
void mousePressEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *);