2007-12-01 10:47:15 +00:00
/*
2015-02-20 14:56:22 +00:00
Copyright 2006 - 2015 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/>.
*/
2007-01-29 00:41:12 +00:00
# include "diagramview.h"
# include "diagram.h"
2013-11-14 10:11:22 +00:00
# include "qetgraphicsitem/customelement.h"
# include "qetgraphicsitem/ghostelement.h"
# include "qetgraphicsitem/conductor.h"
2007-09-25 23:24:36 +00:00
# include "diagramcommands.h"
2009-05-20 21:29:17 +00:00
# include "diagramposition.h"
2007-10-14 10:09:46 +00:00
# include "conductorpropertieswidget.h"
2013-11-14 10:11:22 +00:00
# include "qetgraphicsitem/conductortextitem.h"
# include "qetgraphicsitem/elementtextitem.h"
# include "qetgraphicsitem/independenttextitem.h"
# include "qetgraphicsitem/diagramimageitem.h"
2012-01-22 10:40:37 +00:00
# include "templatelocation.h"
2009-04-03 19:30:25 +00:00
# include "qetapp.h"
# include "qetproject.h"
# include "integrationmoveelementshandler.h"
2012-01-22 10:40:37 +00:00
# include "integrationmovetemplateshandler.h"
2009-04-03 19:30:25 +00:00
# include "qetdiagrameditor.h"
2009-05-01 14:41:33 +00:00
# include "qeticons.h"
2009-08-09 16:02:14 +00:00
# include "qetmessagebox.h"
2010-02-11 23:35:04 +00:00
# include "qtextorientationspinboxwidget.h"
2013-08-24 15:18:45 +00:00
# include <QGraphicsObject>
# include <QGraphicsPixmapItem>
# include <QGraphicsSceneMouseEvent>
2013-12-20 20:30:55 +00:00
# include "factory/elementfactory.h"
2014-07-19 11:42:16 +00:00
# include "diagrampropertiesdialog.h"
2014-09-24 09:38:16 +00:00
# include "dveventinterface.h"
2015-03-04 21:13:13 +00:00
# include "diagrameventaddelement.h"
2015-08-09 12:06:31 +00:00
# include "QPropertyUndoCommand/qpropertyundocommand.h"
2013-04-10 11:10:02 +00:00
2006-10-27 15:47:22 +00:00
/**
2007-09-29 12:54:01 +00:00
Constructeur
2009-11-22 16:12:22 +00:00
@ param diagram Schema a afficher ; si diagram vaut 0 , un nouveau Diagram est utilise
2008-08-10 15:07:59 +00:00
@ param parent Le QWidget parent de cette vue de schema
2006-10-27 15:47:22 +00:00
*/
2014-12-21 12:15:45 +00:00
DiagramView : : DiagramView ( Diagram * diagram , QWidget * parent ) :
QGraphicsView ( parent ) ,
scene ( diagram ) ,
2015-03-27 09:45:19 +00:00
m_event_interface ( nullptr ) ,
m_first_activation ( true )
2014-12-21 12:15:45 +00:00
{
2014-08-18 18:26:38 +00:00
grabGesture ( Qt : : PinchGesture ) ;
2008-07-17 22:57:50 +00:00
setAttribute ( Qt : : WA_DeleteOnClose , true ) ;
2006-10-27 15:47:22 +00:00
setInteractive ( true ) ;
2013-08-24 15:18:45 +00:00
2012-04-28 16:45:13 +00:00
QString whatsthis = tr (
2015-03-02 20:14:56 +00:00
" Ceci est la zone dans laquelle vous concevez vos schémas en y ajoutant "
" des éléments et en posant des conducteurs entre leurs bornes. Il est "
" également possible d'ajouter des textes indépendants. " ,
2012-04-28 16:45:13 +00:00
" \" What's this? \" tip "
) ;
setWhatsThis ( whatsthis ) ;
2007-02-17 18:59:18 +00:00
// active l'antialiasing
setRenderHint ( QPainter : : Antialiasing , true ) ;
setRenderHint ( QPainter : : TextAntialiasing , true ) ;
setRenderHint ( QPainter : : SmoothPixmapTransform , true ) ;
2009-04-03 19:30:25 +00:00
setScene ( scene ) ;
2007-09-29 09:52:35 +00:00
scene - > undoStack ( ) . setClean ( ) ;
2009-05-01 14:41:33 +00:00
setWindowIcon ( QET : : Icons : : QETLogo ) ;
2007-01-28 00:53:17 +00:00
setTransformationAnchor ( QGraphicsView : : AnchorUnderMouse ) ;
setResizeAnchor ( QGraphicsView : : AnchorUnderMouse ) ;
setAlignment ( Qt : : AlignLeft | Qt : : AlignTop ) ;
2009-04-03 19:30:25 +00:00
setSelectionMode ( ) ;
2007-03-03 23:35:14 +00:00
adjustSceneRect ( ) ;
2007-09-29 09:52:35 +00:00
updateWindowTitle ( ) ;
2007-11-02 18:04:13 +00:00
context_menu = new QMenu ( this ) ;
2009-05-01 14:41:33 +00:00
paste_here = new QAction ( QET : : Icons : : EditPaste , tr ( " Coller ici " , " context menu action " ) , this ) ;
2007-11-02 18:04:13 +00:00
connect ( paste_here , SIGNAL ( triggered ( ) ) , this , SLOT ( pasteHere ( ) ) ) ;
2014-01-06 18:21:58 +00:00
connect ( scene , SIGNAL ( showDiagram ( Diagram * ) ) , this , SIGNAL ( showDiagram ( Diagram * ) ) ) ;
2009-04-18 15:30:44 +00:00
connect ( scene , SIGNAL ( selectionChanged ( ) ) , this , SIGNAL ( selectionChanged ( ) ) ) ;
2015-03-27 09:45:19 +00:00
connect ( scene , SIGNAL ( sceneRectChanged ( QRectF ) ) , this , SLOT ( adjustSceneRect ( ) ) ) ;
2010-12-20 02:45:36 +00:00
connect ( & ( scene - > border_and_titleblock ) , SIGNAL ( diagramTitleChanged ( const QString & ) ) , this , SLOT ( updateWindowTitle ( ) ) ) ;
2013-11-29 14:42:03 +00:00
connect ( diagram , SIGNAL ( editElementRequired ( ElementsLocation ) ) , this , SIGNAL ( editElementRequired ( ElementsLocation ) ) ) ;
connect ( diagram , SIGNAL ( findElementRequired ( ElementsLocation ) ) , this , SIGNAL ( findElementRequired ( ElementsLocation ) ) ) ;
2009-04-03 19:30:25 +00:00
connect ( this , SIGNAL ( aboutToAddElement ( ) ) , this , SLOT ( addDroppedElement ( ) ) , Qt : : QueuedConnection ) ;
2012-01-22 10:40:37 +00:00
connect (
this , SIGNAL ( aboutToSetDroppedTitleBlockTemplate ( const TitleBlockTemplateLocation & ) ) ,
this , SLOT ( setDroppedTitleBlockTemplate ( const TitleBlockTemplateLocation & ) ) ,
Qt : : QueuedConnection
) ;
2011-08-22 11:17:10 +00:00
QShortcut * edit_conductor_color_shortcut = new QShortcut ( QKeySequence ( Qt : : Key_F2 ) , this ) ;
connect ( edit_conductor_color_shortcut , SIGNAL ( activated ( ) ) , this , SLOT ( editSelectedConductorColor ( ) ) ) ;
2006-10-27 15:47:22 +00:00
}
2007-04-12 03:13:13 +00:00
/**
Destructeur
*/
DiagramView : : ~ DiagramView ( ) {
}
2006-10-27 15:47:22 +00:00
/**
2009-04-18 15:30:44 +00:00
Selectionne tous les objets du schema
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : selectAll ( ) {
2009-04-18 15:30:44 +00:00
scene - > selectAll ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
2009-04-18 15:30:44 +00:00
Deslectionne tous les objets selectionnes
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : selectNothing ( ) {
2009-04-18 15:30:44 +00:00
scene - > deselectAll ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
2009-04-18 15:30:44 +00:00
Inverse l ' etat de selection de tous les objets du schema
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : selectInvert ( ) {
2009-04-18 15:30:44 +00:00
scene - > invertSelection ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
Supprime les composants selectionnes
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : deleteSelection ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2007-11-09 13:06:51 +00:00
DiagramContent removed_content = scene - > selectedContent ( ) ;
2006-10-27 15:47:22 +00:00
scene - > clearSelection ( ) ;
2007-11-09 13:06:51 +00:00
scene - > undoStack ( ) . push ( new DeleteElementsCommand ( scene , removed_content ) ) ;
2007-12-22 14:59:38 +00:00
adjustSceneRect ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
Pivote les composants selectionnes
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : rotateSelection ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2009-11-29 21:56:48 +00:00
// recupere les elements et les champs de texte a pivoter
2013-11-14 10:11:22 +00:00
QList < Element * > elements_to_rotate ;
2009-11-29 21:56:48 +00:00
QList < DiagramTextItem * > texts_to_rotate ;
2013-08-24 15:18:45 +00:00
QList < DiagramImageItem * > images_to_rotate ;
2006-10-27 15:47:22 +00:00
foreach ( QGraphicsItem * item , scene - > selectedItems ( ) ) {
2007-09-27 15:36:15 +00:00
if ( Element * e = qgraphicsitem_cast < Element * > ( item ) ) {
2013-11-14 10:11:22 +00:00
elements_to_rotate < < e ;
2010-04-18 17:59:54 +00:00
} else if ( ConductorTextItem * cti = qgraphicsitem_cast < ConductorTextItem * > ( item ) ) {
texts_to_rotate < < cti ;
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( item ) ) {
texts_to_rotate < < iti ;
2009-12-13 22:12:52 +00:00
} else if ( ElementTextItem * eti = qgraphicsitem_cast < ElementTextItem * > ( item ) ) {
// on ne pivote un texte d'element que si son parent n'est pas selectionne
if ( eti - > parentItem ( ) & & ! eti - > parentItem ( ) - > isSelected ( ) ) {
texts_to_rotate < < eti ;
}
2013-08-24 15:18:45 +00:00
} else if ( DiagramImageItem * dii = qgraphicsitem_cast < DiagramImageItem * > ( item ) ) {
images_to_rotate < < dii ;
2009-12-13 22:12:52 +00:00
}
2006-10-27 15:47:22 +00:00
}
2009-11-29 21:56:48 +00:00
// effectue les rotations s'il y a quelque chose a pivoter
2013-08-24 15:18:45 +00:00
if ( elements_to_rotate . isEmpty ( ) & & texts_to_rotate . isEmpty ( ) & & images_to_rotate . isEmpty ( ) ) return ;
scene - > undoStack ( ) . push ( new RotateElementsCommand ( elements_to_rotate , texts_to_rotate , images_to_rotate ) ) ;
2006-10-27 15:47:22 +00:00
}
2010-02-11 23:35:04 +00:00
void DiagramView : : rotateTexts ( ) {
if ( scene - > isReadOnly ( ) ) return ;
// recupere les champs de texte a orienter
QList < DiagramTextItem * > texts_to_rotate ;
foreach ( QGraphicsItem * item , scene - > selectedItems ( ) ) {
2010-04-18 17:59:54 +00:00
if ( ConductorTextItem * cti = qgraphicsitem_cast < ConductorTextItem * > ( item ) ) {
texts_to_rotate < < cti ;
} else if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( item ) ) {
texts_to_rotate < < iti ;
2010-02-11 23:35:04 +00:00
} else if ( ElementTextItem * eti = qgraphicsitem_cast < ElementTextItem * > ( item ) ) {
// ici, on pivote un texte d'element meme si son parent est selectionne
texts_to_rotate < < eti ;
}
}
// effectue les rotations s'il y a quelque chose a pivoter
if ( texts_to_rotate . isEmpty ( ) ) return ;
// demande un angle a l'utilisateur
QDialog ori_text_dialog ( diagramEditor ( ) ) ;
ori_text_dialog . setSizeGripEnabled ( false ) ;
2015-03-02 20:14:56 +00:00
# ifdef Q_OS_MAC
2010-02-11 23:35:04 +00:00
ori_text_dialog . setWindowFlags ( Qt : : Sheet ) ;
# endif
2015-03-02 20:14:56 +00:00
ori_text_dialog . setWindowTitle ( tr ( " Orienter les textes sélectionnés " , " window title " ) ) ;
2010-02-11 23:35:04 +00:00
// ori_text_dialog.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QTextOrientationSpinBoxWidget * ori_widget = QETApp : : createTextOrientationSpinBoxWidget ( ) ;
ori_widget - > setParent ( & ori_text_dialog ) ;
if ( texts_to_rotate . count ( ) = = 1 ) {
ori_widget - > setOrientation ( texts_to_rotate . at ( 0 ) - > rotationAngle ( ) ) ;
}
ori_widget - > spinBox ( ) - > selectAll ( ) ;
// boutons
QDialogButtonBox buttons ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
connect ( & buttons , SIGNAL ( accepted ( ) ) , & ori_text_dialog , SLOT ( accept ( ) ) ) ;
connect ( & buttons , SIGNAL ( rejected ( ) ) , & ori_text_dialog , SLOT ( reject ( ) ) ) ;
// ajout dans une disposition verticale
QVBoxLayout layout_v ( & ori_text_dialog ) ;
layout_v . setSizeConstraint ( QLayout : : SetFixedSize ) ;
layout_v . addWidget ( ori_widget ) ;
layout_v . addStretch ( ) ;
layout_v . addWidget ( & buttons ) ;
// si le dialogue est accepte
if ( ori_text_dialog . exec ( ) = = QDialog : : Accepted ) {
scene - > undoStack ( ) . push ( new RotateTextsCommand ( texts_to_rotate , ori_widget - > orientation ( ) ) ) ;
}
}
2006-10-27 15:47:22 +00:00
/**
2008-08-10 15:07:59 +00:00
Accepte ou refuse le drag ' n drop en fonction du type de donnees entrant
2006-10-27 15:47:22 +00:00
@ param e le QDragEnterEvent correspondant au drag ' n drop tente
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : dragEnterEvent ( QDragEnterEvent * e ) {
2009-04-03 19:30:25 +00:00
if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-element-uri " ) ) {
e - > acceptProposedAction ( ) ;
2012-01-22 10:40:37 +00:00
} else if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-titleblock-uri " ) ) {
e - > acceptProposedAction ( ) ;
2013-10-26 11:46:59 +00:00
} else if ( e - > mimeData ( ) - > hasText ( ) ) {
e - > acceptProposedAction ( ) ;
2009-04-03 19:30:25 +00:00
} else {
e - > ignore ( ) ;
}
2006-10-27 15:47:22 +00:00
}
/**
2008-08-10 15:07:59 +00:00
Gere les dragleaveevent
2006-10-27 15:47:22 +00:00
@ param e le QDragEnterEvent correspondant au drag ' n drop sortant
*/
2009-11-22 16:12:22 +00:00
void DiagramView : : dragLeaveEvent ( QDragLeaveEvent * e ) {
Q_UNUSED ( e ) ;
2007-09-25 23:24:36 +00:00
}
2006-10-27 15:47:22 +00:00
/**
2008-08-10 15:07:59 +00:00
Accepte ou refuse le drag ' n drop en fonction du type de donnees entrant
2006-10-27 15:47:22 +00:00
@ param e le QDragMoveEvent correspondant au drag ' n drop tente
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : dragMoveEvent ( QDragMoveEvent * e ) {
2006-10-27 15:47:22 +00:00
if ( e - > mimeData ( ) - > hasFormat ( " text/plain " ) ) e - > acceptProposedAction ( ) ;
else e - > ignore ( ) ;
}
/**
2012-01-22 10:40:37 +00:00
Handle the drops accepted on diagram ( elements and title block templates ) .
@ param e the QDropEvent describing the current drag ' n drop
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : dropEvent ( QDropEvent * e ) {
2012-01-22 10:40:37 +00:00
if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-element-uri " ) ) {
handleElementDrop ( e ) ;
} else if ( e - > mimeData ( ) - > hasFormat ( " application/x-qet-titleblock-uri " ) ) {
handleTitleBlockDrop ( e ) ;
2013-10-26 11:46:59 +00:00
} else if ( e - > mimeData ( ) - > hasText ( ) ) {
handleTextDrop ( e ) ;
2012-01-22 10:40:37 +00:00
}
}
/**
Handle the drop of an element .
@ param e the QDropEvent describing the current drag ' n drop
*/
void DiagramView : : handleElementDrop ( QDropEvent * e ) {
// fetch the element location from the drop event
2009-04-03 19:30:25 +00:00
QString elmt_path = e - > mimeData ( ) - > text ( ) ;
2012-01-22 10:40:37 +00:00
2009-04-03 19:30:25 +00:00
ElementsLocation location ( ElementsLocation : : locationFromString ( elmt_path ) ) ;
// verifie qu'il existe un element correspondant a cet emplacement
ElementsCollectionItem * dropped_item = QETApp : : collectionItem ( location ) ;
if ( ! dropped_item ) return ;
2015-03-04 21:13:13 +00:00
diagram ( ) - > setEventInterface ( new DiagramEventAddElement ( location , diagram ( ) , mapToScene ( e - > pos ( ) ) ) ) ;
//Set focus to the view to get event
this - > setFocus ( ) ;
2009-04-03 19:30:25 +00:00
2015-03-04 21:13:13 +00:00
// next_location_ = location;
// next_position_ = e-> pos();
2009-04-03 19:30:25 +00:00
2015-03-04 21:13:13 +00:00
// emit(aboutToAddElement());
2006-10-27 15:47:22 +00:00
}
2012-01-22 10:40:37 +00:00
/**
Handle the drop of an element .
@ param e the QDropEvent describing the current drag ' n drop
*/
void DiagramView : : handleTitleBlockDrop ( QDropEvent * e ) {
// fetch the title block template location from the drop event
TitleBlockTemplateLocation tbt_loc ;
tbt_loc . fromString ( e - > mimeData ( ) - > text ( ) ) ;
if ( tbt_loc . isValid ( ) ) {
emit ( aboutToSetDroppedTitleBlockTemplate ( tbt_loc ) ) ;
}
}
2013-10-26 11:46:59 +00:00
/**
* @ brief DiagramView : : handleTextDrop
2014-09-24 09:38:16 +00:00
* handle the drop of text
2013-10-26 11:46:59 +00:00
* @ param e the QDropEvent describing the current drag ' n drop
*/
void DiagramView : : handleTextDrop ( QDropEvent * e ) {
2014-09-24 09:38:16 +00:00
if ( scene - > isReadOnly ( ) | | ( e - > mimeData ( ) - > hasText ( ) = = false ) ) return ;
2014-10-30 13:29:58 +00:00
2014-12-14 13:06:21 +00:00
IndependentTextItem * iti = new IndependentTextItem ( e - > mimeData ( ) - > text ( ) ) ;
2014-10-30 13:29:58 +00:00
if ( e - > mimeData ( ) - > hasHtml ( ) ) {
iti - > setHtml ( e - > mimeData ( ) - > text ( ) ) ;
}
scene - > undoStack ( ) . push ( new AddItemCommand < IndependentTextItem * > ( iti , scene , mapToScene ( e - > pos ( ) ) ) ) ;
2013-10-26 11:46:59 +00:00
}
2006-10-27 15:47:22 +00:00
/**
2013-04-16 12:00:41 +00:00
Set the Diagram in visualisation mode
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : setVisualisationMode ( ) {
2006-10-27 15:47:22 +00:00
setDragMode ( ScrollHandDrag ) ;
2009-04-03 19:30:25 +00:00
applyReadOnly ( ) ;
2007-09-08 19:09:59 +00:00
setInteractive ( false ) ;
2006-10-27 15:47:22 +00:00
emit ( modeChanged ( ) ) ;
}
/**
2013-04-16 12:00:41 +00:00
Set the Diagram in Selection mode
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : setSelectionMode ( ) {
2006-10-27 15:47:22 +00:00
setDragMode ( RubberBandDrag ) ;
2007-09-08 19:09:59 +00:00
setInteractive ( true ) ;
2009-04-03 19:30:25 +00:00
applyReadOnly ( ) ;
2006-10-27 15:47:22 +00:00
emit ( modeChanged ( ) ) ;
}
/**
2015-03-29 12:15:25 +00:00
* @ brief DiagramView : : zoomIn
* Zoom in the current folio
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : zoomIn ( ) {
2015-03-29 12:15:25 +00:00
scale ( 1.15 , 1.15 ) ;
2007-09-04 18:15:41 +00:00
adjustGridToZoom ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
2015-03-29 12:15:25 +00:00
* @ brief DiagramView : : zoomOut
* Zoom out the current folio .
* If zoom - out - beyond - of - folio is true in common setting , the zoom out is infinite
* else zoom out is stopped when the entire folio is visible .
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : zoomOut ( ) {
2015-03-29 12:15:25 +00:00
if ( QETApp : : settings ( ) . value ( " diagrameditor/zoom-out-beyond-of-folio " , false ) . toBool ( ) | |
( horizontalScrollBar ( ) - > maximum ( ) | | verticalScrollBar ( ) - > maximum ( ) ) )
scale ( 0.85 , 0.85 ) ;
2007-09-04 18:15:41 +00:00
adjustGridToZoom ( ) ;
2006-10-27 15:47:22 +00:00
}
2014-08-18 18:26:38 +00:00
/**
2015-03-29 12:15:25 +00:00
* @ brief DiagramView : : zoomInSlowly
* Like zoomIn but more slowly
*/
2014-08-18 18:26:38 +00:00
void DiagramView : : zoomInSlowly ( ) {
scale ( 1.02 , 1.02 ) ;
adjustGridToZoom ( ) ;
}
/**
2015-03-29 12:15:25 +00:00
* @ brief DiagramView : : zoomOutSlowly
* Like zoomOut but more slowly
*/
2014-08-18 18:26:38 +00:00
void DiagramView : : zoomOutSlowly ( ) {
2015-03-29 12:15:25 +00:00
if ( QETApp : : settings ( ) . value ( " diagrameditor/zoom-out-beyond-of-folio " , false ) . toBool ( ) | |
( horizontalScrollBar ( ) - > maximum ( ) | | verticalScrollBar ( ) - > maximum ( ) ) )
scale ( 0.98 , 0.98 ) ;
2014-08-18 18:26:38 +00:00
adjustGridToZoom ( ) ;
}
2006-10-27 15:47:22 +00:00
/**
Agrandit ou rectrecit le schema de facon a ce que tous les elements du
schema soient visibles a l ' ecran . S ' il n ' y a aucun element sur le schema ,
le zoom est reinitialise
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : zoomFit ( ) {
2007-03-03 23:35:14 +00:00
adjustSceneRect ( ) ;
2015-03-27 09:45:19 +00:00
fitInView ( scene - > sceneRect ( ) , Qt : : KeepAspectRatio ) ;
2007-09-04 18:15:41 +00:00
adjustGridToZoom ( ) ;
2006-10-27 15:47:22 +00:00
}
2012-08-12 11:46:42 +00:00
/**
Adjust zoom to fit all elements in the view , regardless of diagram borders .
*/
void DiagramView : : zoomContent ( ) {
fitInView ( scene - > itemsBoundingRect ( ) , Qt : : KeepAspectRatio ) ;
adjustGridToZoom ( ) ;
}
2006-10-27 15:47:22 +00:00
/**
Reinitialise le zoom
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : zoomReset ( ) {
2006-10-27 15:47:22 +00:00
resetMatrix ( ) ;
2007-09-04 18:15:41 +00:00
adjustGridToZoom ( ) ;
2006-10-27 15:47:22 +00:00
}
/**
2008-08-10 15:07:59 +00:00
Copie les elements selectionnes du schema dans le presse - papier puis les supprime
2006-10-27 15:47:22 +00:00
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : cut ( ) {
copy ( ) ;
2007-11-11 16:12:45 +00:00
DiagramContent cut_content = scene - > selectedContent ( ) ;
2007-09-26 12:36:31 +00:00
scene - > clearSelection ( ) ;
2007-11-11 16:12:45 +00:00
scene - > undoStack ( ) . push ( new CutDiagramCommand ( scene , cut_content ) ) ;
2006-10-27 15:47:22 +00:00
}
/**
2008-08-10 15:07:59 +00:00
Copie les elements selectionnes du schema dans le presse - papier
2006-10-27 15:47:22 +00:00
*/
2007-09-29 12:54:01 +00:00
void DiagramView : : copy ( ) {
2006-10-27 15:47:22 +00:00
QClipboard * presse_papier = QApplication : : clipboard ( ) ;
QString contenu_presse_papier = scene - > toXml ( false ) . toString ( 4 ) ;
if ( presse_papier - > supportsSelection ( ) ) presse_papier - > setText ( contenu_presse_papier , QClipboard : : Selection ) ;
presse_papier - > setText ( contenu_presse_papier ) ;
}
/**
2007-11-02 18:04:13 +00:00
Importe les elements contenus dans le presse - papier dans le schema
@ param pos coin superieur gauche ( en coordonnees de la scene ) du rectangle
englobant le contenu colle
@ param clipboard_mode Type de presse - papier a prendre en compte
2006-10-27 15:47:22 +00:00
*/
2007-11-02 18:04:13 +00:00
void DiagramView : : paste ( const QPointF & pos , QClipboard : : Mode clipboard_mode ) {
2012-03-24 14:34:25 +00:00
if ( ! isInteractive ( ) | | scene - > isReadOnly ( ) ) return ;
2009-04-03 19:30:25 +00:00
2007-11-02 18:04:13 +00:00
QString texte_presse_papier = QApplication : : clipboard ( ) - > text ( clipboard_mode ) ;
if ( ( texte_presse_papier ) . isEmpty ( ) ) return ;
2006-10-27 15:47:22 +00:00
QDomDocument document_xml ;
if ( ! document_xml . setContent ( texte_presse_papier ) ) return ;
2007-09-26 12:36:31 +00:00
2007-11-09 13:06:51 +00:00
// objet pour recuperer le contenu ajoute au schema par le coller
DiagramContent content_pasted ;
scene - > fromXml ( document_xml , pos , false , & content_pasted ) ;
2007-09-26 12:36:31 +00:00
2007-11-02 18:04:13 +00:00
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
2007-11-09 13:06:51 +00:00
if ( content_pasted . count ( ) ) {
2007-09-26 12:36:31 +00:00
scene - > clearSelection ( ) ;
2007-11-09 13:06:51 +00:00
scene - > undoStack ( ) . push ( new PasteDiagramCommand ( scene , content_pasted ) ) ;
2007-12-22 14:59:38 +00:00
adjustSceneRect ( ) ;
2007-09-26 12:36:31 +00:00
}
2006-10-27 15:47:22 +00:00
}
2009-04-13 01:35:01 +00:00
/**
Colle le contenu du presse - papier sur le schema a la position de la souris
*/
2007-11-02 18:04:13 +00:00
void DiagramView : : pasteHere ( ) {
paste ( mapToScene ( paste_here_pos ) ) ;
}
2006-10-27 15:47:22 +00:00
/**
2015-03-24 22:21:58 +00:00
Manage the events press click :
2013-04-10 11:10:02 +00:00
* click to add an independent text field
2006-10-27 15:47:22 +00:00
*/
2007-01-29 00:41:12 +00:00
void DiagramView : : mousePressEvent ( QMouseEvent * e ) {
2014-06-07 21:03:49 +00:00
2012-03-24 14:34:25 +00:00
if ( fresh_focus_in_ ) {
switchToVisualisationModeIfNeeded ( e ) ;
fresh_focus_in_ = false ;
}
2014-03-18 16:12:51 +00:00
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > mousePressEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
2013-04-08 19:38:50 +00:00
}
2013-04-08 19:46:11 +00:00
}
2014-06-17 09:08:41 +00:00
2015-03-24 22:21:58 +00:00
//Start drag view when hold the middle button
if ( e - > button ( ) = = Qt : : MidButton )
{
rubber_band_origin = e - > pos ( ) ;
2013-05-11 18:20:26 +00:00
setCursor ( Qt : : ClosedHandCursor ) ;
2013-04-15 13:17:06 +00:00
}
2014-06-17 09:08:41 +00:00
2014-03-18 16:12:51 +00:00
else QGraphicsView : : mousePressEvent ( e ) ;
2013-04-15 13:17:06 +00:00
}
2013-05-11 18:20:26 +00:00
/**
* @ brief DiagramView : : mouseMoveEvent
* Manage the event move mouse
*/
void DiagramView : : mouseMoveEvent ( QMouseEvent * e ) {
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > mouseMoveEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
}
2015-03-24 22:21:58 +00:00
//Drag the view
if ( e - > buttons ( ) = = Qt : : MidButton )
{
QScrollBar * h = horizontalScrollBar ( ) ;
QScrollBar * v = verticalScrollBar ( ) ;
QPointF pos = rubber_band_origin - e - > pos ( ) ;
rubber_band_origin = e - > pos ( ) ;
h - > setValue ( h - > value ( ) + pos . x ( ) ) ;
v - > setValue ( v - > value ( ) + pos . y ( ) ) ;
2013-05-11 18:20:26 +00:00
}
2014-06-17 09:08:41 +00:00
2014-03-18 16:12:51 +00:00
else QGraphicsView : : mouseMoveEvent ( e ) ;
2013-05-11 18:20:26 +00:00
}
/**
* @ brief DiagramView : : mouseReleaseEvent
* Manage event release click mouse
*/
void DiagramView : : mouseReleaseEvent ( QMouseEvent * e ) {
2014-06-17 09:08:41 +00:00
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > mouseReleaseEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
2014-06-17 09:08:41 +00:00
}
2014-09-24 09:38:16 +00:00
//Stop drag view
if ( e - > button ( ) = = Qt : : MidButton ) setCursor ( Qt : : ArrowCursor ) ;
2014-06-17 09:08:41 +00:00
2014-03-18 16:12:51 +00:00
else QGraphicsView : : mouseReleaseEvent ( e ) ;
2013-05-11 18:20:26 +00:00
}
2014-08-29 02:33:38 +00:00
/**
* @ brief DiagramView : : gestures
* @ return
*/
bool DiagramView : : gestures ( ) const {
2014-09-01 14:56:11 +00:00
return ( QETApp : : settings ( ) . value ( " diagramview/gestures " , false ) . toBool ( ) ) ;
2014-08-31 09:45:01 +00:00
}
2014-08-29 02:33:38 +00:00
2007-10-04 14:30:52 +00:00
/**
2013-04-13 14:02:47 +00:00
Manage wheel event of mouse
2013-04-10 11:10:02 +00:00
@ param e QWheelEvent
2007-10-04 14:30:52 +00:00
*/
void DiagramView : : wheelEvent ( QWheelEvent * e ) {
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > wheelEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
}
2013-04-13 14:02:47 +00:00
//Zoom and scrolling
2014-08-31 09:45:01 +00:00
if ( gestures ( ) ) {
if ( e - > modifiers ( ) & Qt : : ControlModifier )
e - > delta ( ) > 0 ? zoomInSlowly ( ) : zoomOutSlowly ( ) ;
else
QGraphicsView : : wheelEvent ( e ) ;
} else {
e - > delta ( ) > 0 ? zoomIn ( ) : zoomOut ( ) ;
}
2014-08-18 18:26:38 +00:00
}
/**
* Utilise le pincement du trackpad pour zoomer
* @ brief DiagramView : : gestureEvent
* @ param event
* @ return
*/
bool DiagramView : : gestureEvent ( QGestureEvent * event ) {
if ( QGesture * gesture = event - > gesture ( Qt : : PinchGesture ) ) {
QPinchGesture * pinch = static_cast < QPinchGesture * > ( gesture ) ;
if ( pinch - > changeFlags ( ) & QPinchGesture : : ScaleFactorChanged ) {
qreal value = gesture - > property ( " scaleFactor " ) . toReal ( ) ;
if ( value > 1 ) {
zoomInSlowly ( ) ;
} else {
zoomOutSlowly ( ) ;
}
2013-04-10 11:10:02 +00:00
}
}
2014-08-18 18:26:38 +00:00
return true ;
2007-10-04 14:30:52 +00:00
}
2014-08-18 18:26:38 +00:00
2012-03-24 14:34:25 +00:00
/**
Handles " Focus in " events . Reimplemented here to store the fact the focus
was freshly acquired again using the mouse . This information is later used
in DiagramView : : mousePressEvent ( ) .
*/
void DiagramView : : focusInEvent ( QFocusEvent * e ) {
if ( e - > reason ( ) = = Qt : : MouseFocusReason ) {
fresh_focus_in_ = true ;
}
}
/**
Handles " key press " events . Reimplemented here to switch to visualisation
mode if needed .
*/
void DiagramView : : keyPressEvent ( QKeyEvent * e ) {
2014-10-10 18:16:02 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > keyPressEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
}
2012-03-24 14:34:25 +00:00
switchToVisualisationModeIfNeeded ( e ) ;
QGraphicsView : : keyPressEvent ( e ) ;
}
/**
Handles " key release " events . Reimplemented here to switch to selection
mode if needed .
*/
void DiagramView : : keyReleaseEvent ( QKeyEvent * e ) {
2014-10-10 18:16:02 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > KeyReleaseEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
}
2012-03-24 14:34:25 +00:00
switchToSelectionModeIfNeeded ( e ) ;
QGraphicsView : : keyReleaseEvent ( e ) ;
}
2006-10-27 15:47:22 +00:00
/**
2009-04-03 19:30:25 +00:00
@ return le titre de cette vue ; cela correspond au titre du schema
visualise precede de la mention " Schema " . Si le titre du schema est vide ,
la mention " Schema sans titre " est utilisee
@ see Diagram : : title ( )
2007-04-09 02:56:47 +00:00
*/
2009-04-03 19:30:25 +00:00
QString DiagramView : : title ( ) const {
QString view_title ;
QString diagram_title ( scene - > title ( ) ) ;
if ( diagram_title . isEmpty ( ) ) {
2013-03-03 17:07:05 +00:00
view_title = tr ( " Sans titre " , " what to display for untitled diagrams " ) ;
2008-02-24 20:13:45 +00:00
} else {
2013-03-03 16:59:52 +00:00
view_title = diagram_title ;
2007-02-01 01:07:26 +00:00
}
2009-04-03 19:30:25 +00:00
return ( view_title ) ;
2007-02-01 01:07:26 +00:00
}
2007-04-09 02:56:47 +00:00
/**
2014-07-19 11:42:16 +00:00
* @ brief DiagramView : : editDiagramProperties
* Edit the properties of the viewed digram
*/
2009-04-03 19:30:25 +00:00
void DiagramView : : editDiagramProperties ( ) {
2014-07-19 11:42:16 +00:00
DiagramPropertiesDialog : : diagramPropertiesDialog ( scene , diagramEditor ( ) ) ;
2007-02-01 01:07:26 +00:00
}
2007-04-09 02:56:47 +00:00
/**
2010-04-24 22:37:45 +00:00
@ return true s ' il y a des items selectionnes sur le schema , false sinon
2007-04-09 02:56:47 +00:00
*/
2007-02-01 01:07:26 +00:00
bool DiagramView : : hasSelectedItems ( ) {
return ( scene - > selectedItems ( ) . size ( ) > 0 ) ;
}
2010-04-24 22:37:45 +00:00
/**
@ return true s ' il y a des items selectionnes sur le schema et que ceux - ci
peuvent etre copies dans le presse - papier , false sinon
*/
bool DiagramView : : hasCopiableItems ( ) {
foreach ( QGraphicsItem * qgi , scene - > selectedItems ( ) ) {
if (
qgraphicsitem_cast < Element * > ( qgi ) | |
2013-08-24 15:18:45 +00:00
qgraphicsitem_cast < IndependentTextItem * > ( qgi ) | |
2014-03-02 13:49:11 +00:00
qgraphicsitem_cast < QetShapeItem * > ( qgi ) | |
2013-08-24 15:18:45 +00:00
qgraphicsitem_cast < DiagramImageItem * > ( qgi )
2010-04-24 22:37:45 +00:00
) {
return ( true ) ;
}
}
return ( false ) ;
}
/**
@ return true s ' il y a des items selectionnes sur le schema et que ceux - ci
peuvent etre supprimes , false sinon
*/
bool DiagramView : : hasDeletableItems ( ) {
foreach ( QGraphicsItem * qgi , scene - > selectedItems ( ) ) {
if (
qgraphicsitem_cast < Element * > ( qgi ) | |
qgraphicsitem_cast < Conductor * > ( qgi ) | |
2013-08-24 15:18:45 +00:00
qgraphicsitem_cast < IndependentTextItem * > ( qgi ) | |
2014-03-02 13:49:11 +00:00
qgraphicsitem_cast < QetShapeItem * > ( qgi ) | |
2013-08-24 15:18:45 +00:00
qgraphicsitem_cast < DiagramImageItem * > ( qgi )
2010-04-24 22:37:45 +00:00
) {
return ( true ) ;
}
}
return ( false ) ;
}
2007-04-09 02:56:47 +00:00
/**
Ajoute une colonne au schema .
*/
2007-02-01 01:07:26 +00:00
void DiagramView : : addColumn ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2010-12-20 02:45:36 +00:00
BorderProperties old_bp = scene - > border_and_titleblock . exportBorder ( ) ;
BorderProperties new_bp = scene - > border_and_titleblock . exportBorder ( ) ;
2008-08-15 12:46:22 +00:00
new_bp . columns_count + = 1 ;
scene - > undoStack ( ) . push ( new ChangeBorderCommand ( scene , old_bp , new_bp ) ) ;
2007-02-01 01:07:26 +00:00
}
2007-04-09 02:56:47 +00:00
/**
Enleve une colonne au schema .
*/
2007-02-01 01:07:26 +00:00
void DiagramView : : removeColumn ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2010-12-20 02:45:36 +00:00
BorderProperties old_bp = scene - > border_and_titleblock . exportBorder ( ) ;
BorderProperties new_bp = scene - > border_and_titleblock . exportBorder ( ) ;
2008-08-15 12:46:22 +00:00
new_bp . columns_count - = 1 ;
scene - > undoStack ( ) . push ( new ChangeBorderCommand ( scene , old_bp , new_bp ) ) ;
2007-02-01 01:07:26 +00:00
}
2007-02-03 02:00:18 +00:00
2007-04-09 02:56:47 +00:00
/**
Agrandit le schema en hauteur
*/
2008-08-10 15:07:59 +00:00
void DiagramView : : addRow ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2010-12-20 02:45:36 +00:00
BorderProperties old_bp = scene - > border_and_titleblock . exportBorder ( ) ;
BorderProperties new_bp = scene - > border_and_titleblock . exportBorder ( ) ;
2008-08-15 12:46:22 +00:00
new_bp . rows_count + = 1 ;
scene - > undoStack ( ) . push ( new ChangeBorderCommand ( scene , old_bp , new_bp ) ) ;
2007-03-03 23:35:14 +00:00
}
2007-04-09 02:56:47 +00:00
/**
Retrecit le schema en hauteur
*/
2008-08-10 15:07:59 +00:00
void DiagramView : : removeRow ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2010-12-20 02:45:36 +00:00
BorderProperties old_bp = scene - > border_and_titleblock . exportBorder ( ) ;
BorderProperties new_bp = scene - > border_and_titleblock . exportBorder ( ) ;
2008-08-15 12:46:22 +00:00
new_bp . rows_count - = 1 ;
scene - > undoStack ( ) . push ( new ChangeBorderCommand ( scene , old_bp , new_bp ) ) ;
2007-02-03 02:00:18 +00:00
}
2007-03-03 23:35:14 +00:00
/**
2015-03-27 09:45:19 +00:00
* @ brief DiagramView : : adjustSceneRect
* Calcul and set the area of the scene visualized by this view
* The area are diagram sceneRect * 2.
*/
void DiagramView : : adjustSceneRect ( )
{
QRectF scene_rect = scene - > sceneRect ( ) ;
scene_rect . adjust ( - Diagram : : margin , - Diagram : : margin , Diagram : : margin , Diagram : : margin ) ;
setSceneRect ( scene_rect ) ;
2007-02-03 02:00:18 +00:00
}
2007-09-04 18:15:41 +00:00
2007-10-10 17:50:26 +00:00
/**
Met a jour le titre du widget
*/
2007-09-29 09:52:35 +00:00
void DiagramView : : updateWindowTitle ( ) {
2014-01-05 15:00:46 +00:00
emit ( titleChanged ( this , title ( ) ) ) ;
2007-09-29 09:52:35 +00:00
}
2007-10-10 17:50:26 +00:00
/**
2013-04-10 11:10:02 +00:00
Enables or disables the drawing grid according to the amount of pixels display
2007-10-10 17:50:26 +00:00
*/
2007-09-04 18:15:41 +00:00
void DiagramView : : adjustGridToZoom ( ) {
QRectF viewed_scene = viewedSceneRect ( ) ;
scene - > setDisplayGrid ( viewed_scene . width ( ) < 2000 | | viewed_scene . height ( ) < 2000 ) ;
}
2007-10-10 17:50:26 +00:00
/**
@ return le rectangle du schema ( classe Diagram ) visualise par ce DiagramView
*/
2007-09-04 18:15:41 +00:00
QRectF DiagramView : : viewedSceneRect ( ) const {
// recupere la taille du widget viewport
QSize viewport_size = viewport ( ) - > size ( ) ;
// recupere la transformation viewport -> scene
QTransform view_to_scene = viewportTransform ( ) . inverted ( ) ;
// mappe le coin superieur gauche et le coin inferieur droit de la viewport sur la scene
QPointF scene_left_top = view_to_scene . map ( QPointF ( 0.0 , 0.0 ) ) ;
QPointF scene_right_bottom = view_to_scene . map ( QPointF ( viewport_size . width ( ) , viewport_size . height ( ) ) ) ;
// en deduit le rectangle visualise par la scene
return ( QRectF ( scene_left_top , scene_right_bottom ) ) ;
}
2007-10-03 13:11:47 +00:00
2009-04-03 19:30:25 +00:00
/**
Cette methode permet de determiner s ' il faut ou non integrer au projet un
element dont on connait l ' emplacement .
L ' element droppe est integre a la collection du projet :
* s ' il appartient a un autre projet , quelque soit la specification de
l ' utilisateur a ce propos ;
* s ' il appartient a la collection commune ou a la collection
personnelle ET que l ' utilisateur a autorise l ' integration automatique
des elements dans les projets .
@ param location Emplacement de l ' element
@ return true si l ' element doit etre integre , false sinon
*/
bool DiagramView : : mustIntegrateElement ( const ElementsLocation & location ) const {
// l'utilisateur a-t-il autorise l'integration automatique des elements dans les projets ?
bool auto_integration_enabled = QETApp : : settings ( ) . value ( " diagrameditor/integrate-elements " , true ) . toBool ( ) ;
// l'element appartient-il a un projet et si oui, est-ce un autre projet ?
bool elmt_from_project = location . project ( ) ;
bool elmt_from_another_project = elmt_from_project & & location . project ( ) ! = scene - > project ( ) ;
// faut-il integrer l'element ?
bool must_integrate_element = ( elmt_from_another_project | | ( auto_integration_enabled & & ! elmt_from_project ) ) ;
return ( must_integrate_element ) ;
}
2012-01-22 10:40:37 +00:00
/**
@ param tbt_loc A title block template location
@ return true if the title block template needs to be integrated in the
parent project before being applied to the current diagram , or false if it
can be directly applied
*/
bool DiagramView : : mustIntegrateTitleBlockTemplate ( const TitleBlockTemplateLocation & tbt_loc ) const {
2012-04-04 16:13:08 +00:00
// unlike elements, the integration of title block templates is mandatory, so we simply check whether the parent project of the template is also the parent project of the diagram
2012-01-22 10:40:37 +00:00
QETProject * tbt_parent_project = tbt_loc . parentProject ( ) ;
if ( ! tbt_parent_project ) return ( true ) ;
return ( tbt_parent_project ! = scene - > project ( ) ) ;
}
2009-04-03 19:30:25 +00:00
/**
@ param location Emplacement de l ' element a ajouter sur le schema
@ param pos Position ( dans les coordonnees de la vue ) a laquelle l ' element sera ajoute
*/
bool DiagramView : : addElementAtPos ( const ElementsLocation & location , const QPoint & pos ) {
// construit une instance de l'element correspondant a l'emplacement
2009-04-13 01:35:01 +00:00
int state ;
2014-12-14 13:06:21 +00:00
Element * el = ElementFactory : : Instance ( ) - > createElement ( location , 0 , & state ) ;
2009-04-13 01:35:01 +00:00
if ( state ) {
2009-04-03 19:30:25 +00:00
delete el ;
return ( false ) ;
}
2014-10-10 08:58:44 +00:00
//Add element to diagram
diagram ( ) - > undoStack ( ) . push ( new AddItemCommand < Element * > ( el , diagram ( ) , mapToScene ( pos ) ) ) ;
2009-04-03 19:30:25 +00:00
return ( true ) ;
}
/**
Fait en sorte que le schema ne soit editable que s ' il n ' est pas en lecture
seule
*/
void DiagramView : : applyReadOnly ( ) {
if ( ! scene ) return ;
bool is_writable = ! scene - > isReadOnly ( ) ;
setInteractive ( is_writable ) ;
setAcceptDrops ( is_writable ) ;
}
2009-05-17 02:13:40 +00:00
/**
Edite les proprietes des objets selectionnes
*/
void DiagramView : : editSelectionProperties ( ) {
2013-11-29 14:42:03 +00:00
// get selection
2009-05-17 02:13:40 +00:00
DiagramContent selection = scene - > selectedContent ( ) ;
2013-11-29 14:42:03 +00:00
// if selection contains nothing return
2009-05-17 02:13:40 +00:00
int selected_items_count = selection . count ( DiagramContent : : All | DiagramContent : : SelectedOnly ) ;
if ( ! selected_items_count ) return ;
2013-11-29 14:42:03 +00:00
// if selection contains one item and this item can be editable, edit this item with an appropriate dialog
if ( selected_items_count = = 1 & & selection . items ( DiagramContent : : Elements |
DiagramContent : : AnyConductor |
DiagramContent : : SelectedOnly ) . size ( ) ) {
// edit conductor
if ( selection . conductors ( DiagramContent : : AnyConductor | DiagramContent : : SelectedOnly ) . size ( ) )
2014-09-02 18:41:25 +00:00
selection . conductors ( ) . first ( ) - > editProperty ( ) ;
2013-11-29 14:42:03 +00:00
// edit element
else if ( selection . elements . size ( ) )
selection . elements . toList ( ) . first ( ) - > editProperty ( ) ;
2009-05-17 02:13:40 +00:00
}
2013-11-29 14:42:03 +00:00
else {
2015-03-02 20:14:56 +00:00
QET : : QetMessageBox : : information (
2013-11-29 14:42:03 +00:00
this ,
2015-03-02 20:14:56 +00:00
tr ( " Propriétés de la sélection " ) ,
2013-11-29 14:42:03 +00:00
QString (
tr (
2015-03-02 20:14:56 +00:00
" La sélection contient %1. " ,
2013-11-29 14:42:03 +00:00
" %1 is a sentence listing the selected objects "
)
) . arg ( selection . sentence ( DiagramContent : : All | DiagramContent : : SelectedOnly ) )
) ;
}
2009-05-17 02:13:40 +00:00
}
2011-08-22 11:17:10 +00:00
/**
Edit the color of the selected conductor ; does nothing if multiple conductors are selected
*/
void DiagramView : : editSelectedConductorColor ( ) {
// retrieve selected content
DiagramContent selection = scene - > selectedContent ( ) ;
// we'll focus on the selected conductor (we do not handle multiple conductors edition)
QList < Conductor * > selected_conductors = selection . conductors ( DiagramContent : : AnyConductor | DiagramContent : : SelectedOnly ) ;
if ( selected_conductors . count ( ) = = 1 ) {
editConductorColor ( selected_conductors . at ( 0 ) ) ;
}
}
/**
Edit the color of the given conductor
@ param edited_conductor Conductor we want to change the color
*/
2015-08-09 12:06:31 +00:00
void DiagramView : : editConductorColor ( Conductor * edited_conductor )
{
if ( scene - > isReadOnly ( ) | | ! edited_conductor ) return ;
2011-08-22 11:17:10 +00:00
2015-08-09 12:06:31 +00:00
// store the initial properties of the provided conductor
2011-08-22 11:17:10 +00:00
ConductorProperties initial_properties = edited_conductor - > properties ( ) ;
2015-08-09 12:06:31 +00:00
// prepare a color dialog showing the initial conductor color
2011-08-22 11:17:10 +00:00
QColorDialog * color_dialog = new QColorDialog ( this ) ;
color_dialog - > setWindowTitle ( tr ( " Choisir la nouvelle couleur de ce conducteur " ) ) ;
2015-03-02 20:14:56 +00:00
# ifdef Q_OS_MAC
2012-04-10 17:22:49 +00:00
color_dialog - > setWindowFlags ( Qt : : Sheet ) ;
2011-08-22 11:17:10 +00:00
# endif
color_dialog - > setCurrentColor ( initial_properties . color ) ;
2015-08-09 12:06:31 +00:00
// asks the user what color he wishes to apply
if ( color_dialog - > exec ( ) = = QDialog : : Accepted )
{
2011-08-22 11:17:10 +00:00
QColor new_color = color_dialog - > selectedColor ( ) ;
2015-08-09 12:06:31 +00:00
if ( new_color ! = initial_properties . color )
{
// the user chose a different color
QVariant old_value , new_value ;
old_value . setValue ( initial_properties ) ;
initial_properties . color = new_color ;
new_value . setValue ( initial_properties ) ;
QPropertyUndoCommand * undo = new QPropertyUndoCommand ( edited_conductor , " properties " , old_value , new_value ) ;
undo - > setText ( tr ( " Modifier les propriétés d'un conducteur " , " undo caption " ) ) ;
diagram ( ) - > undoStack ( ) . push ( undo ) ;
2011-08-22 11:17:10 +00:00
}
2007-10-03 13:11:47 +00:00
}
}
2007-10-06 18:37:21 +00:00
/**
Reinitialise le profil des conducteurs selectionnes
*/
void DiagramView : : resetConductors ( ) {
2009-04-03 19:30:25 +00:00
if ( scene - > isReadOnly ( ) ) return ;
2007-10-06 18:37:21 +00:00
// recupere les conducteurs selectionnes
QSet < Conductor * > selected_conductors = scene - > selectedConductors ( ) ;
// repere les conducteurs modifies (= profil non nul)
2007-10-22 20:27:39 +00:00
QHash < Conductor * , ConductorProfilesGroup > conductors_and_profiles ;
2007-10-06 18:37:21 +00:00
foreach ( Conductor * conductor , selected_conductors ) {
2007-10-22 20:27:39 +00:00
ConductorProfilesGroup profile = conductor - > profiles ( ) ;
if (
! profile [ Qt : : TopLeftCorner ] . isNull ( ) | | \
! profile [ Qt : : TopRightCorner ] . isNull ( ) | | \
! profile [ Qt : : BottomLeftCorner ] . isNull ( ) | | \
! profile [ Qt : : BottomRightCorner ] . isNull ( )
) {
conductors_and_profiles . insert ( conductor , profile ) ;
}
2007-10-06 18:37:21 +00:00
}
if ( conductors_and_profiles . isEmpty ( ) ) return ;
scene - > undoStack ( ) . push ( new ResetConductorCommand ( conductors_and_profiles ) ) ;
}
2007-10-12 10:58:57 +00:00
/**
Gere les evenements de la DiagramView
@ param e Evenement
*/
2015-03-27 09:45:19 +00:00
/**
* @ brief DiagramView : : event
* Manage the event on this diagram view .
* - At first activation ( QEvent : : WindowActivate or QEvent : : Show ) we zoomFit .
* - Convert event interpreted to mouse event to gesture event if needed .
* - send Shortcut to view ( by default send to QMenu / QAction )
* @ param e the event .
* @ return
*/
2007-10-12 10:58:57 +00:00
bool DiagramView : : event ( QEvent * e ) {
2015-03-27 09:45:19 +00:00
if ( Q_UNLIKELY ( m_first_activation ) ) {
if ( e - > type ( ) = = QEvent : : Show ) {
zoomFit ( ) ;
m_first_activation = false ;
}
}
2014-08-18 18:26:38 +00:00
// By default touch events are converted to mouse events. So
// after this event we will get a mouse event also but we want
// to handle touch events as gestures only. So we need this safeguard
// to block mouse events that are actually generated from touch.
if ( e - > type ( ) = = QEvent : : Gesture )
return gestureEvent ( static_cast < QGestureEvent * > ( e ) ) ;
2007-10-12 10:58:57 +00:00
// fait en sorte que les raccourcis clavier arrivent prioritairement sur la
// vue plutot que de remonter vers les QMenu / QAction
2010-03-28 16:27:48 +00:00
if (
e - > type ( ) = = QEvent : : ShortcutOverride & &
2012-03-24 14:34:25 +00:00
selectedItemHasFocus ( )
2010-03-28 16:27:48 +00:00
) {
2007-10-12 10:58:57 +00:00
e - > accept ( ) ;
return ( true ) ;
}
return ( QGraphicsView : : event ( e ) ) ;
2007-10-12 12:54:25 +00:00
}
2007-10-27 13:18:17 +00:00
2012-03-24 14:34:25 +00:00
/**
Switch to visualisation mode if the user is pressing Ctrl and Shift .
@ return true if the view was switched to visualisation mode , false
otherwise .
*/
bool DiagramView : : switchToVisualisationModeIfNeeded ( QInputEvent * e ) {
if ( isCtrlShifting ( e ) & & ! selectedItemHasFocus ( ) ) {
if ( dragMode ( ) ! = QGraphicsView : : ScrollHandDrag ) {
setVisualisationMode ( ) ;
return ( true ) ;
}
}
return ( false ) ;
}
/**
Switch back to selection mode if the user is not pressing Ctrl and Shift .
@ return true if the view was switched to selection mode , false
otherwise .
*/
bool DiagramView : : switchToSelectionModeIfNeeded ( QInputEvent * e ) {
2014-09-24 09:38:16 +00:00
if ( ! selectedItemHasFocus ( ) & & ! isCtrlShifting ( e ) ) {
2012-03-24 14:34:25 +00:00
setSelectionMode ( ) ;
return ( true ) ;
}
return ( false ) ;
}
/**
@ return true if the user is pressing Ctrl and Shift simultaneously .
*/
bool DiagramView : : isCtrlShifting ( QInputEvent * e ) {
bool result = false ;
// note: QInputEvent::modifiers and QKeyEvent::modifiers() do not return the
// same values, hence the casts
if ( e - > type ( ) = = QEvent : : KeyPress | | e - > type ( ) = = QEvent : : KeyRelease ) {
if ( QKeyEvent * ke = static_cast < QKeyEvent * > ( e ) ) {
result = ( ke - > modifiers ( ) = = ( Qt : : ControlModifier | Qt : : ShiftModifier ) ) ;
}
} else if ( e - > type ( ) > = QEvent : : MouseButtonPress & & e - > type ( ) < = QEvent : : MouseMove ) {
if ( QMouseEvent * me = static_cast < QMouseEvent * > ( e ) ) {
result = ( me - > modifiers ( ) = = ( Qt : : ControlModifier | Qt : : ShiftModifier ) ) ;
}
}
return ( result ) ;
}
/**
@ return true if there is a selected item and that item has the focus .
*/
bool DiagramView : : selectedItemHasFocus ( ) {
return (
scene - > hasFocus ( ) & &
scene - > focusItem ( ) & &
scene - > focusItem ( ) - > isSelected ( )
) ;
}
2013-09-10 14:44:25 +00:00
/**
2014-09-25 09:44:41 +00:00
* @ brief DiagramView : : editSelection
* Edit the selected item if he can be edited and if only one item is selected
2013-09-10 14:44:25 +00:00
*/
2014-09-25 09:44:41 +00:00
void DiagramView : : editSelection ( ) {
if ( scene - > isReadOnly ( ) | | scene - > selectedItems ( ) . size ( ) ! = 1 ) return ;
2013-09-10 14:44:25 +00:00
2015-02-20 18:44:44 +00:00
QGraphicsItem * item = scene - > selectedItems ( ) . first ( ) ;
//We use dynamic_cast instead of qgraphicsitem_cast for QetGraphicsItem
//because they haven't got they own type().
//Use qgraphicsitem_cast will have weird behavior for this class.
if ( IndependentTextItem * iti = qgraphicsitem_cast < IndependentTextItem * > ( item ) )
2014-09-25 09:44:41 +00:00
iti - > edit ( ) ;
2015-02-20 18:44:44 +00:00
else if ( QetGraphicsItem * qgi = dynamic_cast < QetGraphicsItem * > ( item ) )
2014-09-25 09:44:41 +00:00
qgi - > editProperty ( ) ;
2015-02-20 18:44:44 +00:00
else if ( Conductor * c = qgraphicsitem_cast < Conductor * > ( item ) )
c - > editProperty ( ) ;
2014-03-07 08:05:25 +00:00
}
2013-08-24 15:18:45 +00:00
/**
2014-09-24 09:38:16 +00:00
* @ brief DiagramView : : setEventInterface
* Set an event interface to diagram view .
*/
2015-03-02 20:14:56 +00:00
void DiagramView : : setEventInterface ( DVEventInterface * event_interface ) {
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) delete m_event_interface ;
2015-03-02 20:14:56 +00:00
m_event_interface = event_interface ;
2008-07-09 21:14:30 +00:00
}
2007-11-02 18:04:13 +00:00
/**
Gere le menu contextuel
@ param e Evenement decrivant la demande de menu contextuel
*/
void DiagramView : : contextMenuEvent ( QContextMenuEvent * e ) {
2015-03-02 20:14:56 +00:00
if ( QGraphicsItem * qgi = scene - > itemAt ( mapToScene ( e - > pos ( ) ) , transform ( ) ) ) {
2007-11-02 18:04:13 +00:00
if ( ! qgi - > isSelected ( ) ) scene - > clearSelection ( ) ;
qgi - > setSelected ( true ) ;
}
if ( QETDiagramEditor * qde = diagramEditor ( ) ) {
context_menu - > clear ( ) ;
if ( scene - > selectedItems ( ) . isEmpty ( ) ) {
paste_here_pos = e - > pos ( ) ;
2007-11-03 20:20:34 +00:00
paste_here - > setEnabled ( Diagram : : clipboardMayContainDiagram ( ) ) ;
2007-11-02 18:04:13 +00:00
context_menu - > addAction ( paste_here ) ;
context_menu - > addSeparator ( ) ;
context_menu - > addAction ( qde - > infos_diagram ) ;
2014-06-07 21:03:49 +00:00
context_menu - > addActions ( qde - > m_row_column_actions_group . actions ( ) ) ;
2007-11-02 18:04:13 +00:00
} else {
context_menu - > addAction ( qde - > cut ) ;
context_menu - > addAction ( qde - > copy ) ;
context_menu - > addSeparator ( ) ;
2009-05-17 02:13:40 +00:00
context_menu - > addAction ( qde - > conductor_reset ) ;
context_menu - > addSeparator ( ) ;
2014-06-07 21:03:49 +00:00
context_menu - > addActions ( qde - > m_selection_actions_group . actions ( ) ) ;
2007-11-02 18:04:13 +00:00
}
// affiche le menu contextuel
context_menu - > popup ( e - > globalPos ( ) ) ;
}
e - > accept ( ) ;
}
2009-04-13 01:35:01 +00:00
/**
@ return l ' editeur de schemas parent ou 0
*/
2007-11-02 18:04:13 +00:00
QETDiagramEditor * DiagramView : : diagramEditor ( ) const {
// remonte la hierarchie des widgets
QWidget * w = const_cast < DiagramView * > ( this ) ;
while ( w - > parentWidget ( ) & & ! w - > isWindow ( ) ) {
w = w - > parentWidget ( ) ;
}
// la fenetre est supposee etre un QETDiagramEditor
return ( qobject_cast < QETDiagramEditor * > ( w ) ) ;
}
2007-12-01 12:42:31 +00:00
/**
2014-09-24 09:38:16 +00:00
* @ brief DiagramView : : mouseDoubleClickEvent
* @ param e
*/
2007-12-01 12:42:31 +00:00
void DiagramView : : mouseDoubleClickEvent ( QMouseEvent * e ) {
2014-09-24 09:38:16 +00:00
if ( m_event_interface ) {
if ( m_event_interface - > mouseDoubleClickEvent ( e ) ) {
if ( m_event_interface - > isFinish ( ) ) {
emit ( itemAdded ( ) ) ;
delete m_event_interface ; m_event_interface = nullptr ;
}
return ;
}
}
2010-12-20 02:45:36 +00:00
BorderTitleBlock & bi = scene - > border_and_titleblock ;
2007-12-01 12:42:31 +00:00
2014-09-02 18:41:25 +00:00
//Get the click pos on the diagram
2007-12-01 12:42:31 +00:00
QPointF click_pos = viewportTransform ( ) . inverted ( ) . map ( e - > pos ( ) ) ;
2015-03-18 18:07:18 +00:00
if ( bi . titleBlockRect ( ) . contains ( click_pos ) | | bi . columnsRect ( ) . contains ( click_pos ) | | bi . rowsRect ( ) . contains ( click_pos ) ) {
2014-09-02 18:41:25 +00:00
e - > accept ( ) ;
2009-04-03 19:30:25 +00:00
editDiagramProperties ( ) ;
2014-09-02 18:41:25 +00:00
return ;
2007-12-01 12:42:31 +00:00
}
2014-09-02 18:41:25 +00:00
QGraphicsView : : mouseDoubleClickEvent ( e ) ;
2007-12-01 12:42:31 +00:00
}
2009-04-03 19:30:25 +00:00
/**
2012-01-22 10:40:37 +00:00
Cette methode ajoute l ' element designe par l ' emplacement location a la
2009-04-03 19:30:25 +00:00
position pos . Si necessaire , elle demande l ' integration de l ' element au
projet .
@ see mustIntegrateElement
*/
void DiagramView : : addDroppedElement ( ) {
ElementsLocation location = next_location_ ;
QPoint pos = next_position_ ;
if ( ! mustIntegrateElement ( location ) ) {
addElementAtPos ( location , pos ) ;
} else {
QString error_msg ;
IntegrationMoveElementsHandler * integ_handler = new IntegrationMoveElementsHandler ( this ) ;
QString integ_path = scene - > project ( ) - > integrateElement ( location . toString ( ) , integ_handler , error_msg ) ;
delete integ_handler ;
if ( integ_path . isEmpty ( ) ) {
2009-04-13 01:35:01 +00:00
qDebug ( ) < < " DiagramView::addDroppedElement : Impossible d'ajouter l'element. Motif : " < < qPrintable ( error_msg ) ;
2009-04-03 19:30:25 +00:00
return ;
}
addElementAtPos ( ElementsLocation : : locationFromString ( integ_path ) , pos ) ;
}
adjustSceneRect ( ) ;
}
2012-01-22 10:40:37 +00:00
/**
@ param tbt TitleBlockTemplateLocation
*/
void DiagramView : : setDroppedTitleBlockTemplate ( const TitleBlockTemplateLocation & tbt ) {
// fetch the current title block properties
TitleBlockProperties titleblock_properties_before = scene - > border_and_titleblock . exportTitleBlock ( ) ;
// check the provided template is not already applied
QETProject * tbt_parent_project = tbt . parentProject ( ) ;
if ( tbt_parent_project & & tbt_parent_project = = scene - > project ( ) ) {
// same parent project and same name = same title block template
if ( tbt . name ( ) = = titleblock_properties_before . template_name ) return ;
}
// integrate the provided template into the project if needed
QString integrated_template_name = tbt . name ( ) ;
if ( mustIntegrateTitleBlockTemplate ( tbt ) ) {
IntegrationMoveTitleBlockTemplatesHandler * handler = new IntegrationMoveTitleBlockTemplatesHandler ( this ) ;
//QString error_message;
integrated_template_name = scene - > project ( ) - > integrateTitleBlockTemplate ( tbt , handler ) ;
if ( integrated_template_name . isEmpty ( ) ) return ;
}
// apply the provided title block template
if ( titleblock_properties_before . template_name = = integrated_template_name ) return ;
TitleBlockProperties titleblock_properties_after = titleblock_properties_before ;
titleblock_properties_after . template_name = integrated_template_name ;
scene - > undoStack ( ) . push ( new ChangeTitleBlockCommand ( scene , titleblock_properties_before , titleblock_properties_after ) ) ;
adjustSceneRect ( ) ;
}