diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 14c5820ea..07999345d 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -54,6 +54,7 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : QGraphicsView(pare setAttribute(Qt::WA_DeleteOnClose, true); setInteractive(true); current_behavior = noAction; + m_polyline_added = false; QString whatsthis = tr( "Ceci est la zone dans laquelle vous concevez vos sch\351mas en y ajoutant" @@ -448,7 +449,7 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { fresh_focus_in_ = false; } - if (isInteractive() && !scene -> isReadOnly() && e -> buttons() == Qt::LeftButton) { + if (isInteractive() && !scene -> isReadOnly() && e -> button() == Qt::LeftButton) { switch (current_behavior) { case noAction: QGraphicsView::mousePressEvent(e); @@ -473,6 +474,19 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { newShapeItem = new QetShapeItem(rubber_band_origin, rubber_band_origin, QetShapeItem::Ellipse); scene -> addItem(newShapeItem); break; + case addingPolyline: + if (!m_polyline_added) { + setContextMenuPolicy(Qt::NoContextMenu); //< for finish the polyline we must to right click, + // We disable the context menu + newShapeItem = new QetShapeItem(rubber_band_origin, rubber_band_origin, QetShapeItem::Polyline); + scene -> addItem(newShapeItem); + m_polyline_added = true; + } else { + newShapeItem->setNextPoint(Diagram::snapToGrid(rubber_band_origin)); //< this point is ok for pos + newShapeItem->setNextPoint(Diagram::snapToGrid(rubber_band_origin)); //< Add new point for next segment. the pos of this point + // can be changed by calling QetShapItem::setP2() + } + break; case dragView: current_behavior = noAction; QGraphicsView::mousePressEvent(e); @@ -482,13 +496,13 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { break; } } - // workaround for drag view with hold wheel click and drag mouse - // see also mouseMoveEvent() and mouseReleaseEvent() - else if (e -> buttons() == Qt::MidButton) { + + //Start drag view when hold the middle button + else if (e -> button() == Qt::MidButton) { setCursor(Qt::ClosedHandCursor); - center_view_ = mapToScene(this -> viewport() -> rect()).boundingRect().center(); - return; + center_view_ = mapToScene(this -> viewport() -> rect().center()); } + else QGraphicsView::mousePressEvent(e); } @@ -497,15 +511,19 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { * Manage the event move mouse */ void DiagramView::mouseMoveEvent(QMouseEvent *e) { - if ((e -> buttons() & Qt::MidButton) == Qt::MidButton) { + //Drag the view + if (e -> buttons() == Qt::MidButton) { QPointF move = rubber_band_origin - mapToScene(e -> pos()); this -> centerOn(center_view_ + move); - center_view_ = mapToScene(this -> viewport() -> rect()).boundingRect().center(); - return; + center_view_ = mapToScene( this -> viewport() -> rect().center() ); } - else if (e -> buttons() == Qt::LeftButton && current_behavior & addingShape) { + + //Add point P2 to the curent shape + else if ( (e -> buttons() == Qt::LeftButton && current_behavior &addingShape) || + (current_behavior == addingPolyline && m_polyline_added) ) { newShapeItem->setP2(mapToScene(e->pos())); } + else QGraphicsView::mouseMoveEvent(e); } @@ -514,16 +532,28 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e) { * Manage event release click mouse */ void DiagramView::mouseReleaseEvent(QMouseEvent *e) { - if (e -> button() == Qt::MidButton) { - setCursor(Qt::ArrowCursor); - return; - } - else if (current_behavior & addingShape) { + //Stop drag view + if (e -> button() == Qt::MidButton) setCursor(Qt::ArrowCursor); + + // Add shape define by 2 points + else if (current_behavior & adding2PShape) { // place it to the good position with an undo command scene -> undoStack().push(new AddShapeCommand(scene, newShapeItem, rubber_band_origin)); emit(itemAdded()); current_behavior = noAction; } + + // Add polyline shape + else if (e -> button() == Qt::RightButton && current_behavior == addingPolyline) { + newShapeItem->setP2(rubber_band_origin); + scene -> undoStack().push(new AddShapeCommand(scene, newShapeItem, newShapeItem->scenePos())); + emit(itemAdded()); + current_behavior = noAction; + m_polyline_added = false; + setContextMenuPolicy(Qt::DefaultContextMenu); //< the polyline is finish, + // We make context menu available + } + else QGraphicsView::mouseReleaseEvent(e); } @@ -1245,6 +1275,13 @@ void DiagramView::addEllipse() { current_behavior = addingEllipse; } +/** + * @brief DiagramView::addPolyline + */ +void DiagramView::addPolyline() { + current_behavior = addingPolyline; +} + /** * @brief DiagramView::editImage * open edit image dialog if only one image is selected diff --git a/sources/diagramview.h b/sources/diagramview.h index ef339299a..96e40a678 100644 --- a/sources/diagramview.h +++ b/sources/diagramview.h @@ -46,8 +46,10 @@ class DiagramView : public QGraphicsView { addingLine =8, addingRectangle =16, addingEllipse =32, - addingShape =56, - dragView =64}; + adding2PShape =56, + addingPolyline =64, + addingShape =120, + dragView =124}; private: DiagramView(const DiagramView &); @@ -67,6 +69,7 @@ class DiagramView : public QGraphicsView { QImage image_to_add_; QetShapeItem *newShapeItem; QPointF rubber_band_origin; + bool m_polyline_added; // methods public: @@ -88,6 +91,7 @@ class DiagramView : public QGraphicsView { void addLine(); void addRectangle(); void addEllipse(); + void addPolyline(); void editImage(); void editShape(); IndependentTextItem *addDiagramTextAtPos(const QPointF &, const QString &text = 0); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index 7824fa1a0..4072ceb1d 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -348,12 +348,14 @@ void QETDiagramEditor::actions() { QAction *add_line = m_add_item_actions_group.addAction( QET::Icons::PartLine, tr("Ajouter une liaison mecanique") ); QAction *add_rectangle = m_add_item_actions_group.addAction( QET::Icons::PartRectangle, tr("Ajouter une zone rectangle") ); QAction *add_ellipse = m_add_item_actions_group.addAction( QET::Icons::PartEllipse, tr("Ajouter une zone ellipse") ); + QAction *add_polyline = m_add_item_actions_group.addAction( QET::Icons::PartPolygon, tr("Ajouter une zone polyligne") ); connect( add_text, SIGNAL( triggered() ), this, SLOT( slot_addText() ) ); connect( add_image, SIGNAL( triggered() ), this, SLOT( slot_addImage() ) ); connect( add_line, SIGNAL( triggered() ), this, SLOT( slot_addLine() ) ); connect( add_rectangle, SIGNAL( triggered() ), this, SLOT( slot_addRectangle() ) ); connect( add_ellipse, SIGNAL( triggered() ), this, SLOT( slot_addEllipse() ) ); + connect( add_polyline, SIGNAL( triggered() ), this, SLOT( slot_addPolyline() ) ); foreach(QAction *action, m_add_item_actions_group.actions()) action->setCheckable(true); @@ -1557,6 +1559,14 @@ void QETDiagramEditor::slot_addEllipse() { if (DiagramView *dv = currentDiagram()) dv -> addEllipse(); } +/** + * @brief QETDiagramEditor::slot_addPolyline + * add polyline to current diagram + */ +void QETDiagramEditor::slot_addPolyline() { + if (DiagramView *dv = currentDiagram()) dv -> addPolyline(); +} + /** * @brief QETDiagramEditor::slot_editSelection * edit the selected item if he can be edited and if only one item is selected diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index 74b56a384..9139c9c15 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -132,6 +132,7 @@ class QETDiagramEditor : public QETMainWindow { void slot_addLine(); void slot_addRectangle(); void slot_addEllipse(); + void slot_addPolyline(); void slot_editSelection(); void setWindowedMode(); void setTabbedMode(); diff --git a/sources/qetgraphicsitem/qetshapeitem.cpp b/sources/qetgraphicsitem/qetshapeitem.cpp index ddbcf3429..c4f2149c6 100644 --- a/sources/qetgraphicsitem/qetshapeitem.cpp +++ b/sources/qetgraphicsitem/qetshapeitem.cpp @@ -19,6 +19,7 @@ #include "diagramcommands.h" #include "createdxf.h" #include "diagram.h" +#include "qet.h" /** @@ -37,6 +38,7 @@ QetShapeItem::QetShapeItem(QPointF p1, QPointF p2, ShapeType type, QGraphicsItem m_P2 (Diagram::snapToGrid(p2)) { + if (type == Polyline) m_polygon << m_P1 << m_P2; setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); } @@ -57,11 +59,10 @@ void QetShapeItem::setStyle(Qt::PenStyle newStyle) /** * @brief QetShapeItem::scale - * Preview the scale of this item to factor + * Scale this item by (factor / 100 ). * @param factor */ void QetShapeItem::previewScale(int factor) { - setTransformOriginPoint(boundingRect().center()); if (factor >= 1 && factor <= 200) { qreal new_scale = factor; new_scale /= 100; @@ -71,14 +72,34 @@ void QetShapeItem::previewScale(int factor) { /** * @brief QetShapeItem::setP2 - * Set the second point of this item + * Set the second point of this item. + * If this item is a polyline, + * the last point of the polyline is replaced by P2. * @param P2 */ void QetShapeItem::setP2(QPointF P2) { P2 = Diagram::snapToGrid(P2); - if (P2 == m_P2) return; + + if (m_shapeType == Polyline) { + prepareGeometryChange(); + m_polygon.replace(m_polygon.size()-1, P2); + } + else { + if (P2 == m_P2) return; + prepareGeometryChange(); + m_P2 = P2; + } + setTransformOriginPoint(boundingRect().center()); +} + +/** + * @brief QetShapeItem::setNextPoint + * Add a new point to the curent polygon + * @param P the new point. + */ +void QetShapeItem::setNextPoint(QPointF P) { prepareGeometryChange(); - m_P2 = P2; + m_polygon.append(Diagram::snapToGrid(P)); setTransformOriginPoint(boundingRect().center()); } @@ -87,6 +108,9 @@ void QetShapeItem::setP2(QPointF P2) { * @return the bounding rect of this item */ QRectF QetShapeItem::boundingRect() const { + if (m_shapeType == Polyline) + return ( shape().boundingRect()); + QRectF b(m_P1, m_P2); return b.normalized(); } @@ -112,6 +136,9 @@ QPainterPath QetShapeItem::shape() const { case Ellipse: path.addEllipse(boundingRect()); break; + case Polyline: + path.addPolygon(m_polygon); + break; default: Q_ASSERT(false); break; @@ -129,6 +156,7 @@ void QetShapeItem::changeGraphicsItem(const ShapeType &newtype) { if (newtype == m_shapeType) return; prepareGeometryChange(); m_shapeType = newtype; + setTransformOriginPoint(boundingRect().center()); } /** @@ -145,8 +173,6 @@ void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti QPen pen; pen.setStyle(m_shapeStyle); if (isSelected()) pen.setColor(Qt::red); - // Disable Antialiasing - painter -> setRenderHint(QPainter::Antialiasing, false); painter->setPen(pen); // TODO for printing line type on Windows @@ -165,6 +191,9 @@ void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti case Ellipse: painter->drawEllipse(boundingRect()); break; + case Polyline: + painter->drawPolyline(m_polygon); + break; } } @@ -178,10 +207,19 @@ bool QetShapeItem::fromXml(const QDomElement &e) { if (e.tagName() != "shape") return (false); m_shapeStyle = Qt::PenStyle(e.attribute("style","0").toInt()); - m_P1.setX(e.attribute("x1", 0).toDouble()); - m_P1.setY(e.attribute("y1", 0).toDouble()); - m_P2.setX(e.attribute("x2", 0).toDouble()); - m_P2.setY(e.attribute("y2", 0).toDouble()); + + if (e.attribute("type", "0").toInt() != Polyline) { + m_P1.setX(e.attribute("x1", 0).toDouble()); + m_P1.setY(e.attribute("y1", 0).toDouble()); + m_P2.setX(e.attribute("x2", 0).toDouble()); + m_P2.setY(e.attribute("y2", 0).toDouble()); + } + + else { + foreach(QDomElement de, QET::findInDomElement(e, "points", "point")) { + m_polygon << QPointF(de.attribute("x", 0).toDouble(), de.attribute("y", 0).toDouble()); + } + } changeGraphicsItem(QetShapeItem::ShapeType(e.attribute("type","0").toInt())); return (true); @@ -199,10 +237,25 @@ QDomElement QetShapeItem::toXml(QDomDocument &document) const { //write some attribute result.setAttribute("type", QString::number(m_shapeType)); result.setAttribute("style", QString::number(m_shapeStyle)); - result.setAttribute("x1", mapToScene(m_P1).x()); - result.setAttribute("y1", mapToScene(m_P1).y()); - result.setAttribute("x2", mapToScene(m_P2).x()); - result.setAttribute("y2", mapToScene(m_P2).y()); + + if (m_shapeType != Polyline) { + result.setAttribute("x1", mapToScene(m_P1).x()); + result.setAttribute("y1", mapToScene(m_P1).y()); + result.setAttribute("x2", mapToScene(m_P2).x()); + result.setAttribute("y2", mapToScene(m_P2).y()); + } + + else { + QDomElement points = document.createElement("points"); + foreach(QPointF p, m_polygon) { + QDomElement point = document.createElement("point"); + QPointF pf = mapToScene(p); + point.setAttribute("x", pf.x()); + point.setAttribute("y", pf.y()); + points.appendChild(point); + } + result.appendChild(points); + } return(result); } diff --git a/sources/qetgraphicsitem/qetshapeitem.h b/sources/qetgraphicsitem/qetshapeitem.h index 29b62da86..ee6e517cb 100644 --- a/sources/qetgraphicsitem/qetshapeitem.h +++ b/sources/qetgraphicsitem/qetshapeitem.h @@ -33,7 +33,8 @@ class QetShapeItem : public QetGraphicsItem Q_ENUMS(ShapeType) enum ShapeType {Line =0, Rectangle =1, - Ellipse =2}; + Ellipse =2, + Polyline =3 }; enum { Type = UserType + 1008 }; @@ -55,7 +56,8 @@ class QetShapeItem : public QetGraphicsItem virtual void editProperty(); - void setP2(QPointF P2); + void setP2 (QPointF P2); + void setNextPoint (QPointF P); QRectF boundingRect() const; QPainterPath shape() const; @@ -74,5 +76,6 @@ class QetShapeItem : public QetGraphicsItem ShapeType m_shapeType; Qt::PenStyle m_shapeStyle; QPointF m_P1, m_P2; + QPolygonF m_polygon; }; #endif // QETSHAPEITEM_H