Element editor : Element primitive decorator doesn't manage anymore the text field when a single text is selected

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5000 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2017-08-01 19:37:04 +00:00
parent b9013a8914
commit 86cb13f74d
11 changed files with 126 additions and 542 deletions

View File

@@ -109,31 +109,10 @@ void ElementPrimitiveDecorator::paint(QPainter *painter, const QStyleOptionGraph
/** /**
@param items the new list of items this decorator is suposed to manipulate. @param items the new list of items this decorator is suposed to manipulate.
*/ */
void ElementPrimitiveDecorator::setItems(const QList<CustomElementPart *> &items) { void ElementPrimitiveDecorator::setItems(const QList<CustomElementPart *> &items)
if (CustomElementPart *single_item = singleItem()) { {
if (items.count() == 1 && items.first() == single_item) {
// no actual change
goto end_setItems;
}
// break any connection between the former single selected item (if any) and
// the decorator
single_item -> setDecorator(0);
if (QGraphicsObject *single_object = dynamic_cast<QGraphicsObject *>(single_item)) {
disconnect(single_object, 0, this, 0);
}
}
decorated_items_ = items; decorated_items_ = items;
// when only a single primitive is selected, the decorator behaves specially
// to enable extra features, such as text edition, internal points movements,
// etc.
if (CustomElementPart *single_item = singleItem()) {
single_item -> setDecorator(this);
}
end_setItems:
adjust(); adjust();
show(); show();
if (focusItem() != this) { if (focusItem() != this) {
@@ -224,15 +203,6 @@ void ElementPrimitiveDecorator::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ {
if (internalBoundingRect().contains(pos)) if (internalBoundingRect().contains(pos))
{ {
if (CustomElementPart *single_item = singleItem())
{
bool event_accepted = single_item -> singleItemPressEvent(this, event);
if (event_accepted)
{
event -> ignore();
return;
}
}
current_operation_square_ = QET::MoveArea; current_operation_square_ = QET::MoveArea;
accept = true; accept = true;
} }
@@ -255,21 +225,6 @@ void ElementPrimitiveDecorator::mousePressEvent(QGraphicsSceneMouseEvent *event)
event -> ignore(); event -> ignore();
} }
/**
Handle events generated when mouse buttons are double clicked.
@param event Object describing the mouse event
*/
void ElementPrimitiveDecorator::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
//QGraphicsObject::mouseDoubleClickEvent(event);
if (CustomElementPart *single_item = singleItem()) {
bool event_accepted = single_item -> singleItemDoubleClickEvent(this, event);
if (event_accepted) {
event -> ignore();
return;
}
}
}
/** /**
Handle event generated when the mouse is moved and the decorator is the mouse grabber item. Handle event generated when the mouse is moved and the decorator is the mouse grabber item.
@param event Object describing the mouse event @param event Object describing the mouse event
@@ -320,17 +275,6 @@ void ElementPrimitiveDecorator::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QPointF rounded_current_position = snapConstPointToGrid(current_position); QPointF rounded_current_position = snapConstPointToGrid(current_position);
movement = rounded_current_position - decorated_items_.at(0) -> toItem() -> scenePos(); movement = rounded_current_position - decorated_items_.at(0) -> toItem() -> scenePos();
} }
else {
// Neither a movement nor a scaling operation -- perhaps the underlying item
// is interested in the mouse event for custom operations?
if (CustomElementPart *single_item = singleItem()) {
bool event_accepted = single_item -> singleItemMoveEvent(this, event);
if (event_accepted) {
event -> ignore();
return;
}
}
}
QRectF bounding_rect = modified_bounding_rect_; QRectF bounding_rect = modified_bounding_rect_;
applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_); applyMovementToRect(current_operation_square_, movement, modified_bounding_rect_);
@@ -370,15 +314,7 @@ void ElementPrimitiveDecorator::mouseReleaseEvent(QGraphicsSceneMouseEvent *even
MovePartsCommand *move_command = new MovePartsCommand(movement, 0, graphicsItems()); MovePartsCommand *move_command = new MovePartsCommand(movement, 0, graphicsItems());
command = move_command; command = move_command;
} }
} else { }
if (CustomElementPart *single_item = singleItem()) {
bool event_accepted = single_item -> singleItemReleaseEvent(this, event);
if (event_accepted) {
event -> ignore();
return;
}
}
}
if (command) { if (command) {
emit(actionFinished(command)); emit(actionFinished(command));

View File

@@ -66,7 +66,6 @@ class ElementPrimitiveDecorator : public QGraphicsObject
protected: protected:
void hoverMoveEvent(QGraphicsSceneHoverEvent *); void hoverMoveEvent(QGraphicsSceneHoverEvent *);
void mousePressEvent(QGraphicsSceneMouseEvent *); void mousePressEvent(QGraphicsSceneMouseEvent *);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
void mouseMoveEvent(QGraphicsSceneMouseEvent *); void mouseMoveEvent(QGraphicsSceneMouseEvent *);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *); void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
void keyPressEvent(QKeyEvent *); void keyPressEvent(QKeyEvent *);

View File

@@ -1064,12 +1064,8 @@ void ElementScene::managePrimitivesGroups()
// should we hide the decorator? // should we hide the decorator?
QList<QGraphicsItem *> selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals); QList<QGraphicsItem *> selected_items = zItems(ElementScene::Selected | ElementScene::IncludeTerminals);
if (selected_items.size() == 0) if (selected_items.size() <= 1)
m_decorator -> hide(); m_decorator -> hide();
else if (selected_items.size() == 1 &&
selected_items.first()->type() != PartText::Type &&
selected_items.first()->type() != PartTextField::Type)
m_decorator->hide();
else else
{ {
m_decorator -> setZValue(1000000); m_decorator -> setZValue(1000000);

View File

@@ -44,14 +44,14 @@ class ElementScene : public QGraphicsScene
public: public:
enum Behavior { Normal, PasteArea, AddPart }; enum Behavior { Normal, PasteArea, AddPart };
enum ItemOption { enum ItemOption {
SortByZValue = 1, SortByZValue = 1,
IncludeTerminals = 2, IncludeTerminals = 2,
IncludeHelperItems = 4, IncludeHelperItems = 4,
Selected = 8, Selected = 8,
NonSelected = 16, NonSelected = 16,
SelectedOrNot = 24 SelectedOrNot = 24
}; };
Q_DECLARE_FLAGS(ItemOptions, ItemOption) Q_DECLARE_FLAGS(ItemOptions, ItemOption)
// constructors, destructor // constructors, destructor
public: public:
@@ -168,15 +168,15 @@ class ElementScene : public QGraphicsScene
void stackAction(ElementEditionCommand *); void stackAction(ElementEditionCommand *);
signals: signals:
/// Signal emitted after one or several parts were added /// Signal emitted after one or several parts were added
void partsAdded(); void partsAdded();
/// Signal emitted after one or several parts were removed /// Signal emitted after one or several parts were removed
void partsRemoved(); void partsRemoved();
/// Signal emitted when the zValue of one or several parts change /// Signal emitted when the zValue of one or several parts change
void partsZValueChanged(); void partsZValueChanged();
/// Signal emitted when users have defined the copy/paste area /// Signal emitted when users have defined the copy/paste area
void pasteAreaDefined(const QRectF &); void pasteAreaDefined(const QRectF &);
/// Signal emitted when need zoomFit /// Signal emitted when need zoomFit
void needZoomFit(); void needZoomFit();
}; };

View File

@@ -118,7 +118,7 @@ class CustomElementGraphicPart : public QGraphicsObject, public CustomElementPar
Filling _filling ; Filling _filling ;
Color _color; Color _color;
bool _antialiased; bool _antialiased;
QPointF m_origin_pos, m_mouse_to_origin_pos; QPointF m_origin_pos;
}; };
typedef CustomElementGraphicPart CEGP; typedef CustomElementGraphicPart CEGP;

View File

@@ -49,16 +49,6 @@ QGraphicsItem *CustomElementPart::toItem() {
return(dynamic_cast<QGraphicsItem *>(this)); return(dynamic_cast<QGraphicsItem *>(this));
} }
/**
This method is called by the decorator when it manages only a single
primitive. This brings the possibility to implement custom behaviour, such
as text edition, points edition or specific resizing.
The default implementation does nothing.
*/
void CustomElementPart::setDecorator(ElementPrimitiveDecorator *decorator) {
Q_UNUSED(decorator)
}
/** /**
This method is called by the decorator when it needs to determine the best This method is called by the decorator when it needs to determine the best
way to interactively scale a primitive. It is typically called when only a way to interactively scale a primitive. It is typically called when only a
@@ -70,46 +60,6 @@ QET::ScalingMethod CustomElementPart::preferredScalingMethod() const {
return(QET::SnapScalingPointToGrid); return(QET::SnapScalingPointToGrid);
} }
/**
This method is called by the decorator when it manages only a single
primitive and it received a mouse press event.
The implementation should return true if the primitive accepts the event, false otherwise.
The default implementation returns false.
*/
bool CustomElementPart::singleItemPressEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *) {
return(false);
}
/**
This method is called by the decorator when it manages only a single
primitive and it received a mouse move event.
The implementation should return true if the primitive accepts the event, false otherwise.
The default implementation returns false.
*/
bool CustomElementPart::singleItemMoveEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *) {
return(false);
}
/**
This method is called by the decorator when it manages only a single
primitive and it received a mouse release event.
The implementation should return true if the primitive accepts the event, false otherwise.
The default implementation returns false.
*/
bool CustomElementPart::singleItemReleaseEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *) {
return(false);
}
/**
This method is called by the decorator when it manages only a single
primitive and it received a mouse double click event.
The implementation should return true if the primitive accepts the event, false otherwise.
The default implementation returns false.
*/
bool CustomElementPart::singleItemDoubleClickEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *) {
return(false);
}
/** /**
Helper method to map points in CustomElementPart::handleUserTransformation() Helper method to map points in CustomElementPart::handleUserTransformation()
@param initial_selection_rect Selection rectangle when the movement started, in scene coordinates @param initial_selection_rect Selection rectangle when the movement started, in scene coordinates

View File

@@ -103,12 +103,7 @@ class CustomElementPart {
virtual QGraphicsItem *toItem(); virtual QGraphicsItem *toItem();
virtual void setDecorator(ElementPrimitiveDecorator *);
virtual QET::ScalingMethod preferredScalingMethod() const; virtual QET::ScalingMethod preferredScalingMethod() const;
virtual bool singleItemPressEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemMoveEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemReleaseEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemDoubleClickEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
protected: protected:
QList<QPointF> mapPoints(const QRectF &, const QRectF &, const QList<QPointF> &); QList<QPointF> mapPoints(const QRectF &, const QRectF &, const QList<QPointF> &);

View File

@@ -26,20 +26,17 @@
Constructeur Constructeur
@param editor L'editeur d'element concerne @param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce texte statique @param parent Le QGraphicsItem parent de ce texte statique
@param scene La scene sur laquelle figure ce texte statique
*/ */
PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent, ElementScene *scene) : PartText::PartText(QETElementEditor *editor, QGraphicsItem *parent) :
QGraphicsTextItem(parent), QGraphicsTextItem(parent),
CustomElementPart(editor), CustomElementPart(editor),
previous_text(), previous_text()
decorator_(0)
{ {
Q_UNUSED(scene)
document() -> setDocumentMargin(1.0); document() -> setDocumentMargin(1.0);
setDefaultTextColor(Qt::black); setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont()); setFont(QETApp::diagramTextsFont());
real_font_size_ = font().pointSize(); real_font_size_ = font().pointSize();
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsMovable);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
setDefaultTextColor(Qt::black); setDefaultTextColor(Qt::black);
setPlainText(QObject::tr("T", "default text when adding a text in the element editor")); setPlainText(QObject::tr("T", "default text when adding a text in the element editor"));
@@ -231,150 +228,37 @@ void PartText::handleUserTransformation(const QRectF &initial_selection_rect, co
setProperty("real_size", qMax(1, qRound(new_font_size))); setProperty("real_size", qMax(1, qRound(new_font_size)));
} }
/**
Dessine le texte statique. void PartText::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
@param painter QPainter a utiliser pour effectuer le rendu {
@param qsogi Pptions de dessin if((event->buttons() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable))
@param widget Widget sur lequel on dessine (facultatif) {
*/ QPointF pos = event->scenePos() + (m_origine_pos - event->buttonDownScenePos(Qt::LeftButton));
void PartText::paint(QPainter *painter, const QStyleOptionGraphicsItem *qsogi, QWidget *widget) { event->modifiers() == Qt::ControlModifier ? setPos(pos) : setPos(elementScene()->snapToGrid(pos));
// According to the source code of QGraphicsTextItem::paint(), this should }
// avoid the drawing of the dashed rectangle around the text. else
QStyleOptionGraphicsItem our_qsogi(*qsogi); QGraphicsObject::mouseMoveEvent(event);
our_qsogi.state = QStyle::State_None;
QGraphicsTextItem::paint(painter, &our_qsogi, widget);
#ifdef QET_DEBUG_EDITOR_TEXTS
painter -> setPen(Qt::blue);
painter -> drawRect(boundingRect());
painter -> setPen(Qt::red);
drawPoint(painter, QPointF(0, 0));
painter -> setPen(Qt::green);
drawPoint(painter, mapFromScene(pos()));
#endif
} }
/** void PartText::mousePressEvent(QGraphicsSceneMouseEvent *event)
Handle context menu events. {
@param event Object describing the context menu event to handle. if(event->button() == Qt::LeftButton)
*/ m_origine_pos = this->pos();
void PartText::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
Q_UNUSED(event); QGraphicsObject::mousePressEvent(event);
} }
/** void PartText::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Handle events generated when the mouse hovers over the decorator. {
@param event Object describing the hover event. if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origine_pos != pos())
*/ {
void PartText::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origine_pos), QVariant(pos()));
// force the cursor when the text is being edited undo->setText(tr("Déplacer un texte"));
if (hasFocus() && decorator_) { undo->enableAnimation();
decorator_ -> setCursor(Qt::IBeamCursor); elementScene()->undoStack().push(undo);
} }
QGraphicsTextItem::hoverMoveEvent(event);
}
/** QGraphicsObject::mouseReleaseEvent(event);
@reimp CustomElementPart::setDecorator(ElementPrimitiveDecorator *)
Install or remove a sceneEventFilter on the decorator and ensure it will
adjust itself while the text is being edited.
*/
void PartText::setDecorator(ElementPrimitiveDecorator *decorator) {
if (decorator) {
decorator -> installSceneEventFilter(this);
// ensure the decorator will adjust itself when the text area expands or shrinks
connect(document(), SIGNAL(contentsChanged()), decorator, SLOT(adjust()));
}
else {
decorator_ -> removeSceneEventFilter(this);
endEdition();
}
decorator_ = decorator;
}
/**
@reimp QGraphicsItem::sceneEventFilter(QGraphicsItem *, QEvent *).
Intercepts events before they reach the watched target, i.e. typically the
primitives decorator.
This method mainly works with key strokes (F2, escape) and double clicks to
begin or end text edition.
*/
bool PartText::sceneEventFilter(QGraphicsItem *watched, QEvent *event) {
if (watched != decorator_) return(false);
QPointF event_scene_pos = QET::graphicsSceneEventPos(event);
if (!event_scene_pos.isNull()) {
if (contains(mapFromScene(event_scene_pos))) {
if (hasFocus()) {
return sceneEvent(event); // manually deliver the event to this item
return(true); // prevent this event from being delivered to any item
} else {
if (event -> type() == QEvent::GraphicsSceneMouseDoubleClick) {
mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
}
}
}
}
else if (event -> type() == QEvent::KeyRelease || event -> type() == QEvent::KeyPress) {
// Intercept F2 and escape keystrokes to focus in and out
QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
if (!hasFocus() && key_event -> key() == Qt::Key_F2) {
setEditable(true);
QTextCursor qtc = textCursor();
qtc.setPosition(qMax(0, document()->characterCount() - 1));
setTextCursor(qtc);
} else if (hasFocus() && key_event -> key() == Qt::Key_Escape) {
endEdition();
}
if (hasFocus()) {
sceneEvent(event); // manually deliver the event to this item
return(true); // prevent this event from being delivered to any item
}
}
return(false);
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartText::singleItemPressEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartText::singleItemMoveEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartText::singleItemReleaseEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartText::singleItemDoubleClickEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
// calling mouseDoubleClickEvent() will set this text item editable and grab keyboard focus
if (event -> button() == Qt::LeftButton) {
mouseDoubleClickEvent(event);
return(true);
}
return(false);
} }
/** /**
@@ -442,27 +326,4 @@ void PartText::endEdition()
setTextCursor(qtc); setTextCursor(qtc);
setEditable(false); setEditable(false);
if (decorator_) {
decorator_ -> setFocus();
}
} }
#ifdef QET_DEBUG_EDITOR_TEXTS
/**
Dessine deux petites fleches pour mettre un point en valeur
@param painter QPainter a utiliser pour effectuer le rendu
@param point Point a dessiner
*/
void PartText::drawPoint(QPainter *painter, const QPointF &point) {
qreal px = point.x();
qreal py = point.y();
qreal size_1 = 5.0;
qreal size_2 = 1.0;
painter -> drawLine(QLineF(px, py, px + size_1, py));
painter -> drawLine(QLineF(px + size_1 - size_2, py - size_2, px + size_1, py));
painter -> drawLine(QLineF(px + size_1 - size_2, py + size_2, px + size_1, py));
painter -> drawLine(QLineF(px, py, px, py + size_1));
painter -> drawLine(QLineF(px, py + size_1, px - size_2, py + size_1 - size_2));
painter -> drawLine(QLineF(px, py + size_1, px + size_2, py + size_1 - size_2));
}
#endif

View File

@@ -31,7 +31,7 @@ class PartText : public QGraphicsTextItem, public CustomElementPart {
// constructors, destructor // constructors, destructor
public: public:
PartText(QETElementEditor *, QGraphicsItem * = 0, ElementScene * = 0); PartText(QETElementEditor *, QGraphicsItem * = 0);
virtual ~PartText(); virtual ~PartText();
private: private:
@@ -55,12 +55,6 @@ class PartText : public QGraphicsTextItem, public CustomElementPart {
virtual QRectF sceneGeometricRect() const; virtual QRectF sceneGeometricRect() const;
virtual void startUserTransformation(const QRectF &); virtual void startUserTransformation(const QRectF &);
virtual void handleUserTransformation(const QRectF &, const QRectF &); virtual void handleUserTransformation(const QRectF &, const QRectF &);
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0 );
virtual void setDecorator(ElementPrimitiveDecorator *);
virtual bool singleItemPressEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemMoveEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemReleaseEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemDoubleClickEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
///PROPERTY ///PROPERTY
void setProperty(const char *name, const QVariant &value) {QGraphicsTextItem::setProperty(name, value);} void setProperty(const char *name, const QVariant &value) {QGraphicsTextItem::setProperty(name, value);}
@@ -81,31 +75,29 @@ class PartText : public QGraphicsTextItem, public CustomElementPart {
Q_PROPERTY(QString text READ toPlainText WRITE setPlainText) Q_PROPERTY(QString text READ toPlainText WRITE setPlainText)
public slots: public slots:
void adjustItemPosition(int = 0); void adjustItemPosition(int = 0);
void setEditable(bool); void setEditable(bool);
void startEdition(); void startEdition();
void endEdition(); void endEdition();
protected: protected:
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual bool sceneEventFilter(QGraphicsItem *, QEvent *); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
virtual void focusInEvent(QFocusEvent *); virtual void focusInEvent(QFocusEvent *);
virtual void focusOutEvent(QFocusEvent *); virtual void focusOutEvent(QFocusEvent *);
virtual void keyPressEvent(QKeyEvent *); virtual void keyPressEvent(QKeyEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &); virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const; QRectF boundingRect() const;
private: private:
QPointF margin() const; QPointF margin() const;
#ifdef QET_DEBUG_EDITOR_TEXTS QString previous_text;
void drawPoint(QPainter *, const QPointF &); qreal real_font_size_;
#endif QPointF saved_point_;
QString previous_text; qreal saved_font_size_;
qreal real_font_size_; QGraphicsItem *decorator_;
QPointF saved_point_; QPointF m_origine_pos;
qreal saved_font_size_;
QGraphicsItem *decorator_;
}; };
#endif #endif

View File

@@ -20,26 +20,24 @@
#include "elementprimitivedecorator.h" #include "elementprimitivedecorator.h"
#include "qetapp.h" #include "qetapp.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h" #include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
/** /**
Constructeur Constructeur
@param editor L'editeur d'element concerne @param editor L'editeur d'element concerne
@param parent Le QGraphicsItem parent de ce champ de texte @param parent Le QGraphicsItem parent de ce champ de texte
@param scene La scene sur laquelle figure ce champ de texte
*/ */
PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) : PartTextField::PartTextField(QETElementEditor *editor, QGraphicsItem *parent) :
QGraphicsTextItem(parent), QGraphicsTextItem(parent),
CustomElementPart(editor), CustomElementPart(editor),
follow_parent_rotations(true), follow_parent_rotations(true),
m_tagg("none"), m_tagg("none"),
previous_text(), previous_text()
decorator_(0)
{ {
Q_UNUSED(scene);
setDefaultTextColor(Qt::black); setDefaultTextColor(Qt::black);
setFont(QETApp::diagramTextsFont()); setFont(QETApp::diagramTextsFont());
real_font_size_ = font().pointSize(); real_font_size_ = font().pointSize();
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges); setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsMovable);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
setPlainText(QObject::tr("_", "default text when adding a textfield in the element editor")); setPlainText(QObject::tr("_", "default text when adding a textfield in the element editor"));
@@ -112,73 +110,43 @@ QPointF PartTextField::margin() const {
return(QPointF(0.0, boundingRect().bottom() / 2.0)); return(QPointF(0.0, boundingRect().bottom() / 2.0));
} }
/** void PartTextField::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
Handle context menu events. {
@param event Object describing the context menu event to handle. if((event->buttons() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable))
*/ {
void PartTextField::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QPointF pos = event->scenePos() + (m_origine_pos - event->buttonDownScenePos(Qt::LeftButton));
Q_UNUSED(event); event->modifiers() == Qt::ControlModifier ? setPos(pos) : setPos(elementScene()->snapToGrid(pos));
}
else
QGraphicsObject::mouseMoveEvent(event);
}
void PartTextField::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
m_origine_pos = this->pos();
QGraphicsObject::mousePressEvent(event);
}
void PartTextField::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origine_pos != pos())
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origine_pos), QVariant(pos()));
undo->setText(tr("Déplacer un champ texte"));
undo->enableAnimation();
elementScene()->undoStack().push(undo);
}
QGraphicsObject::mouseReleaseEvent(event);
} }
/** /**
Handle events generated when the mouse hovers over the decorator. * @brief PartTextField::focusInEvent
@param event Object describing the hover event. * @param e The QFocusEvent object describing the focus gain.
*/ Start text edition when the item gains focus.
void PartTextField::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { */
// force the cursor when the text is being edited
if (hasFocus() && decorator_) {
decorator_ -> setCursor(Qt::IBeamCursor);
}
QGraphicsTextItem::hoverMoveEvent(event);
}
/**
@reimp QGraphicsItem::sceneEventFilter(QGraphicsItem *, QEvent *).
Intercepts events before they reach the watched target, i.e. typically the
primitives decorator.
This method mainly works with key strokes (F2, escape) and double clicks to
begin or end text edition.
*/
bool PartTextField::sceneEventFilter(QGraphicsItem *watched, QEvent *event) {
if (watched != decorator_) return(false);
QPointF event_scene_pos = QET::graphicsSceneEventPos(event);
if (!event_scene_pos.isNull()) {
if (contains(mapFromScene(event_scene_pos))) {
if (hasFocus()) {
return sceneEvent(event); // manually deliver the event to this item
return(true); // prevent this event from being delivered to any item
} else {
if (event -> type() == QEvent::GraphicsSceneMouseDoubleClick) {
mouseDoubleClickEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
}
}
}
}
else if (event -> type() == QEvent::KeyRelease || event -> type() == QEvent::KeyPress) {
// Intercept F2 and escape keystrokes to focus in and out
QKeyEvent *key_event = static_cast<QKeyEvent *>(event);
if (!hasFocus() && key_event -> key() == Qt::Key_F2) {
setEditable(true);
QTextCursor qtc = textCursor();
qtc.setPosition(qMax(0, document()->characterCount() - 1));
setTextCursor(qtc);
} else if (hasFocus() && key_event -> key() == Qt::Key_Escape) {
endEdition();
}
if (hasFocus()) {
sceneEvent(event); // manually deliver the event to this item
return(true); // prevent this event from being delivered to any item
}
}
return(false);
}
/*
@reimp QGraphicsItem::focusInEvent(QFocusEvent *)
@param e The QFocusEvent object describing the focus gain.
Start text edition when the item gains focus.
*/
void PartTextField::focusInEvent(QFocusEvent *e) { void PartTextField::focusInEvent(QFocusEvent *e) {
startEdition(); startEdition();
QGraphicsTextItem::focusInEvent(e); QGraphicsTextItem::focusInEvent(e);
@@ -286,88 +254,6 @@ void PartTextField::handleUserTransformation(const QRectF &initial_selection_rec
qreal new_font_size = saved_font_size_ * sy; qreal new_font_size = saved_font_size_ * sy;
setProperty("real_size", qMax(1, qRound(new_font_size))); setProperty("real_size", qMax(1, qRound(new_font_size)));
} }
/**
Dessine le texte statique.
@param painter QPainter a utiliser pour effectuer le rendu
@param qsogi Pptions de dessin
@param widget Widget sur lequel on dessine (facultatif)
*/
void PartTextField::paint(QPainter *painter, const QStyleOptionGraphicsItem *qsogi, QWidget *widget) {
// According to the source code of QGraphicsTextItem::paint(), this should
// avoid the drawing of the dashed rectangle around the text.
QStyleOptionGraphicsItem our_qsogi(*qsogi);
our_qsogi.state = QStyle::State_None;
QGraphicsTextItem::paint(painter, &our_qsogi, widget);
#ifdef QET_DEBUG_EDITOR_TEXTS
painter -> setPen(Qt::blue);
painter -> drawRect(boundingRect());
painter -> setPen(Qt::red);
drawPoint(painter, QPointF(0, 0));
painter -> setPen(QColor("#800000"));
drawPoint(painter, mapFromScene(pos()));
#endif
}
/**
@reimp CustomElementPart::setDecorator(ElementPrimitiveDecorator *)
Install or remove a sceneEventFilter on the decorator and ensure it will
adjust itself while the text is being edited.
*/
void PartTextField::setDecorator(ElementPrimitiveDecorator *decorator) {
if (decorator) {
decorator -> installSceneEventFilter(this);
// ensure the decorator will adjust itself when the text area expands or shrinks
connect(document(), SIGNAL(contentsChanged()), decorator, SLOT(adjust()));
}
else {
decorator_ -> removeSceneEventFilter(this);
endEdition();
}
decorator_ = decorator;
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartTextField::singleItemPressEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartTextField::singleItemMoveEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartTextField::singleItemReleaseEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
Q_UNUSED(event)
return(hasFocus());
}
/**
Accept the mouse \a event relayed by \a decorator if this text item has focus.
*/
bool PartTextField::singleItemDoubleClickEvent(ElementPrimitiveDecorator *decorator, QGraphicsSceneMouseEvent *event) {
Q_UNUSED(decorator)
// calling mouseDoubleClickEvent() will set this text item editable and grab keyboard focus
if (event -> button() == Qt::LeftButton) {
mouseDoubleClickEvent(event);
return(true);
}
return(false);
}
/** /**
Cette methode s'assure que la position du champ de texte est coherente Cette methode s'assure que la position du champ de texte est coherente
@@ -434,27 +320,4 @@ void PartTextField::endEdition()
setTextCursor(qtc); setTextCursor(qtc);
setEditable(false); setEditable(false);
if (decorator_) {
decorator_ -> setFocus();
}
} }
#ifdef QET_DEBUG_EDITOR_TEXTS
/**
Dessine deux petites fleches pour mettre un point en valeur
@param painter QPainter a utiliser pour effectuer le rendu
@param point Point a dessiner
*/
void PartTextField::drawPoint(QPainter *painter, const QPointF &point) {
qreal px = point.x();
qreal py = point.y();
qreal size_1 = 5.0;
qreal size_2 = 1.0;
painter -> drawLine(QLineF(px, py, px + size_1, py));
painter -> drawLine(QLineF(px + size_1 - size_2, py - size_2, px + size_1, py));
painter -> drawLine(QLineF(px + size_1 - size_2, py + size_2, px + size_1, py));
painter -> drawLine(QLineF(px, py, px, py + size_1));
painter -> drawLine(QLineF(px, py + size_1, px - size_2, py + size_1 - size_2));
painter -> drawLine(QLineF(px, py + size_1, px + size_2, py + size_1 - size_2));
}
#endif

View File

@@ -29,12 +29,13 @@ class ElementPrimitiveDecorator;
a default value. The field will remain editable once the element is added onto a default value. The field will remain editable once the element is added onto
a diagram. lorsque l'element sera pose sur un schema. a diagram. lorsque l'element sera pose sur un schema.
*/ */
class PartTextField : public QGraphicsTextItem, public CustomElementPart { class PartTextField : public QGraphicsTextItem, public CustomElementPart
{
Q_OBJECT Q_OBJECT
// constructors, destructor // constructors, destructor
public: public:
PartTextField(QETElementEditor *, QGraphicsItem * = 0, QGraphicsScene * = 0); PartTextField(QETElementEditor *, QGraphicsItem * = 0);
virtual ~PartTextField(); virtual ~PartTextField();
private: private:
@@ -61,12 +62,6 @@ class PartTextField : public QGraphicsTextItem, public CustomElementPart {
virtual QRectF sceneGeometricRect() const; virtual QRectF sceneGeometricRect() const;
virtual void startUserTransformation(const QRectF &); virtual void startUserTransformation(const QRectF &);
virtual void handleUserTransformation(const QRectF &, const QRectF &); virtual void handleUserTransformation(const QRectF &, const QRectF &);
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0 );
virtual void setDecorator(ElementPrimitiveDecorator *);
virtual bool singleItemPressEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemMoveEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemReleaseEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
virtual bool singleItemDoubleClickEvent(ElementPrimitiveDecorator *, QGraphicsSceneMouseEvent *);
///PROPERTY ///PROPERTY
virtual void setProperty(const char *name, const QVariant &value) {QGraphicsTextItem::setProperty(name, value);} virtual void setProperty(const char *name, const QVariant &value) {QGraphicsTextItem::setProperty(name, value);}
@@ -101,26 +96,23 @@ class PartTextField : public QGraphicsTextItem, public CustomElementPart {
void startEdition(); void startEdition();
void endEdition(); void endEdition();
protected: protected:
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual bool sceneEventFilter(QGraphicsItem *, QEvent *); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
virtual void focusInEvent(QFocusEvent *); virtual void focusInEvent(QFocusEvent *);
virtual void focusOutEvent(QFocusEvent *); virtual void focusOutEvent(QFocusEvent *);
virtual void keyPressEvent(QKeyEvent *); virtual void keyPressEvent(QKeyEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual QVariant itemChange(GraphicsItemChange, const QVariant &); virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
QRectF boundingRect() const; QRectF boundingRect() const;
private: private:
QPointF margin() const; QPointF margin() const;
#ifdef QET_DEBUG_EDITOR_TEXTS QString previous_text;
void drawPoint(QPainter *, const QPointF &); qreal real_font_size_;
#endif QPointF saved_point_;
QString previous_text; qreal saved_font_size_;
qreal real_font_size_; QPointF m_origine_pos;
QPointF saved_point_;
qreal saved_font_size_;
QGraphicsItem *decorator_;
}; };
#endif #endif