2007-12-01 10:47:15 +00:00
/*
2012-01-01 22:51:51 +00:00
Copyright 2006 - 2012 Xavier Guerrin
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>
2007-10-03 17:02:39 +00:00
# include "conductor.h"
2010-04-18 17:59:54 +00:00
# include "conductortextitem.h"
2007-01-30 22:32:21 +00:00
# include "customelement.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 "elementtextitem.h"
2010-05-08 21:24:43 +00:00
# include "elementsmover.h"
# include "elementtextsmover.h"
2010-04-18 17:59:54 +00:00
# include "exportdialog.h"
# include "ghostelement.h"
# include "independenttextitem.h"
# include "qetapp.h"
2006-10-27 15:47:22 +00:00
2007-10-10 22:35:32 +00:00
const int Diagram : : xGrid = 10 ;
const int Diagram : : yGrid = 10 ;
const qreal Diagram : : margin = 5.0 ;
2006-10-27 15:47:22 +00:00
/**
Constructeur
@ param parent Le QObject parent du schema
*/
2007-10-11 12:51:56 +00:00
Diagram : : Diagram ( QObject * parent ) :
QGraphicsScene ( parent ) ,
draw_grid ( true ) ,
use_border ( true ) ,
2009-04-03 19:30:25 +00:00
draw_terminals ( true ) ,
2009-11-22 16:12:22 +00:00
draw_colored_conductors_ ( true ) ,
2009-04-03 19:30:25 +00:00
project_ ( 0 ) ,
2011-08-29 21:50:43 +00:00
read_only_ ( false ) ,
diagram_qet_version_ ( - 1 )
2007-10-11 12:51:56 +00:00
{
2008-07-17 22:57:50 +00:00
undo_stack = new QUndoStack ( ) ;
qgi_manager = new QGIManager ( this ) ;
2006-10-27 15:47:22 +00:00
setBackgroundBrush ( Qt : : white ) ;
2007-10-03 17:02:39 +00:00
conductor_setter = new QGraphicsLineItem ( 0 , 0 ) ;
conductor_setter - > setZValue ( 1000000 ) ;
2006-10-27 15:47:22 +00:00
QPen t ;
t . setColor ( Qt : : black ) ;
t . setWidthF ( 1.5 ) ;
t . setStyle ( Qt : : DashLine ) ;
2007-10-03 17:02:39 +00:00
conductor_setter - > setPen ( t ) ;
conductor_setter - > setLine ( QLineF ( QPointF ( 0.0 , 0.0 ) , QPointF ( 0.0 , 0.0 ) ) ) ;
2010-05-08 21:24:43 +00:00
// initialise les objets gerant les deplacements
elements_mover_ = new ElementsMover ( ) ; // deplacements d'elements/conducteurs/textes
element_texts_mover_ = new ElementTextsMover ( ) ; // deplacements d'ElementTextItem
2010-12-24 23:35:40 +00:00
connect (
& border_and_titleblock , SIGNAL ( needTitleBlockTemplate ( const QString & ) ) ,
this , SLOT ( setTitleBlockTemplate ( const QString & ) )
) ;
2012-02-06 21:21:43 +00:00
connect (
& border_and_titleblock , SIGNAL ( diagramTitleChanged ( const QString & ) ) ,
this , SLOT ( titleChanged ( const QString & ) )
) ;
2006-10-27 15:47:22 +00:00
}
2007-04-12 03:13:13 +00:00
/**
Destructeur
*/
Diagram : : ~ Diagram ( ) {
2008-07-17 22:57:50 +00:00
// suppression de la liste des annulations - l'undo stack fait appel au qgimanager pour supprimer certains elements
delete undo_stack ;
// suppression du QGIManager - tous les elements qu'il connait sont supprimes
delete qgi_manager ;
2010-05-08 21:24:43 +00:00
// suppression des objets gerant les deplacements
delete elements_mover_ ;
delete element_texts_mover_ ;
2008-07-17 22:57:50 +00:00
// recense les items supprimables
QList < QGraphicsItem * > deletable_items ;
foreach ( QGraphicsItem * qgi , items ( ) ) {
if ( qgi - > parentItem ( ) ) continue ;
if ( qgraphicsitem_cast < Conductor * > ( qgi ) ) continue ;
deletable_items < < qgi ;
}
2010-12-19 18:14:05 +00:00
2008-07-17 22:57:50 +00:00
// suppression des items supprimables
foreach ( QGraphicsItem * qgi_d , deletable_items ) {
delete qgi_d ;
}
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 ) ;
p - > setBrush ( Qt : : white ) ;
p - > drawRect ( r ) ;
2007-09-04 18:15:41 +00:00
if ( draw_grid ) {
2006-10-27 15:47:22 +00:00
// dessine les points de la grille
p - > setPen ( Qt : : black ) ;
p - > setBrush ( Qt : : NoBrush ) ;
qreal limite_x = r . x ( ) + r . width ( ) ;
qreal limite_y = r . y ( ) + r . height ( ) ;
int g_x = ( int ) ceil ( r . x ( ) ) ;
2007-10-10 22:35:32 +00:00
while ( g_x % xGrid ) + + g_x ;
2006-10-27 15:47:22 +00:00
int g_y = ( int ) ceil ( r . 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
2010-12-20 02:45:36 +00:00
if ( use_border ) border_and_titleblock . draw ( p , margin , margin ) ;
2006-10-27 15:47:22 +00:00
p - > restore ( ) ;
}
2007-09-15 23:45:27 +00:00
/**
2007-10-10 17:50:26 +00:00
Gere les enfoncements de touches du clavier
2007-09-15 23:45:27 +00:00
@ param e QKeyEvent decrivant l ' evenement clavier
*/
void Diagram : : keyPressEvent ( QKeyEvent * e ) {
2012-04-28 23:22:34 +00:00
bool transmit_event = true ;
2009-04-03 19:30:25 +00:00
if ( ! isReadOnly ( ) ) {
QPointF movement ;
switch ( e - > key ( ) ) {
case Qt : : Key_Left : movement = QPointF ( - xGrid , 0.0 ) ; break ;
case Qt : : Key_Right : movement = QPointF ( + xGrid , 0.0 ) ; break ;
case Qt : : Key_Up : movement = QPointF ( 0.0 , - yGrid ) ; break ;
case Qt : : Key_Down : movement = QPointF ( 0.0 , + yGrid ) ; break ;
}
if ( ! movement . isNull ( ) & & ! focusItem ( ) ) {
2010-05-08 21:24:43 +00:00
beginMoveElements ( ) ;
continueMoveElements ( movement ) ;
2012-04-16 06:33:26 +00:00
e - > accept ( ) ;
2012-04-28 23:22:34 +00:00
transmit_event = false ;
2009-04-03 19:30:25 +00:00
}
2007-09-15 23:45:27 +00:00
}
2012-04-28 23:22:34 +00:00
if ( transmit_event ) {
2012-04-16 06:33:26 +00:00
QGraphicsScene : : keyPressEvent ( e ) ;
}
2007-09-15 23:45:27 +00:00
}
2007-10-10 17:50:26 +00:00
/**
Gere les relachements de touches du clavier
@ param e QKeyEvent decrivant l ' evenement clavier
*/
2007-09-15 23:45:27 +00:00
void Diagram : : keyReleaseEvent ( QKeyEvent * e ) {
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
) {
2010-05-08 21:24:43 +00:00
endMoveElements ( ) ;
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
}
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 ;
if ( ! use_border ) {
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 ,
2010-12-20 02:45:36 +00:00
border_and_titleblock . borderWidth ( ) + 2.0 * margin ,
border_and_titleblock . borderHeight ( ) + 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 ( ) ;
foreach ( QGraphicsItem * qgi , selected_elmts ) qgi - > setSelected ( false ) ;
// 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
foreach ( QGraphicsItem * qgi , selected_elmts ) qgi - > setSelected ( true ) ;
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 ;
if ( ! use_border ) {
QRectF items_rect = itemsBoundingRect ( ) ;
image_width = items_rect . width ( ) ;
image_height = items_rect . height ( ) ;
} else {
2010-12-20 02:45:36 +00:00
image_width = border_and_titleblock . borderWidth ( ) ;
image_height = border_and_titleblock . borderHeight ( ) ;
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 ( ) ) ;
}
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
2007-03-09 19:18:55 +00:00
QDomElement racine = document . createElement ( " diagram " ) ;
2006-10-27 15:47:22 +00:00
2011-08-29 21:50:43 +00:00
// add the application version number
racine . setAttribute ( " version " , QET : : version ) ;
2006-10-27 15:47:22 +00:00
// proprietes du schema
2010-04-18 21:08:49 +00:00
if ( whole_content ) {
2011-01-09 00:01:38 +00:00
border_and_titleblock . titleBlockToXml ( racine ) ;
border_and_titleblock . borderToXml ( racine ) ;
2007-10-14 21:38:27 +00:00
// type de conducteur par defaut
QDomElement default_conductor = document . createElement ( " defaultconductor " ) ;
2009-04-03 19:30:25 +00:00
defaultConductorProperties . toXml ( default_conductor ) ;
2007-10-14 21:38:27 +00:00
racine . appendChild ( default_conductor ) ;
2006-10-27 15:47:22 +00:00
}
document . appendChild ( racine ) ;
// si le schema ne contient pas d'element (et donc pas de conducteurs), on retourne de suite le document XML
if ( items ( ) . isEmpty ( ) ) return ( document ) ;
2007-10-27 13:18:17 +00:00
// creation de trois listes : une qui contient les elements, une qui contient les conducteurs, une qui contient les champs de texte
QList < Element * > list_elements ;
QList < Conductor * > list_conductors ;
QList < DiagramTextItem * > list_texts ;
2006-10-27 15:47:22 +00:00
2009-04-11 13:09:47 +00:00
// Determine les elements a "XMLiser"
2006-10-27 15:47:22 +00:00
foreach ( QGraphicsItem * qgi , items ( ) ) {
if ( Element * elmt = qgraphicsitem_cast < Element * > ( qgi ) ) {
2010-04-18 21:08:49 +00:00
if ( whole_content ) list_elements < < elmt ;
2007-10-27 13:18:17 +00:00
else if ( elmt - > isSelected ( ) ) list_elements < < elmt ;
2007-10-03 17:02:39 +00:00
} else if ( Conductor * f = qgraphicsitem_cast < Conductor * > ( qgi ) ) {
2010-04-18 21:08:49 +00:00
if ( whole_content ) list_conductors < < f ;
2007-01-29 00:41:12 +00:00
// lorsqu'on n'exporte pas tout le diagram, il faut retirer les conducteurs non selectionnes
2010-04-18 17:59:54 +00:00
// et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas selectionne
else if ( f - > terminal1 - > parentItem ( ) - > isSelected ( ) & & f - > terminal2 - > parentItem ( ) - > isSelected ( ) ) {
list_conductors < < f ;
2007-10-27 13:18:17 +00:00
}
2010-04-18 17:59:54 +00:00
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( qgi ) ) {
2010-04-18 21:08:49 +00:00
if ( whole_content ) list_texts < < iti ;
2010-04-18 17:59:54 +00:00
else if ( iti - > isSelected ( ) ) list_texts < < iti ;
2006-10-27 15:47:22 +00: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
// enregistrement des elements
2007-10-27 13:18:17 +00:00
if ( ! list_elements . isEmpty ( ) ) {
QDomElement elements = document . createElement ( " elements " ) ;
foreach ( Element * elmt , list_elements ) {
elements . appendChild ( elmt - > toXml ( document , table_adr_id ) ) ;
}
racine . appendChild ( elements ) ;
2006-10-27 15:47:22 +00:00
}
// enregistrement des conducteurs
2007-10-27 13:18:17 +00:00
if ( ! list_conductors . isEmpty ( ) ) {
QDomElement conductors = document . createElement ( " conductors " ) ;
foreach ( Conductor * cond , list_conductors ) {
conductors . appendChild ( cond - > toXml ( document , table_adr_id ) ) ;
}
racine . appendChild ( conductors ) ;
}
// enregistrement des champs de texte
if ( ! list_texts . isEmpty ( ) ) {
QDomElement inputs = document . createElement ( " inputs " ) ;
foreach ( DiagramTextItem * dti , list_texts ) {
inputs . appendChild ( dti - > toXml ( document ) ) ;
}
racine . appendChild ( inputs ) ;
2006-10-27 15:47:22 +00:00
}
// on retourne le document XML ainsi genere
return ( document ) ;
}
/**
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 ) ;
// initialise le document XML interne a partir de l'element XML fourni en parametre
if ( from_xml ) {
xml_document . clear ( ) ;
xml_document . appendChild ( xml_document . importNode ( document , true ) ) ;
// a ce stade, le document XML interne contient le code XML qui a ete importe, et non pas une version re-exporte par la methode toXml()
}
return ( from_xml ) ;
}
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 ) {
QDomElement root = document ;
2006-10-27 15:47:22 +00:00
// le premier element doit etre un schema
2007-10-27 13:18:17 +00:00
if ( root . tagName ( ) ! = " diagram " ) return ( false ) ;
2007-01-29 00:41:12 +00:00
2006-10-27 15:47:22 +00:00
// lecture des attributs de ce schema
2007-01-28 00:53:17 +00:00
if ( consider_informations ) {
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 ;
}
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
2007-10-14 21:38:27 +00:00
// repere le permier element "defaultconductor"
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
}
2007-01-28 00:53:17 +00:00
}
2006-10-27 15:47:22 +00:00
// si la racine n'a pas d'enfant : le chargement est fini (schema vide)
2009-04-03 19:30:25 +00:00
if ( root . firstChild ( ) . isNull ( ) ) {
write ( document ) ;
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 & &
project_ - > state ( ) = = QETProject : : ProjectParsingRunning
) ;
2007-10-27 13:18:17 +00:00
// chargement de tous les elements du fichier XML
QList < Element * > added_elements ;
QHash < int , Terminal * > table_adr_id ;
2010-04-18 17:59:54 +00:00
foreach ( QDomElement element_xml , QET : : findInDomElement ( root , " elements " , " element " ) ) {
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 " ) ;
2009-04-03 19:30:25 +00:00
ElementsLocation element_location = ElementsLocation ( type_id ) ;
if ( type_id . startsWith ( " embed:// " ) ) element_location . setProject ( project_ ) ;
CustomElement * nvel_elmt = new CustomElement ( element_location ) ;
2007-10-27 13:18:17 +00:00
if ( nvel_elmt - > isNull ( ) ) {
2009-04-13 01:35:01 +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 ( nvel_elmt - > state ( ) ) ;
qDebug ( ) < < qPrintable ( debug_message ) ;
2007-10-27 13:18:17 +00:00
delete nvel_elmt ;
2009-04-03 19:30:25 +00:00
2009-04-13 01:35:01 +00:00
qDebug ( ) < < " Diagram::fromXml() : Utilisation d'un GhostElement en lieu et place de cet element. " ;
2009-04-03 19:30:25 +00:00
nvel_elmt = new GhostElement ( element_location ) ;
2007-10-27 13:18:17 +00:00
}
// charge les caracteristiques de l'element
2010-07-18 19:16:52 +00:00
if ( nvel_elmt - > fromXml ( element_xml , table_adr_id , handle_inputs_rotation ) ) {
2007-10-27 13:18:17 +00:00
// ajout de l'element au schema et a la liste des elements ajoutes
2009-04-04 21:47:07 +00:00
addElement ( nvel_elmt ) ;
2007-10-27 13:18:17 +00:00
added_elements < < nvel_elmt ;
} else {
delete nvel_elmt ;
2009-04-13 01:35:01 +00:00
qDebug ( ) < < " Diagram::fromXml() : Le chargement des parametres d'un element a echoue " ;
2006-10-27 15:47:22 +00:00
}
}
2007-10-27 13:18:17 +00:00
// chargement de tous les textes du fichiers XML
2010-04-18 17:59:54 +00:00
QList < IndependentTextItem * > added_texts ;
foreach ( QDomElement text_xml , QET : : findInDomElement ( root , " inputs " , " input " ) ) {
IndependentTextItem * iti = new IndependentTextItem ( this ) ;
iti - > fromXml ( text_xml ) ;
addIndependentTextItem ( iti ) ;
added_texts < < iti ;
2007-10-27 13:18:17 +00:00
}
2006-10-27 15:47:22 +00:00
2007-10-27 13:18:17 +00:00
// gere la translation des nouveaux elements et texte si celle-ci est demandee
2006-10-27 15:47:22 +00:00
if ( position ! = QPointF ( ) ) {
// determine quel est le coin superieur gauche du rectangle entourant les elements ajoutes
qreal minimum_x = 0 , minimum_y = 0 ;
bool init = false ;
2007-10-27 13:18:17 +00:00
QList < QGraphicsItem * > added_items ;
foreach ( Element * added_element , added_elements ) added_items < < added_element ;
foreach ( DiagramTextItem * added_text , added_texts ) added_items < < added_text ;
foreach ( QGraphicsItem * item , added_items ) {
2007-11-02 18:04:13 +00:00
QPointF csg = item - > mapToScene ( item - > boundingRect ( ) ) . boundingRect ( ) . topLeft ( ) ;
2006-10-27 15:47:22 +00:00
qreal px = csg . x ( ) ;
qreal py = csg . y ( ) ;
if ( ! init ) {
minimum_x = px ;
minimum_y = py ;
init = true ;
} else {
if ( px < minimum_x ) minimum_x = px ;
if ( py < minimum_y ) minimum_y = py ;
}
}
qreal diff_x = position . x ( ) - minimum_x ;
qreal diff_y = position . y ( ) - minimum_y ;
2007-10-27 13:18:17 +00:00
foreach ( Element * added_element , added_elements ) {
added_element - > setPos ( added_element - > pos ( ) . x ( ) + diff_x , added_element - > pos ( ) . y ( ) + diff_y ) ;
}
foreach ( DiagramTextItem * added_text , added_texts ) {
added_text - > setPos ( added_text - > pos ( ) . x ( ) + diff_x , added_text - > pos ( ) . y ( ) + diff_y ) ;
2006-10-27 15:47:22 +00:00
}
}
// chargement de tous les Conducteurs du fichier XML
2007-10-27 13:18:17 +00:00
QList < Conductor * > added_conductors ;
foreach ( QDomElement f , QET : : findInDomElement ( root , " conductors " , " conductor " ) ) {
if ( ! Conductor : : valideXml ( f ) ) continue ;
// verifie que les bornes que le conducteur relie sont connues
int id_p1 = f . attribute ( " terminal1 " ) . toInt ( ) ;
int id_p2 = f . attribute ( " terminal2 " ) . toInt ( ) ;
if ( table_adr_id . contains ( id_p1 ) & & table_adr_id . contains ( id_p2 ) ) {
// pose le conducteur... si c'est possible
Terminal * p1 = table_adr_id . value ( id_p1 ) ;
Terminal * p2 = table_adr_id . value ( id_p2 ) ;
if ( p1 ! = p2 ) {
bool can_add_conductor = true ;
2007-12-09 10:30:35 +00:00
bool cia = ( ( Element * ) p2 - > parentItem ( ) ) - > internalConnections ( ) ;
2007-10-27 13:18:17 +00:00
if ( ! cia ) {
foreach ( QGraphicsItem * item , p2 - > parentItem ( ) - > children ( ) ) {
if ( item = = p1 ) can_add_conductor = false ;
2007-02-18 19:33:15 +00:00
}
2006-10-27 15:47:22 +00:00
}
2007-10-27 13:18:17 +00:00
if ( can_add_conductor ) {
2010-04-18 17:59:54 +00:00
Conductor * c = new Conductor ( table_adr_id . value ( id_p1 ) , table_adr_id . value ( id_p2 ) , this ) ;
2007-10-27 13:18:17 +00:00
c - > fromXml ( f ) ;
added_conductors < < c ;
}
}
2009-04-13 01:35:01 +00:00
} else qDebug ( ) < < " Diagram::fromXml() : Le chargement du conducteur " < < id_p1 < < id_p2 < < " a echoue " ;
2006-10-27 15:47:22 +00:00
}
2007-10-27 13:18:17 +00:00
// remplissage des listes facultatives
2009-04-28 18:04:29 +00:00
if ( content_ptr ) {
2010-05-08 21:24:43 +00:00
content_ptr - > elements = added_elements . toSet ( ) ;
content_ptr - > conductorsToMove = added_conductors . toSet ( ) ;
content_ptr - > textFields = added_texts . toSet ( ) ;
2007-11-09 13:06:51 +00:00
}
2007-10-27 13:18:17 +00:00
2006-10-27 15:47:22 +00:00
return ( true ) ;
}
2009-04-03 19:30:25 +00:00
/**
Enregistre le schema XML dans son document XML interne et emet le signal
written ( ) .
*/
void Diagram : : write ( ) {
qDebug ( ) < < qPrintable ( QString ( " Diagram::write() : saving changes from diagram \" %1 \" [%2] " ) . arg ( title ( ) ) . arg ( QET : : pointerString ( this ) ) ) ;
write ( toXml ( ) . documentElement ( ) ) ;
undoStack ( ) . setClean ( ) ;
}
/**
Enregistre un element XML dans son document XML interne et emet le signal
written ( ) .
@ param element xml a enregistrer
*/
void Diagram : : write ( const QDomElement & element ) {
xml_document . clear ( ) ;
xml_document . appendChild ( xml_document . importNode ( element , true ) ) ;
emit ( written ( ) ) ;
}
/**
@ return true si la fonction write a deja ete appele ( pour etre plus exact :
si le document XML utilise en interne n ' est pas vide ) , false sinon
*/
bool Diagram : : wasWritten ( ) const {
return ( ! xml_document . isNull ( ) ) ;
}
/**
@ return le schema en XML tel qu ' il doit etre enregistre dans le fichier projet
@ param xml_doc document XML a utiliser pour creer l ' element
*/
QDomElement Diagram : : writeXml ( QDomDocument & xml_doc ) const {
// si le schema n'a pas ete enregistre explicitement, on n'ecrit rien
if ( ! wasWritten ( ) ) return ( QDomElement ( ) ) ;
QDomElement diagram_elmt = xml_document . documentElement ( ) ;
QDomNode new_node = xml_doc . importNode ( diagram_elmt , true ) ;
return ( new_node . toElement ( ) ) ;
}
2009-04-04 21:47:07 +00:00
/**
Ajoute un element sur le schema
@ param element Element a ajouter
*/
void Diagram : : addElement ( Element * element ) {
if ( ! element | | isReadOnly ( ) ) return ;
// ajoute l'element au schema
if ( element - > scene ( ) ! = this ) {
addItem ( element ) ;
}
// surveille les modifications de ses champs de texte
foreach ( ElementTextItem * eti , element - > texts ( ) ) {
connect (
eti ,
SIGNAL ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) ) ,
this ,
SLOT ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) )
) ;
}
}
/**
Ajoute un conducteur sur le schema
@ param conductor Conducteur a ajouter
*/
void Diagram : : addConductor ( Conductor * conductor ) {
if ( ! conductor | | isReadOnly ( ) ) return ;
// ajoute le conducteur au schema
if ( conductor - > scene ( ) ! = this ) {
addItem ( conductor ) ;
conductor - > terminal1 - > addConductor ( conductor ) ;
conductor - > terminal2 - > addConductor ( conductor ) ;
}
}
/**
Aoute un champ de texte independant sur le schema
2010-04-18 17:59:54 +00:00
@ param iti Champ de texte a ajouter
2009-04-04 21:47:07 +00:00
*/
2010-04-18 17:59:54 +00:00
void Diagram : : addIndependentTextItem ( IndependentTextItem * iti ) {
if ( ! iti | | isReadOnly ( ) ) return ;
2009-04-04 21:47:07 +00:00
// ajoute le champ de texte au schema
2010-04-18 17:59:54 +00:00
if ( iti - > scene ( ) ! = this ) {
addItem ( iti ) ;
2009-04-04 21:47:07 +00:00
}
// surveille les modifications apportees au champ de texte
connect (
2010-04-18 17:59:54 +00:00
iti ,
2009-04-04 21:47:07 +00:00
SIGNAL ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) ) ,
this ,
SLOT ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) )
) ;
}
/**
Enleve un element du schema
@ param element Element a enlever
*/
void Diagram : : removeElement ( Element * element ) {
if ( ! element | | isReadOnly ( ) ) return ;
// enleve l'element au schema
removeItem ( element ) ;
// arrete la surveillance des modifications de ses champs de texte
foreach ( ElementTextItem * eti , element - > texts ( ) ) {
disconnect (
eti ,
SIGNAL ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) ) ,
this ,
SLOT ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) )
) ;
}
}
/**
Enleve un conducteur du schema
@ param conductor Conducteur a enlever
*/
void Diagram : : removeConductor ( Conductor * conductor ) {
if ( ! conductor | | isReadOnly ( ) ) return ;
// detache le conducteur sans le detruire
conductor - > terminal1 - > removeConductor ( conductor ) ;
conductor - > terminal2 - > removeConductor ( conductor ) ;
// enleve le conducteur du schema
removeItem ( conductor ) ;
}
/**
Enleve un champ de texte independant du schema
2010-04-18 17:59:54 +00:00
@ param iti Champ de texte a enlever
2009-04-04 21:47:07 +00:00
*/
2010-04-18 17:59:54 +00:00
void Diagram : : removeIndependentTextItem ( IndependentTextItem * iti ) {
if ( ! iti | | isReadOnly ( ) ) return ;
2009-04-04 21:47:07 +00:00
// enleve le champ de texte au schema
2010-04-18 17:59:54 +00:00
removeItem ( iti ) ;
2009-04-04 21:47:07 +00:00
// arrete la surveillance des modifications apportees au champ de texte
disconnect (
2010-04-18 17:59:54 +00:00
iti ,
2009-04-04 21:47:07 +00:00
SIGNAL ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) ) ,
this ,
SLOT ( diagramTextChanged ( DiagramTextItem * , const QString & , const QString & ) )
) ;
}
2012-02-06 21:21:43 +00:00
void Diagram : : titleChanged ( const QString & title ) {
emit ( diagramTitleChanged ( this , title ) ) ;
}
2008-07-09 21:14:30 +00:00
/**
Gere le fait qu ' un texte du schema ait ete modifie
@ param text_item Texte modifie
@ param old_text Ancien texte
@ param new_text Nouveau texte
*/
void Diagram : : diagramTextChanged ( DiagramTextItem * text_item , const QString & old_text , const QString & new_text ) {
if ( ! text_item ) return ;
2008-07-17 22:57:50 +00:00
undo_stack - > push ( new ChangeDiagramTextCommand ( text_item , old_text , new_text ) ) ;
2008-07-09 21:14:30 +00:00
}
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
*/
void Diagram : : titleBlockTemplateRemoved ( const QString & template_name , const QString & new_template ) {
2010-12-24 23:35:40 +00:00
if ( border_and_titleblock . titleBlockTemplateName ( ) ! = template_name ) return ;
const TitleBlockTemplate * final_template = project_ - > getTemplateByName ( new_template ) ;
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 .
*/
void Diagram : : setTitleBlockTemplate ( const QString & template_name ) {
if ( ! project_ ) return ;
QString current_name = border_and_titleblock . titleBlockTemplateName ( ) ;
const TitleBlockTemplate * titleblock_template = project_ - > getTemplateByName ( template_name ) ;
border_and_titleblock . titleBlockTemplateRemoved ( current_name , titleblock_template ) ;
2012-01-23 20:36:51 +00:00
if ( template_name ! = current_name ) {
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 ) ;
foreach ( QGraphicsItem * qgi , items ( ) ) qgi - > setSelected ( true ) ;
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 ) ;
foreach ( QGraphicsItem * item , items ( ) ) item - > setSelected ( ! item - > isSelected ( ) ) ;
blockSignals ( false ) ;
emit ( selectionChanged ( ) ) ;
2007-02-25 17:53:16 +00:00
}
2007-01-28 00:53:17 +00:00
/**
@ return Le rectangle ( coordonnees par rapport a la scene ) delimitant le bord du schema
*/
2007-01-29 00:41:12 +00:00
QRectF Diagram : : border ( ) const {
2007-01-28 00:53:17 +00:00
return (
QRectF (
2007-10-10 22:35:32 +00:00
margin ,
margin ,
2010-12-20 02:45:36 +00:00
border_and_titleblock . borderWidth ( ) ,
border_and_titleblock . borderHeight ( )
2007-01-28 00:53:17 +00:00
)
) ;
}
2007-09-05 20:42:08 +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
}
/**
@ return la liste des elements de ce schema
*/
QList < CustomElement * > Diagram : : customElements ( ) const {
QList < CustomElement * > elements_list ;
foreach ( QGraphicsItem * qgi , items ( ) ) {
if ( CustomElement * elmt = qgraphicsitem_cast < CustomElement * > ( qgi ) ) {
elements_list < < elmt ;
}
}
return ( elements_list ) ;
}
2009-04-13 01:35:01 +00:00
/**
2010-05-08 21:24:43 +00:00
Initialise un deplacement d ' elements , conducteurs et champs de texte sur le
schema .
@ param driver_item Item deplace par la souris et ne necessitant donc pas
d ' etre deplace lors des appels a continueMovement .
@ see ElementsMover
2009-04-13 01:35:01 +00:00
*/
2010-05-08 21:24:43 +00:00
int Diagram : : beginMoveElements ( QGraphicsItem * driver_item ) {
return ( elements_mover_ - > beginMovement ( this , driver_item ) ) ;
2007-09-15 22:14:23 +00:00
}
2009-04-13 01:35:01 +00:00
/**
2010-05-08 21:24:43 +00:00
Prend en compte un mouvement composant un deplacement d ' elements ,
conducteurs et champs de texte
@ param movement mouvement a ajouter au deplacement en cours
@ see ElementsMover
2009-04-13 01:35:01 +00:00
*/
2010-05-08 21:24:43 +00:00
void Diagram : : continueMoveElements ( const QPointF & movement ) {
elements_mover_ - > continueMovement ( movement ) ;
2007-09-15 22:14:23 +00:00
}
2007-09-30 12:35:25 +00:00
2007-10-27 13:18:17 +00:00
/**
2010-05-08 21:24:43 +00:00
Finalise un deplacement d ' elements , conducteurs et champs de texte
@ see ElementsMover
2007-10-27 13:18:17 +00:00
*/
2010-05-08 21:24:43 +00:00
void Diagram : : endMoveElements ( ) {
elements_mover_ - > endMovement ( ) ;
2007-10-27 13:18:17 +00:00
}
2010-04-24 20:42:20 +00:00
/**
2010-05-08 21:24:43 +00:00
Initialise un deplacement d ' ElementTextItems
@ param driver_item Item deplace par la souris et ne necessitant donc pas
d ' etre deplace lors des appels a continueMovement .
@ see ElementTextsMover
2010-04-24 20:42:20 +00:00
*/
2010-05-08 21:24:43 +00:00
int Diagram : : beginMoveElementTexts ( QGraphicsItem * driver_item ) {
return ( element_texts_mover_ - > beginMovement ( this , driver_item ) ) ;
}
/**
Prend en compte un mouvement composant un deplacement d ' ElementTextItems
@ param movement mouvement a ajouter au deplacement en cours
@ see ElementTextsMover
*/
void Diagram : : continueMoveElementTexts ( const QPointF & movement ) {
element_texts_mover_ - > continueMovement ( movement ) ;
}
/**
Finalise un deplacement d ' ElementTextItems
@ see ElementTextsMover
*/
void Diagram : : endMoveElementTexts ( ) {
element_texts_mover_ - > endMovement ( ) ;
2010-04-24 20:42:20 +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
*/
bool Diagram : : usesElement ( const ElementsLocation & location ) {
foreach ( CustomElement * element , customElements ( ) ) {
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 ( ) ) ;
}
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 ) {
// decale la position pour prendre en compte les marges en haut a gauche du schema
QPointF final_pos = pos - QPointF ( margin , margin ) ;
2010-12-20 02:45:36 +00:00
// delegue le calcul au BorderTitleBlock
DiagramPosition diagram_position = border_and_titleblock . convertPosition ( final_pos ) ;
2009-05-20 21:29:17 +00:00
// embarque la position cartesienne
diagram_position . setPosition ( pos ) ;
return ( diagram_position ) ;
}
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 ) {
foreach ( QGraphicsItem * qgi , items ( ) ) {
if ( Terminal * t = qgraphicsitem_cast < Terminal * > ( qgi ) ) {
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 ;
2007-10-03 13:11:47 +00:00
foreach ( QGraphicsItem * qgi , selectedItems ( ) ) {
2007-10-03 17:02:39 +00:00
if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( qgi ) ) {
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
2010-02-11 23:35:04 +00:00
/**
@ return la liste de tous les textes selectionnes : les textes independants ,
mais aussi ceux rattaches a des conducteurs ou des elements
*/
QSet < DiagramTextItem * > Diagram : : selectedTexts ( ) const {
QSet < DiagramTextItem * > selected_texts ;
foreach ( QGraphicsItem * item , selectedItems ( ) ) {
2010-04-18 17:59:54 +00:00
if ( ConductorTextItem * cti = qgraphicsitem_cast < ConductorTextItem * > ( item ) ) {
selected_texts < < cti ;
2010-02-11 23:35:04 +00:00
} else if ( ElementTextItem * eti = qgraphicsitem_cast < ElementTextItem * > ( item ) ) {
selected_texts < < eti ;
2010-04-18 17:59:54 +00:00
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( item ) ) {
selected_texts < < iti ;
2010-02-11 23:35:04 +00:00
}
}
return ( selected_texts ) ;
}
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 {
return ( project_ ) ;
}
/**
@ param project le nouveau projet auquel ce schema appartient ou 0 s ' il
s ' agit d ' un schema independant . Indiquer 0 pour rendre ce schema independant .
*/
void Diagram : : setProject ( QETProject * project ) {
project_ = project ;
}
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 {
if ( ! project_ ) return ( - 1 ) ;
return ( project_ - > folioIndex ( this ) ) ;
}
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_ ;
}
if ( fallback_to_project & & project_ ) {
return ( project_ - > declaredQElectroTechVersion ( ) ) ;
}
return ( - 1 ) ;
}
2009-04-03 19:30:25 +00:00
/**
@ return true si le schema est en lecture seule
*/
bool Diagram : : isReadOnly ( ) const {
return ( read_only_ ) ;
}
/**
@ param read_only true pour passer le schema en lecture seule , false sinon
*/
void Diagram : : setReadOnly ( bool read_only ) {
if ( read_only_ ! = read_only ) {
read_only_ = read_only ;
emit ( readOnlyChanged ( read_only_ ) ) ;
}
}
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 ;
foreach ( QGraphicsItem * qgi , items ( ) ) {
if ( Element * e = qgraphicsitem_cast < Element * > ( qgi ) ) {
dc . elements < < e ;
2010-04-18 17:59:54 +00:00
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( qgi ) ) {
dc . textFields < < iti ;
2007-11-09 13:06:51 +00:00
} else if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( qgi ) ) {
dc . conductorsToMove < < c ;
}
}
return ( dc ) ;
}
/**
@ return le contenu selectionne du schema .
*/
DiagramContent Diagram : : selectedContent ( ) {
DiagramContent dc ;
2007-11-11 16:12:45 +00:00
2010-05-08 21:24:43 +00:00
// recupere les elements deplaces
foreach ( QGraphicsItem * item , selectedItems ( ) ) {
if ( Element * elmt = qgraphicsitem_cast < Element * > ( item ) ) {
dc . elements < < elmt ;
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( item ) ) {
dc . textFields < < iti ;
} else if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( item ) ) {
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
2007-11-11 16:12:45 +00:00
if (
! c - > terminal1 - > parentItem ( ) - > isSelected ( ) & & \
! c - > terminal2 - > parentItem ( ) - > isSelected ( )
) {
dc . otherConductors < < c ;
}
}
}
2010-05-08 21:24:43 +00:00
// pour chaque element deplace, determine les conducteurs qui seront modifies
foreach ( Element * elmt , dc . elements ) {
foreach ( Terminal * terminal , elmt - > terminals ( ) ) {
foreach ( Conductor * conductor , terminal - > conductors ( ) ) {
Terminal * other_terminal ;
if ( conductor - > terminal1 = = terminal ) {
other_terminal = conductor - > terminal2 ;
} else {
other_terminal = conductor - > terminal1 ;
}
// si les deux elements du conducteur sont deplaces
if ( dc . elements . contains ( other_terminal - > parentElement ( ) ) ) {
dc . conductorsToMove < < conductor ;
} else {
dc . conductorsToUpdate < < conductor ;
}
}
}
}
2007-11-09 13:06:51 +00:00
return ( dc ) ;
}
2009-06-16 22:37:15 +00:00
/**
@ return true s ' il est possible de tourner les elements selectionnes .
Concretement , cette methode retourne true s ' il y a des elements selectionnes
et qu ' au moins l ' un d ' entre eux peut etre pivote .
*/
bool Diagram : : canRotateSelection ( ) const {
foreach ( QGraphicsItem * qgi , selectedItems ( ) ) {
2010-04-18 17:59:54 +00:00
if ( qgraphicsitem_cast < IndependentTextItem * > ( qgi ) ) {
2009-11-29 21:56:48 +00:00
return ( true ) ;
2009-12-13 22:12:52 +00:00
} else if ( qgraphicsitem_cast < ElementTextItem * > ( qgi ) ) {
return ( true ) ;
2010-04-18 17:59:54 +00:00
} else if ( qgraphicsitem_cast < ConductorTextItem * > ( qgi ) ) {
return ( true ) ;
2009-11-29 21:56:48 +00:00
} else if ( Element * e = qgraphicsitem_cast < Element * > ( qgi ) ) {
2009-06-16 22:37:15 +00:00
// l'element est-il pivotable ?
if ( e - > orientation ( ) . current ( ) ! = e - > orientation ( ) . next ( ) ) {
return ( true ) ;
}
}
}
return ( false ) ;
}