Merge commits "r4999, r500, r5001" to branch 0.60

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/branches/0.60@5033 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
scorpio810
2017-08-27 13:55:10 +00:00
parent fad7ba8347
commit 9b4b317d7f
39 changed files with 2571 additions and 1862 deletions

View File

@@ -78,17 +78,16 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
terminal1(p1),
terminal2(p2),
m_mouse_over(false),
m_handler(10),
m_text_item(0),
segments(NULL),
moving_segment(false),
m_moving_segment(false),
modified_path(false),
has_to_save_profile(false),
must_highlight_(Conductor::None)
{
//set Zvalue at 11 to be upper than the DiagramImageItem and element
setZValue(11);
previous_z_value = zValue();
m_previous_z_value = zValue();
//Add this conductor to the list of conductor of each of the two terminal
bool ajout_p1 = terminal1 -> addConductor(this);
@@ -117,7 +116,7 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
//Generate the path of this conductor.
generateConductorPath(terminal1 -> dockConductor(), terminal1 -> orientation(), terminal2 -> dockConductor(), terminal2 -> orientation());
setFlags(QGraphicsItem::ItemIsSelectable);
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsScenePositionChanges);
setAcceptHoverEvents(true);
// Add the text field
@@ -137,6 +136,7 @@ Conductor::Conductor(Terminal *p1, Terminal* p2) :
*/
Conductor::~Conductor()
{
removeHandler();
terminal1->removeConductor(this);
terminal2->removeConductor(this);
deleteSegments();
@@ -171,30 +171,39 @@ void Conductor::updatePath(const QRectF &rect) {
}
/**
Genere le QPainterPath a partir de la liste des points
*/
void Conductor::segmentsToPath() {
// chemin qui sera dessine
* @brief Conductor::segmentsToPath
* Generate the QPainterPath from the list of points
*/
void Conductor::segmentsToPath()
{
QPainterPath path;
// s'il n'y a pa des segments, on arrete la
if (segments == NULL) setPath(path);
if (segments == NULL)
setPath(path);
// demarre le chemin
//Start the path
path.moveTo(segments -> firstPoint());
// parcourt les segments pour dessiner le chemin
//Each segments
ConductorSegment *segment = segments;
while(segment -> hasNextSegment()) {
path.lineTo(segment -> secondPoint());
segment = segment -> nextSegment();
}
// termine le chemin
//Finish the path
path.lineTo(segment -> secondPoint());
// affecte le chemin au conducteur
setPath(path);
//If conductor is selected and he's not being modified
//we update the position of the handlers
if (isSelected() && !m_moving_segment)
{
if(handlerPoints().size() == m_handler_vector.size())
adjusteHandlerPos();
else
removeHandler();
addHandler();
}
}
/**
@@ -467,7 +476,7 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
qp -> save();
qp -> setRenderHint(QPainter::Antialiasing, false);
// determine la couleur du conducteur
// Set the color of conductor
QColor final_conductor_color(m_properties.color);
if (must_highlight_ == Normal) {
final_conductor_color = QColor::fromRgb(69, 137, 255, 255);
@@ -486,24 +495,38 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
//Draw the conductor bigger when is hovered
conductor_pen.setWidthF(m_mouse_over? (m_properties.cond_size) +4 : (m_properties.cond_size));
// affectation du QPen et de la QBrush modifies au QPainter
//Set the QPen and QBrush to the QPainter
qp -> setBrush(conductor_brush);
QPen final_conductor_pen = conductor_pen;
// modification du QPen generique pour lui affecter la couleur et le style adequats
//Set the conductor style
final_conductor_pen.setColor(final_conductor_color);
final_conductor_pen.setStyle(m_properties.style);
final_conductor_pen.setJoinStyle(Qt::SvgMiterJoin); // meilleur rendu des pointilles
final_conductor_pen.setJoinStyle(Qt::SvgMiterJoin); // better rendering with dot
// utilisation d'un trait "cosmetique" en-dessous d'un certain zoom
//Use a cosmetique line, below a certain zoom
if (options && options -> levelOfDetail < 1.0) {
final_conductor_pen.setCosmetic(true);
}
qp -> setPen(final_conductor_pen);
// dessin du conducteur
//Draw the conductor
qp -> drawPath(path());
//Draw the second color
if(m_properties.m_bicolor)
{
final_conductor_pen.setColor(m_properties.m_color_2);
final_conductor_pen.setStyle(Qt::CustomDashLine);
QVector<qreal> dash_pattern;
dash_pattern << m_properties.m_dash_size-2 << m_properties.m_dash_size;
final_conductor_pen.setDashPattern(dash_pattern);
qp->save();
qp->setPen(final_conductor_pen);
qp->drawPath(path());
qp->restore();
}
if (m_properties.type == ConductorProperties::Single) {
qp -> setBrush(final_conductor_color);
m_properties.singleLineProperties.draw(
@@ -514,11 +537,7 @@ void Conductor::paint(QPainter *qp, const QStyleOptionGraphicsItem *options, QWi
if (isSelected()) qp -> setBrush(Qt::NoBrush);
}
//Draw the squares used to modify the path of conductor when he is selected
if (isSelected())
m_handler.drawHandler(qp, handlerPoints());
// dessine les eventuelles jonctions
//Draw the junctions
QList<QPointF> junctions_list = junctions();
if (!junctions_list.isEmpty()) {
final_conductor_pen.setStyle(Qt::SolidLine);
@@ -587,70 +606,18 @@ void Conductor::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
*/
void Conductor::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
//Left clic
if (event->buttons() & Qt::LeftButton)
{
//If user click on a handler (square used to modify the path of conductor),
//we get the segment corresponding to the handler
int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
if (index > -1)
{
moving_segment = true;
moved_segment = segmentsList().at(index+1);
before_mov_text_pos_ = m_text_item -> pos();
}
}
QGraphicsPathItem::mousePressEvent(event);
if (event -> modifiers() & Qt::ControlModifier)
if (event->modifiers() & Qt::ControlModifier)
setSelected(!isSelected());
}
/**
* @brief Conductor::mouseMoveEvent
* Manage the mouse move event
* @param event
*/
void Conductor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
//Left clic
if ((event->buttons() & Qt::LeftButton) && moving_segment)
{
//Snap the mouse pos to grid
QPointF pos_ = Diagram::snapToGrid(event->pos());
//Position of the last point
QPointF p = moved_segment -> middle();
//Calcul the movement
moved_segment -> moveX(pos_.x() - p.x());
moved_segment -> moveY(pos_.y() - p.y());
//Apply the movement
modified_path = true;
has_to_save_profile = true;
segmentsToPath();
calculateTextItemPosition();
}
QGraphicsPathItem::mouseMoveEvent(event);
}
/**
* @brief Conductor::mouseReleaseEvent
* Manage the mouse release event
* @param event
*/
void Conductor::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
moving_segment = false;
if (has_to_save_profile)
{
saveProfile();
has_to_save_profile = false;
}
if (!(event -> modifiers() & Qt::ControlModifier))
QGraphicsPathItem::mouseReleaseEvent(event);
}
@@ -678,56 +645,209 @@ void Conductor::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
}
/**
* @brief Conductor::hoverMoveEvent conductor
* @param e QGraphicsSceneHoverEvent describing the event
* @brief Conductor::itemChange
* @param change
* @param value
* @return
*/
void Conductor::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (isSelected())
if (change == QGraphicsItem::ItemSelectedChange)
{
//If user hover an handler (square used to modify the path of conductor),
//we get the segment corresponding to the handler
int index = m_handler.pointIsHoverHandler(event->pos(), handlerPoints());
if (index > -1)
if (value.toBool())
{
ConductorSegment *segment_ = segmentsList().at(index+1);
if (m_handler.pointIsInHandler(event->pos(), segment_->secondPoint()))
setCursor(Qt::ForbiddenCursor);
else if (m_handler.pointIsInHandler(event->pos(), segment_->middle()))
setCursor(segmentsList().at(index+1)->isVertical() ? Qt::SplitHCursor : Qt::SplitVCursor);
m_previous_z_value = zValue();
setZValue(qAbs(m_previous_z_value) + 10000);
addHandler();
}
else
setCursor(Qt::ArrowCursor);
{
setZValue(m_previous_z_value);
removeHandler();
}
}
QGraphicsPathItem::hoverMoveEvent(event);
else if (change == QGraphicsItem::ItemSceneHasChanged)
{
calculateTextItemPosition();
if(!scene())
removeHandler();
else if (scene() && isSelected())
addHandler();
}
else if (change == QGraphicsItem::ItemVisibleHasChanged) {
calculateTextItemPosition();
}
else if (change == QGraphicsItem::ItemPositionHasChanged && isSelected()) {
adjusteHandlerPos();
}
return(QGraphicsPathItem::itemChange(change, value));
}
/**
Gere les changements relatifs au conducteur
Reimplemente ici pour :
* positionner le conducteur en avant-plan lorsqu'il est selectionne
@param change Type de changement
@param value Valeur relative au changement
*/
QVariant Conductor::itemChange(GraphicsItemChange change, const QVariant &value) {
if (change == QGraphicsItem::ItemSelectedChange) {
if (value.toBool()) {
// le conducteur vient de se faire selectionner
previous_z_value = zValue();
setZValue(qAbs(previous_z_value) + 10000);
} else {
// le conducteur vient de se faire deselectionner
setZValue(previous_z_value);
* @brief Conductor::sceneEventFilter
* @param watched
* @param event
* @return
*/
bool Conductor::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
//Watched must be an handler
if(watched->type() == QetGraphicsHandlerItem::Type)
{
QetGraphicsHandlerItem *qghi = qgraphicsitem_cast<QetGraphicsHandlerItem *>(watched);
if(m_handler_vector.contains(qghi)) //Handler must be in m_vector_index, then we can start resize
{
m_vector_index = m_handler_vector.indexOf(qghi);
if (m_vector_index != -1)
{
if(event->type() == QEvent::GraphicsSceneMousePress) //Click
{
handlerMousePressEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
{
handlerMouseMoveEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
{
handlerMouseReleaseEvent(qghi, static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
}
}
} else if (change == QGraphicsItem::ItemSceneHasChanged) {
// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
calculateTextItemPosition();
} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
// permet de positionner correctement le texte du conducteur lors de son ajout a un schema
calculateTextItemPosition();
}
return(QGraphicsPathItem::itemChange(change, value));
return false;
}
/**
* @brief Conductor::adjusteHandlerPos
* Adjust the position of the handler item
*/
void Conductor::adjusteHandlerPos()
{
if (m_handler_vector.isEmpty())
return;
if (m_handler_vector.size() == handlerPoints().size())
{
QVector <QPointF> points_vector = mapToScene(handlerPoints());
for (int i = 0 ; i < points_vector.size() ; ++i)
m_handler_vector.at(i)->setPos(points_vector.at(i));
}
}
/**
* @brief Conductor::handlerMousePressEvent
* @param qghi
* @param event
*/
void Conductor::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event);
//we get the segment corresponding to the handler
if (m_vector_index > -1)
{
qghi->setColor(Qt::cyan);
m_moving_segment = true;
m_moved_segment = segmentsList().at(m_vector_index+1);
before_mov_text_pos_ = m_text_item -> pos();
for(QetGraphicsHandlerItem *handler : m_handler_vector)
if(handler != qghi)
handler->hide();
}
}
/**
* @brief Conductor::handlerMouseMoveEvent
* @param qghi
* @param event
*/
void Conductor::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
if (m_moving_segment)
{
//Snap the mouse pos to grid
QPointF pos_ = Diagram::snapToGrid(mapFromItem(qghi, event->pos()));
//Position of the last point
QPointF p = m_moved_segment -> middle();
//Calcul the movement
m_moved_segment -> moveX(pos_.x() - p.x());
m_moved_segment -> moveY(pos_.y() - p.y());
//Apply the movement
modified_path = true;
has_to_save_profile = true;
segmentsToPath();
calculateTextItemPosition();
qghi->setPos(mapToScene(m_moved_segment->middle()));
}
}
/**
* @brief Conductor::handlerMouseReleaseEvent
* @param qghi
* @param event
*/
void Conductor::handlerMouseReleaseEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event);
Q_UNUSED(qghi);
m_vector_index = -1;
m_moving_segment = false;
if (has_to_save_profile)
{
saveProfile();
has_to_save_profile = false;
}
//When handler is released, the conductor can have more segment than befor the handler was moved
//then we remove all handles and new ones are added
removeHandler();
addHandler();
}
/**
* @brief Conductor::addHandler
* Add handlers for this item
*/
void Conductor::addHandler()
{
if (m_handler_vector.isEmpty() && scene())
{
m_handler_vector = QetGraphicsHandlerItem::handlerForPoint(mapToScene(handlerPoints()));
for(QetGraphicsHandlerItem *handler : m_handler_vector)
{
handler->setColor(Qt::blue);
scene()->addItem(handler);
handler->installSceneEventFilter(this);
handler->setZValue(this->zValue()+1);
}
}
}
/**
* @brief Conductor::removeHandler
* Remove the handlers of this item
*/
void Conductor::removeHandler()
{
if (!m_handler_vector.isEmpty())
{
qDeleteAll(m_handler_vector);
m_handler_vector.clear();
}
}
/**
@@ -752,23 +872,7 @@ QPainterPath Conductor::shape() const
pps.setJoinStyle(conductor_pen.joinStyle());
QPainterPath shape_(pps.createStroke(path()));
/**
Add handle rect to path, occur a weird bug.
when the conductor is removed from the scene he continue to be painted in the scene and make artefact.
If we save (exactly when we clear the undo stack of project when saving), Qet crash,
Don't add the handle rect to the path seem to work well.
More information here :
https://qelectrotech.org/bugtracker/view.php?id=107
https://qelectrotech.org/forum/viewtopic.php?pid=5619#p5619
https://qelectrotech.org/forum/viewtopic.php?pid=5067#p5067
**/
// if (isSelected()) {
// foreach (QRectF rect, m_handler.handlerRect(handlerPoints())) {
// shape_.addRect(rect);
// }
// }
return shape_;
}