2018-07-19 14:14:31 +00:00
/*
2020-06-15 17:42:37 +02:00
Copyright 2006 - 2020 The QElectroTech Team
2007-12-01 10:47:15 +00:00
This file is part of QElectroTech .
QElectroTech is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
QElectroTech is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with QElectroTech . If not , see < http : //www.gnu.org/licenses/>.
*/
2006-10-27 15:47:22 +00:00
# include <math.h>
2013-11-14 10:11:22 +00:00
# include "qetgraphicsitem/conductor.h"
# include "qetgraphicsitem/conductortextitem.h"
2013-12-20 20:30:55 +00:00
# include "factory/elementfactory.h"
2007-01-29 00:41:12 +00:00
# include "diagram.h"
2007-09-26 17:14:09 +00:00
# include "diagramcommands.h"
2007-11-09 13:06:51 +00:00
# include "diagramcontent.h"
2009-05-20 21:29:17 +00:00
# include "diagramposition.h"
2010-04-18 17:59:54 +00:00
# include "exportdialog.h"
2013-11-14 10:11:22 +00:00
# include "qetgraphicsitem/independenttextitem.h"
# include "qetgraphicsitem/diagramimageitem.h"
2014-02-28 14:30:59 +00:00
# include "qetgraphicsitem/qetshapeitem.h"
2014-07-21 20:44:32 +00:00
# include "terminal.h"
2015-03-04 21:13:13 +00:00
# include "diagrameventinterface.h"
2016-07-18 17:37:02 +00:00
# include "qetapp.h"
# include "elementcollectionhandler.h"
2016-07-20 15:07:21 +00:00
# include "element.h"
2016-07-26 18:52:49 +00:00
# include "diagramview.h"
2017-08-03 17:36:08 +00:00
# include "dynamicelementtextitem.h"
2017-12-05 20:51:54 +00:00
# include "elementtextitemgroup.h"
# include "undocommand/addelementtextcommand.h"
2018-06-17 18:21:56 +00:00
# include "QPropertyUndoCommand/qpropertyundocommand.h"
2020-04-17 18:40:28 +02:00
# include "qetgraphicstableitem.h"
# include "qetxml.h"
# include "elementprovider.h"
2020-06-14 16:22:23 +02:00
# include <cassert>
2006-10-27 15:47:22 +00:00
2019-02-21 00:02:49 +00:00
int Diagram : : xGrid = 10 ;
int Diagram : : yGrid = 10 ;
int Diagram : : xKeyGrid = 10 ;
int Diagram : : yKeyGrid = 10 ;
2019-02-24 15:44:47 +00:00
int Diagram : : xKeyGridFine = 1 ;
int Diagram : : yKeyGridFine = 1 ;
2007-10-10 22:35:32 +00:00
const qreal Diagram : : margin = 5.0 ;
2013-12-26 17:59:58 +00:00
// static variable to keep track of present background color of the diagram.
QColor Diagram : : background_color = Qt : : white ;
2014-12-21 12:50:26 +00:00
2006-10-27 15:47:22 +00:00
/**
2020-08-02 15:09:21 +02:00
@ brief Diagram : : Diagram
Constructor
@ param project : The project of this diagram and also parent QObject
*/
2014-12-21 12:50:26 +00:00
Diagram : : Diagram ( QETProject * project ) :
QGraphicsScene ( project ) ,
2020-07-06 21:52:14 +02:00
m_project ( project ) ,
2014-12-21 12:50:26 +00:00
diagram_qet_version_ ( - 1 ) ,
draw_grid_ ( true ) ,
use_border_ ( true ) ,
draw_terminals_ ( true ) ,
2015-03-04 21:13:13 +00:00
draw_colored_conductors_ ( true ) ,
2016-07-20 15:07:21 +00:00
m_event_interface ( nullptr ) ,
2016-12-10 12:00:52 +00:00
m_freeze_new_elements ( false ) ,
2016-09-01 19:41:49 +00:00
m_freeze_new_conductors_ ( false )
2007-10-11 12:51:56 +00:00
{
2017-10-09 16:05:19 +00:00
setItemIndexMethod ( QGraphicsScene : : NoIndex ) ;
2020-08-02 15:09:21 +02:00
/* Set to no index,
* because they can be the source of the crash with conductor and shape ghost .
* https : //forum.qt.io/topic/71316/qgraphicsscenefinditembsptreevisitor-visit-crashes-due-to-an-obsolete-paintevent-after-qgraphicsscene-removeitem
* https : //stackoverflow.com/questions/38458830/crash-after-qgraphicssceneremoveitem-with-custom-item-class
* http : //www.qtcentre.org/archive/index.php/t-33730.html
* http : //tech-artists.org/t/qt-properly-removing-qgraphicitems/3063
*/
2020-07-06 21:52:14 +02:00
2012-11-09 21:09:24 +00:00
qgi_manager_ = new QGIManager ( this ) ;
2006-10-27 15:47:22 +00:00
setBackgroundBrush ( Qt : : white ) ;
2017-08-05 02:06:59 +00:00
conductor_setter_ = new QGraphicsLineItem ( nullptr ) ;
2012-11-09 21:09:24 +00:00
conductor_setter_ - > setZValue ( 1000000 ) ;
2015-03-04 21:13:13 +00:00
2015-03-02 20:14:56 +00:00
QPen pen ( Qt : : NoBrush , 1.5 , Qt : : DashLine ) ;
pen . setColor ( Qt : : black ) ;
conductor_setter_ - > setPen ( pen ) ;
2014-10-25 21:21:52 +00:00
2014-12-21 12:50:26 +00:00
connect ( & border_and_titleblock , SIGNAL ( needTitleBlockTemplate ( const QString & ) ) , this , SLOT ( setTitleBlockTemplate ( const QString & ) ) ) ;
connect ( & border_and_titleblock , SIGNAL ( diagramTitleChanged ( const QString & ) ) , this , SLOT ( titleChanged ( const QString & ) ) ) ;
2016-08-21 19:37:32 +00:00
connect ( & border_and_titleblock , SIGNAL ( titleBlockFolioChanged ( const QString & ) ) , this , SLOT ( titleChanged ( const QString & ) ) ) ;
2015-03-30 15:58:16 +00:00
connect ( & border_and_titleblock , SIGNAL ( borderChanged ( QRectF , QRectF ) ) , this , SLOT ( adjustSceneRect ( ) ) ) ;
2016-08-21 19:37:32 +00:00
connect ( & border_and_titleblock , SIGNAL ( titleBlockFolioChanged ( const QString & ) ) , this , SLOT ( updateLabels ( ) ) ) ;
2016-07-26 18:52:49 +00:00
connect ( this , SIGNAL ( diagramActivated ( ) ) , this , SLOT ( loadElmtFolioSeq ( ) ) ) ;
2016-08-29 15:37:42 +00:00
connect ( this , SIGNAL ( diagramActivated ( ) ) , this , SLOT ( loadCndFolioSeq ( ) ) ) ;
2015-03-30 15:58:16 +00:00
adjustSceneRect ( ) ;
2006-10-27 15:47:22 +00:00
}
2007-04-12 03:13:13 +00:00
/**
2014-04-20 23:37:03 +00:00
* @ brief Diagram : : ~ Diagram
* Destructor
*/
2017-08-03 17:36:08 +00:00
Diagram : : ~ Diagram ( )
{
//First clear every selection to close an hypothetical editor
clearSelection ( ) ;
// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
2014-01-05 15:00:46 +00:00
undoStack ( ) . clear ( ) ;
2017-08-03 17:36:08 +00:00
//delete of QGIManager, every elements he knows are removed
2012-11-09 21:09:24 +00:00
delete qgi_manager_ ;
2017-08-03 17:36:08 +00:00
// remove of conductor setter
2013-09-17 20:14:30 +00:00
delete conductor_setter_ ;
2015-03-04 21:13:13 +00:00
2017-08-03 17:36:08 +00:00
if ( m_event_interface )
delete m_event_interface ;
2010-05-08 21:24:43 +00:00
2017-08-03 17:36:08 +00:00
// list removable items
2008-07-17 22:57:50 +00:00
QList < QGraphicsItem * > deletable_items ;
2017-07-20 12:40:30 +00:00
for ( QGraphicsItem * qgi : items ( ) )
2017-08-03 17:36:08 +00:00
{
if ( qgi - > parentItem ( ) ) continue ;
if ( qgraphicsitem_cast < Conductor * > ( qgi ) ) continue ;
2008-07-17 22:57:50 +00:00
deletable_items < < qgi ;
}
2014-04-20 23:37:03 +00:00
qDeleteAll ( deletable_items ) ;
2007-09-29 12:54:01 +00:00
}
2007-04-12 03:13:13 +00:00
2006-10-27 15:47:22 +00:00
/**
Dessine l ' arriere - plan du schema , cad la grille .
@ param p Le QPainter a utiliser pour dessiner
@ param r Le rectangle de la zone a dessiner
*/
2007-01-29 00:41:12 +00:00
void Diagram : : drawBackground ( QPainter * p , const QRectF & r ) {
2006-10-27 15:47:22 +00:00
p - > save ( ) ;
2007-02-01 01:07:26 +00:00
// desactive tout antialiasing, sauf pour le texte
2006-10-27 15:47:22 +00:00
p - > setRenderHint ( QPainter : : Antialiasing , false ) ;
2007-02-01 01:07:26 +00:00
p - > setRenderHint ( QPainter : : TextAntialiasing , true ) ;
2006-10-27 15:47:22 +00:00
p - > setRenderHint ( QPainter : : SmoothPixmapTransform , false ) ;
// dessine un fond blanc
p - > setPen ( Qt : : NoPen ) ;
2013-12-26 17:59:58 +00:00
//set brush color to present background color.
p - > setBrush ( Diagram : : background_color ) ;
2006-10-27 15:47:22 +00:00
p - > drawRect ( r ) ;
2012-11-09 21:09:24 +00:00
if ( draw_grid_ ) {
2015-03-02 20:14:56 +00:00
//Draw the point of the grid
// if background color is black, then grid spots shall be white, else they shall be black in color.
QPen pen ;
Diagram : : background_color = = Qt : : black ? pen . setColor ( Qt : : white ) : pen . setColor ( Qt : : black ) ;
pen . setCosmetic ( true ) ;
p - > setPen ( pen ) ;
2006-10-27 15:47:22 +00:00
p - > setBrush ( Qt : : NoBrush ) ;
2015-03-24 23:10:15 +00:00
2015-03-29 12:15:25 +00:00
//If user allow zoom out beyond of folio, we draw grid outside of border.
2015-09-16 15:11:13 +00:00
QSettings settings ;
2019-03-04 08:55:06 +00:00
int xGrid = settings . value ( " diagrameditor/Xgrid " , Diagram : : xGrid ) . toInt ( ) ;
int yGrid = settings . value ( " diagrameditor/Ygrid " , Diagram : : yGrid ) . toInt ( ) ;
2015-09-16 15:11:13 +00:00
QRectF rect = settings . value ( " diagrameditor/zoom-out-beyond-of-folio " , false ) . toBool ( ) ?
2015-03-24 23:10:15 +00:00
r :
border_and_titleblock . insideBorderRect ( ) . intersected ( r ) ;
2015-03-14 21:40:44 +00:00
qreal limite_x = rect . x ( ) + rect . width ( ) ;
qreal limite_y = rect . y ( ) + rect . height ( ) ;
2006-10-27 15:47:22 +00:00
2018-07-30 15:24:29 +00:00
int g_x = ( int ) ceil ( rect . x ( ) ) ;
2007-10-10 22:35:32 +00:00
while ( g_x % xGrid ) + + g_x ;
2018-07-30 15:24:29 +00:00
int g_y = ( int ) ceil ( rect . y ( ) ) ;
2007-10-10 22:35:32 +00:00
while ( g_y % yGrid ) + + g_y ;
2006-10-27 15:47:22 +00:00
2010-01-10 20:22:52 +00:00
QPolygon points ;
2007-10-10 22:35:32 +00:00
for ( int gx = g_x ; gx < limite_x ; gx + = xGrid ) {
for ( int gy = g_y ; gy < limite_y ; gy + = yGrid ) {
2010-01-10 20:22:52 +00:00
points < < QPoint ( gx , gy ) ;
2006-10-27 15:47:22 +00:00
}
}
2010-01-10 20:22:52 +00:00
p - > drawPoints ( points ) ;
2006-10-27 15:47:22 +00:00
}
2007-01-28 00:53:17 +00:00
2015-03-16 13:29:27 +00:00
if ( use_border_ ) border_and_titleblock . draw ( p ) ;
2006-10-27 15:47:22 +00:00
p - > restore ( ) ;
}
2007-09-15 23:45:27 +00:00
/**
2015-03-04 21:13:13 +00:00
* @ brief Diagram : : mouseDoubleClickEvent
* This event is managed by diagram event interface if any .
* @ param event :
*/
void Diagram : : mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * event )
{
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > mouseDoubleClickEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2015-03-04 21:13:13 +00:00
QGraphicsScene : : mouseDoubleClickEvent ( event ) ;
}
/**
* @ brief Diagram : : mousePressEvent
* This event is managed by diagram event interface if any .
* @ param event
*/
void Diagram : : mousePressEvent ( QGraphicsSceneMouseEvent * event )
{
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > mousePressEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2015-03-04 21:13:13 +00:00
QGraphicsScene : : mousePressEvent ( event ) ;
}
/**
* @ brief Diagram : : mouseMoveEvent
* This event is managed by diagram event interface if any .
* @ param event
*/
void Diagram : : mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
{
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > mouseMoveEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2015-03-04 21:13:13 +00:00
QGraphicsScene : : mouseMoveEvent ( event ) ;
}
/**
* @ brief Diagram : : mouseReleaseEvent
* This event is managed by diagram event interface if any .
* @ param event
*/
void Diagram : : mouseReleaseEvent ( QGraphicsSceneMouseEvent * event )
{
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > mouseReleaseEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2015-03-04 21:13:13 +00:00
QGraphicsScene : : mouseReleaseEvent ( event ) ;
}
/**
* @ brief Diagram : : wheelEvent
* This event is managed by diagram event interface if any .
* @ param event
*/
void Diagram : : wheelEvent ( QGraphicsSceneWheelEvent * event )
{
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > wheelEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2015-11-09 20:20:11 +00:00
QGraphicsScene : : wheelEvent ( event ) ;
2015-03-04 21:13:13 +00:00
}
/**
* @ brief Diagram : : keyPressEvent
* This event is managed by diagram event interface if any .
* Else move selected elements
* @ param e
*/
2017-12-05 20:51:54 +00:00
void Diagram : : keyPressEvent ( QKeyEvent * event )
2015-03-04 21:13:13 +00:00
{
2019-02-21 00:02:49 +00:00
QSettings settings ;
2019-03-04 08:55:06 +00:00
int xKeyGrid = settings . value ( " diagrameditor/key_Xgrid " , Diagram : : xKeyGrid ) . toInt ( ) ;
int yKeyGrid = settings . value ( " diagrameditor/key_Ygrid " , Diagram : : yKeyGrid ) . toInt ( ) ;
2019-03-05 13:48:47 +00:00
int xKeyGridFine = settings . value ( " diagrameditor/key_fine_Xgrid " , Diagram : : xKeyGridFine ) . toInt ( ) ;
2019-03-04 08:55:06 +00:00
int yKeyGridFine = settings . value ( " diagrameditor/key_fine_Ygrid " , Diagram : : yKeyGridFine ) . toInt ( ) ;
2019-01-14 18:25:43 +00:00
event - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > keyPressEvent ( event ) ;
if ( event - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2017-12-05 20:51:54 +00:00
if ( ! isReadOnly ( ) )
{
2009-04-03 19:30:25 +00:00
QPointF movement ;
2016-06-09 20:46:27 +00:00
qreal top_position = 0 ;
qreal left_position = 0 ;
2017-12-05 20:51:54 +00:00
DiagramContent dc ( this ) ;
if ( ! dc . items ( DiagramContent : : All ) . isEmpty ( ) )
{
2019-02-21 00:02:49 +00:00
//Move item with the keyboard arrow
2017-12-05 20:51:54 +00:00
if ( event - > modifiers ( ) = = Qt : : NoModifier )
{
switch ( event - > key ( ) )
{
case Qt : : Key_Left :
for ( Element * item : dc . m_elements )
{
2018-06-07 16:29:41 +00:00
left_position = item - > sceneBoundingRect ( ) . x ( ) ;
if ( left_position < = 5 )
2017-12-05 20:51:54 +00:00
return ;
}
2019-02-21 00:02:49 +00:00
movement = QPointF ( - xKeyGrid , 0.0 ) ;
2017-12-05 20:51:54 +00:00
break ;
case Qt : : Key_Right :
2019-02-21 00:02:49 +00:00
movement = QPointF ( + xKeyGrid , 0.0 ) ;
2017-12-05 20:51:54 +00:00
break ;
case Qt : : Key_Up :
for ( Element * item : dc . m_elements )
{
2018-06-07 16:29:41 +00:00
top_position = item - > sceneBoundingRect ( ) . y ( ) ;
if ( top_position < = 5 )
2017-12-05 20:51:54 +00:00
return ;
}
2019-02-21 00:02:49 +00:00
movement = QPointF ( 0.0 , - yKeyGrid ) ;
2017-12-05 20:51:54 +00:00
break ;
case Qt : : Key_Down :
2019-02-21 00:02:49 +00:00
movement = QPointF ( 0.0 , + yKeyGrid ) ;
2017-12-05 20:51:54 +00:00
break ;
}
if ( ! movement . isNull ( ) & & ! focusItem ( ) )
{
2018-04-05 09:37:35 +00:00
m_elements_mover . beginMovement ( this ) ;
m_elements_mover . continueMovement ( movement ) ;
2017-12-05 20:51:54 +00:00
event - > accept ( ) ;
2016-06-09 20:46:27 +00:00
return ;
2016-08-08 16:42:47 +00:00
}
2017-12-05 20:51:54 +00:00
}
2020-07-15 19:57:37 +02:00
else if ( event - > modifiers ( ) = = Qt : : AltModifier )
{
switch ( event - > key ( ) )
{
case Qt : : Key_Left :
for ( Element * item : dc . m_elements )
{
left_position = item - > sceneBoundingRect ( ) . x ( ) ;
if ( left_position < = 5 )
return ;
}
movement = QPointF ( - xKeyGridFine , 0.0 ) ;
break ;
case Qt : : Key_Right :
movement = QPointF ( + xKeyGridFine , 0.0 ) ;
break ;
case Qt : : Key_Up :
for ( Element * item : dc . m_elements )
{
top_position = item - > sceneBoundingRect ( ) . y ( ) ;
if ( top_position < = 5 )
return ;
}
movement = QPointF ( 0.0 , - yKeyGridFine ) ;
break ;
case Qt : : Key_Down :
movement = QPointF ( 0.0 , + yKeyGridFine ) ;
break ;
}
if ( ! movement . isNull ( ) & & ! focusItem ( ) )
{
m_elements_mover . beginMovement ( this ) ;
m_elements_mover . continueMovement ( movement ) ;
event - > accept ( ) ;
return ;
}
}
else if ( event - > modifiers ( ) = = Qt : : ControlModifier )
2017-12-05 20:51:54 +00:00
{
//Adjust the alignment of a texts group
if ( selectedItems ( ) . size ( ) = = 1 & & selectedItems ( ) . first ( ) - > type ( ) = = QGraphicsItemGroup : : Type )
{
if ( ElementTextItemGroup * etig = dynamic_cast < ElementTextItemGroup * > ( selectedItems ( ) . first ( ) ) )
{
if ( event - > key ( ) = = Qt : : Key_Left & & etig - > alignment ( ) ! = Qt : : AlignLeft )
undoStack ( ) . push ( new AlignmentTextsGroupCommand ( etig , Qt : : AlignLeft ) ) ;
else if ( event - > key ( ) = = Qt : : Key_Up & & etig - > alignment ( ) ! = Qt : : AlignVCenter )
undoStack ( ) . push ( new AlignmentTextsGroupCommand ( etig , Qt : : AlignVCenter ) ) ;
else if ( event - > key ( ) = = Qt : : Key_Right & & etig - > alignment ( ) ! = Qt : : AlignRight )
undoStack ( ) . push ( new AlignmentTextsGroupCommand ( etig , Qt : : AlignRight ) ) ;
}
2016-06-09 20:46:27 +00:00
}
2017-12-05 20:51:54 +00:00
}
2016-05-13 15:00:22 +00:00
}
2017-12-05 20:51:54 +00:00
event - > ignore ( ) ;
QGraphicsScene : : keyPressEvent ( event ) ;
2012-04-16 06:33:26 +00:00
}
2007-09-15 23:45:27 +00:00
}
2007-10-10 17:50:26 +00:00
/**
2015-03-04 21:13:13 +00:00
* @ brief Diagram : : keyReleaseEvent
* This event is managed by diagram event interface if any .
* Else move selected element
* @ param e
*/
void Diagram : : keyReleaseEvent ( QKeyEvent * e )
{
2019-01-14 18:25:43 +00:00
e - > setAccepted ( false ) ;
if ( m_event_interface ) {
m_event_interface - > keyReleaseEvent ( e ) ;
if ( e - > isAccepted ( ) ) {
2017-05-13 16:01:47 +00:00
return ;
}
2019-01-14 18:25:43 +00:00
}
2017-05-13 16:01:47 +00:00
2012-04-28 23:22:34 +00:00
bool transmit_event = true ;
2009-04-03 19:30:25 +00:00
if ( ! isReadOnly ( ) ) {
// detecte le relachement d'une touche de direction ( = deplacement d'elements)
if (
2010-05-08 21:24:43 +00:00
( e - > key ( ) = = Qt : : Key_Left | | e - > key ( ) = = Qt : : Key_Right | |
e - > key ( ) = = Qt : : Key_Up | | e - > key ( ) = = Qt : : Key_Down ) & &
! e - > isAutoRepeat ( )
2009-04-03 19:30:25 +00:00
) {
2018-04-05 09:37:35 +00:00
m_elements_mover . endMovement ( ) ;
2012-04-28 23:22:34 +00:00
e - > accept ( ) ;
transmit_event = false ;
2009-04-03 19:30:25 +00:00
}
2007-09-26 17:14:09 +00:00
}
2012-04-28 23:22:34 +00:00
if ( transmit_event ) {
2012-04-16 06:33:26 +00:00
QGraphicsScene : : keyReleaseEvent ( e ) ;
}
2007-09-15 23:45:27 +00:00
}
2020-04-12 18:51:38 +02:00
/**
* @ brief Diagram : : uuid
* @ return the uuid of this diagram
*/
QUuid Diagram : : uuid ( ) {
return m_uuid ;
}
2015-03-04 21:13:13 +00:00
/**
* @ brief Diagram : : setEventInterface
* Set event_interface has current interface .
* Diagram become the ownership of event_interface
* If there is a previous interface , they will be delete before
* and call init ( ) to the new interface .
* @ param event_interface
*/
void Diagram : : setEventInterface ( DiagramEventInterface * event_interface )
{
if ( m_event_interface )
{
delete m_event_interface ;
event_interface - > init ( ) ;
}
m_event_interface = event_interface ;
2019-01-14 18:25:43 +00:00
connect ( m_event_interface , & DiagramEventInterface : : finish , [ this ] ( )
{
delete this - > m_event_interface ;
this - > m_event_interface = nullptr ;
} ) ;
2015-03-04 21:13:13 +00:00
}
2017-07-26 08:55:32 +00:00
/**
* @ brief Diagram : : clearEventInterface
* Clear the current event interface .
*/
void Diagram : : clearEventInterface ( )
{
if ( m_event_interface )
{
delete m_event_interface ;
m_event_interface = nullptr ;
}
}
2014-07-31 10:02:33 +00:00
/**
* @ brief Diagram : : conductorsAutonumName
* @ return the name of autonum to use .
*/
QString Diagram : : conductorsAutonumName ( ) const {
return m_conductors_autonum_name ;
}
/**
* @ brief Diagram : : setConductorsAutonumName
* @ param name , name of autonum to use .
*/
void Diagram : : setConductorsAutonumName ( const QString & name ) {
m_conductors_autonum_name = name ;
}
2006-11-11 18:25:42 +00:00
/**
Exporte le schema vers une image
@ return Une QImage representant le schema
*/
2007-10-05 12:06:39 +00:00
bool Diagram : : toPaintDevice ( QPaintDevice & pix , int width , int height , Qt : : AspectRatioMode aspectRatioMode ) {
2007-02-01 01:07:26 +00:00
// determine la zone source = contenu du schema + marges
QRectF source_area ;
2012-11-09 21:09:24 +00:00
if ( ! use_border_ ) {
2007-02-01 01:07:26 +00:00
source_area = itemsBoundingRect ( ) ;
2007-10-10 22:35:32 +00:00
source_area . translate ( - margin , - margin ) ;
source_area . setWidth ( source_area . width ( ) + 2.0 * margin ) ;
source_area . setHeight ( source_area . height ( ) + 2.0 * margin ) ;
2007-02-01 01:07:26 +00:00
} else {
source_area = QRectF (
0.0 ,
0.0 ,
2015-03-18 18:07:18 +00:00
border_and_titleblock . borderAndTitleBlockRect ( ) . width ( ) + 2.0 * margin ,
border_and_titleblock . borderAndTitleBlockRect ( ) . height ( ) + 2.0 * margin
2007-02-01 01:07:26 +00:00
) ;
}
2007-01-20 18:11:42 +00:00
// si les dimensions ne sont pas precisees, l'image est exportee a l'echelle 1:1
QSize image_size = ( width = = - 1 & & height = = - 1 ) ? source_area . size ( ) . toSize ( ) : QSize ( width , height ) ;
// prepare le rendu
2006-10-27 15:47:22 +00:00
QPainter p ;
2007-10-05 12:06:39 +00:00
if ( ! p . begin ( & pix ) ) return ( false ) ;
2006-10-27 15:47:22 +00:00
// rendu antialiase
p . setRenderHint ( QPainter : : Antialiasing , true ) ;
p . setRenderHint ( QPainter : : TextAntialiasing , true ) ;
p . setRenderHint ( QPainter : : SmoothPixmapTransform , true ) ;
2007-01-20 18:11:42 +00:00
// deselectionne tous les elements
QList < QGraphicsItem * > selected_elmts = selectedItems ( ) ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , selected_elmts ) qgi - > setSelected ( false ) ;
2007-01-20 18:11:42 +00:00
// effectue le rendu lui-meme
2007-10-05 12:06:39 +00:00
render ( & p , QRect ( QPoint ( 0 , 0 ) , image_size ) , source_area , aspectRatioMode ) ;
2006-10-27 15:47:22 +00:00
p . end ( ) ;
2007-01-20 18:11:42 +00:00
// restaure les elements selectionnes
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , selected_elmts ) qgi - > setSelected ( true ) ;
2007-01-20 18:11:42 +00:00
2007-10-05 12:06:39 +00:00
return ( true ) ;
2006-10-27 15:47:22 +00:00
}
2007-01-20 18:11:42 +00:00
/**
Permet de connaitre les dimensions qu ' aura l ' image generee par la methode toImage ( )
@ return La taille de l ' image generee par toImage ( )
*/
2007-01-29 00:41:12 +00:00
QSize Diagram : : imageSize ( ) const {
2007-02-01 01:07:26 +00:00
// determine la zone source = contenu du schema + marges
qreal image_width , image_height ;
2012-11-09 21:09:24 +00:00
if ( ! use_border_ ) {
2007-02-01 01:07:26 +00:00
QRectF items_rect = itemsBoundingRect ( ) ;
image_width = items_rect . width ( ) ;
image_height = items_rect . height ( ) ;
} else {
2015-03-18 18:07:18 +00:00
image_width = border_and_titleblock . borderAndTitleBlockRect ( ) . width ( ) ;
image_height = border_and_titleblock . borderAndTitleBlockRect ( ) . height ( ) ;
2007-02-01 01:07:26 +00:00
}
2007-01-20 18:11:42 +00:00
2007-10-10 22:35:32 +00:00
image_width + = 2.0 * margin ;
image_height + = 2.0 * margin ;
2007-01-20 18:11:42 +00:00
// renvoie la taille de la zone source
2007-02-01 01:07:26 +00:00
return ( QSizeF ( image_width , image_height ) . toSize ( ) ) ;
2007-01-20 18:11:42 +00:00
}
2009-04-03 19:30:25 +00:00
/**
@ return true si le schema est considere comme vide , false sinon .
Un schema vide ne contient ni element , ni conducteur , ni champ de texte
*/
bool Diagram : : isEmpty ( ) const {
return ( ! items ( ) . count ( ) ) ;
}
2013-04-19 14:59:20 +00:00
/**
* @ brief Diagram : : potential
* @ return all potential in the diagram
* each potential are in the QList and each conductors of one potential are in the QSet
*/
QList < QSet < Conductor * > > Diagram : : potentials ( ) {
QList < QSet < Conductor * > > potential_List ;
if ( content ( ) . conductors ( ) . size ( ) = = 0 ) return ( potential_List ) ; //return an empty potential
QList < Conductor * > conductors_list = content ( ) . conductors ( ) ;
do {
QSet < Conductor * > one_potential = conductors_list . first ( ) - > relatedPotentialConductors ( ) ;
one_potential < < conductors_list . takeFirst ( ) ;
2017-02-05 16:18:50 +00:00
foreach ( Conductor * c , one_potential ) conductors_list . removeOne ( c ) ;
2013-04-19 14:59:20 +00:00
potential_List < < one_potential ;
} while ( ! conductors_list . empty ( ) ) ;
return ( potential_List ) ;
}
2006-10-27 15:47:22 +00:00
/**
Exporte tout ou partie du schema
2010-04-18 21:00:27 +00:00
@ param whole_content Booleen ( a vrai par defaut ) indiquant si le XML genere doit
representer l ' integralite du schema ou seulement le contenu selectionne
2006-10-27 15:47:22 +00:00
@ return Un Document XML ( QDomDocument )
*/
2010-04-18 21:00:27 +00:00
QDomDocument Diagram : : toXml ( bool whole_content ) {
2006-10-27 15:47:22 +00:00
// document
QDomDocument document ;
// racine de l'arbre XML
2020-04-17 18:40:28 +02:00
auto dom_root = document . createElement ( " diagram " ) ;
2006-10-27 15:47:22 +00:00
2011-08-29 21:50:43 +00:00
// add the application version number
2020-04-17 18:40:28 +02:00
dom_root . setAttribute ( " version " , QET : : version ) ;
2011-08-29 21:50:43 +00:00
2006-10-27 15:47:22 +00:00
// proprietes du schema
2010-04-18 21:08:49 +00:00
if ( whole_content ) {
2020-04-17 18:40:28 +02:00
border_and_titleblock . titleBlockToXml ( dom_root ) ;
border_and_titleblock . borderToXml ( dom_root ) ;
2007-10-14 21:38:27 +00:00
2014-08-04 14:39:57 +00:00
// Default conductor properties
2007-10-14 21:38:27 +00:00
QDomElement default_conductor = document . createElement ( " defaultconductor " ) ;
2009-04-03 19:30:25 +00:00
defaultConductorProperties . toXml ( default_conductor ) ;
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( default_conductor ) ;
2014-08-04 14:39:57 +00:00
// Conductor autonum
if ( ! m_conductors_autonum_name . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
dom_root . setAttribute ( " conductorAutonum " , m_conductors_autonum_name ) ;
2014-08-04 14:39:57 +00:00
}
2016-07-20 15:07:21 +00:00
//Default New Element
2020-04-17 18:40:28 +02:00
dom_root . setAttribute ( " freezeNewElement " , m_freeze_new_elements ? " true " : " false " ) ;
2016-07-26 18:52:49 +00:00
2016-09-01 19:41:49 +00:00
//Default New Conductor
2020-04-17 18:40:28 +02:00
dom_root . setAttribute ( " freezeNewConductor " , m_freeze_new_conductors_ ? " true " : " false " ) ;
2016-09-01 19:41:49 +00:00
2016-08-29 15:37:42 +00:00
//Element Folio Sequential Variables
2016-07-26 18:52:49 +00:00
if ( ! m_elmt_unitfolio_max . isEmpty ( ) | | ! m_elmt_tenfolio_max . isEmpty ( ) | | ! m_elmt_hundredfolio_max . isEmpty ( ) ) {
2016-08-29 15:37:42 +00:00
QDomElement elmtfoliosequential = document . createElement ( " elementautonumfoliosequentials " ) ;
2016-07-26 18:52:49 +00:00
if ( ! m_elmt_unitfolio_max . isEmpty ( ) ) {
QDomElement elmtfolioseq = document . createElement ( " elementunitfolioseq " ) ;
2016-08-29 15:37:42 +00:00
folioSequentialsToXml ( & m_elmt_unitfolio_max , & elmtfolioseq , " sequf_ " , " unitfolioseq " , & document ) ;
elmtfoliosequential . appendChild ( elmtfolioseq ) ;
2016-07-26 18:52:49 +00:00
}
if ( ! m_elmt_tenfolio_max . isEmpty ( ) ) {
QDomElement elmtfolioseq = document . createElement ( " elementtenfolioseq " ) ;
2016-08-29 15:37:42 +00:00
folioSequentialsToXml ( & m_elmt_tenfolio_max , & elmtfolioseq , " seqtf_ " , " tenfolioseq " , & document ) ;
elmtfoliosequential . appendChild ( elmtfolioseq ) ;
2016-07-26 18:52:49 +00:00
}
if ( ! m_elmt_hundredfolio_max . isEmpty ( ) ) {
QDomElement elmtfolioseq = document . createElement ( " elementhundredfolioseq " ) ;
2016-08-29 15:37:42 +00:00
folioSequentialsToXml ( & m_elmt_hundredfolio_max , & elmtfolioseq , " seqhf_ " , " hundredfolioseq " , & document ) ;
elmtfoliosequential . appendChild ( elmtfolioseq ) ;
2016-07-26 18:52:49 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( elmtfoliosequential ) ;
2016-08-29 15:37:42 +00:00
}
//Conductor Folio Sequential Variables
if ( ! m_cnd_unitfolio_max . isEmpty ( ) | | ! m_cnd_tenfolio_max . isEmpty ( ) | | ! m_cnd_hundredfolio_max . isEmpty ( ) ) {
QDomElement cndfoliosequential = document . createElement ( " conductorautonumfoliosequentials " ) ;
QHash < QString , QStringList > : : iterator i ;
if ( ! m_cnd_unitfolio_max . isEmpty ( ) ) {
QDomElement cndfolioseq = document . createElement ( " conductorunitfolioseq " ) ;
folioSequentialsToXml ( & m_cnd_unitfolio_max , & cndfolioseq , " sequf_ " , " unitfolioseq " , & document ) ;
cndfoliosequential . appendChild ( cndfolioseq ) ;
}
if ( ! m_cnd_tenfolio_max . isEmpty ( ) ) {
QDomElement cndfolioseq = document . createElement ( " conductortenfolioseq " ) ;
folioSequentialsToXml ( & m_cnd_tenfolio_max , & cndfolioseq , " seqtf_ " , " tenfolioseq " , & document ) ;
cndfoliosequential . appendChild ( cndfolioseq ) ;
}
if ( ! m_cnd_hundredfolio_max . isEmpty ( ) ) {
QDomElement cndfolioseq = document . createElement ( " conductorhundredfolioseq " ) ;
folioSequentialsToXml ( & m_cnd_hundredfolio_max , & cndfolioseq , " seqhf_ " , " hundredfolioseq " , & document ) ;
cndfoliosequential . appendChild ( cndfolioseq ) ;
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( cndfoliosequential ) ;
2016-07-26 18:52:49 +00:00
}
2006-10-27 15:47:22 +00:00
}
2016-07-18 17:37:02 +00:00
else {
//this method with whole_content to false,
//is often use to copy and paste the current selection
//so we add the id of the project where copy occur.
2020-04-17 18:40:28 +02:00
dom_root . setAttribute ( " projectId " , QETApp : : projectId ( m_project ) ) ;
2016-07-18 17:37:02 +00:00
}
2020-04-17 18:40:28 +02:00
document . appendChild ( dom_root ) ;
2006-10-27 15:47:22 +00:00
2020-04-17 18:40:28 +02:00
if ( items ( ) . isEmpty ( ) )
return ( document ) ;
2006-10-27 15:47:22 +00:00
2020-04-17 18:40:28 +02:00
QVector < Element * > list_elements ;
QVector < Conductor * > list_conductors ;
QVector < DiagramTextItem * > list_texts ;
QVector < DiagramImageItem * > list_images ;
QVector < QetShapeItem * > list_shapes ;
QVector < QetGraphicsTableItem * > table_vector ;
//Ckeck graphics item to "XMLise"
for ( QGraphicsItem * qgi : items ( ) )
{
switch ( qgi - > type ( ) )
{
case Element : : Type : {
auto elmt = static_cast < Element * > ( qgi ) ;
if ( whole_content | | elmt - > isSelected ( ) )
list_elements < < elmt ;
break ;
}
case Conductor : : Type : {
auto cond = static_cast < Conductor * > ( qgi ) ;
if ( whole_content )
list_conductors < < cond ;
//When we did not export the whole diagram, we must to remove the non selected conductors.
//At this step that mean a conductor which one of these two element are not selected
else if ( cond - > terminal1 - > parentItem ( ) - > isSelected ( ) & & cond - > terminal2 - > parentItem ( ) - > isSelected ( ) )
list_conductors < < cond ;
break ;
}
case DiagramImageItem : : Type : {
auto image = static_cast < DiagramImageItem * > ( qgi ) ;
if ( whole_content | | image - > isSelected ( ) )
list_images < < image ;
break ;
}
case IndependentTextItem : : Type : {
auto indi_text = static_cast < IndependentTextItem * > ( qgi ) ;
if ( whole_content | | indi_text - > isSelected ( ) )
list_texts < < indi_text ;
break ;
}
case QetShapeItem : : Type : {
auto shape = static_cast < QetShapeItem * > ( qgi ) ;
if ( whole_content | | shape - > isSelected ( ) )
list_shapes < < shape ;
break ;
}
case QetGraphicsTableItem : : Type : {
auto table = static_cast < QetGraphicsTableItem * > ( qgi ) ;
if ( whole_content | | table - > isSelected ( ) )
table_vector < < table ;
2007-10-27 13:18:17 +00:00
}
2006-10-27 15:47:22 +00:00
}
}
2020-04-17 18:40:28 +02:00
// table de correspondance entre les adresses des bornes et leurs ids
2007-01-29 20:14:26 +00:00
QHash < Terminal * , int > table_adr_id ;
2007-02-24 18:37:07 +00:00
2007-10-27 13:18:17 +00:00
if ( ! list_elements . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
auto dom_elements = document . createElement ( " elements " ) ;
for ( auto elmt : list_elements ) {
dom_elements . appendChild ( elmt - > toXml ( document , table_adr_id ) ) ;
2007-10-27 13:18:17 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( dom_elements ) ;
2006-10-27 15:47:22 +00:00
}
2007-10-27 13:18:17 +00:00
if ( ! list_conductors . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
auto dom_conductors = document . createElement ( " conductors " ) ;
for ( auto cond : list_conductors ) {
dom_conductors . appendChild ( cond - > toXml ( document , table_adr_id ) ) ;
2007-10-27 13:18:17 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( dom_conductors ) ;
2007-10-27 13:18:17 +00:00
}
if ( ! list_texts . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
auto dom_texts = document . createElement ( " inputs " ) ;
for ( auto dti : list_texts ) {
dom_texts . appendChild ( dti - > toXml ( document ) ) ;
2007-10-27 13:18:17 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( dom_texts ) ;
2006-10-27 15:47:22 +00:00
}
2013-08-24 15:18:45 +00:00
if ( ! list_images . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
auto dom_images = document . createElement ( " images " ) ;
for ( auto dii : list_images ) {
dom_images . appendChild ( dii - > toXml ( document ) ) ;
2013-08-24 15:18:45 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( dom_images ) ;
2013-08-24 15:18:45 +00:00
}
2014-02-28 14:30:59 +00:00
if ( ! list_shapes . isEmpty ( ) ) {
2020-04-17 18:40:28 +02:00
auto dom_shapes = document . createElement ( " shapes " ) ;
for ( auto dii : list_shapes ) {
dom_shapes . appendChild ( dii - > toXml ( document ) ) ;
}
dom_root . appendChild ( dom_shapes ) ;
}
if ( table_vector . size ( ) ) {
auto tables = document . createElement ( " tables " ) ;
for ( auto table : table_vector ) {
tables . appendChild ( table - > toXml ( document ) ) ;
2014-02-28 14:30:59 +00:00
}
2020-04-17 18:40:28 +02:00
dom_root . appendChild ( tables ) ;
2014-02-28 14:30:59 +00:00
}
2020-04-17 18:40:28 +02:00
2006-10-27 15:47:22 +00:00
return ( document ) ;
}
2016-07-26 18:52:49 +00:00
/**
2016-08-29 15:37:42 +00:00
+ * @ brief Diagram : : folioSequentialsToXml
+ * Add folio sequential to QDomElement
2016-07-26 18:52:49 +00:00
+ * @ param domElement to add attributes
+ * @ param hash to retrieve content with content
+ * @ param sequential type
+ */
2018-07-19 14:14:31 +00:00
void Diagram : : folioSequentialsToXml ( QHash < QString , QStringList > * hash , QDomElement * domElement , const QString & seq_type , const QString & type , QDomDocument * doc ) {
2016-07-26 18:52:49 +00:00
QHash < QString , QStringList > : : iterator i ;
for ( i = hash - > begin ( ) ; i ! = hash - > end ( ) ; i + + ) {
2016-08-25 16:28:11 +00:00
QDomElement folioseq = doc - > createElement ( type ) ;
folioseq . setAttribute ( " title " , i . key ( ) ) ;
2016-07-26 18:52:49 +00:00
for ( int j = 0 ; j < i . value ( ) . size ( ) ; j + + ) {
2016-08-25 16:28:11 +00:00
folioseq . setAttribute ( seq_type + QString : : number ( j + 1 ) , i . value ( ) . at ( j ) ) ;
2016-07-26 18:52:49 +00:00
}
2016-08-25 16:28:11 +00:00
domElement - > appendChild ( folioseq ) ;
2016-07-26 18:52:49 +00:00
}
}
2006-10-27 15:47:22 +00:00
/**
2009-04-03 19:30:25 +00:00
Importe le schema decrit dans un document XML . Si une position est
2006-11-11 18:25:42 +00:00
precisee , les elements importes sont positionnes de maniere a ce que le
coin superieur gauche du plus petit rectangle pouvant les entourant tous
( le bounding rect ) soit a cette position .
2006-10-27 15:47:22 +00:00
@ param document Le document XML a analyser
2009-04-03 19:30:25 +00:00
@ param position La position du schema importe
2007-09-26 12:36:31 +00:00
@ param consider_informations Si vrai , les informations complementaires
( auteur , titre , . . . ) seront prises en compte
2009-04-28 18:04:29 +00:00
@ param content_ptr si ce pointeur vers un DiagramContent est different de 0 ,
il sera rempli avec le contenu ajoute au schema par le fromXml
2006-10-27 15:47:22 +00:00
@ return true si l ' import a reussi , false sinon
*/
2007-11-09 13:06:51 +00:00
bool Diagram : : fromXml ( QDomDocument & document , QPointF position , bool consider_informations , DiagramContent * content_ptr ) {
2007-10-27 13:18:17 +00:00
QDomElement root = document . documentElement ( ) ;
2009-04-03 19:30:25 +00:00
return ( fromXml ( root , position , consider_informations , content_ptr ) ) ;
}
2009-04-28 18:04:29 +00:00
/**
Importe le schema decrit dans un element XML . Cette methode delegue son travail a Diagram : : fromXml
Si l ' import reussit , cette methode initialise egalement le document XML
interne permettant de bien gerer l ' enregistrement de ce schema dans le
projet auquel il appartient .
@ see Diagram : : fromXml
@ param document Le document XML a analyser
@ param position La position du schema importe
@ param consider_informations Si vrai , les informations complementaires
( auteur , titre , . . . ) seront prises en compte
@ param content_ptr si ce pointeur vers un DiagramContent est different de 0 ,
il sera rempli avec le contenu ajoute au schema par le fromXml
@ return true si l ' import a reussi , false sinon
*/
bool Diagram : : initFromXml ( QDomElement & document , QPointF position , bool consider_informations , DiagramContent * content_ptr ) {
// import le contenu et les proprietes du schema depuis l'element XML fourni en parametre
bool from_xml = fromXml ( document , position , consider_informations , content_ptr ) ;
return ( from_xml ) ;
}
2020-05-26 18:47:24 +02:00
/*!
* \ brief findTerminal
* Find terminal to which the conductor should be connected
* \ param conductor_index 1 or 2 depending on which terminal is searched
* \ param f Conductor xml element
* \ param table_adr_id Hash table to all terminal id assignement ( legacy )
* \ param added_elements Elements found in the xml file
* \ return
*/
Terminal * findTerminal ( int conductor_index , QDomElement & f , QHash < int , Terminal * > & table_adr_id , QList < Element * > & added_elements ) {
2020-07-15 19:57:37 +02:00
assert ( conductor_index = = 1 | | conductor_index = = 2 ) ;
QString element_index = " element " + QString : : number ( conductor_index ) ;
QString terminal_index = " terminal " + QString : : number ( conductor_index ) ;
if ( f . hasAttribute ( element_index ) ) {
QUuid element_uuid = QUuid ( f . attribute ( element_index ) ) ;
// element1 did not exist in the conductor part of the xml until prior 0.7
// It is used as an indicator that uuid's are used to identify terminals
bool element_found = false ;
for ( auto element : added_elements ) {
if ( element - > uuid ( ) ! = element_uuid )
continue ;
element_found = true ;
QUuid terminal_uuid = QUuid ( f . attribute ( terminal_index ) ) ;
for ( auto terminal : element - > terminals ( ) ) {
if ( terminal - > uuid ( ) ! = terminal_uuid )
continue ;
return terminal ;
}
qDebug ( ) < < " Diagram::fromXml() : " < < terminal_index < < " : " < < terminal_uuid < < " not found in " < < element_index < < " : " < < element_uuid ;
break ;
}
if ( ! element_found )
qDebug ( ) < < " Diagram::fromXml() : " < < element_index < < " : " < < element_uuid < < " not found " ;
} else {
// Backward compatibility. Until version 0.7 a generated id is used to link the terminal.
int id_p1 = f . attribute ( terminal_index ) . toInt ( ) ;
if ( ! table_adr_id . contains ( id_p1 ) ) {
qDebug ( ) < < " Diagram::fromXml() : terminal id " < < id_p1 < < " not found " ;
} else
return table_adr_id . value ( id_p1 ) ;
}
return nullptr ;
2020-05-26 18:47:24 +02:00
}
2009-04-03 19:30:25 +00:00
/**
Importe le schema decrit dans un element XML . Si une position est
precisee , les elements importes sont positionnes de maniere a ce que le
coin superieur gauche du plus petit rectangle pouvant les entourant tous
( le bounding rect ) soit a cette position .
@ param document Le document XML a analyser
@ param position La position du schema importe
@ param consider_informations Si vrai , les informations complementaires
( auteur , titre , . . . ) seront prises en compte
2009-04-28 18:04:29 +00:00
@ param content_ptr si ce pointeur vers un DiagramContent est different de 0 ,
il sera rempli avec le contenu ajoute au schema par le fromXml
2009-04-03 19:30:25 +00:00
@ return true si l ' import a reussi , false sinon
*/
bool Diagram : : fromXml ( QDomElement & document , QPointF position , bool consider_informations , DiagramContent * content_ptr ) {
2018-07-19 14:14:31 +00:00
const QDomElement & root = document ;
2014-08-04 14:39:57 +00:00
// The first element must be a diagram
2007-10-27 13:18:17 +00:00
if ( root . tagName ( ) ! = " diagram " ) return ( false ) ;
2007-01-29 00:41:12 +00:00
2014-08-04 14:39:57 +00:00
// Read attributes of this diagram
2007-01-28 00:53:17 +00:00
if ( consider_informations ) {
2014-08-04 14:39:57 +00:00
// Version of diagram
2011-08-29 21:50:43 +00:00
bool conv_ok ;
qreal version_value = root . attribute ( " version " ) . toDouble ( & conv_ok ) ;
if ( conv_ok ) {
diagram_qet_version_ = version_value ;
}
2014-08-04 14:39:57 +00:00
// Load border and titleblock
2011-01-09 00:01:38 +00:00
border_and_titleblock . titleBlockFromXml ( root ) ;
border_and_titleblock . borderFromXml ( root ) ;
2007-11-14 20:27:45 +00:00
2014-08-04 14:39:57 +00:00
// Find the element "defaultconductor".
// If found, load default conductor properties.
2011-01-09 00:01:38 +00:00
QDomElement default_conductor_elmt = root . firstChildElement ( " defaultconductor " ) ;
if ( ! default_conductor_elmt . isNull ( ) ) {
defaultConductorProperties . fromXml ( default_conductor_elmt ) ;
2007-10-14 21:38:27 +00:00
}
2014-08-04 14:39:57 +00:00
// Load the autonum
m_conductors_autonum_name = root . attribute ( " conductorAutonum " ) ;
2016-07-20 15:07:21 +00:00
// Load Freeze New Element
2016-12-10 12:00:52 +00:00
m_freeze_new_elements = root . attribute ( " freezeNewElement " ) . toInt ( ) ;
2016-07-26 18:52:49 +00:00
2016-09-01 19:41:49 +00:00
// Load Freeze New Conductor
m_freeze_new_conductors_ = root . attribute ( " freezeNewConductor " ) . toInt ( ) ;
2016-08-29 15:37:42 +00:00
//Load Element Folio Sequential
folioSequentialsFromXml ( root , & m_elmt_unitfolio_max , " elementunitfolioseq " , " sequf_ " , " unitfolioseq " , " elementautonumfoliosequentials " ) ;
folioSequentialsFromXml ( root , & m_elmt_tenfolio_max , " elementtenfolioseq " , " seqtf_ " , " tenfolioseq " , " elementautonumfoliosequentials " ) ;
folioSequentialsFromXml ( root , & m_elmt_hundredfolio_max , " elementhundredfolioseq " , " seqhf_ " , " hundredfolioseq " , " elementautonumfoliosequentials " ) ;
//Load Conductor Folio Sequential
folioSequentialsFromXml ( root , & m_cnd_unitfolio_max , " conductorunitfolioseq " , " sequf_ " , " unitfolioseq " , " conductorautonumfoliosequentials " ) ;
folioSequentialsFromXml ( root , & m_cnd_tenfolio_max , " conductortenfolioseq " , " seqtf_ " , " tenfolioseq " , " conductorautonumfoliosequentials " ) ;
folioSequentialsFromXml ( root , & m_cnd_hundredfolio_max , " conductorhundredfolioseq " , " seqhf_ " , " hundredfolioseq " , " conductorautonumfoliosequentials " ) ;
2007-01-28 00:53:17 +00:00
}
2016-07-26 18:52:49 +00:00
2014-08-04 14:39:57 +00:00
// if child haven't got a child, loading is finish (diagram is empty)
2009-04-03 19:30:25 +00:00
if ( root . firstChild ( ) . isNull ( ) ) {
return ( true ) ;
}
2007-10-27 13:18:17 +00:00
2011-08-29 21:50:43 +00:00
// Backward compatibility: prior to version 0.3, we need to compensate, at
// diagram-opening time, the rotation of the element for each of its
// textfields having the "FollowParentRotation" option disabled.
// After 0.3, elements textfields get userx, usery and userrotation attributes
// that explicitly specify their position and orientation.
qreal project_qet_version = declaredQElectroTechVersion ( true ) ;
bool handle_inputs_rotation = (
project_qet_version ! = - 1 & & project_qet_version < 0.3 & &
2016-03-15 18:42:18 +00:00
m_project - > state ( ) = = QETProject : : ProjectParsingRunning
2011-08-29 21:50:43 +00:00
) ;
2016-07-18 17:37:02 +00:00
//If paste from another project
if ( root . hasAttribute ( " projectId " ) ) {
QETProject * other_project = QETApp : : project ( root . attribute ( " projectId " , " -1 " ) . toInt ( ) ) ;
//We try to paste from another project, then befor paste elements,
//we must to import the definition of the pasted elements (owned by other project)
//in the embedded collection of this project
if ( other_project & & other_project ! = m_project ) {
ElementCollectionHandler ech ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement element_xml , QET : : findInDomElement ( root , " elements " , " element " ) ) {
2016-07-18 17:37:02 +00:00
if ( ! Element : : valideXml ( element_xml ) ) continue ;
QString type_id = element_xml . attribute ( " type " ) ;
if ( type_id . startsWith ( " embed:// " ) ) {
ElementsLocation location ( type_id , other_project ) ;
ech . importFromProject ( m_project , location ) ;
}
}
}
}
2015-05-18 22:19:14 +00:00
//Load all elements from the XML
2007-10-27 13:18:17 +00:00
QList < Element * > added_elements ;
QHash < int , Terminal * > table_adr_id ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement element_xml , QET : : findInDomElement ( root , " elements " , " element " ) )
2015-05-18 22:19:14 +00:00
{
2010-04-18 17:59:54 +00:00
if ( ! Element : : valideXml ( element_xml ) ) continue ;
2007-10-27 13:18:17 +00:00
2007-12-05 21:16:01 +00:00
// cree un element dont le type correspond a l'id type
2010-04-18 17:59:54 +00:00
QString type_id = element_xml . attribute ( " type " ) ;
2016-03-15 18:42:18 +00:00
ElementsLocation element_location ;
if ( type_id . startsWith ( " embed:// " ) ) {
element_location = ElementsLocation ( type_id , m_project ) ;
}
else {
element_location = ElementsLocation ( type_id ) ;
}
2009-04-03 19:30:25 +00:00
2013-12-20 20:30:55 +00:00
int state = 0 ;
2017-08-05 02:06:59 +00:00
Element * nvel_elmt = ElementFactory : : Instance ( ) - > createElement ( element_location , nullptr , & state ) ;
2015-05-18 22:19:14 +00:00
if ( state )
{
2013-12-20 20:30:55 +00:00
QString debug_message = QString ( " Diagram::fromXml() : Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2 " ) . arg ( element_location . path ( ) ) . arg ( state ) ;
2009-04-13 01:35:01 +00:00
qDebug ( ) < < qPrintable ( debug_message ) ;
2007-10-27 13:18:17 +00:00
delete nvel_elmt ;
2018-10-10 16:48:44 +00:00
continue ;
2007-10-27 13:18:17 +00:00
}
2018-01-19 12:17:20 +00:00
addItem ( nvel_elmt ) ;
//Loading fail, remove item from the diagram
if ( ! nvel_elmt - > fromXml ( element_xml , table_adr_id , handle_inputs_rotation ) )
{
removeItem ( nvel_elmt ) ;
2007-10-27 13:18:17 +00:00
delete nvel_elmt ;
2009-04-13 01:35:01 +00:00
qDebug ( ) < < " Diagram::fromXml() : Le chargement des parametres d'un element a echoue " ;
2018-01-19 12:17:20 +00:00
} else {
added_elements < < nvel_elmt ;
2006-10-27 15:47:22 +00:00
}
}
2020-04-17 18:40:28 +02:00
// Load text
2010-04-18 17:59:54 +00:00
QList < IndependentTextItem * > added_texts ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement text_xml , QET : : findInDomElement ( root , " inputs " , " input " ) ) {
2018-07-30 15:24:29 +00:00
IndependentTextItem * iti = new IndependentTextItem ( ) ;
2010-04-18 17:59:54 +00:00
iti - > fromXml ( text_xml ) ;
2014-10-10 08:58:44 +00:00
addItem ( iti ) ;
2010-04-18 17:59:54 +00:00
added_texts < < iti ;
2007-10-27 13:18:17 +00:00
}
2013-08-24 15:18:45 +00:00
2020-04-17 18:40:28 +02:00
// Load image
2013-08-24 15:18:45 +00:00
QList < DiagramImageItem * > added_images ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement image_xml , QET : : findInDomElement ( root , " images " , " image " ) ) {
2018-07-30 15:24:29 +00:00
DiagramImageItem * dii = new DiagramImageItem ( ) ;
2013-08-24 15:18:45 +00:00
dii - > fromXml ( image_xml ) ;
addItem ( dii ) ;
added_images < < dii ;
}
2014-02-28 14:30:59 +00:00
2020-04-17 18:40:28 +02:00
// Load shape
2014-02-28 14:30:59 +00:00
QList < QetShapeItem * > added_shapes ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement shape_xml , QET : : findInDomElement ( root , " shapes " , " shape " ) ) {
2014-02-28 14:30:59 +00:00
QetShapeItem * dii = new QetShapeItem ( QPointF ( 0 , 0 ) ) ;
dii - > fromXml ( shape_xml ) ;
addItem ( dii ) ;
added_shapes < < dii ;
}
2014-11-14 19:58:25 +00:00
2014-12-23 19:00:37 +00:00
// Load conductor
2007-10-27 13:18:17 +00:00
QList < Conductor * > added_conductors ;
2017-02-05 16:18:50 +00:00
foreach ( QDomElement f , QET : : findInDomElement ( root , " conductors " , " conductor " ) )
2014-12-23 19:00:37 +00:00
{
2007-10-27 13:18:17 +00:00
if ( ! Conductor : : valideXml ( f ) ) continue ;
2014-12-23 19:00:37 +00:00
//Check if terminal that conductor must be linked is know
2020-05-26 18:47:24 +02:00
2020-07-15 19:57:37 +02:00
Terminal * p1 = findTerminal ( 1 , f , table_adr_id , added_elements ) ;
Terminal * p2 = findTerminal ( 2 , f , table_adr_id , added_elements ) ;
if ( p1 & & p2 & & p1 ! = p2 )
{
Conductor * c = new Conductor ( p1 , p2 ) ;
if ( c - > isValid ( ) )
{
addItem ( c ) ;
c - > fromXml ( f ) ;
added_conductors < < c ;
}
else
delete c ;
}
2006-10-27 15:47:22 +00:00
}
2014-11-14 19:58:25 +00:00
2020-04-17 18:40:28 +02:00
//Load tables
QVector < QetGraphicsTableItem * > added_tables ;
for ( auto dom_table : QETXML : : subChild ( root , " tables " , QetGraphicsTableItem : : xmlTagName ( ) ) )
{
auto table = new QetGraphicsTableItem ( ) ;
addItem ( table ) ;
table - > fromXml ( dom_table ) ;
added_tables < < table ;
}
2014-11-14 19:58:25 +00:00
2020-04-17 18:40:28 +02:00
//Translate items if a new position was given in parameter
if ( position ! = QPointF ( ) )
{
QVector < QGraphicsItem * > added_items ;
for ( auto element : added_elements ) added_items < < element ;
for ( auto cond : added_conductors ) added_items < < cond ;
for ( auto shape : added_shapes ) added_items < < shape ;
for ( auto text : added_texts ) added_items < < text ;
for ( auto image : added_images ) added_items < < image ;
for ( auto table : added_tables ) added_items < < table ;
//Get the top left corner of the rectangle that contain all added items
2014-11-14 19:58:25 +00:00
QRectF items_rect ;
2020-04-17 18:40:28 +02:00
for ( auto item : added_items ) {
items_rect = items_rect . united ( item - > mapToScene ( item - > boundingRect ( ) ) . boundingRect ( ) ) ;
2014-11-14 19:58:25 +00:00
}
QPointF point_ = items_rect . topLeft ( ) ;
QPointF pos_ = Diagram : : snapToGrid ( QPointF ( position . x ( ) - point_ . x ( ) ,
2020-08-02 12:07:22 +02:00
position . y ( ) - point_ . y ( ) ) ) ;
2014-11-14 19:58:25 +00:00
2020-04-17 18:40:28 +02:00
//Translate all added items
for ( auto qgi : added_items )
qgi - > setPos ( qgi - > pos ( ) + = pos_ ) ;
2014-11-14 19:58:25 +00:00
}
2007-10-27 13:18:17 +00:00
2020-04-17 18:40:28 +02:00
//Filling of falculatory lists
2009-04-28 18:04:29 +00:00
if ( content_ptr ) {
2020-04-17 18:40:28 +02:00
content_ptr - > m_elements = added_elements ;
2018-04-23 13:50:36 +00:00
content_ptr - > m_conductors_to_move = added_conductors ;
2020-06-07 09:03:42 +02:00
# if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) // ### Qt 6: remove
2020-04-17 18:40:28 +02:00
content_ptr - > m_text_fields = added_texts . toSet ( ) ;
content_ptr - > m_images = added_images . toSet ( ) ;
content_ptr - > m_shapes = added_shapes . toSet ( ) ;
2020-06-07 09:03:42 +02:00
# else
2020-07-19 22:06:42 +02:00
# pragma message("@TODO remove code for QT 5.14 or later")
2020-06-07 09:03:42 +02:00
content_ptr - > m_text_fields = QSet < IndependentTextItem * > (
added_texts . begin ( ) ,
added_texts . end ( ) ) ;
content_ptr - > m_images = QSet < DiagramImageItem * > (
added_images . begin ( ) ,
added_images . end ( ) ) ;
content_ptr - > m_shapes = QSet < QetShapeItem * > (
added_shapes . begin ( ) ,
added_shapes . end ( ) ) ;
# endif
2020-04-17 18:40:28 +02:00
content_ptr - > m_tables = added_tables ;
2017-08-03 17:36:08 +00:00
}
2020-04-17 18:40:28 +02:00
2015-03-30 15:58:16 +00:00
adjustSceneRect ( ) ;
2006-10-27 15:47:22 +00:00
return ( true ) ;
}
2016-07-26 18:52:49 +00:00
/**
2016-08-29 15:37:42 +00:00
* @ brief Diagram : : folioSequentialsFromXml
* Load folio sequential from QDomElement
2016-07-26 18:52:49 +00:00
* @ param root containing all folio sequentials
* @ param hash to be loaded with content
* @ param folioSeq type
* @ param seq type
2016-08-25 16:28:11 +00:00
* @ param type of sequential
2016-07-26 18:52:49 +00:00
*/
2018-07-19 14:14:31 +00:00
void Diagram : : folioSequentialsFromXml ( const QDomElement & root , QHash < QString , QStringList > * hash , const QString & folioSeq , const QString & seq , const QString & type , const QString & autonumFolioSeqType ) {
2017-02-05 16:18:50 +00:00
foreach ( QDomElement folioSeqAutoNum , QET : : findInDomElement ( root , autonumFolioSeqType , folioSeq ) ) {
2016-08-25 16:28:11 +00:00
for ( QDomElement folioseq = folioSeqAutoNum . firstChildElement ( type ) ; ! folioseq . isNull ( ) ; folioseq = folioseq . nextSiblingElement ( type ) ) {
QString title = folioseq . attribute ( " title " ) ;
QStringList list ;
int i = 1 ;
while ( folioseq . hasAttribute ( seq + QString : : number ( i ) ) ) {
list < < folioseq . attribute ( seq + QString : : number ( i ) ) ;
i + + ;
}
hash - > insert ( title , list ) ;
2016-07-26 18:52:49 +00:00
}
}
}
2016-10-17 14:26:13 +00:00
/**
* @ brief Diagram : : refreshContents
* refresh all content of diagram .
* - refresh conductor text .
* - linking the elements waiting to be linked
2017-10-26 17:12:49 +00:00
* - Refresh the connection of the dynamic element text item ( use for text with source of text label )
2016-10-17 14:26:13 +00:00
*/
2017-10-26 17:12:49 +00:00
void Diagram : : refreshContents ( )
{
2020-04-17 18:40:28 +02:00
ElementProvider provider_ ( this ) ;
2017-10-26 17:12:49 +00:00
for ( Element * elmt : elements ( ) )
{
2013-12-31 14:39:34 +00:00
elmt - > initLink ( project ( ) ) ;
2017-10-26 17:12:49 +00:00
for ( DynamicElementTextItem * deti : elmt - > dynamicTextItems ( ) )
deti - > refreshLabelConnection ( ) ;
}
2016-10-17 14:26:13 +00:00
2017-10-26 17:12:49 +00:00
for ( Conductor * conductor : conductors ( ) )
2016-10-17 14:26:13 +00:00
conductor - > refreshText ( ) ;
2020-04-17 18:40:28 +02:00
for ( auto table : provider_ . table ( ) )
table - > initLink ( ) ;
2013-12-31 14:39:34 +00:00
}
2009-04-04 21:47:07 +00:00
/**
2014-10-10 08:58:44 +00:00
* @ brief Diagram : : addItem
2015-07-12 15:05:59 +00:00
* Réimplemented from QGraphicsScene : : addItem ( QGraphicsItem * item )
* Do some specific operation if item need it ( for exemple an element )
2014-10-10 08:58:44 +00:00
* @ param item
*/
2015-07-12 15:05:59 +00:00
void Diagram : : addItem ( QGraphicsItem * item )
{
if ( ! item | | isReadOnly ( ) | | item - > scene ( ) = = this ) return ;
QGraphicsScene : : addItem ( item ) ;
2014-10-10 08:58:44 +00:00
2015-07-12 15:05:59 +00:00
switch ( item - > type ( ) )
{
2020-07-01 18:31:19 +02:00
case Element : : Type :
{
m_project - > dataBase ( ) - > addElement ( static_cast < Element * > ( item ) ) ;
break ;
}
2015-07-12 15:05:59 +00:00
case Conductor : : Type :
{
2018-07-30 15:24:29 +00:00
Conductor * conductor = static_cast < Conductor * > ( item ) ;
2015-07-12 15:05:59 +00:00
conductor - > terminal1 - > addConductor ( conductor ) ;
conductor - > terminal2 - > addConductor ( conductor ) ;
conductor - > calculateTextItemPosition ( ) ;
break ;
}
2019-02-19 16:42:07 +00:00
default : { break ; }
2009-04-04 21:47:07 +00:00
}
}
/**
2014-10-10 08:58:44 +00:00
* @ brief Diagram : : removeItem
2020-07-01 18:31:19 +02:00
* Reimplemented from QGraphicsScene : : removeItem ( QGraphicsItem * item )
2015-07-12 15:05:59 +00:00
* Do some specific operation if item need it ( for exemple an element )
* @ param item
2014-10-10 08:58:44 +00:00
*/
2015-07-12 15:05:59 +00:00
void Diagram : : removeItem ( QGraphicsItem * item )
{
if ( ! item | | isReadOnly ( ) ) return ;
2014-10-10 08:58:44 +00:00
2015-07-12 15:05:59 +00:00
switch ( item - > type ( ) )
{
2017-01-02 13:42:16 +00:00
case Element : : Type :
{
2020-07-01 18:31:19 +02:00
auto elmt = static_cast < Element * > ( item ) ;
2017-01-02 13:42:16 +00:00
elmt - > unlinkAllElements ( ) ;
2020-07-01 18:31:19 +02:00
m_project - > dataBase ( ) - > removeElement ( elmt ) ;
2017-01-02 13:42:16 +00:00
break ;
2019-02-19 16:42:07 +00:00
}
2015-07-12 15:05:59 +00:00
case Conductor : : Type :
{
2018-07-30 15:24:29 +00:00
Conductor * conductor = static_cast < Conductor * > ( item ) ;
2015-07-12 15:05:59 +00:00
conductor - > terminal1 - > removeConductor ( conductor ) ;
conductor - > terminal2 - > removeConductor ( conductor ) ;
break ;
}
2019-02-19 16:42:07 +00:00
default : { break ; }
2015-07-12 15:05:59 +00:00
}
2009-04-04 21:47:07 +00:00
2014-10-10 08:58:44 +00:00
QGraphicsScene : : removeItem ( item ) ;
}
2020-08-02 15:09:21 +02:00
/**
@ brief Diagram : : titleChanged
emit ( diagramTitleChanged ( this , title ) ) ;
@ param title
*/
2012-02-06 21:21:43 +00:00
void Diagram : : titleChanged ( const QString & title ) {
emit ( diagramTitleChanged ( this , title ) ) ;
}
2010-12-24 21:00:11 +00:00
/**
This slot may be used to inform the diagram object that the given title
block template has changed . The diagram will thus flush its title
block - dedicated rendering cache .
@ param template_name Name of the title block template that has changed
*/
void Diagram : : titleBlockTemplateChanged ( const QString & template_name ) {
2010-12-24 23:35:40 +00:00
if ( border_and_titleblock . titleBlockTemplateName ( ) ! = template_name ) return ;
border_and_titleblock . titleBlockTemplateChanged ( template_name ) ;
2010-12-24 21:00:11 +00:00
update ( ) ;
}
/**
This slot has to be be used to inform this class that the given title block
template is about to be removed and is no longer accessible . This class
will either use the provided optional TitleBlockTemplate or the default
title block provided by QETApp : : defaultTitleBlockTemplate ( )
@ param template_name Name of the title block template that has changed
@ param new_template ( Optional ) Name of the title block template to use instead
*/
2015-11-16 08:59:43 +00:00
void Diagram : : titleBlockTemplateRemoved ( const QString & template_name , const QString & new_template )
{
if ( border_and_titleblock . titleBlockTemplateName ( ) ! = template_name ) return ;
2016-03-15 18:42:18 +00:00
const TitleBlockTemplate * final_template = m_project - > embeddedTitleBlockTemplatesCollection ( ) - > getTemplate ( new_template ) ;
2010-12-24 23:35:40 +00:00
border_and_titleblock . titleBlockTemplateRemoved ( template_name , final_template ) ;
update ( ) ;
}
/**
Set the template to use to render the title block of this diagram .
@ param template_name Name of the title block template .
*/
2015-11-16 08:59:43 +00:00
void Diagram : : setTitleBlockTemplate ( const QString & template_name )
{
2016-03-15 18:42:18 +00:00
if ( ! m_project ) return ;
2010-12-24 23:35:40 +00:00
QString current_name = border_and_titleblock . titleBlockTemplateName ( ) ;
2016-03-15 18:42:18 +00:00
const TitleBlockTemplate * titleblock_template = m_project - > embeddedTitleBlockTemplatesCollection ( ) - > getTemplate ( template_name ) ;
2010-12-24 23:35:40 +00:00
border_and_titleblock . titleBlockTemplateRemoved ( current_name , titleblock_template ) ;
2012-01-23 20:36:51 +00:00
2015-11-16 08:59:43 +00:00
if ( template_name ! = current_name )
2012-01-23 20:36:51 +00:00
emit ( usedTitleBlockTemplateChanged ( template_name ) ) ;
2010-12-24 21:00:11 +00:00
}
2007-02-25 17:53:16 +00:00
/**
2009-04-18 15:30:44 +00:00
Selectionne tous les objets du schema
2007-02-25 17:53:16 +00:00
*/
2009-04-18 15:30:44 +00:00
void Diagram : : selectAll ( ) {
if ( items ( ) . isEmpty ( ) ) return ;
blockSignals ( true ) ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) qgi - > setSelected ( true ) ;
2009-04-18 15:30:44 +00:00
blockSignals ( false ) ;
emit ( selectionChanged ( ) ) ;
}
/**
Deslectionne tous les objets selectionnes
*/
void Diagram : : deselectAll ( ) {
if ( items ( ) . isEmpty ( ) ) return ;
clearSelection ( ) ;
}
/**
Inverse l ' etat de selection de tous les objets du schema
*/
void Diagram : : invertSelection ( ) {
if ( items ( ) . isEmpty ( ) ) return ;
blockSignals ( true ) ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * item , items ( ) ) item - > setSelected ( ! item - > isSelected ( ) ) ;
2009-04-18 15:30:44 +00:00
blockSignals ( false ) ;
emit ( selectionChanged ( ) ) ;
2007-02-25 17:53:16 +00:00
}
2016-07-20 21:54:54 +00:00
/**
* @ brief Diagram : : updateLabels
* Update elements and conductors that reference folio field
* in their labels .
*/
2018-03-25 14:33:49 +00:00
void Diagram : : updateLabels ( )
{
for ( Conductor * cnd : content ( ) . conductors ( ) )
{
2016-12-28 10:03:47 +00:00
cnd - > refreshText ( ) ;
2016-07-20 21:54:54 +00:00
}
}
2016-07-26 18:52:49 +00:00
/**
* @ brief Diagram : : insertFolioSeqHash
* This class inserts a stringlist containing all
* sequential variables related to an autonum in a QHash
* @ param Hash to be accessed
* @ param autonum title
* @ param sequential to be treated
* @ param type to be treated
* @ param Numerotation Context to be manipulated
*/
2018-07-19 14:14:31 +00:00
void Diagram : : insertFolioSeqHash ( QHash < QString , QStringList > * hash , const QString & title , const QString & type , NumerotationContext * nc ) {
2016-08-29 15:37:42 +00:00
QStringList max ;
for ( int i = 0 ; i < nc - > size ( ) ; i + + ) {
if ( nc - > itemAt ( i ) . at ( 0 ) = = type ) {
nc - > replaceValue ( i , QString : : number ( nc - > itemAt ( i ) . at ( 3 ) . toInt ( ) ) ) ;
max . append ( QString : : number ( nc - > itemAt ( i ) . at ( 3 ) . toInt ( ) - nc - > itemAt ( i ) . at ( 2 ) . toInt ( ) ) ) ;
2016-07-26 18:52:49 +00:00
}
}
2016-08-29 15:37:42 +00:00
hash - > insert ( title , max ) ;
2016-07-26 18:52:49 +00:00
}
/**
2016-08-29 15:37:42 +00:00
* @ brief Diagram : : loadFolioSeqHash
2016-07-26 18:52:49 +00:00
* This class loads all folio sequential variables
* related to the current autonum
* @ param Hash to be accessed
* @ param autonum title
* @ param sequential to be treated
* @ param type to be treated
* @ param Numerotation Context to be manipulated
*/
2018-07-19 14:14:31 +00:00
void Diagram : : loadFolioSeqHash ( QHash < QString , QStringList > * hash , const QString & title , const QString & type , NumerotationContext * nc ) {
2016-07-26 18:52:49 +00:00
int j = 0 ;
for ( int i = 0 ; i < nc - > size ( ) ; i + + ) {
if ( nc - > itemAt ( i ) . at ( 0 ) = = type ) {
QString new_value ;
new_value = QString : : number ( hash - > value ( title ) . at ( j ) . toInt ( ) + nc - > itemAt ( i ) . at ( 2 ) . toInt ( ) ) ;
nc - > replaceValue ( i , new_value ) ;
j + + ;
}
}
}
2018-06-17 18:21:56 +00:00
/**
* @ brief Diagram : : changeZValue
* Change the Z value of the current selected item , according to @ option
*/
void Diagram : : changeZValue ( QET : : DepthOption option )
{
DiagramContent dc ( this ) ;
QUndoCommand * undo = new QUndoCommand ( tr ( " Modifier la profondeur " ) ) ;
QList < QGraphicsItem * > l = dc . items ( DiagramContent : : SelectedOnly | \
DiagramContent : : Elements | \
DiagramContent : : Shapes | \
DiagramContent : : Images ) ;
QList < QGraphicsObject * > list ;
for ( QGraphicsItem * item : l )
list < < item - > toGraphicsObject ( ) ;
qreal maxz = 0 ,
minz = 0 ;
for ( QGraphicsItem * item : this - > items ( ) )
{
qreal z = item - > zValue ( ) ;
if ( z > = Terminal : : Z - 2 )
continue ;
maxz = std : : max ( maxz , z ) ;
minz = std : : min ( minz , z ) ;
}
if ( option = = QET : : Raise )
{
for ( QGraphicsObject * qgo : list )
if ( qgo - > zValue ( ) < ( Terminal : : Z - 2 ) ) //Ensure item is always below terminal
new QPropertyUndoCommand ( qgo , " z " , qgo - > zValue ( ) , qgo - > zValue ( ) + 1 , undo ) ;
}
else if ( option = = QET : : Lower )
{
for ( QGraphicsObject * qgo : list )
if ( qgo - > zValue ( ) < ( Terminal : : Z - 2 ) ) //Ensure item is always below terminal
new QPropertyUndoCommand ( qgo , " z " , qgo - > zValue ( ) , qgo - > zValue ( ) - 1 , undo ) ;
}
else if ( option = = QET : : BringForward )
{
for ( QGraphicsObject * qgo : list )
new QPropertyUndoCommand ( qgo , " z " , qgo - > zValue ( ) , maxz + 1 , undo ) ;
}
else if ( option = = QET : : SendBackward )
{
for ( QGraphicsObject * qgo : list )
new QPropertyUndoCommand ( qgo , " z " , qgo - > zValue ( ) , minz - 1 , undo ) ;
}
if ( undo - > childCount ( ) )
this - > undoStack ( ) . push ( undo ) ;
else
delete undo ;
}
2016-07-26 18:52:49 +00:00
/**
* @ brief Diagram : : loadElmtFolioSeq
* This class loads all folio sequential variables related
* to the current autonum
*/
void Diagram : : loadElmtFolioSeq ( ) {
QString title = project ( ) - > elementCurrentAutoNum ( ) ;
NumerotationContext nc = project ( ) - > elementAutoNum ( title ) ;
2016-08-29 15:37:42 +00:00
2016-07-26 18:52:49 +00:00
//Unit Folio
if ( m_elmt_unitfolio_max . isEmpty ( ) | | ! m_elmt_unitfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %sequf_ " ) ) {
insertFolioSeqHash ( & m_elmt_unitfolio_max , title , " unitfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
else if ( m_elmt_unitfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %sequf_ " ) ) {
loadFolioSeqHash ( & m_elmt_unitfolio_max , title , " unitfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
2016-08-29 15:37:42 +00:00
2016-07-26 18:52:49 +00:00
//Ten Folio
if ( m_elmt_tenfolio_max . isEmpty ( ) | | ! m_elmt_tenfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %seqtf_ " ) ) {
insertFolioSeqHash ( & m_elmt_tenfolio_max , title , " tenfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
else if ( m_elmt_tenfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %seqtf_ " ) ) {
loadFolioSeqHash ( & m_elmt_tenfolio_max , title , " tenfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
2016-08-29 15:37:42 +00:00
2016-07-26 18:52:49 +00:00
//Hundred Folio
if ( m_elmt_hundredfolio_max . isEmpty ( ) | | ! m_elmt_hundredfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %seqhf_ " ) ) {
insertFolioSeqHash ( & m_elmt_hundredfolio_max , title , " hundredfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
else if ( m_elmt_hundredfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-08-29 15:37:42 +00:00
if ( project ( ) - > elementAutoNumCurrentFormula ( ) . contains ( " %seqhf_ " ) ) {
loadFolioSeqHash ( & m_elmt_hundredfolio_max , title , " hundredfolio " , & nc ) ;
project ( ) - > addElementAutoNum ( title , nc ) ;
}
}
}
/**
* @ brief Diagram : : loadCndFolioSeq
* This class loads all conductor folio sequential variables related
* to the current autonum
*/
void Diagram : : loadCndFolioSeq ( ) {
//Conductor
QString title = project ( ) - > conductorCurrentAutoNum ( ) ;
NumerotationContext nc = project ( ) - > conductorAutoNum ( title ) ;
2016-12-06 19:49:18 +00:00
QString formula = autonum : : numerotationContextToFormula ( nc ) ;
2016-08-29 15:37:42 +00:00
//Unit Folio
if ( m_cnd_unitfolio_max . isEmpty ( ) | | ! m_cnd_unitfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %sequf_ " ) ) {
2016-08-29 15:37:42 +00:00
insertFolioSeqHash ( & m_cnd_unitfolio_max , title , " unitfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
}
else if ( m_cnd_unitfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %sequf_ " ) ) {
2016-08-29 15:37:42 +00:00
loadFolioSeqHash ( & m_cnd_unitfolio_max , title , " unitfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
}
//Ten Folio
if ( m_cnd_tenfolio_max . isEmpty ( ) | | ! m_cnd_tenfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %seqtf_ " ) ) {
2016-08-29 15:37:42 +00:00
insertFolioSeqHash ( & m_cnd_tenfolio_max , title , " tenfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
}
else if ( m_cnd_tenfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %seqtf_ " ) ) {
2016-08-29 15:37:42 +00:00
loadFolioSeqHash ( & m_cnd_tenfolio_max , title , " tenfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
}
//Hundred Folio
if ( m_cnd_hundredfolio_max . isEmpty ( ) | | ! m_cnd_hundredfolio_max . contains ( title ) ) {
//Insert Initial Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %seqhf_ " ) ) {
2016-08-29 15:37:42 +00:00
insertFolioSeqHash ( & m_cnd_hundredfolio_max , title , " hundredfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
}
else if ( m_cnd_hundredfolio_max . contains ( title ) ) {
//Load Folio Current Value
2016-12-06 19:49:18 +00:00
if ( formula . contains ( " %seqhf_ " ) ) {
2016-08-29 15:37:42 +00:00
loadFolioSeqHash ( & m_cnd_hundredfolio_max , title , " hundredfolio " , & nc ) ;
project ( ) - > addConductorAutoNum ( title , nc ) ;
}
2016-07-26 18:52:49 +00:00
}
}
2009-04-03 19:30:25 +00:00
/**
@ return le titre du cartouche
*/
QString Diagram : : title ( ) const {
2010-12-20 02:45:36 +00:00
return ( border_and_titleblock . title ( ) ) ;
2009-04-03 19:30:25 +00:00
}
2013-12-29 13:39:48 +00:00
QList < Element * > Diagram : : elements ( ) const {
QList < Element * > element_list ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) {
2018-07-30 15:24:29 +00:00
if ( Element * elmt = qgraphicsitem_cast < Element * > ( qgi ) )
2013-12-29 13:39:48 +00:00
element_list < < elmt ;
}
return ( element_list ) ;
}
2016-09-01 19:41:49 +00:00
/**
* @ brief Diagram : : conductors
* Return the list containing all conductors
*/
QList < Conductor * > Diagram : : conductors ( ) const {
QList < Conductor * > cnd_list ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) {
2018-07-30 15:24:29 +00:00
if ( Conductor * cnd = qgraphicsitem_cast < Conductor * > ( qgi ) )
2016-09-01 19:41:49 +00:00
cnd_list < < cnd ;
}
return ( cnd_list ) ;
}
2018-04-05 09:37:35 +00:00
ElementsMover & Diagram : : elementsMover ( ) {
return m_elements_mover ;
2007-09-15 22:14:23 +00:00
}
2018-04-05 09:37:35 +00:00
ElementTextsMover & Diagram : : elementTextsMover ( ) {
return m_element_texts_mover ;
2014-10-25 21:21:52 +00:00
}
2009-04-03 19:30:25 +00:00
/**
Permet de savoir si un element est utilise sur un schema
@ param location Emplacement d ' un element
@ return true si l ' element location est utilise sur ce schema , false sinon
*/
2018-08-23 19:41:58 +00:00
bool Diagram : : usesElement ( const ElementsLocation & location )
{
for ( Element * element : elements ( ) ) {
2009-04-03 19:30:25 +00:00
if ( element - > location ( ) = = location ) {
return ( true ) ;
}
}
return ( false ) ;
}
2012-01-23 20:36:51 +00:00
/**
@ param a title block template name
@ return true if the provided template is used by this diagram , false
otherwise .
*/
bool Diagram : : usesTitleBlockTemplate ( const QString & name ) {
return ( name = = border_and_titleblock . titleBlockTemplateName ( ) ) ;
}
2016-07-20 15:07:21 +00:00
/**
* @ brief Diagram : : freezeElements
* Freeze every existent element label .
*/
2016-12-10 12:00:52 +00:00
void Diagram : : freezeElements ( bool freeze ) {
2017-02-05 16:18:50 +00:00
foreach ( Element * elmt , elements ( ) ) {
2016-12-10 12:00:52 +00:00
elmt - > freezeLabel ( freeze ) ;
2016-07-20 15:07:21 +00:00
}
}
/**
* @ brief Diagram : : unfreezeElements
* Unfreeze every existent element label .
*/
void Diagram : : unfreezeElements ( ) {
2017-02-05 16:18:50 +00:00
foreach ( Element * elmt , elements ( ) ) {
2016-12-10 12:00:52 +00:00
elmt - > freezeLabel ( false ) ;
2016-07-20 15:07:21 +00:00
}
}
/**
2016-09-01 19:41:49 +00:00
* @ brief Diagram : : freezeNewElements
2016-07-20 15:07:21 +00:00
* Set new element label to be frozen .
*/
2016-09-01 19:41:49 +00:00
void Diagram : : setFreezeNewElements ( bool b ) {
2016-12-10 12:00:52 +00:00
m_freeze_new_elements = b ;
2016-07-20 15:07:21 +00:00
}
/**
* @ brief Diagram : : freezeNewElements
* @ return current freeze new element status .
*/
bool Diagram : : freezeNewElements ( ) {
2016-12-10 12:00:52 +00:00
return m_freeze_new_elements ;
2016-07-20 15:07:21 +00:00
}
2016-09-01 19:41:49 +00:00
/**
* @ brief Diagram : : freezeConductors
* Freeze every existent conductor label .
*/
2016-12-12 10:52:44 +00:00
void Diagram : : freezeConductors ( bool freeze ) {
2017-02-05 16:18:50 +00:00
foreach ( Conductor * cnd , conductors ( ) ) {
2016-12-12 10:52:44 +00:00
cnd - > setFreezeLabel ( freeze ) ;
2016-09-01 19:41:49 +00:00
}
}
/**
* @ brief Diagram : : setfreezeNewConductors
* Set new conductor label to be frozen .
*/
void Diagram : : setFreezeNewConductors ( bool b ) {
m_freeze_new_conductors_ = b ;
}
/**
* @ brief Diagram : : freezeNewConductors
* @ return current freeze new conductor status .
*/
bool Diagram : : freezeNewConductors ( ) {
return m_freeze_new_conductors_ ;
}
2015-03-30 15:58:16 +00:00
/**
* @ brief Diagram : : adjustSceneRect
* Recalcul and adjust the size of the scene
*/
void Diagram : : adjustSceneRect ( )
{
QRectF old_rect = sceneRect ( ) ;
setSceneRect ( border_and_titleblock . borderAndTitleBlockRect ( ) . united ( itemsBoundingRect ( ) ) ) ;
update ( old_rect . united ( sceneRect ( ) ) ) ;
}
2009-11-22 16:12:22 +00:00
/**
Cette methode permet d ' appliquer de nouvelles options de rendu tout en
accedant aux proprietes de rendu en cours .
@ param new_properties Nouvelles options de rendu a appliquer
@ return les options de rendu avant l ' application de new_properties
*/
ExportProperties Diagram : : applyProperties ( const ExportProperties & new_properties ) {
// exporte les options de rendu en cours
ExportProperties old_properties ;
old_properties . draw_grid = displayGrid ( ) ;
2010-12-20 02:45:36 +00:00
old_properties . draw_border = border_and_titleblock . borderIsDisplayed ( ) ;
2011-01-09 00:01:38 +00:00
old_properties . draw_titleblock = border_and_titleblock . titleBlockIsDisplayed ( ) ;
2009-11-22 16:12:22 +00:00
old_properties . draw_terminals = drawTerminals ( ) ;
old_properties . draw_colored_conductors = drawColoredConductors ( ) ;
old_properties . exported_area = useBorder ( ) ? QET : : BorderArea : QET : : ElementsArea ;
// applique les nouvelles options de rendu
setUseBorder ( new_properties . exported_area = = QET : : BorderArea ) ;
setDrawTerminals ( new_properties . draw_terminals ) ;
setDrawColoredConductors ( new_properties . draw_colored_conductors ) ;
setDisplayGrid ( new_properties . draw_grid ) ;
2010-12-20 02:45:36 +00:00
border_and_titleblock . displayBorder ( new_properties . draw_border ) ;
border_and_titleblock . displayTitleBlock ( new_properties . draw_titleblock ) ;
2009-11-22 16:12:22 +00:00
// retourne les anciennes options de rendu
return ( old_properties ) ;
}
2009-05-20 21:29:17 +00:00
/**
@ param pos Position cartesienne ( ex : 10.3 , 45.2 ) a transformer en position
dans la grille ( ex : B2 )
@ return la position dans la grille correspondant a pos
*/
DiagramPosition Diagram : : convertPosition ( const QPointF & pos ) {
2010-12-20 02:45:36 +00:00
// delegue le calcul au BorderTitleBlock
2015-03-18 18:07:18 +00:00
DiagramPosition diagram_position = border_and_titleblock . convertPosition ( pos ) ;
2009-05-20 21:29:17 +00:00
// embarque la position cartesienne
diagram_position . setPosition ( pos ) ;
return ( diagram_position ) ;
}
2014-06-14 16:04:34 +00:00
/**
* @ brief Diagram : : snapToGrid
* Return a nearest snap point of p
* @ param p point to find the nearest snaped point
* @ return
*/
2015-02-12 21:37:56 +00:00
QPointF Diagram : : snapToGrid ( const QPointF & p )
{
2020-03-27 21:21:49 +01:00
QSettings settings ;
int xGrid = settings . value ( " diagrameditor/Xgrid " , Diagram : : xGrid ) . toInt ( ) ;
int yGrid = settings . value ( " diagrameditor/Ygrid " , Diagram : : yGrid ) . toInt ( ) ;
//Return a point rounded to the nearest pixel
2015-02-12 21:37:56 +00:00
if ( QApplication : : keyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) )
{
int p_x = qRound ( p . x ( ) ) ;
int p_y = qRound ( p . y ( ) ) ;
return ( QPointF ( p_x , p_y ) ) ;
2015-02-12 12:43:13 +00:00
}
2015-02-12 21:37:56 +00:00
//Return a point snapped to the grid
2020-03-27 21:21:49 +01:00
int p_x = qRound ( p . x ( ) / xGrid ) * xGrid ;
int p_y = qRound ( p . y ( ) / yGrid ) * yGrid ;
2014-06-14 16:04:34 +00:00
return ( QPointF ( p_x , p_y ) ) ;
}
2015-02-12 12:43:13 +00:00
2007-10-10 17:50:26 +00:00
/**
Definit s ' il faut afficher ou non les bornes
@ param dt true pour afficher les bornes , false sinon
*/
2007-09-30 12:35:25 +00:00
void Diagram : : setDrawTerminals ( bool dt ) {
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) {
2018-07-30 15:24:29 +00:00
if ( Terminal * t = qgraphicsitem_cast < Terminal * > ( qgi ) ) {
2007-09-30 12:35:25 +00:00
t - > setVisible ( dt ) ;
}
}
}
2007-10-03 13:11:47 +00:00
2009-11-22 16:12:22 +00:00
/**
Definit s ' il faut respecter ou non les couleurs des conducteurs .
Si non , les conducteurs sont tous dessines en noir .
@ param dcc true pour respecter les couleurs , false sinon
*/
void Diagram : : setDrawColoredConductors ( bool dcc ) {
draw_colored_conductors_ = dcc ;
}
2007-10-10 17:50:26 +00:00
/**
@ return la liste des conducteurs selectionnes sur le schema
*/
2007-10-03 17:02:39 +00:00
QSet < Conductor * > Diagram : : selectedConductors ( ) const {
QSet < Conductor * > conductors_set ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , selectedItems ( ) ) {
2018-07-30 15:24:29 +00:00
if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( qgi ) ) {
2007-10-03 17:02:39 +00:00
conductors_set < < c ;
2007-10-03 13:11:47 +00:00
}
}
2007-10-03 17:02:39 +00:00
return ( conductors_set ) ;
2007-10-03 13:11:47 +00:00
}
2007-11-03 20:20:34 +00:00
/// @return true si le presse-papier semble contenir un schema
bool Diagram : : clipboardMayContainDiagram ( ) {
QString clipboard_text = QApplication : : clipboard ( ) - > text ( ) . trimmed ( ) ;
bool may_be_diagram = clipboard_text . startsWith ( " <diagram " ) & & clipboard_text . endsWith ( " </diagram> " ) ;
return ( may_be_diagram ) ;
}
2007-11-09 13:06:51 +00:00
2009-04-03 19:30:25 +00:00
/**
@ return le projet auquel ce schema appartient ou 0 s ' il s ' agit d ' un schema
independant .
*/
QETProject * Diagram : : project ( ) const {
2016-03-15 18:42:18 +00:00
return ( m_project ) ;
2009-04-03 19:30:25 +00:00
}
2009-04-05 11:48:26 +00:00
2011-09-08 19:03:13 +00:00
/**
@ return the folio number of this diagram within its parent project , or - 1
if it is has no parent project
*/
int Diagram : : folioIndex ( ) const {
2016-03-15 18:42:18 +00:00
if ( ! m_project ) return ( - 1 ) ;
return ( m_project - > folioIndex ( this ) ) ;
2011-09-08 19:03:13 +00:00
}
2011-08-29 21:50:43 +00:00
/**
@ param fallback_to_project When a diagram does not have a declared version ,
this method will use the one declared by its parent project only if
fallback_to_project is true .
@ return the declared QElectroTech version of this diagram
*/
qreal Diagram : : declaredQElectroTechVersion ( bool fallback_to_project ) const {
if ( diagram_qet_version_ ! = - 1 ) {
return diagram_qet_version_ ;
}
2016-03-15 18:42:18 +00:00
if ( fallback_to_project & & m_project ) {
return ( m_project - > declaredQElectroTechVersion ( ) ) ;
2011-08-29 21:50:43 +00:00
}
return ( - 1 ) ;
}
2009-04-03 19:30:25 +00:00
/**
2014-12-21 13:17:35 +00:00
* @ brief Diagram : : isReadOnly
* @ return true if this diagram is read only .
* This method is same has call Diagram : : project ( ) - > isReadOnly ( )
*/
bool Diagram : : isReadOnly ( ) const
{
2016-03-15 18:42:18 +00:00
return m_project - > isReadOnly ( ) ;
2009-04-03 19:30:25 +00:00
}
2007-11-09 13:06:51 +00:00
/**
@ return Le contenu du schema . Les conducteurs sont tous places dans
conductorsToMove .
*/
DiagramContent Diagram : : content ( ) const {
DiagramContent dc ;
2017-02-05 16:18:50 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) {
2018-07-30 15:24:29 +00:00
if ( Element * e = qgraphicsitem_cast < Element * > ( qgi ) ) {
2017-08-03 17:36:08 +00:00
dc . m_elements < < e ;
2018-07-30 15:24:29 +00:00
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( qgi ) ) {
2017-08-03 17:36:08 +00:00
dc . m_text_fields < < iti ;
2018-07-30 15:24:29 +00:00
} else if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( qgi ) ) {
2017-08-03 17:36:08 +00:00
dc . m_conductors_to_move < < c ;
2007-11-09 13:06:51 +00:00
}
}
return ( dc ) ;
}
2009-06-16 22:37:15 +00:00
/**
2017-08-03 17:36:08 +00:00
* @ brief Diagram : : canRotateSelection
* @ return True if a least one of selected items can be rotated
*/
bool Diagram : : canRotateSelection ( ) const
{
for ( QGraphicsItem * qgi : selectedItems ( ) )
{
if ( qgi - > type ( ) = = IndependentTextItem : : Type | |
qgi - > type ( ) = = ConductorTextItem : : Type | |
qgi - > type ( ) = = DiagramImageItem : : Type | |
qgi - > type ( ) = = Element : : Type | |
2017-12-05 20:51:54 +00:00
qgi - > type ( ) = = DynamicElementTextItem : : Type )
return true ;
if ( qgi - > type ( ) = = QGraphicsItemGroup : : Type )
if ( dynamic_cast < ElementTextItemGroup * > ( qgi ) )
return true ;
2009-06-16 22:37:15 +00:00
}
2017-08-03 17:36:08 +00:00
return false ;
2009-06-16 22:37:15 +00:00
}